转载

MySQL案例-replication"卡死"

-------------------------------------------------------------------------------------------------短文---------------------------------------------------------------------------------------------------------------
场景:
MySQL-5.7.17, 主从架构, 业务读写分离, 只读从库的SQL线程卡在某一个事务两个多小时没有动过, IO线程正常;

结论:
给某个表加上了索引, 同步开始追赶 _(:з」∠)_
叮嘱程序要养成加主键的好习惯.....ㄟ( ▔, ▔ )ㄏ


分析:
第一反应是bug?? hang住了? 在delete几千万的表??  _(:з」∠)_;

事务提交策略是2,0, 没有开启log_slave_update, 按道理来说, 纯粹的执行事务, 不应该会卡住, 后台的一些线程也是suspending, 不是running, 好像也不是线程之间的问题, 看看relaylog里面是什么语句...

卡住的地方, 可以看到是929064394事务
MySQL案例-replication"卡死"

把relaylog转义一下, 找一下这个事务, 发现确实是很多的delete语句(内容已处理)
MySQL案例-replication"卡死"

大概统计了一下, 删除了有15W左右的数据, 然后看了一下两个多小时的时间, 同步进度如何...
MySQL案例-replication"卡死"

只从速度上看, 还得卡两个多小时, 而且之后还有类似的语句, 真要完全追上, 估计.....

于是看了眼这个tmp_log表的结构


点击(此处)折叠或打开

  1. CREATE TABLE `tmp_log` (
  2.   `s_id` int DEFAULT NULL,
  3.   `d_id` int DEFAULT NULL
  4. ) ENGINE=InnoDB

木有主键..... _(:з」∠)_

同步和主键有什么关系?
MySQL同步的时候, 会去利用主键来搜索需要修改的行(或者是一些二级索引); 

PS: 具体的资料可以参考
slave_rows_search_algorithms的官方解释, 默认的设置下, 如果没主键也没有二级索引(where条件可用), 那么就会用全表扫描来搜索数据;
摘抄部分

点击(此处)折叠或打开

  1. ? 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.
  2. ? 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.
  3. ? 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这么慢?"了, 把表加上索引吧...

"想办法"停掉了同步, 加上索引之后, 同步恢复正常了;


正文到此结束
Loading...