TiDB集群大规模删除实践
一、 背景
集群在写入了一定的时间后,是存在一些历史可以删除的数据的,为了对集群的空间释放,我和业务一并讨论和计划了待删除的表,但是在drop数据时发现集群QPS有抖动,经过排查发现触发了compaction的流控
集群配置
1集群版本:v3.0.5 2集群配置:普通SSD磁盘,128G内存,40 核cpu 3tidb21 TiDB/PD/pump/prometheus/grafana/CCS 4tidb22 TiDB/PD/pump 5tidb23 TiDB/PD/pump 6tidb01 TiKV 7tidb02 TiKV 8tidb03 TiKV 9tidb04 TiKV 10tidb05 TiKV 11tidb06 TiKV 12tidb07 TiKV 13tidb08 TiKV 14tidb09 TiKV 15tidb10 TiKV 16tidb11 TiKV 17tidb12 TiKV 18tidb13 TiKV 19tidb14 TiKV 20tidb15 TiKV 21tidb16 TiKV 22tidb17 TiKV 23tidb18 TiKV 24tidb19 TiKV 25tidb20 TiKV 26wtidb29 TiKV 27wtidb30 TiKV
二、现象
我们首先收到了如下报警:

乍一看引起的报警问题还是蛮多的,但其实看本质和操作时间点,是在集群drop大批量数据后(本案例是drop近30T数据),且到经过GC life time后触发的,因此基本定位到主要是因为drop大批量表,GC回收时导致的
看到pending_task,write_stall等报警,第一反应就是GC回收空间时占用IO导致了集群资源争用。
业务也发现积压和OPS抖动,duration升高,如下图

三、排查步骤
根据以往经验,pending_task和stall我们先看一下集群的繁忙状态:

