mysql 主从 编码_mysql 主从复制slave代码分析(1)

源码阅读推荐工具:

vim + ctag + cscope + ycm+ indexer+nerdtree+taglist

详细使用请google

编译源码的时候首先需要开启HAVE_REPLICATION宏定义

在执行 start slave命令后,mysql会执行sql_parse 中SQLCOM_SLAVE_START分支

res= start_slave(thd, active_mi, 1 /* net report*/);

slave 从这个函数开始执行,5.6中这个函数在rpl_slave.cc中

函数传人三个参数,第一个参数定义了线程描述符,每个客户端都有一个线程处理,在

这个地方还负责创建slave复制线程(IO)和延迟插入线程(Sql)

第二个参数主要是主库信息,供slave 线程从主库dump binlog使用

第三个参数

int start_slave(THD* thd , Master_info* mi, bool net_report) {

if (global_init_info(mi, false, thread_mask))

else if (server_id_supplied && *mi->host)

lave_errno = start_slave_threads(false/

}

global_init_info来初始化主库信息,start_slave_threads会先启动io 线程,io线程启动无误启动sql 线程

最后terminate_slave_threads确保io,sql同时启动

int start_slave_threads(bool need_lock_slave, bool wait_for_start,

Master_info* mi, int thread_mask)

{

if (thread_mask & SLAVE_IO)

start_slave_thread(…handle_slave_io..)

if (!error && (thread_mask & SLAVE_SQL))

start_slave_thread(….handle_slave_sql…)

if (error)

terminate_slave_threads(mi, thread_mask & SLAVE_IO, need_lock_slave);

}

handle_slave_io  handle_slave_sql为线程处理函数,下面先看一下io读写线程,发现mysql

的io是只起了一个线程来做这个事情,应该是为了保持binlog event的时序性

pthread_handler_t handle_slave_io(void *arg)

{

if (RUN_HOOK(binlog_relay_io, thread_start, (thd, mi)))

}

rpl_handler.h中展开宏RUN_HOOK:

#define RUN_HOOK(group, hook, args) \

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

group ##_delegate->hook args)

发现调用了binlog_relay_io_delegate->thread_start(thd, mi)

int Binlog_relay_IO_delegate::thread_start(THD *thd, Master_info *mi)

{

init_param(&param, mi);

FOREACH_OBSERVER(ret, thread_start, thd, (&param));

}

init_param主要是为了初始化参数(主库的用户名,密码,binlog文件名,binlog读取的偏移量),展开宏

#define FOREACH_OBSERVER(r, f, thd, args) \

Observer_info_iterator iter= observer_info_iter(); \

Observer_info *info= iter++; \

for (; info; info= iter++) \

{ \

if (((Observer *)info->observer)->f \

&& ((Observer *)info->observer)->f args) \

} \

到这里就很清楚了,此处用了观察者模式,最终回调typedef Binlog_relay_IO_observer Observer;

的thread_start,初始化的时候Binlog_relay_IO_observer是以插件的形式通过register_binlog_relay_io_observer函数注册到观察者list里面,所以最终实现io的功能是在plugin/semisync实现。

从补丁目录找到下面的结构体,所以上面分析的thread_start 函数其实是指向repl_semi_slave_io_start

的函数指针,至此mysql slave io hook启动。

Binlog_relay_IO_observer relay_io_observer = {

sizeof(Binlog_relay_IO_observer), // len

repl_semi_slave_io_start, // start

repl_semi_slave_io_end, // stop

repl_semi_slave_request_dump, // request_transmit

repl_semi_slave_read_event, // after_read_event

repl_semi_slave_queue_event, // after_queue_event

repl_semi_reset_slave, // reset

};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值