乐趣区

关于测试:测试环境治理之MYSQL索引优化篇

作者:京东物流 李光新

1 治理背景

测试环境这个话题对于开发和测试同学肯定不生疏,大家简直每天都会接触。然而说到对测试环境的印象,却鲜有好评:

•环境不稳固,测试五分钟,排查两小时

•根底建设不全,导致验证不充沛,脱漏缺点

•多人共用,节点梗塞

这些问题在行业内其实不足为奇,针对测试环境的治理,不得不引起咱们的器重。

首先咱们要清晰的认知到,测试环境治理做的不好,不光有重大的品质危险,还会十分影响迭代效率,所以这件事件很重要。那在解决它之前,咱们首先要去想想,对于测试环境咱们到底有哪些诉求?

很显著,测试环境的定位就是满足产研测的测试需要,保障产品迭代品质。所以从应用类型上,个别要撑持集成测试,零碎测试,甚至故障测试等。

而这些环境背地,其实都随同着 非功能性要求,重点体现在:

1. 从使用者角度

•想用就有,不要期待

•要低保护,高稳固

1. 从企业角度

•低成本,高效率

简略总结一下,现实的测试环境应该是:自在连贯、随时可用、互访可控。

那么事实中的测试环境又是怎么的呢?所谓“现实很饱满,事实很骨感”,对于一线测试工程师可能会发现,实在的测试环境并非这么现实。

测试同学算是测试环境的次要使用者,对测试环境的治理理当负有间接责任。不过事实中,常常看到的是,测试同学因自身测试工作较多,且测试环境治理也要求具备肯定的零碎运维能力,导致相对而言,测试同学要想做好测试环境治理,也不容易~

上面就次要给大家分享一次理论工作中的 Mysql 性能优化实际,与大家共勉~

问题点:物流中台运单 waybill.etms 利用,因为包裹表未应用索引,导致的 cpu 飚高问题

2 剖析过程

1. 不论是在日常自动化测试还是功能测试过程中,常常会遇到数据库数据落库比较慢的场景,不仅影响功能测试进度,还会影响自动化的执行时长和成功率,在此背景下,开展如下排查工作~

2. 查问两个异样运单,发现数据落库在十分钟以上,开展剖析,

3. 发现都是查问 delivery\_package\_d 抛出异样,狐疑是不是共性问题;

ybill_log.log:2022-03-17 14:42:03 ERROR com.jd.etms.waybill.worker.business.WaybillCreateFromBusiLogic handling:65 - Bus 运单 JDVE00001018005 接货平台下发解决异样
waybill_log.log-org.springframework.jdbc.UncategorizedSQLException: 
waybill_log.log-### Error querying database. Cause: com.mysql.jdbc.exceptions.MySQLTimeoutException: Statement cancelled due to timeout or client request
waybill_log.log-### The error may exist in mybatis/mysql/DeliveryPackageDDao.xml
waybill_log.log-### The error may involve defaultParameterMap
waybill_log.log-### The error occurred while setting parameters
waybill_log.log-### SQL: select   package_id,package_barcode,waybill_code,vendor_barcode,good_weigth,good_volume,remark,  create_time,update_time,yn,again_weight,weigh_User_Name,weigh_Time,pack_time,again_weight_volume,package_state,data_version,flag,expected_delivered_time,packwk_no,store_id,cky2   from delivery_package_d  where waybill_code=? and yn=1
waybill_log.log-### Cause: com.mysql.jdbc.exceptions.MySQLTimeoutException: Statement cancelled due to timeout or client request
waybill_log.log-; uncategorized SQLException for SQL []; SQL state [null]; error code [0]; Statement cancelled due to timeout or client request; nested exception is com.mysql.jdbc.exceptions.MySQLTimeoutException: Statement cancelled due to timeout or client request
waybill_log.log-    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:83) ~[spring-jdbc-3.2.18.RELEASE.jar:3.2.18.RELEASE]


4. 间接搜异样日志关键字,“接货平台下发解决异样”,确认揣测正确;

5. 排查异样 sql:

waybill_log.log-### SQL: select   package_id,package_barcode,waybill_code,vendor_barcode,good_weigth,good_volume,remark,  create_time,update_time,yn,again_weight,weigh_User_Name,weigh_Time,pack_time,again_weight_volume,package_state,data_version,flag,expected_delivered_time,packwk_no,store_id,cky2   from delivery_package_d  where waybill_code=? and yn=1
waybill_log.log-### Cause: com.mysql.jdbc.exceptions.MySQLTimeoutException: Statement cancelled due to timeout or client request


从下面 sql 中能够定位到,是查问表 delivery\_package\_d 时呈现了问题,而且是 执行超时,不是连贯超时,所以能够排除是连贯的问题,与研发沟通,狐疑是索引的问题;

