MySQL深入——18

我们来看看一主多从的情况

比如A是主库,A’ B C D都是副库,但A与A'互为备库,当A库出现问题,我现在要将主库转到A’该怎么办。

以下是基于位点的主备切换 

CHANGE MASTER TO
MASTER_HOST=$host_name
MASTER_PORT=$port
MASTER_USER=$user_name
MASTER_PASSWORD=$password
MASTER_LOG_FILE=$master_log_name
MASTER_LOG_POS=$master_log_pos

其中的MASTER_LOG_FILE和MASTER_LOG_POS表示要从主库的MASTER_LOG_FILE文件的MASTER_LOG_POS这个位置的日志继续同步,这个位置就是指同步位点,即为主库对应的文件名和日志偏移量。

这里就有一个问题,既然A'是新的主库,就要把节点B设置为A’的从库,就要执行change master命令。就得得到这两个参数的值,那么如何找呢??

因为考虑到要找一个稍微靠前的节点,然后通过判断跳过在从库B上执行过的事务。

找共同位点的方法:1.新主库A'将relay log 全部完成

2.A'上执行show master status命令得A'上最新的file和position

3.取原主库A的故障时刻T

4.用MySQLbinlog的工具解析A'的File得到T时刻的位点

解析后看到end_log_pos为“123”就表示 A’这个实例,在T时刻写入新的binlog位置,将123作为master_log_pos用于节点B的change master 命令里。

但是这种方法是不太精确的,比如在T时刻,主库A已经完成了insert语句插入一个新记录R,然后已经将binlog传给了A'和B,传完之后A就立刻下线了。在传完瞬间,因为B库上的binlog已经完成,那么就存在这个新纪录R,在新主库A'上,R是存在的,日志写在123之后,对B使用change master指到了A'的123位置,就会把这个R数据传过去又进行同步操作,那么B的同步线程就会报错 Duplicate entry ‘idof_R’ for key ‘PRIMARY’的错误,只是出现主键冲突的错误,这有两个方式解决

1.主题跳过一个事务, sql_slave_skip_count=1;

                                     set global

                                     start slave

因为切换过程当中,有可能不只执行一个事务,所以每次执行的时候碰到这个错误都得执行上述操作。

2.设置slave_skip_errors参数

1032指插入数据时唯一键冲突

1062指删除时找不到行

主从转换完成之后要设置为空。

GTID

MySQL 5.6 引入GTID解决了上述出现错误的情况

GTID全称为Global Transaction Identifior也就是全局事务ID是一个事务在提交的时候生成的,是这个事务唯一的标识。

GTID=server_uuid:gno

server_uuid是一个实例第一次启动时自动生成的,是一个全局唯一的值。

其中gno为一个整数的初始值为1,每次提交事务的时候分配给这个事务并+1。

GTID模式的启动

只需在启动MySQL实例时,加上参数gtid_mode=on和enforce_gtid_cnsistenc=on就可以了。

在GTID模式下,每一个事务都与一个GTID对应。

GTID有两种生成方式,取决于session变量gtid_next的值

1.当它等于automatic时,代表使用默认值。这时,Mysql就会吧Server_uuid:gno分配给这个事务,记录binlog的时候会先记录一行set(@@SESSION.GTID_NEXT=‘sever_uuid;gno’)

将这个GTID加入本实例的GTID实例的集合当中

2.当它等于一个指定的GTID的值时,比如通过set gtid_next='current_gtid'指定为current_gtid时,存在两种情况

     1.current_gtid存在于实例GTID集合当中,接下来执行的事务会被系统忽略。

     2.如它没有存在其中,就会直接将它分配给接下来要执行的事务,也就是系统无需生成一个gtid给这个事务,也无需给gno上加1。

这样一个MySQL实例维护一个GTID。

基于GTID的主备切换

在GTID模式下,备库B要设置为新主库A’的从库的语法如下:

CHANGE MASTER TO
MASTER_HOST=$host_name
MASTER_PORT=$port
MASTER_USER=$user_name
MASTER_PASSWORD=$password
master_auto_position=1

master_auto_position=1表示主备关系使用GTID协议。

A’ GTID集合设为set_a B为set_b

在实例B上执行start slave命令,取binlog的逻辑

1.实例B指定主库A'

2.实例B将set_b发给主库A’

3.A’得出set_b与set_a的差集,也就是存在于set_a不存在于set_b的GTID集合,判断出A’是否包含这个差集当中所以的binlog事务,若是包含了,A’就在自己的binlog文件中找出第一个不存在set_b的事务逐个发给B,如果没有包含,这就表示A'就把实例B的binlog给删掉了,就直接返回错误。

你可能感兴趣的:(mysql,数据库)