首页 > 数据库 > 数据库开发技术 > 为什么?双主备库只读,主库还有大量延迟
最近第一时间收到了薛晓刚老师的新书 《DBA实战手记》,感谢薛晓刚老师送书。
最近又遇到了双主的主库,备库只读,监控发现主库大量延迟的情况(不推荐配置双主)。这里用主库表示读写库,用备库表示只读库。存在问题在于主库的mi->rli->last_master_timestamp得不到更新,因为没有event进行修改,而这个值长期不更新,一般只有在从库binlog切换的时候才会更新。那么只要show slave status满足条件就会进入计算延迟环节且只要计算延迟就很高,但是关键是什么时候回满足条件,这是关键。
这里,主库会接受来自从库的event,也就是事物的event会回传,但是event会过滤掉,但是主库的pos是需要更新的,这包含IO线程和SQL线程都需要更新自身的POS,也就是主库的show slave status看到的POS,这些POS需要跟上从库的binlog位点。也就是在主库大概有3个任务需要完成,
那么IO线程更新和SQL线程更新是一个异步通知的过程,这是根本问题,很容易模拟,就是将SQL线程更新应用的pos线程给他停止掉这个时候show slave status就能出现主库延迟,其中我们watch mi->master_log_pos观察io线程更改pos,同时gdb 断点exec_relay_log_event,理论上就是不让SQL线程更新pos,而io线程更新了pos,这个时候show slave status命令只要执行就会进入延迟计算环节,然后得出延迟输出。重现方式,如下,
3 hw watchpoint keep y *((my_off_t *) 0x65364a8)
breakpoint already hit 2 times
4 hw watchpoint keep y *((my_off_t *) 0x65364a8)
5 breakpoint keep y 0x0000000001848850 in exec_relay_log_event(THD*, Relay_log_info*) at /opt/percona-server-locks-detail-5.7.22/sql/rpl_slave.cc:5161
Old value = 376
New value = 416
Hardware watchpoint 4: *((my_off_t *) 0x65364a8)
Old value = 376
New value = 416
Master_info::set_master_log_pos (this=0x65341f0, log_pos=416) at /opt/percona-server-locks-detail-5.7.22/sql/rpl_mi.h:312
312 }
(gdb) c
Continuing.
Hardware watchpoint 3: *((my_off_t *) 0x65364a8)
Old value = 416
New value = 447
Hardware watchpoint 4: *((my_off_t *) 0x65364a8)
Old value = 416
New value = 447
Master_info::set_master_log_pos (this=0x65341f0, log_pos=447) at /opt/percona-server-locks-detail-5.7.22/sql/rpl_mi.h:312
312 }
(gdb) c
Continuing.
(gdb) info threads
Id Target Id Frame
49 Thread 0x7fff385a3700 (LWP 9745) "mysqld" (running)
48 Thread 0x7fff385e5700 (LWP 9732) "mysqld" (running)
47 Thread 0x7fff50059700 (LWP 9731) "mysqld" (running)
46 Thread 0x7fff593f9700 (LWP 9730) "mysqld" (running)
45 Thread 0x7fff5943b700 (LWP 9729) "mysqld" (running)
44 Thread 0x7fff5947d700 (LWP 9728) "mysqld" exec_relay_log_event (thd=0x7ffed4000950, rli=0x653cda0) at /opt/percona-server-locks-detail-5.7.22/sql/rpl_slave.cc:5161
* 43 Thread 0x7fff594bf700 (LWP 9727) "mysqld" (running)
42 Thread 0x7fff59501700 (LWP 9674) "mysqld" (running)
41 Thread 0x7fff59543700 (LWP 9669) "mysqld" (running)
(gdb) n
3836 max(0L, time_diff) : 0));
(gdb) p time_diff
$6 = 131
这里就是延迟的131秒
输出显示如下,
那么结合模拟的过程来看,实际上这种情况是不可避免的,并且,
原文作者:MySQL学习;如有侵权,请联系管理员删除。