果然,我们得到了预期的结果,集群在drop操作后爆出了server is busy,官网关于server is busy有如下相关内容:
1通过查看监控:Grafana -> TiKV -> errors 确认具体 busy 原因。在ERROR页面我们看到了server is busy 有峰值,这是 TiKV 自身的流控机制,TiKV 通过这种方式告知 tidb/ti-client 当前 TiKV 的压力过大,稍后再尝试,本案例是因为大批量drop导致的busy。 2 3同时,我们发现告警中包含了write_stall,关于write stall,一个 TiKV 包含两个 RocksDB 实例,一个用于存储 Raft 日志,位于 data/raft。另一个用于存储真正的数据,位于 data/db。通过 grep "Stalling" RocksDB 日志查看 stall 的具体原因。 4• level0 sst 太多导致 stall,可以添加参数 [rocksdb] max-sub-compactions = 2(或者 3),加快 level0 sst 往下 compact 的速度。该参数的意思是将从 level0 到 level1 的 compaction 任务最多切成 max-sub-compactions 个子任务交给多线程并发执行,这个我们现在开的是4。 5• pending compaction bytes 太多导致 stall,磁盘 I/O 能力在业务高峰跟不上写入,可以通过调大对应 Column Family (CF) 的 soft-pending-compaction-bytes-limit 和 hard-pending-compaction-bytes-limit 参数来缓解: 6• 如果 pending compaction bytes 达到该阈值,RocksDB 会放慢写入速度。默认值 64GB,[rocksdb.defaultcf] soft-pending-compaction-bytes-limit = "128GB"。 7• 如果 pending compaction bytes 达到该阈值,RocksDB 会 stop 写入,通常不太可能触发该情况,因为在达到 soft-pending-compaction-bytes-limit 的阈值之后会放慢写入速度。默认值 256GB,hard-pending-compaction-bytes-limit = "512GB"。 8• 如果磁盘 IO 能力持续跟不上写入,建议扩容。如果磁盘的吞吐达到了上限(例如 SATA SSD 的吞吐相对 NVME SSD 会低很多)导致 write stall,但是 CPU 资源又比较充足,可以尝试采用压缩率更高的压缩算法来缓解磁盘的压力,用 CPU 资源换磁盘资源。 9• 比如 default cf compaction 压力比较大,调整参数 [rocksdb.defaultcf] compression-per-level = ["no", "no", "lz4", "lz4", "lz4", "zstd", "zstd"] 改成 compression-per-level = ["no", "no", "zstd", "zstd", "zstd", "zstd", "zstd"]。
其实手册里已经写得很详细了
我们在日志中发现了如下内容:
12020/06/30-12:36:33.758200 7f3586fff700 [WARN] [db/column_family.cc:823] [write] Stalling writes because of estimated pending compaction bytes 69565867323 rate 13421767 22020/06/30-12:36:34.692021 7f359727e700 [WARN] [db/column_family.cc:823] [write] Stalling writes because of estimated pending compaction bytes 69653348050 rate 10737413 32020/06/30-12:36:34.692218 7f3597e7f700 [WARN] [db/column_family.cc:823] [write] Stalling writes because of estimated pending compaction bytes 69653348050 rate 8589930 42020/06/30-12:36:35.767359 7f35887fd700 [WARN] [db/column_family.cc:823] [write] Stalling writes because of estimated pending compaction bytes 69556916359 rate 10737412 52020/06/30-12:36:36.668152 7f35853ff700 [WARN] [db/column_family.cc:823] [write] Stalling writes because of estimated pending compaction bytes 69372668753 rate 13421765 62020/06/30-12:36:36.668323 7f3587dfc700 [WARN] [db/column_family.cc:823] [write] Stalling writes because of estimated pending compaction bytes 69372668753 rate 10737412 72020/06/30-12:36:37.834539 7f359727e700 [WARN] [db/column_family.cc:823] [write] Stalling writes because of estimated pending compaction bytes 68959655469 rate 13421765 82020/06/30-12:36:37.834705 7f35965ff700 [WARN] [db/column_family.cc:823] [write] Stalling writes because of estimated pending compaction bytes 68959655469 rate 10737412 92020/06/30-12:36:37.834780 7f35861fe700 [WARN] [db/column_family.cc:823] [write] Stalling writes because of estimated pending compaction bytes 68959655469 rate 8589929 102020/06/30-12:36:37.834845 7f3586fff700 [WARN] [db/column_family.cc:823] [write] Stalling writes because of estimated pending compaction bytes 68959655469 rate 6871943 112020/06/30-12:36:37.834912 7f3597e7f700 [WARN] [db/column_family.cc:823] [write] Stalling writes because of estimated pending compaction bytes 68959655469 rate 5497554 122020/06/30-12:36:39.076138 7f35887fd700 [WARN] [db/column_family.cc:823] [write] Stalling writes because of estimated pending compaction bytes 68881689347 rate 6871942 132020/06/30-12:36:40.659559 7f3587dfc700 [WARN] [db/column_family.cc:823] [write] Stalling writes because of estimated pending compaction bytes 68785639852 rate 8589927
这里日志很明显是因为compaction到达了阈值限制,引发流控。
监控里也能看到相关超阈值的情况:



