线上负载与 ADD INDEX 相互影响测试

测试目的

测试 OLTP 场景下,ADD INDEX 与线上负载的相互影响。

测试版本、时间、地点

TiDB 版本:v3.0.1

时间:2019 年 7 月

地点:北京

测试环境

测试在 Kubernetes 集群上进行,部署了 3 个 TiDB 实例,3 个 TiKV 实例和 3 个 PD 实例。

版本信息

组件GitHash
TiDB9e4e8da3c58c65123db5f26409759fe1847529f8
TiKV4151dc8878985df191b47851d67ca21365396133
PD811ce0b9a1335d1b2a049fd97ef9e186f1c9efc1

Sysbench 版本:1.0.17

TiDB 参数配置

TiDB、TiKV 和 PD 均使用 TiDB Operator 默认配置。

集群拓扑

机器 IP部署实例
172.31.8.8Sysbench
172.31.7.69, 172.31.5.152, 172.31.11.133PD
172.31.4.172, 172.31.1.155, 172.31.9.210TiKV
172.31.7.80, 172.31.5.163, 172.31.11.123TiDB

使用 Sysbench 模拟线上负载

使用 Sysbench 向集群导入 1 张表,200 万行数据

执行如下命令导入数据:

sysbench oltp_common \ --threads=16 \ --rand-type=uniform \ --db-driver=mysql \ --mysql-db=sbtest \ --mysql-host=$tidb_host \ --mysql-port=$tidb_port \ --mysql-user=root \ prepare --tables=1 --table-size=2000000

执行如下命令测试数据:

sysbench $testname \ --threads=$threads \ --time=300000 \ --report-interval=15 \ --rand-type=uniform \ --rand-seed=$RANDOM \ --db-driver=mysql \ --mysql-db=sbtest \ --mysql-host=$tidb_host \ --mysql-port=$tidb_port \ --mysql-user=root \ run --tables=1 --table-size=2000000

测试方案 1:ADD INDEX 目标列被频繁 Update

  1. 开始 oltp_read_write 测试。
  2. 与步骤 1 同时,使用 alter table sbtest1 add index c_idx(c) 添加索引。
  3. 在步骤 2 结束,即索引添加完成时,停止步骤 1 的测试。
  4. 获取 alter table ... add index 的运行时间、sysbench 在该时间段内的平均 TPS 和 QPS 作为指标。
  5. 逐渐增大 tidb_ddl_reorg_worker_cnttidb_ddl_reorg_batch_size 两个参数的值,重复步骤 1-4。

测试结果

ADD INDEXoltp_read_write 的结果

sysbench TPSsysbench QPS
350.316806

tidb_ddl_reorg_batch_size = 32

tidb_ddl_reorg_worker_cntadd_index_durations(s)sysbench TPSsysbench QPS
1402338.46776
2266330.36001
4174288.55769
8129280.65612
1690263.55273
3254229.24583
4857230.14601

add-index-load-1-b32

tidb_ddl_reorg_batch_size = 64

tidb_ddl_reorg_worker_cntadd_index_durations(s)sysbench TPSsysbench QPS
1264269.45388
2163266.25324
4105272.55430
878262.55228
1657215.54308
3242185.23715
4845189.23794

add-index-load-1-b64

tidb_ddl_reorg_batch_size = 128

tidb_ddl_reorg_worker_cntadd_index_durations(s)sysbench TPSsysbench QPS
1171289.15779
2110274.25485
479250.65011
851246.14922
1639171.13431
3235130.82629
4835120.52425

add-index-load-1-b128

tidb_ddl_reorg_batch_size = 256

tidb_ddl_reorg_worker_cntadd_index_durations(s)sysbench TPSsysbench QPS
1145283.05659
296282.25593
456236.54735
845194.23882
1639149.32893
3236113.52268
483386.21715

add-index-load-1-b256

tidb_ddl_reorg_batch_size = 512

tidb_ddl_reorg_worker_cntadd_index_durations(s)sysbench TPSsysbench QPS
1135257.85147
278252.85053
449222.74478
836145.42904
16331092190
323372.51503
483354.21318

add-index-load-1-b512

tidb_ddl_reorg_batch_size = 1024

tidb_ddl_reorg_worker_cntadd_index_durations(s)sysbench TPSsysbench QPS
1111244.34885
278228.44573
454168.83320
839123.82475
163659.61213
324293.21835
4851115.72261

add-index-load-1-b1024

tidb_ddl_reorg_batch_size = 2048

tidb_ddl_reorg_worker_cntadd_index_durations(s)sysbench TPSsysbench QPS
1918243.34855
21160209.94194
4342185.43707
81316151.03027
1679530.5679
32113026.69547
4889327.5552

add-index-load-1-b2048

tidb_ddl_reorg_batch_size = 4096

tidb_ddl_reorg_worker_cntadd_index_durations(s)sysbench TPSsysbench QPS
13042200.04001
23022203.84076
4858195.53971
83015177.13522
16837143.82875
329421142267
4818754.21416

