MySQL:半同步(三)从库端初始化和回调函数

MySQL:半同步(三)从库端初始化和回调函数,第1张

semisync_slave_plugin.cc

semisync.cc

继承自ReplSemiSyncBase

执行语句

INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'

相关调用过程

调用者:IO线程

回调时机

具体过程

这个回调函数比较简单,只是设置了从库是否使用为半同步方式,但是随后还会修改,参考repl_semi_slave_request_dump回调函数。

调用者:IO线程

回调时机

具体过程

这个回调函数也很简单只是将 rpl_semi_sync_slave_status状态设置为OFF

调用者:IO线程

回调方式:

具体过程

我们可以看到这里在和主库进行交互,实际探测主库是否安装了半同步插件,没有的话rpl_semi_sync_slave_status也会在io线程启动时刻设置为OFF。

调用者:IO线程

回调方式

具体过程

可以看到这个回调函数主要通过读取event,然后通过kPacketFlagSync去判断是否本event需要进行ack反馈。注意是否需要反馈是放在semi_sync_need_reply里面的,但是这是全局变量(多源复制如何处理?多源复制不支持半同步)

调用者:IO线程

注意本函数内部会做replay的判断,根据前面的semi_sync_need_reply进行判断如果不是事务的最后一个event则不需要反馈ack

回调方式

具体过程:

可以看到这个回调函数,实际的构建了需要反馈的信息给主库的Ack_recevier线程。

MySQL semisync replication配置及源代码实现

之前一直没有对semi sync做太多的关注,原因是线上的生产环境使用的非常少,最近需要提升semisync的生产环境优先级,以适应数据保护非常严格的场景,借此机会了解一下semisync,顺便过了一下大部分代码,以帮助后续的性能优化工作,以下分析基于代码MySQL5.6.13

如何配置

semisync的配置非常简单,采用MySQL Plugin的方式,在主库和备库上分别安装不同的插件,当然你也可以主库备库全部标准安装上,使用参数来控制sesmisync;

INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'

INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'

正常情况下,这两个PLUGIN都应该被标准安装,谁知道哪天备库会不会被切换成主库呢。

安装完PLUGIN后,我们可以根据拓扑结构来定义主库和备库的配置,主要包括以下几个配置项;

1.rpl_semi_sync_master_enabled

—控制主库上是否开启semisync, 打开或关闭,立刻生效

2.rpl_semi_sync_slave_enabled

—控制备库是否开启semisync,

当主库打开semisync时,则必须至少要有一个链接的备库是打开semisync的,否则主库线程每次都会去等待,直至超时;因此如果想关闭semisync必须要先关闭主库配置,再关闭备库配置

3.rpl_semi_sync_master_timeout

—控制主库上客户端的等待时间,当超过这么长时间等待后,客户端返回,同步复制退化成原生的异步复制

单位为毫秒,默认值为10000,即10秒

4.rpl_semi_sync_master_wait_no_slave

默认打开,表示当备库起来后,并跟上主库时,自动切换到同步模式,如果关闭,即使备库起来并跟上了,也不会启用半同步;

5.rpl_semi_sync_master_trace_level 以及

rpl_semi_sync_slave_trace_level

— 输出监控信息的级别,详细点击见文档,不同的级别,可能输出更详细的信息,用于DEBUG

运行状态变量也比较丰富,不细说了,网上介绍的很多,官方文档也很详细

root@(none) 02:58:27>show status like '%semi%'

+--------------------------------------------+-------+

| Variable_name | Value |

+--------------------------------------------+-------+

| Rpl_semi_sync_master_clients | 0 |

| Rpl_semi_sync_master_net_avg_wait_time | 0 |

| Rpl_semi_sync_master_net_wait_time | 0 |

| Rpl_semi_sync_master_net_waits | 0 |

| Rpl_semi_sync_master_no_times | 0 |

| Rpl_semi_sync_master_no_tx | 0 |

| Rpl_semi_sync_master_status| OFF |

| Rpl_semi_sync_master_timefunc_failures | 0 |

| Rpl_semi_sync_master_tx_avg_wait_time | 0 |

| Rpl_semi_sync_master_tx_wait_time | 0 |

| Rpl_semi_sync_master_tx_waits | 0 |

| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |

| Rpl_semi_sync_master_wait_sessions | 0 |

| Rpl_semi_sync_master_yes_tx| 0 |

| Rpl_semi_sync_slave_status | OFF |

+--------------------------------------------+-------+

15 rows in set (0.00 sec)

详细见文档:http://dev.mysql.com/doc/refman/5.6/en/replication-semisync-interface.html

源代码实现

采用plugin +代码HOOK的方式实现,通过HOOK来回调在plugin中定义的函数

例如:

RUN_HOOK(transaction, after_commit, (head, all))

RUN_HOOK的定义在rpl_hander.h中:

#define RUN_HOOK(group, hook, args) \

(group ##_delegate->is_empty() ? \

0 : group ##_delegate->hook args)

因此上例被转化成

transaction_delegate->after_commit(head, all)

更具体的回调接口函数在sql/rpl_hander.cc文件中定义


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/8352592.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-15
下一篇 2023-04-15

发表评论

登录后才能评论

评论列表(0条)

保存