对所有kv的进行在线配置 soft_pending_compaction_bytes_limit默认64G,hard_pending_compaction_bytes_limit默认256GB。关于这两个参数的含义,上文已经有做说明,当超过阈值时,主要是RocksDB的写入速度会受到影响。
1./tikv-ctl --host=tidb01:20160 modify-tikv-config -m kvdb -n write.soft_pending_compaction_bytes_limit -v 256GB 2./tikv-ctl --host=tidb02:20160 modify-tikv-config -m kvdb -n write.soft_pending_compaction_bytes_limit -v 256GB 3./tikv-ctl --host=tidb03:20160 modify-tikv-config -m kvdb -n write.soft_pending_compaction_bytes_limit -v 256GB 4./tikv-ctl --host=tidb04:20160 modify-tikv-config -m kvdb -n write.soft_pending_compaction_bytes_limit -v 256GB 5./tikv-ctl --host=tidb05:20160 modify-tikv-config -m kvdb -n write.soft_pending_compaction_bytes_limit -v 256GB 6./tikv-ctl --host=tidb06:20160 modify-tikv-config -m kvdb -n write.soft_pending_compaction_bytes_limit -v 256GB 7./tikv-ctl --host=tidb07:20160 modify-tikv-config -m kvdb -n write.soft_pending_compaction_bytes_limit -v 256GB 8./tikv-ctl --host=tidb08:20160 modify-tikv-config -m kvdb -n write.soft_pending_compaction_bytes_limit -v 256GB 9./tikv-ctl --host=tidb09:20160 modify-tikv-config -m kvdb -n write.soft_pending_compaction_bytes_limit -v 256GB 10./tikv-ctl --host=tidb10:20160 modify-tikv-config -m kvdb -n write.soft_pending_compaction_bytes_limit -v 256GB 11./tikv-ctl --host=tidb11:20160 modify-tikv-config -m kvdb -n write.soft_pending_compaction_bytes_limit -v 256GB 12./tikv-ctl --host=tidb12:20160 modify-tikv-config -m kvdb -n write.soft_pending_compaction_bytes_limit -v 256GB 13./tikv-ctl --host=tidb13:20160 modify-tikv-config -m kvdb -n write.soft_pending_compaction_bytes_limit -v 256GB 14./tikv-ctl --host=tidb14:20160 modify-tikv-config -m kvdb -n write.soft_pending_compaction_bytes_limit -v 256GB 15./tikv-ctl --host=tidb15:20160 modify-tikv-config -m kvdb -n write.soft_pending_compaction_bytes_limit -v 256GB 16./tikv-ctl --host=tidb16:20160 modify-tikv-config -m kvdb -n write.soft_pending_compaction_bytes_limit -v 256GB 17./tikv-ctl --host=tidb17:20160 modify-tikv-config -m kvdb -n write.soft_pending_compaction_bytes_limit -v 256GB 18./tikv-ctl --host=tidb18:20160 modify-tikv-config -m kvdb -n write.soft_pending_compaction_bytes_limit -v 256GB 19./tikv-ctl --host=tidb19:20160 modify-tikv-config -m kvdb -n write.soft_pending_compaction_bytes_limit -v 256GB 20./tikv-ctl --host=tidb20:20160 modify-tikv-config -m kvdb -n write.soft_pending_compaction_bytes_limit -v 256GB 21./tikv-ctl --host=wtidb29:20160 modify-tikv-config -m kvdb -n write.soft_pending_compaction_bytes_limit -v 256GB 22./tikv-ctl --host=wtidb30:20160 modify-tikv-config -m kvdb -n write.soft_pending_compaction_bytes_limit -v 256GB 23 24./tikv-ctl --host=tidb01:20160 modify-tikv-config -m kvdb -n write.hard_pending_compaction_bytes_limit -v 512GB 25./tikv-ctl --host=tidb02:20160 modify-tikv-config -m kvdb -n write.hard_pending_compaction_bytes_limit -v 512GB 26./tikv-ctl --host=tidb03:20160 modify-tikv-config -m kvdb -n write.hard_pending_compaction_bytes_limit -v 512GB 27./tikv-ctl --host=tidb04:20160 modify-tikv-config -m kvdb -n write.hard_pending_compaction_bytes_limit -v 512GB 28./tikv-ctl --host=tidb05:20160 modify-tikv-config -m kvdb -n write.hard_pending_compaction_bytes_limit -v 512GB 29./tikv-ctl --host=tidb06:20160 modify-tikv-config -m kvdb -n write.hard_pending_compaction_bytes_limit -v 512GB 30./tikv-ctl --host=tidb07:20160 modify-tikv-config -m kvdb -n write.hard_pending_compaction_bytes_limit -v 512GB 31./tikv-ctl --host=tidb08:20160 modify-tikv-config -m kvdb -n write.hard_pending_compaction_bytes_limit -v 512GB 32./tikv-ctl --host=tidb09:20160 modify-tikv-config -m kvdb -n write.hard_pending_compaction_bytes_limit -v 512GB 33./tikv-ctl --host=tidb10:20160 modify-tikv-config -m kvdb -n write.hard_pending_compaction_bytes_limit -v 512GB 34./tikv-ctl --host=tidb11:20160 modify-tikv-config -m kvdb -n write.hard_pending_compaction_bytes_limit -v 512GB 35./tikv-ctl --host=tidb12:20160 modify-tikv-config -m kvdb -n write.hard_pending_compaction_bytes_limit -v 512GB 36./tikv-ctl --host=tidb13:20160 modify-tikv-config -m kvdb -n write.hard_pending_compaction_bytes_limit -v 512GB 37./tikv-ctl --host=tidb14:20160 modify-tikv-config -m kvdb -n write.hard_pending_compaction_bytes_limit -v 512GB 38./tikv-ctl --host=tidb15:20160 modify-tikv-config -m kvdb -n write.hard_pending_compaction_bytes_limit -v 512GB 39./tikv-ctl --host=tidb16:20160 modify-tikv-config -m kvdb -n write.hard_pending_compaction_bytes_limit -v 512GB 40./tikv-ctl --host=tidb17:20160 modify-tikv-config -m kvdb -n write.hard_pending_compaction_bytes_limit -v 512GB 41./tikv-ctl --host=tidb18:20160 modify-tikv-config -m kvdb -n write.hard_pending_compaction_bytes_limit -v 512GB 42./tikv-ctl --host=tidb19:20160 modify-tikv-config -m kvdb -n write.hard_pending_compaction_bytes_limit -v 512GB 43./tikv-ctl --host=tidb20:20160 modify-tikv-config -m kvdb -n write.hard_pending_compaction_bytes_limit -v 512GB 44./tikv-ctl --host=wtidb29:20160 modify-tikv-config -m kvdb -n write.hard_pending_compaction_bytes_limit -v 512GB 45./tikv-ctl --host=wtidb30:20160 modify-tikv-config -m kvdb -n write.hard_pending_compaction_bytes_limit -v 512GB 46 47./tikv-ctl --host=tidb01:20160 modify-tikv-config -m kvdb -n default.soft_pending_compaction_bytes_limit -v 256GB 48./tikv-ctl --host=tidb02:20160 modify-tikv-config -m kvdb -n default.soft_pending_compaction_bytes_limit -v 256GB 49./tikv-ctl --host=tidb03:20160 modify-tikv-config -m kvdb -n default.soft_pending_compaction_bytes_limit -v 256GB 50./tikv-ctl --host=tidb04:20160 modify-tikv-config -m kvdb -n default.soft_pending_compaction_bytes_limit -v 256GB 51./tikv-ctl --host=tidb05:20160 modify-tikv-config -m kvdb -n default.soft_pending_compaction_bytes_limit -v 256GB 52./tikv-ctl --host=tidb06:20160 modify-tikv-config -m kvdb -n default.soft_pending_compaction_bytes_limit -v 256GB 53./tikv-ctl --host=tidb07:20160 modify-tikv-config -m kvdb -n default.soft_pending_compaction_bytes_limit -v 256GB 54./tikv-ctl --host=tidb08:20160 modify-tikv-config -m kvdb -n default.soft_pending_compaction_bytes_limit -v 256GB 55./tikv-ctl --host=tidb09:20160 modify-tikv-config -m kvdb -n default.soft_pending_compaction_bytes_limit -v 256GB 56./tikv-ctl --host=tidb10:20160 modify-tikv-config -m kvdb -n default.soft_pending_compaction_bytes_limit -v 256GB 57./tikv-ctl --host=tidb11:20160 modify-tikv-config -m kvdb -n default.soft_pending_compaction_bytes_limit -v 256GB 58./tikv-ctl --host=tidb12:20160 modify-tikv-config -m kvdb -n default.soft_pending_compaction_bytes_limit -v 256GB 59./tikv-ctl --host=tidb13:20160 modify-tikv-config -m kvdb -n default.soft_pending_compaction_bytes_limit -v 256GB 60./tikv-ctl --host=tidb14:20160 modify-tikv-config -m kvdb -n default.soft_pending_compaction_bytes_limit -v 256GB 61./tikv-ctl --host=tidb15:20160 modify-tikv-config -m kvdb -n default.soft_pending_compaction_bytes_limit -v 256GB 62./tikv-ctl --host=tidb16:20160 modify-tikv-config -m kvdb -n default.soft_pending_compaction_bytes_limit -v 256GB 63./tikv-ctl --host=tidb17:20160 modify-tikv-config -m kvdb -n default.soft_pending_compaction_bytes_limit -v 256GB 64./tikv-ctl --host=tidb18:20160 modify-tikv-config -m kvdb -n default.soft_pending_compaction_bytes_limit -v 256GB 65./tikv-ctl --host=tidb19:20160 modify-tikv-config -m kvdb -n default.soft_pending_compaction_bytes_limit -v 256GB 66./tikv-ctl --host=tidb20:20160 modify-tikv-config -m kvdb -n default.soft_pending_compaction_bytes_limit -v 256GB 67./tikv-ctl --host=wtidb29:20160 modify-tikv-config -m kvdb -n default.soft_pending_compaction_bytes_limit -v 256GB 68./tikv-ctl --host=wtidb30:20160 modify-tikv-config -m kvdb -n default.soft_pending_compaction_bytes_limit -v 256GB 69 70./tikv-ctl --host=tidb01:20160 modify-tikv-config -m kvdb -n default.hard_pending_compaction_bytes_limit -v 512GB 71./tikv-ctl --host=tidb02:20160 modify-tikv-config -m kvdb -n default.hard_pending_compaction_bytes_limit -v 512GB 72./tikv-ctl --host=tidb03:20160 modify-tikv-config -m kvdb -n default.hard_pending_compaction_bytes_limit -v 512GB 73./tikv-ctl --host=tidb04:20160 modify-tikv-config -m kvdb -n default.hard_pending_compaction_bytes_limit -v 512GB 74./tikv-ctl --host=tidb05:20160 modify-tikv-config -m kvdb -n default.hard_pending_compaction_bytes_limit -v 512GB 75./tikv-ctl --host=tidb06:20160 modify-tikv-config -m kvdb -n default.hard_pending_compaction_bytes_limit -v 512GB 76./tikv-ctl --host=tidb07:20160 modify-tikv-config -m kvdb -n default.hard_pending_compaction_bytes_limit -v 512GB 77./tikv-ctl --host=tidb08:20160 modify-tikv-config -m kvdb -n default.hard_pending_compaction_bytes_limit -v 512GB 78./tikv-ctl --host=tidb09:20160 modify-tikv-config -m kvdb -n default.hard_pending_compaction_bytes_limit -v 512GB 79./tikv-ctl --host=tidb10:20160 modify-tikv-config -m kvdb -n default.hard_pending_compaction_bytes_limit -v 512GB 80./tikv-ctl --host=tidb11:20160 modify-tikv-config -m kvdb -n default.hard_pending_compaction_bytes_limit -v 512GB 81./tikv-ctl --host=tidb12:20160 modify-tikv-config -m kvdb -n default.hard_pending_compaction_bytes_limit -v 512GB 82./tikv-ctl --host=tidb13:20160 modify-tikv-config -m kvdb -n default.hard_pending_compaction_bytes_limit -v 512GB 83./tikv-ctl --host=tidb14:20160 modify-tikv-config -m kvdb -n default.hard_pending_compaction_bytes_limit -v 512GB 84./tikv-ctl --host=tidb15:20160 modify-tikv-config -m kvdb -n default.hard_pending_compaction_bytes_limit -v 512GB 85./tikv-ctl --host=tidb16:20160 modify-tikv-config -m kvdb -n default.hard_pending_compaction_bytes_limit -v 512GB 86./tikv-ctl --host=tidb17:20160 modify-tikv-config -m kvdb -n default.hard_pending_compaction_bytes_limit -v 512GB 87./tikv-ctl --host=tidb18:20160 modify-tikv-config -m kvdb -n default.hard_pending_compaction_bytes_limit -v 512GB 88./tikv-ctl --host=tidb19:20160 modify-tikv-config -m kvdb -n default.hard_pending_compaction_bytes_limit -v 512GB 89./tikv-ctl --host=tidb20:20160 modify-tikv-config -m kvdb -n default.hard_pending_compaction_bytes_limit -v 512GB 90./tikv-ctl --host=wtidb29:20160 modify-tikv-config -m kvdb -n default.hard_pending_compaction_bytes_limit -v 512GB 91./tikv-ctl --host=wtidb30:20160 modify-tikv-config -m kvdb -n default.hard_pending_compaction_bytes_limit -v 512GB 9229
改完后能看到QPS稳定了,之后逐渐恢复正常,同时write stall消失:


