为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。
- 【TiDB 版本】:V3.0.8
- 【问题描述】:执行了一个大表与大表的join的复杂查询,查询完后内存没有释放
为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。
overview 需要哪些
top
(1)、chrome 安装这个插件https://chrome.google.com/webstore/detail/full-page-screen-capture/fdpohaocaechififmbbbbbknoalclacl
(2)、鼠标焦点置于 Dashboard 上,按 ?可显示所有快捷键,先按 d 再按 E 可将所有 Rows 的 Panels 打开,需等待一段时间待页面加载完成。
(3)、使用这个 full-page-screen-capture 插件进行截屏保存
语句是可以执行的,就是tidb 的内存回收好慢
你提的第三点确实是如果是olap 业务会很有效,但是,如果是持续的不同语句查询,内存下不来岂不是oom了
CREATE TABLE kernel_send_order
(
TenantId
int(11) DEFAULT NULL,
ShardId
int(11) DEFAULT NULL,
SendOrderId
bigint(20) NOT NULL COMMENT ‘派件订单ID’,
ExpressNumber
varchar(30) DEFAULT NULL COMMENT ‘快递单号’,
ExpressId
int(11) DEFAULT NULL COMMENT ‘快递公司ID’,
Password
varchar(80) DEFAULT NULL COMMENT ‘取件码’,
StationId
int(20) DEFAULT NULL COMMENT ‘站点ID’,
DeviceId
int(20) DEFAULT NULL COMMENT ‘设备编号 暂时不用’,
DeviceSn
varchar(255) DEFAULT NULL COMMENT ‘设备编号’,
DeviceType
int(11) DEFAULT NULL COMMENT ‘设备类型’,
CellId
int(11) DEFAULT NULL COMMENT ‘智能柜格口号 暂时不用’,
CellSn
varchar(255) DEFAULT NULL COMMENT ‘格口号’,
CellType
int(11) DEFAULT NULL COMMENT ‘格口类型:(1 小格口,2 中格口,3 大格口,4 超大格口)’,
ShelfNo
varchar(20) DEFAULT NULL COMMENT '入库人工货架编号 ',
SendOrderType
int(11) DEFAULT NULL COMMENT ‘订单类型 (参见字典SendOrderType)1智能柜 2站点派件’,
SendOrderStatus
int(11) DEFAULT NULL COMMENT ‘订单状态 1到站 2入库 3出库 没用’,
SendOrderStatusType
int(11) DEFAULT NULL COMMENT ‘订单状态类型 201货架 301已签收 … 没用’,
ArrivePayAmount
int(11) DEFAULT NULL COMMENT ‘到付金额(分)’,
InsteadPayAmount
int(11) DEFAULT NULL COMMENT ‘代付金额(分)’,
CreateTime
datetime(3) NOT NULL COMMENT ‘创建时间’,
UpdateTime
datetime(3) DEFAULT NULL COMMENT ‘修改时间’,
IsArrive
bit(1) DEFAULT NULL COMMENT ‘是否到站’,
ArriveTime
datetime DEFAULT NULL COMMENT ‘到站时间’,
ArriveOperatorId
int(11) DEFAULT NULL COMMENT ‘到站操作人’,
IsExpressIn
bit(1) DEFAULT NULL COMMENT ‘是否入库’,
ExpressInType
int(11) DEFAULT NULL COMMENT ‘入库类型 201货架 202快递柜 203外送’,
ExpressInTime
datetime DEFAULT NULL COMMENT ‘入库时间’,
ExpressInOperatorId
int(11) DEFAULT NULL COMMENT ‘入库操作人’,
IsExpressOut
bit(1) DEFAULT NULL COMMENT ‘是否出库’,
ExpressOutType
int(11) DEFAULT NULL COMMENT ‘出库类型 301已签收 302未签收 303拒收 304退回 305转址 306滞留 307延迟派送 308退件交接 309超期回收(快递柜) 310快递员退柜(快递柜) 311站点管理员退柜(快递柜)\r\
字典类型:ExpressOutType’,
ExpressOutTime
datetime DEFAULT NULL COMMENT ‘出库时间’,
ExpressOutPhoto
text DEFAULT NULL COMMENT ‘出库照片’,
ExpressOutRemark
varchar(255) DEFAULT NULL COMMENT ‘出库备注’,
ExpressOutOperatorId
int(11) DEFAULT NULL COMMENT ‘出库操作人’,
SendOrderAmount
int(11) DEFAULT NULL COMMENT ‘订单金额(派件费)’,
ExpressOutIdentityCardName
varchar(255) DEFAULT NULL COMMENT ‘出库身份证姓名’,
ExpressOutIdentityCardNo
varchar(255) DEFAULT NULL COMMENT ‘出库身份证号’,
ExpressInIdentityCardName
varchar(255) DEFAULT NULL,
ExpressInIdentityCardNo
varchar(255) DEFAULT NULL,
ExpressInPhoto
text DEFAULT NULL,
SubsidiaryCode
varchar(10) DEFAULT NULL COMMENT ‘副柜编号’,
IsLinger
bit(1) DEFAULT NULL COMMENT ‘是否滞留’,
LingerTime
datetime DEFAULT NULL COMMENT ‘滞留时间’,
LingerOperatorId
int(11) DEFAULT NULL COMMENT ‘滞留操作人’,
ArrivePayType
int(11) DEFAULT NULL COMMENT ‘到付支付方式 0无 1现金支付 2扫码支付’,
ExpressInClient
int(11) DEFAULT NULL,
CellLeaseStatus
int(11) DEFAULT NULL,
BoxLeaseStatus
int(11) DEFAULT NULL,
PRIMARY KEY (SendOrderId
,CreateTime
),
KEY CreateTime
(CreateTime
),
KEY Express
(ExpressId
),
KEY ExpressNumber
(ExpressNumber
),
KEY Device
(DeviceSn
),
KEY idxUpdateTime
(UpdateTime
),
KEY idxPwd
(Password
),
KEY idxStatus
(IsExpressIn
,IsExpressOut
,IsLinger
),
KEY idxOprExpress
(ExpressInType
,ExpressInOperatorId
,IsExpressIn
,IsExpressOut
,ExpressOutOperatorId
,ExpressOutType
),
KEY idxLingerSms
(IsExpressIn
,ExpressInType
,IsLinger
,ExpressInOperatorId
),
KEY idxExpressInTime
(ExpressInTime
),
KEY idxLingerTime
(LingerTime
),
KEY idexExpressOutTime
(ExpressOutTime
),
KEY idxInOpr
(ExpressInOperatorId
),
KEY idxOutOpr
(ExpressOutOperatorId
),
KEY idxArriveOpr
(ArriveOperatorId
),
KEY idxStationExpress
(StationId
,IsExpressIn
,IsExpressOut
,ExpressOutType
,ExpressInType
),
KEY idxSendOrderId
(SendOrderId
),
KEY Station
(StationId
,ExpressId
),
KEY Tenant
(TenantId
),
KEY idxStationUpdate
(StationId
,UpdateTime
),
KEY idxTenantStation
(TenantId
,StationId
,ExpressId
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
PARTITION BY RANGE ( to_days(createtime
) ) (
PARTITION p0 VALUES LESS THAN (737060),
PARTITION p1 VALUES LESS THAN (737241),
PARTITION p2 VALUES LESS THAN (737303),
PARTITION p3 VALUES LESS THAN (737364),
PARTITION p4 VALUES LESS THAN (737425),
PARTITION p5 VALUES LESS THAN (737484),
PARTITION p6 VALUES LESS THAN (737545),
PARTITION p7 VALUES LESS THAN (737606),
PARTITION p8 VALUES LESS THAN (737668),
PARTITION p9 VALUES LESS THAN (737729),
PARTITION p10 VALUES LESS THAN (737790),
PARTITION p11 VALUES LESS THAN (737850),
PARTITION p12 VALUES LESS THAN (737911),
PARTITION p13 VALUES LESS THAN (737972),
PARTITION p14 VALUES LESS THAN (738034),
PARTITION p15 VALUES LESS THAN (738095),
PARTITION p16 VALUES LESS THAN (738156),
PARTITION p17 VALUES LESS THAN (738215),
PARTITION p18 VALUES LESS THAN (738276),
PARTITION p19 VALUES LESS THAN (738337),
PARTITION p20 VALUES LESS THAN (738399),
PARTITION p21 VALUES LESS THAN (738460),
PARTITION p22 VALUES LESS THAN (738521)
);
CREATE TABLE kernel_send_order_extend
(
TenantId
int(11) DEFAULT NULL,
ShardId
int(11) DEFAULT NULL,
SendOrderId
bigint(20) NOT NULL,
ReceiverName
varchar(150) DEFAULT NULL,
ReceiverAddress
varchar(200) DEFAULT NULL COMMENT ‘收件人地址’,
ReceiverPhone
varchar(20) DEFAULT NULL COMMENT ‘收件人手机’,
SenderName
varchar(20) DEFAULT NULL COMMENT ‘发件人姓名’,
SenderPhone
varchar(20) DEFAULT NULL COMMENT ‘发件人手机’,
SenderAddress
varchar(200) DEFAULT NULL COMMENT ‘发件人地址’,
Remark
varchar(100) DEFAULT NULL,
Weight
decimal(10,2) DEFAULT NULL,
Num
int(11) DEFAULT NULL,
RejectReason
varchar(100) DEFAULT NULL COMMENT ‘拒收原因 没用’,
OperatorId
int(11) DEFAULT NULL COMMENT ‘操作人Id’,
SendTime
datetime DEFAULT NULL COMMENT ‘外派时间 没用’,
ReceiveTime
datetime DEFAULT NULL COMMENT ‘签收时间 没用’,
PhotoTime
datetime DEFAULT NULL COMMENT ‘拍照时间 没用’,
PhotoURL
varchar(200) DEFAULT NULL COMMENT ‘出库照片地址 没用’,
PhotoStatus
smallint(6) DEFAULT NULL COMMENT ‘出库拍照状态:0 未拍照 1已拍照 没用’,
OrderPasswordStatus
smallint(5) unsigned zerofill DEFAULT ‘00000’ COMMENT ‘订单取件码状态:0 未下发 1 已下发成功 2 终端已成功接收’,
SmsSendStatus
int(11) DEFAULT NULL COMMENT ‘入库短信发送状态 1未发送 2已发送 3接收成功 4接收失败 5重新发送中 6重发成功 7重发失败’,
SmsSendTime
datetime DEFAULT NULL COMMENT ‘短信发送时间’,
SmsReceivedTime
datetime DEFAULT NULL COMMENT ‘短信送达时间’,
WxMsgSendStatus
int(11) DEFAULT NULL COMMENT ‘微信发送状态 1未发送 2已发送 3接收成功 4接收失败 5重新发送中 6重发成功 7重发失败’,
WxMsgSendTime
datetime DEFAULT NULL COMMENT ‘微信消息发送时间’,
createtime
datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
FirstReceiveMsgTime
datetime DEFAULT NULL COMMENT ‘通知首次送达时间’,
MsgSendStatus
int(11) NOT NULL DEFAULT ‘1’ COMMENT ‘消息(取件码)发送状态’,
VoiceSendStatus
int(11) DEFAULT NULL,
VoiceSendTime
datetime DEFAULT NULL,
PRIMARY KEY (SendOrderId
,createtime
),
KEY Tenant
(TenantId
,ShardId
),
KEY CreateTime
(createtime
),
KEY SendOrderId
(SendOrderId
),
KEY ReceiverPhone
(ReceiverPhone
),
KEY MsgSendStatus
(MsgSendStatus
),
KEY WxMsgSendStatus
(WxMsgSendStatus
),
KEY SmsSendStatus
(SmsSendStatus
),
KEY idxMsgStatus
(SmsSendStatus
,WxMsgSendStatus
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
PARTITION BY RANGE ( to_days(createtime
) ) (
PARTITION p0 VALUES LESS THAN (737060),
PARTITION p1 VALUES LESS THAN (737241),
PARTITION p2 VALUES LESS THAN (737303),
PARTITION p3 VALUES LESS THAN (737364),
PARTITION p4 VALUES LESS THAN (737425),
PARTITION p5 VALUES LESS THAN (737484),
PARTITION p6 VALUES LESS THAN (737545),
PARTITION p7 VALUES LESS THAN (737606),
PARTITION p8 VALUES LESS THAN (737668),
PARTITION p9 VALUES LESS THAN (737729),
PARTITION p10 VALUES LESS THAN (737790),
PARTITION p11 VALUES LESS THAN (737850),
PARTITION p12 VALUES LESS THAN (737911),
PARTITION p13 VALUES LESS THAN (737972),
PARTITION p14 VALUES LESS THAN (738034),
PARTITION p15 VALUES LESS THAN (738095),
PARTITION p16 VALUES LESS THAN (738156),
PARTITION p17 VALUES LESS THAN (738215),
PARTITION p18 VALUES LESS THAN (738276),
PARTITION p19 VALUES LESS THAN (738337),
PARTITION p20 VALUES LESS THAN (738399),
PARTITION p21 VALUES LESS THAN (738460),
PARTITION p22 VALUES LESS THAN (738521)
);
select s., e. from kernel_send_order s join kernel_send_order_extend e on s.SendOrderId=e.SendOrderId where s.StationId=83 and s.DeviceSn=‘637637471812’ and s.IsExpressIn=1 and s.IsExpressOut=0 and s.ExpressInType=202;
语句肯定有问题的。我现在在添加索引看下。然后我有个问题像这条语句,执行计划肯定会对kernel_send_order 这张表结算下推tikv 后获取想要的数据推送到tidb,由tidb 内存存储,同时 join 这张表由于没有赛选,所以会全表内容一起存储到tidb内存中,在进行join 是吗?
当前tidb有类似功能coprocessor cache , 结果会在 tidb 缓存,部分中间结果。 具体看实现。而且数据不能修改过,对于olap场景比较适合. 上个贴这个能关吗
3.0 的确是这样的,目前 3.0 没有 join 中间结果落盘的操作,如果这种大查询来的比较频繁,很大概率 TiDB 会 OOM。4.0 有中间结果落盘,应该会有所缓解
一条语句执行完毕后 TiDB 内存的释放速度取决于 golang runtime 的 gc 速度,如果是 AP 业务的话,在 3.0 的集群上可以试着把 TiDB 所在机器的 swap 打开,一定程度上能够缓解
TiDB 目前没有做查询结果的缓存,每次查询来了以后都会计算一次。另外你说的 coprocessor cache 还没有开发完毕,所以暂时还不能使用(这个是针对 TiKV 端的优化,对降低 TiDB Hash Join 的运行时内存帮助不大)
从执行计划来看,s 表上还可以通过更合适的索引进一步降低内存使用。另外可以把 tidb_distsql_scan_concurrency 和 tidb_hash_join_concurrency 调低,这两个分别是汇总 TiKV 数据和在 TiDB 做 Hash Join 的并发参数,调低他们也对节省内存也有帮助。
TiDB 内存的释放速度取决于 golang runtime 的 gc 速度 ,这个速度是不是基于tidb version版本对应的golang version?
通过 top 看 go 的内存不释放是符合预期, top 高可能可能是因为第一个查询执行完后有部分内存 go 没还给操作系统,可以通过 tidb 监控 server - memory usage 看“实际占用内存”( go_memstats_heap_sys_bytes{job=“tidb”} - go_memstats_heap_released_bytes{job=“tidb”})
对于你担心的内存OOM问题, 第二个查询到达需要分配的时候, 第一个运行结束这部分sql,没归还的内存还是可以被第二个查询使用的,所以不会运行第二个 top 不会导致 8 -> 16,可以下看下这篇博客 http://zenlife.tk/go-scavenge.md
gc是go lang的参数,这个不建议修改. 会对性能有影响.
开启swap 后,滚动升级会报错,是否我修改文件跳过即可?