现在的位置: 首页 > 综合 > 正文

(转)MySQL双主复制环境中BINLOG日志的解析

2013年01月21日 ⁄ 综合 ⁄ 共 4819字 ⁄ 字号 评论关闭
MySQL Replication的双主高可用是很常用的数据库高可用方案,在数据库软件升级、大数据量更新、对象结构变更等方面相比普通的M-S结构有巨大优势。但是,多主模式由于只有两个实例,在读写分离方面不太好处理,如果为每个

master各挂载几个slave的话,一旦该master宕机,则这一组slave也统统失去了数据更新的有效来源。

本文主要通过分析MySQL数据库记录的BINLOG日志,验证当某个master宕机时,挂载于其下的slave是否有在不丢失(损坏)数据的前提下,变更master。

文章中的测试环境如下:

MASTER:

10.0.0.110:3306

10.0.0.111:3306

两者互为主从,构成了双主架构。

SLAVE:

10.0.0.111:3307,是10.0.0.110:3306的SLAVE。

有表如下:

mysql> desc j1;

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

| Field | Type        | Null | Key | Default | Extra |

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

| id    | int(11)     | YES  |     | NULL    |       |

| vl    | varchar(20) | YES  |     | NULL    |       |

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

2 rows in set (0.00 sec)

为有效分析mysql的binlog记录的信息,验证不同节点上操作对各slave的影响(每个mysql节点均可视为slave,即使是双主的两个master),下面分别在两个master身份的节点上均执行写操作:

先是在111:3306端操作:

mysql> insert into j1 values (1,'a');

Query OK, 1 row affected (0.00 sec)

然后到110:3306端再操作:

mysql> insert into j1 values (2,'b');

Query OK, 1 row affected (0.00 sec)

下面分别各个节点去查看生成的binlog日志

-----------------------------------------------------------------------------------

110:3306端执行mysqlbinlog

# mysqlbinlog -v --base64-output=DECODE-ROWS binlog/mysql-bin.000019

输出信息中如下:

/*!*/;

# at 547

# at 592

#111117 16:25:14 server id 1113306  end_log_pos 592     Table_map: `jssdb`.`j1` mapped to number 34

#111117 16:25:14 server id 1113306  end_log_pos 628     Write_rows: table id 34 flags: STMT_END_F

### INSERT INTO jssdb.j1

### SET

###   @1=1

###   @2='a'

# at 628

#111117 16:25:14 server id 1113306  end_log_pos 655     Xid = 20

COMMIT/*!*/;

# at 655

#111117 12:40:39 server id 1103306  end_log_pos 729     Query   thread_id=5     exec_time=0     error_code=0

SET TIMESTAMP=1321504839/*!*/;

SET @@session.auto_increment_increment=2, @@session.auto_increment_offset=1/*!*/;

BEGIN

/*!*/;

# at 729

# at 774

#111117 12:40:39 server id 1103306  end_log_pos 774     Table_map: `jssdb`.`j1` mapped to number 34

#111117 12:40:39 server id 1103306  end_log_pos 810     Write_rows: table id 34 flags: STMT_END_F

### INSERT INTO jssdb.j1

### SET

###   @1=2

###   @2='b'

# at 810

#111117 12:40:39 server id 1103306  end_log_pos 837     Xid = 22

COMMIT/*!*/;

DELIMITER ;

# End of log file

ROLLBACK /* added by mysqlbinlog */;

/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;

------------------------------------------------------------------------------------

111:3306

# mysqlbinlog -v --base64-output=DECODE-ROWS 3306/binlog/mysql-bin.000023

输出信息中如下:

/*!*/;

# at 557

# at 602

#111117 16:25:14 server id 1113306  end_log_pos 602     Table_map: `jssdb`.`j1` mapped to number 34

#111117 16:25:14 server id 1113306  end_log_pos 638     Write_rows: table id 34 flags: STMT_END_F

### INSERT INTO jssdb.j1

### SET

###   @1=1

###   @2='a'

# at 638

#111117 16:25:14 server id 1113306  end_log_pos 665     Xid = 16

COMMIT/*!*/;

# at 665

#111117 12:40:39 server id 1103306  end_log_pos 729     Query   thread_id=5     exec_time=14298 error_code=0

SET TIMESTAMP=1321504839/*!*/;

SET @@session.auto_increment_increment=2, @@session.auto_increment_offset=1/*!*/;

BEGIN

/*!*/;

# at 729

# at 774

#111117 12:40:39 server id 1103306  end_log_pos 774     Table_map: `jssdb`.`j1` mapped to number 34

#111117 12:40:39 server id 1103306  end_log_pos 810     Write_rows: table id 34 flags: STMT_END_F

### INSERT INTO jssdb.j1

### SET

###   @1=2

###   @2='b'

# at 810

#111117 12:40:39 server id 1103306  end_log_pos 837     Xid = 19

COMMIT/*!*/;

DELIMITER ;

# End of log file

ROLLBACK /* added by mysqlbinlog */;

/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;

------------------------------------------------------------------------------------

111:3307slave端查看relay-bin-log文件:

# mysqlbinlog -v --base64-output=DECODE-ROWS 3307/data/mysql-relay-bin.000009

输出信息中如下:

/*!*/;

# at 693

# at 738

#111117 16:25:14 server id 1113306  end_log_pos 592     Table_map: `jssdb`.`j1` mapped to number 34

#111117 16:25:14 server id 1113306  end_log_pos 628     Write_rows: table id 34 flags: STMT_END_F

### INSERT INTO jssdb.j1

### SET

###   @1=1

###   @2='a'

# at 774

#111117 16:25:14 server id 1113306  end_log_pos 655     Xid = 20

COMMIT/*!*/;

# at 801

#111117 12:40:39 server id 1103306  end_log_pos 729     Query   thread_id=5     exec_time=0     error_code=0

SET TIMESTAMP=1321504839/*!*/;

SET @@session.auto_increment_increment=2, @@session.auto_increment_offset=1/*!*/;

BEGIN

/*!*/;

# at 875

# at 920

#111117 12:40:39 server id 1103306  end_log_pos 774     Table_map: `jssdb`.`j1` mapped to number 34

#111117 12:40:39 server id 1103306  end_log_pos 810     Write_rows: table id 34 flags: STMT_END_F

### INSERT INTO jssdb.j1

### SET

###   @1=2

###   @2='b'

# at 956

#111117 12:40:39 server id 1103306  end_log_pos 837     Xid = 22

COMMIT/*!*/;

DELIMITER ;

# End of log file

ROLLBACK /* added by mysqlbinlog */;

/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;

------------------------------------------------------------------------------------

通过分析上述信息可以看到,不管master是什么,其slave记录的binlog信息中server id和end_log_pos是恒定的。

由于110:3306和111:3306互为主从关系,而其它slave只能跟一台master,当110或111任意mysql服务中断,可以根据当前slave读取到的binlog位置,重点在于:

#111117 12:40:39 server id 1103306  end_log_pos 837     Xid = 22

每个slave都会有这样的信息(包括110/111和3306),因此可以到仍然alive的master端查看binlog,通过前面那个信息中得到的关键字过滤,确定行号信息中对应的end_log_pos的位置,再向上读取一行,即前一行信息:

# at 810

得到这个信息后,分别在各个slave端change master,指定成当前存活的那个binlog文件和position即可。

抱歉!评论已关闭.