各类 异常 报警 也 恢复 了 正常

等待compaction峰值小时后,要记得调回默认值,否则会导致compaction下不去,这时候占用空间会比较大。
四、相关知识点
开启 Region Merge
1从 TiDB v3.0 开始,Region Merge 默认开启。本案例中的集群版本是3.0.5,默认就开启了。 2开启 Region Merge 也能减少 Region 的个数。与 Region Split 相反,Region Merge 是通过调度把相邻的小 Region 合并的过程。在集群中删除数据或者执行 Drop Table/Truncate Table 语句后,可以将小 Region 甚至空 Region 进行合并以减少资源的消耗。 3通过 pd-ctl 设置以下参数即可开启 Region Merge: 4pd-ctl config set max-merge-region-size 20 5pd-ctl config set max-merge-region-keys 200000 6pd-ctl config set merge-schedule-limit 8
相关配置介绍
1调度相关的配置项。 2max-merge-region-size 3• 控制 Region Merge 的 size 上限,当 Region Size 大于指定值时 PD 不会将其与相邻的 Region 合并。 4• 默认: 20 5max-merge-region-keys 6• 控制 Region Merge 的 key 上限,当 Region key 大于指定值时 PD 不会将其与相邻的 Region 合并。 7• 默认: 200000 8split-merge-interval 9• 控制对同一个 Region 做 split 和 merge 操作的间隔,即对于新 split 的 Region 一段时间内不会被 merge。 10• 默认: 1h
加速merge操作速度
1Region Merge 速度慢也很有可能是受到 limit 配置的限制(merge-schedule-limit 及 region-schedule-limit),或者是与其他调度器产生了竞争。具体来说,可有如下处理方式: 2• 假如已经从相关 Metrics 得知系统中有大量的空 Region,这时可以通过把 max-merge-region-size 和 max-merge-region-keys 调整为较小值来加快 Merge 速度。这是因为 Merge 的过程涉及到副本迁移,所以 Merge 的 Region 越小,速度就越快。如果生成 Merge Operator 的速度很快,想进一步加快 Region Merge 过程,还可以把 patrol-region-interval 调整为 "10ms" ,这个能加快巡检 Region 的速度,但是会消耗更多的 CPU 资源。 3• 创建过大量表后(包括执行 Truncate Table 操作)又清空了。此时如果开启了 split table 特性,这些空 Region 是无法合并的,此时需要调整以下参数关闭这个特性: 4• TiKV: split-region-on-table 设为 false,该参数不支持动态修改。 5• PD: 6• key-type 设为 txn 或者 raw,该参数支持动态修改。 7• key-type 保持 table,同时设置 enable-cross-table-merge为 true,该参数支持动态修改。 8注意: 9在开启 placement-rules后,请合理切换 txn和 raw,避免无法正常解码 key。 10• 对于 3.0.4 和 2.1.16 以前的版本,Region 中 Key 的个数(approximate_keys)在特定情况下(大部分发生在删表之后)统计不准确,造成 keys 的统计值很大,无法满足 max-merge-region-keys 的约束。你可以通过调大 max-merge-region-keys 来避免这个问题。
大批量删除注意事项
1在删除大量数据的时候,建议使用 Delete * from t where xx limit 1000; 这样的方案,通过循环来删除,用 Affected Rows == 0 作为循环结束条件。 2如果一次删除的数据量非常大,这种循环的方式会越来越慢,因为每次删除都是从前向后遍历,前面的删除之后,短时间内会残留不少删除标记(后续会被 GC 清理掉),影响后面的 Delete 语句。所以可以考虑分区表和物理分表,我们这边测试发现物理分表的性能高于分区表,因此最终没有采用分区表的方式。
流控
1TiKV 在 3.0.6 版本开始支持 GC 流控,可通过配置 gc.max-write-bytes-per-sec 限制 GC worker 每秒数据写入量,降低对正常请求的影响,0 为关闭该功能。该配置可通过 tikv-ctl 动态修改: 2 3tikv-ctl --host=ip:port modify-tikv-config -m server -n gc.max_write_bytes_per_sec -v 10MB
五、总结
通过本文,希望能帮助您了解到TiDB在删除大批量数据时应该注意的问题,并提前进行规避,以及整个排查问题的思路,后续有相关大批量删除的新注意事项,也欢迎您随时提出,我会对文章进行补充,谢谢。