背景
在线上环境中,使用MySQL搭建了一个半同步的主从架构,并且主从设置成了无损复制,即变量rpl_semi_sync_master_wait_point设置成了AFTER_SYNC,但是由于性能的问题,将主库设置成了02,即变量sync_binlog设置为0,innodb_flush_log_at_trx_commit设置成了2。导致主库宕机后,主库上的数据丢失,即从库数据多于主库的数据,怎么将主库产生的数据从从库上拉取过来呢?直接将老主库挂在原来的从库下面,发现并没有将丢失的这部分老主库产生的数据的binlog发送并且写入到relaylog里面。最后通过修改老主库的server_id得以解决这个问题。为什么需要修改老主库的server_id从库才会将这部分数据发送写入到relaylog里面呢?
关于sync_binlog和innodb_flush_log_at_trx_commit
对于sync_binlog和innodb_flush_log_at_trx_commit分别是SQL层和存储层的变量,即在什么情况下进行刷盘,这面不详细的介绍。最安全的情况就是将这两个值设置为11,即每个事务提交都会进行binlog和引擎层日志的刷盘。双一保证数据的最大程度的不丢失或者最多丢失最后一个语句或者事务,但是双一的设置会导致服务频繁的IO,影响性能,所以上面我们就设置成了02,即将sync_binlog设置为0,由操作系统控制将文件缓存刷盘,innodb_flush_log_at_trx_commit设置为2,每次事务提交会写入日志文件,但并不会立即刷写到磁盘,日志文件会每秒刷写一次到磁盘,这种情况下,服务的性能会大大的提升,但是也会导致如果发生了主库宕机,会丢失较多的数据。
关于从库的io线程和sql线程
从库用于处理主库日志的两个线程分别为io线程和sql线程,io线程负责获取主库的binlog文件里面的一个个event,然后写入到relaylog文件中,sql线程负责回放这些event。sql/http://rpl_slave.cc文件里面的函数handle_slave_io和handle_slave_sql分别是两个线程的回调函数,首先io线程的处理函数主干流程为:
handle_slave_io
| init_slave_thread // 初始