6. 而后排查数据库索引:

运单数据库是分库分表的,上述包裹表 delivery\_package\_d 有两个表比另外两个表,少了两个索引,定位异样问题,而后增加索引;

ALTER TABLE waybill_0.`delivery_package_d_0` ADD INDEX `idx_package` USING BTREE(`PACKAGE_BARCODE`);
ALTER TABLE waybill_0.`delivery_package_d_0` ADD INDEX `idx_waybill_code` USING BTREE(`WAYBILL_CODE`);
ALTER TABLE waybill_0.`delivery_package_d_0` ADD INDEX `idx_waybill_code_package` USING BTREE(`WAYBILL_CODE`, `PACKAGE_BARCODE`);
ALTER TABLE waybill_0.`delivery_package_d_0` ADD PRIMARY KEY USING BTREE(`PACKAGE_ID`, `CREATE_TIME`);
ALTER TABLE waybill_0.`delivery_package_d_1` ADD INDEX `idx_waybill_code` USING BTREE(`WAYBILL_CODE`);
ALTER TABLE waybill_0.`delivery_package_d_1` ADD INDEX `idx_waybill_code_package` USING BTREE(`WAYBILL_CODE`, `PACKAGE_BARCODE`);
ALTER TABLE waybill_0.`delivery_package_d_1` ADD PRIMARY KEY USING BTREE(`PACKAGE_ID`, `CREATE_TIME`);


2. 查看数据库服务器性能,执行前后性能比照

增加索引后,自动化执行速度和成功率也有显著晋升。

3 扩大剖析

失常状况下,慢 sql 日志是存储在服务器上的,然而也能够通过 mysql 设置来通过数据库查看慢 sql。

慢日志全称为慢查问日志(Slow Query Log),次要用来记录在 MySQL 中执行工夫超过指定工夫的 SQL 语句。通过慢查问日志,能够查找出哪些语句的执行效率低,以便进行优化。

默认状况下,MySQL 并没有开启慢日志,能够通过批改 slow\_query\_log 参数来关上慢日志。与慢日志相干的参数介绍如下:

slow\_query\_log:是否启用慢查问日志,默认为 0,可设置为 0、1,1 示意开启。

slow\_query\_log_file:指定慢查问日志地位及名称,默认值为 host_name-slow.log,可指定绝对路径。

long\_query\_time:慢查问执行工夫阈值,超过此工夫会记录,默认为 10,单位为 s。

log_output:慢查问日志输入指标,默认为 file,即输入到文件。

log_timestamps:次要是管制 error log、slow log、genera log 日志文件中的显示时区,默认应用 UTC 时区,倡议改为 SYSTEM 零碎时区。

log\_queries\_not\_using\_indexes:是否记录所有未应用索引的查问语句,默认为 off。

min\_examined\_row_limit:对于查问扫描行数小于此参数的 SQL,将不会记录到慢查问日志中,默认为 0。

log\_slow\_admin_statements:慢速治理语句是否写入慢日志中,治理语句蕴含 alter table、create index 等,默认为 off 即不写入。

能够先来自定义慢 sql 时长,也就是语句执行超过多长时间会被定义为慢 sql;

show variables like 'long_query_time' // 慢 sql 查问阈值设置


而后,开启是否记录所有未应用索引的查问语句开关 log\_queries\_not\_using\_indexes,默认为 off;

SHOW variables LIKE 'log_queries_not_using_indexes' // 查问未开启索引的开关;set global log_queries_not_using_indexes = on // 开启索引监控开关;

上述开关开启之后,开始剖析异样日志;

show variables like 'log_output' - log_output 默认值是 FILE,是输入在服务器上的;set global log_output = 'TABLE' - 设置为 TABLE,能够间接从数据库查到;

通过数据库查问慢 sql:

select *from mysql.slow_log - 慢日志查问后果;

从上图中能够很显著的看出具体的慢 sql 波及的表,及查问时长,前面就能够针对具体的表进行针对性的优化了~

当然,在理论环境下,不倡议开启 log\_queries\_not\_using\_indexes 参数,此参数关上后可能导致慢日志迅速增长。

所以,针对上述剖析过程,各位操作实现后,能够再敞开慢日志输入到数据库,之后有剖析需要再开启,这样就会无效缩小对数据库的压力。

4 总结

综上,咱们每个人不仅仅是测试环境的使用者,更是测试环境的建设者,每个人都须要无意识的把负责的服务测试环境稳定性晋升上来,这样整体业务的测试环境稳定性能力有保障。

而且,对于测试环境治理和保护这条路,其实是随着解决的问题深刻,须要有很深刻的思考和解决问题能力,随之,对技术的要求也越来越高,当然,这也正是咱们的价值所在。

以上,与君共勉~

退出移动版