场景:
MySQL-5.7.17, 主从架构, 业务读写分离, 只读从库的SQL线程卡在某一个事务两个多小时没有动过, IO线程正常;
结论:
给某个表加上了索引, 同步开始追赶 _(:з」∠)_
叮嘱程序要养成加主键的好习惯.....ㄟ( ▔, ▔ )ㄏ
分析:
第一反应是bug?? hang住了? 在delete几千万的表?? _(:з」∠)_
事务提交策略是2,0, 没有开启log_slave_update, 按道理来说, 纯粹的执行事务, 不应该会卡住, 后台的一些线程也是suspending, 不是running, 好像也不是线程之间的问题, 看看relaylog里面是什么语句...
卡住的地方, 可以看到是929064394事务
把relaylog转义一下, 找一下这个事务, 发现确实是很多的delete语句(内容已处理)
大概统计了一下, 删除了有15W左右的数据, 然后看了一下两个多小时的时间, 同步进度如何...
只从速度上看, 还得卡两个多小时, 而且之后还有类似的语句, 真要完全追上, 估计.....
于是看了眼这个tmp_log表的结构
CREATE TABLE `tmp_log` (
`s_id` int DEFAULT NULL,
`d_id` int DEFAULT NULL
) ENGINE=InnoDB
木有主键..... _(:з」∠)_
同步和主键有什么关系?
MySQL同步的时候, 会去利用主键来搜索需要修改的行(或者是一些二级索引);
PS: 具体的资料可以参考slave_rows_search_algorithms的官方解释, 默认的设置下, 如果没主键也没有二级索引(where条件可用), 那么就会用全表扫描来搜索数据;
摘抄部分
- The default value is TABLE_SCAN,INDEX_SCAN, which means that all searches that can use indexes do use them, and searches without any indexes use table scans.
- To use hashing for any searches that do not use a primary or unique key, set this option to INDEX_SCAN,HASH_SCAN. Specifying INDEX_SCAN,TABLE_SCAN,HASH_SCAN has the same effect as specifying INDEX_SCAN,HASH_SCAN.
- To force hashing for all searches, set this option to TABLE_SCAN,HASH_SCAN.
PPS: 开启HASH_SCAN可能对这个场景有效;
PPPS: HASH_SCAN默认没有开, 并且开启HASH_SCAN在某些情况下会遇到bug, 升级到>=5.7.20的版本之后再考虑开HASH_SCAN;
不打算去定位"为什么从库TABLE_SCAN这么慢?"了, 把表加上索引吧...
"想办法"停掉了同步, 加上索引之后, 同步恢复正常了;