add-index-load-1-b4096

测试结论

ADD INDEX 的目标列正在进行较为频繁的写操作(本测试涉及列的 UPDATEINSERTDELETE),默认 ADD INDEX 配置对系统的线上负载有比较明显的影响,该影响主要来源于 ADD INDEX 与 Column Update 并发进行造成的写冲突,系统的表现反应在:

  • 随着两个参数的逐渐增大,TiKV_prewrite_latch_wait_duration 有明显的升高,造成写入变慢。
  • tidb_ddl_reorg_worker_cnttidb_ddl_reorg_batch_size 非常大时,admin show ddl 命令可以看到 DDL job 的多次重试(例如 Write conflict, txnStartTS 410327455965380624 is stale [try again later], ErrCount:38, SnapshotVersion:410327228136030220),此时 ADD INDEX 会持续非常久才能完成。

测试方案 2:ADD INDEX 目标列不涉及写入(仅查询)

  1. 开始 oltp_read_only 测试。
  2. 与步骤 1 同时,使用 alter table sbtest1 add index c_idx(c) 添加索引。
  3. 在步骤 2 结束,即索引添加完成时,停止步骤 1。
  4. 获取 alter table ... add index 的运行时间、sysbench 在该时间段内的平均 TPS 和 QPS 作为指标。
  5. 逐渐增大 tidb_ddl_reorg_worker_cnttidb_ddl_reorg_batch_size 两个参数,重复步骤 1-4。

测试结果

ADD INDEXoltp_read_only 结果

sysbench TPSsysbench QPS
550.98812.8

tidb_ddl_reorg_batch_size = 32

tidb_ddl_reorg_worker_cntadd_index_durations(s)sysbench TPSsysbench QPS
1376548.98780
2212541.58523
4135538.68549
8114536.78393
1677533.98292
3246533.48103
4846532.28074

add-index-load-2-b32

tidb_ddl_reorg_batch_size = 1024

tidb_ddl_reorg_worker_cntadd_index_durations(s)sysbench TPSsysbench QPS
191536.88316
252533.98165
440522.47947
8365107860
1633485.57704
3231467.57516
4830562.17442

add-index-load-2-b1024

tidb_ddl_reorg_batch_size = 4096

tidb_ddl_reorg_worker_cntadd_index_durations(s)sysbench TPSsysbench QPS
1103502.27823
263486.57672
452467.47516
839452.57302
1635447.27206
3230441.97057
4830440.17004

add-index-load-2-b4096

测试结论

ADD INDEX 的目标列仅有查询负载时,ADD INDEX 对负载的影响不明显。

测试方案 3:集群负载不涉及 ADD INDEX 目标列

  1. 开始 oltp_read_write 测试。
  2. 与步骤 1 同时,使用 alter table test add index pad_idx(pad) 添加索引。
  3. 在步骤 2 结束,即索引添加完成时,停止步骤 1 的测试。
  4. 获取 alter table ... add index 的运行时间、sysbench 在该时间段内的平均 TPS 和 QPS 作为指标。
  5. 逐渐增大 tidb_ddl_reorg_worker_cnttidb_ddl_reorg_batch_size 两个参数,重复步骤 1-4。

测试结果

ADD INDEXoltp_read_write 的结果

sysbench TPSsysbench QPS
350.316806

tidb_ddl_reorg_batch_size = 32

tidb_ddl_reorg_worker_cntadd_index_durations(s)sysbench TPSsysbench QPS
1372350.46892
2207344.26700
4140343.16672
8121339.16579
16763406607
3242343.16695
4842333.46454

add-index-load-3-b32

tidb_ddl_reorg_batch_size = 1024

tidb_ddl_reorg_worker_cntadd_index_durations(s)sysbench TPSsysbench QPS
194352.46794
2503326493
4453306456
836325.56324
1632312.56294
3232300.66017
4831279.55612

add-index-load-3-b1024

tidb_ddl_reorg_batch_size = 4096

tidb_ddl_reorg_worker_cntadd_index_durations(s)sysbench TPSsysbench QPS
1116325.56324
265312.56290
450300.66017
837279.55612
1634250.45365
3232220.24924
4833214.84544

add-index-load-3-b4096

测试结论

ADD INDEX 的目标列与负载无关时,ADD INDEX 对负载的影响不明显。

总结

  • ADD INDEX 的目标列被频繁更新(包含 UPDATEINSERTDELETE)时,默认配置会造成较为频繁的写冲突,使得在线负载较大;同时 ADD INDEX 也可能由于不断地重试,需要很长的时间才能完成。在本次测试中,将 tidb_ddl_reorg_worker_cnttidb_ddl_reorg_batch_size 的乘积调整为默认值的 1/32(例如 tidb_ddl_reorg_worker_cnt = 4,tidb_ddl_reorg_batch_size = 256)可以取得较好的效果。
  • ADD INDEX 的目标列仅涉及查询负载,或者与线上负载不直接相关时,可以直接使用默认配置。