- 【TiDB 版本】:3.0.18
- 【问题描述】:
压测过程中,发现有1台Tikv节点的Coprocessor线程有CPU使用率突增的情况。 导致整体集群的耗时升高,吞吐QPS下降。
目前引入了分区表、对表进行了预分区和shard row_id (SHARD_ROW_ID_BITS=4 PRE_SPLIT_REGIONS=2
) 不确定跟上述两者有没有关联。
OverView
TiDB
TiKV
TiKV Log
report_tikv.log.gz (1.3 MB)
压测过程中,发现有1台Tikv节点的Coprocessor线程有CPU使用率突增的情况。 导致整体集群的耗时升高,吞吐QPS下降。
目前引入了分区表、对表进行了预分区和shard row_id (SHARD_ROW_ID_BITS=4 PRE_SPLIT_REGIONS=2
) 不确定跟上述两者有没有关联。
OverView
TiDB
TiKV
TiKV Log
report_tikv.log.gz (1.3 MB)
另外可以在每个 tidb 节点上执行一下
select digest, avg(query_time), avg(cop_proc_avg), max(cop_proc_avg), min(cop_proc_avg), max(query_time), min(query_time), count(*), max(process_keys), min(process_keys) from slow_query group by digest order by max(process_keys) desc limit 10
查看一下是否有单个 SQL 扫描大量 key 的 SQL
感谢回复。 业务在压测,流量是符合预期的。 并且在没有这台tikv抖动的时候,集群的表现是不错的。
看起来没有选择错误索引导致的大量多余扫描,查询slow_query表的结果是下面这条SQL,是在采集统计信息吗?
select table_id, is_index, hist_id, distinct_count, version, null_count, tot_col_size, stats_ver, flag, correlation, last_analyze_pos from mysql.stats_histograms where table_id = 59;
+------------------------------------------------------------------+---------------------+-------------------------+-------------------+-------------------+--------------------+-----------------+----------+-------------------+-------------------+
| digest | avg(query_time) | avg(cop_proc_avg) | max(cop_proc_avg) | min(cop_proc_avg) | max(query_time) | min(query_time) | count(*) | max(process_keys) | min(process_keys) |
+------------------------------------------------------------------+---------------------+-------------------------+-------------------+-------------------+--------------------+-----------------+----------+-------------------+-------------------+
| ff1ba2b3cf4f7452291642f6399447979825a310ef25a78f01288580f398a3c9 | 4.124901237715329 | 0.0005523113430656937 | 0.0035 | 0 | 8.027359731 | 2.169653653 | 137 | 153 | 87 |
| 3ca4d7ad6f5453533e1ffa909632926e175a0cf57fb20e18609619188f92fb23 | 0.374638620347826 | 0.00014378848913043478 | 0.00075 | 0 | 0.627949915 | 0.300123037 | 92 | 22 | 0 |
| cb8c97359c79849d4a32b475eb14e8c4291a9f322f9cbaf24740ad0602b3c71e | 0.333819091 | 0.000376288 | 0.000376288 | 0.000376288 | 0.333819091 | 0.333819091 | 1 | 11 | 11 |
| 4ef13ef1c364f2ae589706ea4178c0196bcb9add519de2eaabcbcfa7e293dfeb | 4.399714942189788 | 0.009531000860338324 | 0.059 | 0.0035 | 10.950231194 | 0.300065368 | 34870 | 2 | 2 |
| f2181757491266add72af4701519c8f550c6b3c5b6157f9e84a41406203f601f | 0.44100111716666673 | 0.000033333333333333335 | 0.0002 | 0 | 0.800981317 | 0.303475857 | 6 | 1 | 1 |
| d603a1264aa69da6402acfa169ab29a2e42e67c9c07cc5a6bc6f99bfaa2c12f7 | 0.37549234769234324 | 0.0001068213457076567 | 0.0176 | 0 | 1.0398800559999999 | 0.300001624 | 2155 | 1 | 0 |
| 8174d31b76941ac67e4d696c6302e7467a0a6d807e1088695fb62784c4839ca0 | 0.4436913736666667 | 0 | 0 | 0 | 0.647841695 | 0.33014386 | 3 | 1 | 1 |
| cc6cec4b65beef5fd9fb1faa40c33e68061e3ca3e96e3bb93976f9a5b04471c7 | 0.3989145803503936 | 0.00006555118110236222 | 0.0006 | 0 | 0.90459624 | 0.300073032 | 254 | 1 | 0 |
| ba0f82f39f760757dbcf0bbc994981b1010cc2725fe2c2ce00350a3845882423 | 0.4001345275775157 | 0.00007289211242067086 | 0.0014 | 0 | 0.879991574 | 0.300002646 | 1103 | 1 | 0 |
| 45598eab9eddfc31f7b0f98de2b788407674ff110598a4b3852e7111d02666ed | 0.3776148601610486 | 0.00010262172284644192 | 0.0006 | 0 | 0.87830286 | 0.300407991 | 534 | 1 | 0 |
+------------------------------------------------------------------+---------------------+-------------------------+-------------------+-------------------+--------------------+-----------------+----------+-------------------+-------------------+
10 rows in set (1.33 sec)
另一个频次最高的digest,也是内部的一个查询,看起来是新建连接时候,在获取系统变量,这里的性能表现感觉也不是很好。
select HIGH_PRIORITY * from mysql.global_variables where variable_name in (‘autocommit’, ‘sql_mode’, ‘max_allowed_packet’, ‘time_zone’, ‘block_encryption_mode’, ‘wait_timeout’, ‘interactive_timeout’, ‘max_prepared_stmt_count’, ‘auto_increment_increment’, ‘auto_increment_offset’, ‘max_execution_time’, ‘innodb_lock_wait_timeout’, ‘tidb_skip_utf8_check’, ‘tidb_index_join_batch_size’, ‘tidb_index_lookup_size’, ‘tidb_index_lookup_concurrency’, ‘tidb_index_lookup_join_concurrency’, ‘tidb_index_serial_scan_concurrency’, ‘tidb_hash_join_concurrency’, ‘tidb_projection_concurrency’, ‘tidb_hashagg_partial_concurrency’, ‘tidb_hashagg_final_concurrency’, ‘tidb_backoff_lock_fast’, ‘tidb_backoff_weight’, ‘tidb_constraint_check_in_place’, ‘tidb_ddl_reorg_worker_cnt’, ‘tidb_ddl_reorg_batch_size’, ‘tidb_ddl_error_count_limit’, ‘tidb_opt_insubq_to_join_and_agg’, ‘tidb_opt_correlation_threshold’, ‘tidb_opt_correlation_exp_factor’, ‘tidb_distsql_scan_concurrency’, ‘tidb_init_chunk_size’, ‘tidb_max_chunk_size’, ‘tidb_enable_cascades_planner’, ‘tidb_retry_limit’, ‘tidb_disable_txn_auto_retry’, ‘tidb_enable_window_function’, ‘tidb_enable_table_partition’, ‘tidb_enable_fast_analyze’, ‘tidb_expensive_query_time_threshold’, ‘tidb_txn_mode’, ‘tidb_enable_stmt_summary’, ‘tidb_stmt_summary_refresh_interval’, ‘tidb_stmt_summary_history_size’, ‘tidb_max_delta_schema_count’, ‘tidb_store_limit’);
另外我好奇每次都是这台tikv的Coprocessor暴涨, 有什么特别之处?
mysql.stats_histograms 和mysql.global_variables 是否有存在热点的可能性?
看起来可能是由热点的问题
压测从业务入口, SQL相对简单,insert和update较多,select也是基于唯一键
业务是短连接,所以获取global_variables 的次数会更多一些
CREATE TABLE `oms_waybill_tidb` (
`id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '自增id',
`waybill_no` varchar(32) NOT NULL DEFAULT '' COMMENT '运单号',
`order_no` varchar(32) NOT NULL DEFAULT '' COMMENT 'OMS内部订单号',
`pick_dept_code` varchar(32) NOT NULL DEFAULT '' COMMENT '原寄地网点编码',
`send_dept_code` varchar(32) NOT NULL DEFAULT '' COMMENT '目的地网点编码',
`version_no` int(11) NOT NULL DEFAULT '0' COMMENT '版本号,代表oms消息先后',
`send_batch_code` varchar(50) NOT NULL DEFAULT '' COMMENT '派件班次编号',
`send_tc` varchar(100) NOT NULL DEFAULT '' COMMENT '配送地点单元区域',
`pick_aoi` varchar(100) NOT NULL DEFAULT '' COMMENT '起始地AOI Code',
`send_aoi` varchar(100) NOT NULL DEFAULT '' COMMENT '目的AOI Code',
`pick_courier` varchar(30) NOT NULL DEFAULT '' COMMENT '收件实际收派员编号',
`send_distr_courier` varchar(50) NOT NULL DEFAULT '' COMMENT '派件分拣分配员工工号',
`handover_courier` varchar(30) NOT NULL DEFAULT '' COMMENT '交接收派员工号',
`deliver_courier` varchar(30) NOT NULL DEFAULT '' COMMENT '派件实际妥投收派员工号',
`fvp_info` json DEFAULT NULL COMMENT 'fvp信息(装车卸车预测的班次,线路编码,车标号,揽收信息,派送信息等)',
`oms_other` json DEFAULT NULL COMMENT 'oms传过来的其他字段(客户编码,重量,收派件员等)',
`extra` json DEFAULT NULL COMMENT '扩展字段',
`pick_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '揽收时间时间',
`unload_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '最后网点卸车时间',
`send_distr_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '派件分配小哥时间',
`handover_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '交接时间',
`deliver_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '妥投时间',
`flag` bigint(20) NOT NULL DEFAULT '0' COMMENT '标签',
`db_create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '数据库数据创建时间',
`db_update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '数据库数据更新时间',
`send_aoi_guid` varchar(100) NOT NULL DEFAULT '' COMMENT 'send_aoi_guid',
`addressee_aoi_unit` varchar(50) NOT NULL DEFAULT '' COMMENT 'AOI分配单元',
`group_loginids` json DEFAULT NULL COMMENT '小组模式成员',
`distribute_type` tinyint(4) NOT NULL DEFAULT '1' COMMENT '分拣分配方式 1、AOI区域 2、同城融通 3、分配单元',
`send_distr_type` tinyint(4) NOT NULL DEFAULT '1' COMMENT '分拣分配人匹配方式 1、AOI区域 2、分配单元',
PRIMARY KEY (`waybill_no`,`db_create_time`),
KEY `order_no` (`order_no`),
KEY `dest_tm` (`send_dept_code`,`db_update_time`),
KEY `sour_tm` (`pick_dept_code`,`db_update_time`),
KEY `idx_create_time` (`db_create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin/*!90000 SHARD_ROW_ID_BITS=4 PRE_SPLIT_REGIONS=2 */ COMMENT='OMS 运单表'
PARTITION BY RANGE ( unix_timestamp(`db_create_time`) ) (
PARTITION `p6` VALUES LESS THAN (1593532800),
PARTITION `p7` VALUES LESS THAN (1596211200),
PARTITION `p8` VALUES LESS THAN (1598889600),
PARTITION `p9` VALUES LESS THAN (1601481600)
)
CREATE TABLE `fvp_scan_gun` (
`id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '自增id',
`mainWaybillNo` varchar(32) NOT NULL DEFAULT '' COMMENT '主运单号',
`barRecordId` varchar(32) NOT NULL DEFAULT '' COMMENT '数据的唯一编码',
`waybillNo` varchar(32) NOT NULL DEFAULT '' COMMENT '操作对象号码',
`zoneCode` varchar(32) NOT NULL DEFAULT '' COMMENT '操作网点',
`opCode` varchar(32) NOT NULL DEFAULT '' COMMENT '操作码',
`opAttachInfo` varchar(32) NOT NULL DEFAULT '' COMMENT '操作附加信息',
`courierCode` varchar(32) NOT NULL DEFAULT '' COMMENT '收派员工号',
`barOprCode` varchar(32) NOT NULL DEFAULT '' COMMENT '操作员工号',
`barUploadTm` datetime DEFAULT NULL COMMENT '巴枪上传时间',
`objTypeCode` varchar(32) NOT NULL DEFAULT '' COMMENT '操作对象类型',
`contnrCode` varchar(32) NOT NULL DEFAULT '' COMMENT '容器号',
`payFlg` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否已付款标识',
`stayWhyCode` varchar(32) NOT NULL DEFAULT '' COMMENT '滞留原因代码',
`subbillPieceQty` int(11) NOT NULL DEFAULT '0' COMMENT '件数(字母件中的子件数量)',
`barUploadTypeCode` tinyint(4) NOT NULL DEFAULT '0' COMMENT '巴枪输入方法 0正常 1手工输入',
`weightQty` decimal(16,2) NOT NULL DEFAULT '0.00' COMMENT '计费重量',
`feeAmt` decimal(16,2) NOT NULL DEFAULT '0.00' COMMENT '运费',
`accountantCode` varchar(32) NOT NULL DEFAULT '' COMMENT '月结账号',
`otherInfo` varchar(64) NOT NULL DEFAULT '' COMMENT '其他信息',
`opName` varchar(32) NOT NULL DEFAULT '' COMMENT '操作名称',
`zoneTypeCode` tinyint(4) NOT NULL DEFAULT '0' COMMENT '所在地区类型',
`encryptString` varchar(32) NOT NULL DEFAULT '' COMMENT '加密串',
`barSn` varchar(32) NOT NULL DEFAULT '' COMMENT '设备号码,巴枪设备号',
`scheduleCode` varchar(32) NOT NULL DEFAULT '' COMMENT '班次',
`signTypeCode` varchar(32) NOT NULL DEFAULT '' COMMENT '未知作用',
`srcContnrCode` varchar(32) NOT NULL DEFAULT '' COMMENT '源车标号',
`phoneZone` varchar(32) NOT NULL DEFAULT '' COMMENT '电话区号',
`phone` varchar(32) NOT NULL DEFAULT '' COMMENT '电话号码',
`stopOverFlg` tinyint(4) NOT NULL DEFAULT '0' COMMENT '二程接驳 1享受 0不享受',
`batchCode` varchar(32) NOT NULL DEFAULT '' COMMENT '班次:中转班次、航空班次、报关批次、办事处班次',
`destZoneCode` varchar(32) NOT NULL DEFAULT '' COMMENT '目的地代码',
`autoloading` varchar(32) NOT NULL DEFAULT '' COMMENT '巴枪来源1:DT900 2:DTX5 3:HHT 其他未知',
`barScanTm` datetime DEFAULT NULL COMMENT '巴枪扫描时间',
`barScanDt` datetime DEFAULT NULL COMMENT '巴枪扫描日期',
`barUploadOprCode` varchar(32) NOT NULL DEFAULT '' COMMENT '巴枪上传操作员工号',
`status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '推断状态 0 推断可信 1 推断新增 2 推断可疑 3 推断临时 4 推断整车可信 10 辅助推断 ',
`ordinal` bigint(20) NOT NULL DEFAULT '0' COMMENT '序号',
`originalFlag` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否解递归后的原始巴枪轨迹',
`dataStatus` tinyint(4) NOT NULL DEFAULT '0' COMMENT '1 有效 2 无效',
`createTm` datetime DEFAULT NULL COMMENT '更新时间timestamp',
`extendAttach1` varchar(32) NOT NULL DEFAULT '' COMMENT '扩展附加信息1',
`extendAttach2` varchar(32) NOT NULL DEFAULT '' COMMENT '扩展附加信息2',
`extendAttach3` varchar(32) NOT NULL DEFAULT '' COMMENT '扩展附加信息3',
`extendAttach4` varchar(32) NOT NULL DEFAULT '' COMMENT '扩展附加信息4',
`extendAttach5` varchar(32) NOT NULL DEFAULT '' COMMENT '扩展附加信息5',
`extendAttach6` varchar(32) NOT NULL DEFAULT '' COMMENT '扩展附加信息6',
`extendAttach7` varchar(32) NOT NULL DEFAULT '' COMMENT '扩展附加信息7',
`barUploadTmStd` datetime DEFAULT NULL COMMENT '巴枪上传标准时间',
`barScanTmStd` datetime DEFAULT NULL COMMENT '巴枪操作标准时间',
`db_create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '数据库数据创建时间',
`db_update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '数据库数据更新时间',
KEY `mainWaybillNo` (`mainWaybillNo`),
KEY `fvp_scan_gun_courier_index` (`courierCode`,`zoneCode`,`batchCode`,`barScanDt`),
KEY `idx_create_time` (`db_create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin/*!90000 SHARD_ROW_ID_BITS=4 PRE_SPLIT_REGIONS=2 */ COMMENT='FVP 把枪数据'
PARTITION BY RANGE ( unix_timestamp(`db_create_time`) ) (
PARTITION `p6` VALUES LESS THAN (1593532800),
PARTITION `p7` VALUES LESS THAN (1596211200),
PARTITION `p8` VALUES LESS THAN (1598889600),
PARTITION `p9` VALUES LESS THAN (1601481600)
)
怀疑是短连接建立建立时大量获取 global variables 可能会导致,global variables 变量是存储在 TiKV 中持久化的。
是否方便做两个测试:
我怀疑的方向也在这里,看起来耗时都在internel sql上面了。
我们想办法试一下
嗯,可能还是与短链接会有关系
我尝试引入了一个具有连接池的Proxy挡在前面, 降低连接次数。目前看起来效果显著…
PingCAP团队有发现此类问题,或者相关的issue吗?