Xtrabackup 复制一个从库,并启动GTID自动同步

使用innobackupex --user=root --password=pass  --parallel=8 /webdata/hotbak/ 再主库上备份, innobackupex --apply-log --redo-only hotbak/ 回滚没有应用的事务,并把 hotbak copy到从库...

使用innobackupex --user=root --password=pass  --parallel=8 /webdata/hotbak/ 再主库上备份,

innobackupex --apply-log --redo-only hotbak/ 回滚没有应用的事务,并把 hotbak copy到从库中


mysql 5.6的从库必须开启gtid_mode 模式。


一下几行缺一不可

#GTID
gtid_mode = on
enforce_gtid_consistency = 1
log_slave_updates   = 1

任意一个参数不开启则都会报错:

2015-08-09 02:33:57 6512 [ERROR] --gtid-mode=ON or UPGRADE_STEP_1 or UPGRADE_STEP_2 requires --log-bin and --log-slave-updates
2015-08-09 02:33:57 6512 [ERROR] Aborting

2015-08-09 02:39:58 9860 [ERROR] --gtid-mode=ON or UPGRADE_STEP_1 requires --enforce-gtid-consistency
2015-08-09 02:39:58 9860 [ERROR] Aborting

启动从库后,从xtrabackup_binlog_info  中取得 主库当前的 binglog文件,主库执行到的pos位置,执行到的gtid_executed,对于使用gtid自动复制(MASTER_AUTO_POSITION=1)的情况,对我们有用的是最后一个,前两个是数值是传统请求binlog方式。

master-bin.000723812349785  7808555d-17c1-11e5-a86e-00163e000c7c:1-572621999

我们执行下面两调命令:


mysql> SET GLOBAL gtid_purged='7808555d-17c1-11e5-a86e-00163e000c7c:1-572621999'; --备份恢复过来的相当于在从库上重放过的sql gtid 已经到7808555d-17c1-11e5-a86e-00163e000c7c:1-572621999       把这个之后的事务才记录relay log日志

mysql>change master to master_host='10.174.104.218',master_port=3306,master_user='slave_rep',master_password='xxx',master_log_file='master-bin.000723',MASTER_AUTO_POSITION=1;


使用MASTER_AUTO_POSITION=1 ,master_log_file 不需要指定,mysql主库再从库注册后会自动搜,否则会报错

ERROR 1776 (HY000): Parameters MASTER_LOG_FILE, MASTER_LOG_POS, RELAY_LOG_FILE and
RELAY_LOG_POS cannot be set when MASTER_AUTO_POSITION is active.


正确是:mysql>change master to master_host='10.174.104.218',master_port=3306,master_user='slave_rep',master_password='xxx',MASTER_AUTO_POSITION=1;

 Query OK, 0 rows affected, 2 warnings (0.01 sec)

有两个报警,是因为 命令行中使用了明文密码。

mysql> start slave;


MASTER_AUTO_POSITION=1 备库如何发起dump请求,在不指定 master_log_file 和master_log_pos 如和通过gtid 来实现寻找到master_log_file 和master_log_pos的?

引入GTID,最大的好处当然是我们可以随心所欲的切换主备拓扑结构了。在一个正常运行的复制结构中,我们可以在备库简单的执行如下SQL:

CHANGE MASTER TO MASTER_USER=’$USERNAME’, MASTER_HOST=’ ‘, MASTER_PORT=’ ‘, MASTER_AUTO_POSITION=1;

打开GTID后,我们就无需指定binlog文件或者位置,MySQL会自动为我们做这些事情。这里的关键就是MASTER_AUTO_POSITION。IO线程连接主库,可以大概分为以下几步:
1.IO线程在和主库建立TCP链接后,会去获取主库的uuid(get_master_uuid),然后在主库上设置一个用户变量@slave_uuid(io_thread_init_commands)

2.之后,在主库上注册SLAVE(register_slave_on_master)

在主库上调用register_slave来注册备库,将备库的host,user,password,port,server_id等信息记录到slave_list哈希中。

3.调用request_dump,开始向主库请求数据,这里分两种情况:
MASTER_AUTO_POSITION=0时,向主库发送命令的类型为COM_BINLOG_DUMP,这是传统的请求BINLOG的模式
MASTER_AUTO_POSITION=1时,命令类型为COM_BINLOG_DUMP_GTID,这是新的方式。
这里我们只讨论第二种。第二种情况下,会先去读取备库已经执行的gtid集合
quoted code in rpl_slave.cc :

2974   if (command == COM_BINLOG_DUMP_GTID)

2975   {
2976     // get set of GTIDs
2977     Sid_map sid_map(NULL/*no lock needed*/);
2978     Gtid_set gtid_executed(&sid_map);
2979     global_sid_lock->wrlock();
2980     gtid_state->dbug_print();
2981     if (gtid_executed.add_gtid_set(mi->rli->get_gtid_set()) != RETURN_STATUS_OK ||
2982         gtid_executed.add_gtid_set(gtid_state->get_logged_gtids()) !=

2983         RETURN_STATUS_OK)

构建完成发送包后,发送给主库。

在主库上接受到命令后,调用入口函数com_binlog_dump_gtid,流程如下:

1.slave_gtid_executed.add_gtid_encoding(packet_position, data_size) ;读取备库传来的GTID SET 
2.读取备库的uuid(get_slave_uuid),被根据uuid来kill僵尸线程(kill_zombie_dump_threads)
这也是之前SLAVE IO线程执行SET @SLAVE_UUID的用处。
3.进入mysql_binlog_send函数:
         |–>调用MYSQL_BIN_LOG::find_first_log_not_in_gtid_set,从最后一个Binlog开始扫描,获取文件头部的PREVIOUS_GTIDS_LOG_EVENT,如果它是slave_gtid_executed的子集,保存当前binlog文件名,否则继续向前扫描。
         这一步的目的就是为了找出备库执行到的最后一个Binlog文件。
         
         |–>从这个文件头部开始扫描,遇到GTID_EVENT时,会去判断该GTID是否包含在slave_gtid_executed中:
                         Gtid_log_event gtid_ev(packet->ptr() + ev_offset,
                                 packet->length() – checksum_size,
                                 p_fdle);
                          skip_group= slave_gtid_executed->contains_gtid(gtid_ev.get_sidno(sid_map),
                                                     gtid_ev.get_gno());
         主库通过GTID决定是否可以忽略事务,从而决定执行开始的位置 

注意,在使用MASTER_LOG_POSITION后,就不要指定binlog的位置,否则会报错。


GTID复制:

1.主库不能purge从库还没有execute的事务(即从库的executed_GTID要大于主库的GTID_Purged);

2.主库上的事务号不能低于从库(即从库的executed_GTID的最后一个事务要在主库的executed_GTID的范围之内);


  • 发表于 2017-01-07 06:51
  • 阅读 ( 55 )

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
shitian
shitian

662 篇文章

作家榜 »

  1. shitian 662 文章
  2. 石天 437 文章
  3. 每天惠23 33 文章
  4. 小A 29 文章