gtid特性介绍:
GTID(global transaction identifier)是MySQL 5.6的新特性,可以唯一的标识一个事务,由UUID+TID组成:
- UUID是MySQL实例的唯一标识
- TID是该实例上已提交的事务的数量
在主从复制中,GTID代替了classic的复制方法,不再使用binlog+pos开启复制,而是使用master_auto_postion = 1的方式自动匹配GTID断点进行复制。
要开启GTID,只需在MySQL参数文件中添加以下参数:
gtid-mode = ON
enforce_gtid_consistency = 1
通过实例分析下,分析下主备节点的gtid等信息。
先造一些数据。
master
create database udb;
CREATE TABLE `t` (
`id` int(11) NOT NULL,
`c` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
delimiter ;;
create procedure idata()
begin
declare i int;
set i=1;
while(i<=100000) do
insert into t values(i,i);
set i=i+1;
end while;
end;;
delimiter ;
call idata();
主备位置点不同:
master
mysql> show master status;
+------------------+----------+--------------+------------------+-----------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-----------------------------------------------+
| mysql-bin.000004 | 30400896 | | | 51b0432b-b31a-11eb-b2a7-525400c6bc4a:1-100003 |
+------------------+----------+--------------+------------------+-----------------------------------------------+
slave
mysql> show master status;
+------------------+----------+--------------+------------------+-----------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-----------------------------------------------+
| mysql-bin.000005 | 29600896 | | | 51b0432b-b31a-11eb-b2a7-525400c6bc4a:1-100003 |
+------------------+----------+--------------+------------------+-----------------------------------------------+
master
show binlog events in 'mysql-bin.000004' limit 12;
......
| mysql-bin.000004 | 1032 | Rows_query | 3232235528 | 1081 | # insert into t values(i,i) |
| mysql-bin.000004 | 1081 | Table_map | 3232235528 | 1125 | table_id: 110 (udb.t)
mysql> show binary logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 177 |
| mysql-bin.000002 | 177 |
| mysql-bin.000003 | 177 |
| mysql-bin.000004 | 30400896 |
+------------------+-----------+
slave
show binlog events in 'mysql-bin.000004' limit 12;
......
| mysql-bin.000005 | 1024 | Rows_query | 3232235528 | 1073 | # insert into t values(i,i) |
| mysql-bin.000005 | 1073 | Table_map | 3232235528 | 1117 | table_id: 109 (udb.t)
mysql> show binary logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 177 |
| mysql-bin.000002 | 177 |
| mysql-bin.000003 | 177 |
| mysql-bin.000004 | 177 |
| mysql-bin.000005 | 29600896 |
+------------------+-----------+
主备数据一致后,清理主备上的binlog
主从环境下的配置步骤:
a. 启动master和slave,开启replication(即复制)
b. 在master上运行一些测试的语句,看数据是否能够复制到 slave上面
c. 当复制运行正常的话,就在从上stop slave 然后执行 reset slave,去掉不需要的数据
d. 在master上面执行reset master 清除测试产生的数据
用于删除列于在指定的日志或日期之前的日志索引中的所有二进制日志。这些日志也会从记录在日志索引文件中的清单中被删除,这样被给定的日志成为第一个。
PURGE { BINARY | MASTER } LOGS
{ TO 'log_name' | BEFORE datetime_expr }
实例:
PURGE BINARY LOGS TO 'mysql-bin.000002';
PURGE BINARY LOGS BEFORE '2014-04-28 23:59:59';
还有一种通过设置过期时间,清理binlog的方法
set global expire_logs_days = 60;
flush logs;
master
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
slave
mysql> show master status;
+------------------+----------+--------------+------------------+-----------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-----------------------------------------------+
| mysql-bin.000005 | 29600896 | | | 51b0432b-b31a-11eb-b2a7-525400c6bc4a:1-100003 |
+------------------+----------+--------------+------------------+-----------------------------------------------+
通过xtrbackup备份文件+gtid回档到指定时间点的数据,理解gtid_executed/gtid_purged
GTID(global transaction identifier)是MySQL 5.6的新特性,可以唯一的标识一个事务,由UUID+TID组成:
- UUID是MySQL实例的唯一标识
- TID是该实例上已提交的事务的数量
在主从复制中,GTID代替了classic的复制方法,不再使用binlog+pos开启复制,而是使用master_auto_postion = 1的方式自动匹配GTID断点进行复制。
要开启GTID,只需在MySQL参数文件中添加以下参数:
gtid-mode = ON
enforce_gtid_consistency = 1
回档需要的数据:
需要将MySQL(以下简称A库)恢复到时间点 需要具备的前提条件如下:
- 开启GTID
- 有A库昨天凌晨12:00前的xtra备份文件
- 开启binlog日志
查看data目录下xtrabackup_binlog_info文件中记录的GTID:
gtid_executed,全局参数,GTID集合包含所有在该服务器上执行过的事务编号和使用set gtid_purged语句设置过的事务编号,使用SHOW MASTER STATUS和SHOW SLAVE STATUS命令得到的Executed_Gtid_Set列值就取自于全局参数gitd_executed。
gtid_purged,全局参数,GTID集合包含从binlog中purged掉的事务ID,该集合是全局参数gtid_executed的子集。
------------------- >------------------- >------------------- > now
回档点 gtid_purged
[root@service-test1 data]$ cat xtrabackup_binlog_info
mysql-bin.000012 46455554 8133046e-4282-11e6-848e-026ca51d284c:1-4920155
在B库(slave)设置@@global.gtid_purged跳过备份包含的GTID,并执行change master to指定A库为主库:
mysql> SET GLOBAL gtid_purged="8133046e-4282-11e6-848e-026ca51d284c:1-4920155";
Query OK, 0 rows affected (0.00 sec)
mysql> change master to Master_Host ='10.11.21.14',Master_Port=3306,Master_User='replica',Master_Password='XXXXXXXXX',MASTER_AUTO_POSITION=1;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
注意: xtrabackup_binlog_info中的GTID有时不止一个,设置@@global.gtid_purged时指定多个即可,以逗号隔开。
如果set gtid_purged报错,先reset master
从binlog中手动查找回档的位置点
需要特别注意的是,在上述操作后,不要直接start slave,否则B库也又会跑到当前A库的状态
将A库binlog转换为sql语句:
mysqlbinlog -vv mysql-bin.000011 > mysql-bin.000011.sql
找到前一天凌晨12:00左右的位置并记录GTID:
# at 561467475
#160521 0:24:31 server id 212177500 end_log_pos 561467523 CRC32 0x216072ca GTID [commit=yes]
SET @@SESSION.GTID_NEXT= '542ef021-9a64-11e5-bc49-025d3d22c211:1348360'/*!*/;
在B库开启slave并指定恢复到的位置:
mysql> start slave until SQL_BEFORE_GTIDS='542ef021-9a64-11e5-bc49-025d3d22c211:1348360';
当执行到了指定的GTID,SQL线程便会停止,但IO线程还会继续复制。
MASTER_AUTO_POSITION:
该参数在mysql5.6.5版本引入,如果进行change master to时使用MASTER_AUTO_POSITION = 1,slave连接master将使用基于GTID的复制协议。
使用基于GTID协议的复制,slave会告诉master它已经接收到或执行了哪些事务。计算这个集,slave需要读取全局参数gtid_executed以及通过show slave status获取的参数Retrieved_gtid_set。
结果集作为初次握手的一部分,发送到master,master发回它已经执行的且不在结果集这部分的所有事务。如果这些事务在master的binlog文件中已经被清除,master将会发送一个ER_MASTER_HAS_PURGED_REQUIRED_GTIDS错误信息到slave,复制将不会开启。
使用基于GTID的复制时(MASTER_AUTO_POSITION = 1),首先要开启gtid_mode(在my.cnf中设置gtid-mode = ON),MASTER_LOG_FILE 与 MASTER_LOG_POS也不能使用,否则会报错。
使用GTID后想要恢复到老的基于文件的复制协议,在change master to时需要指定MASTER_AUTO_POSITION = 0以及MASTER_LOG_FILE 或 MASTER_LOG_POSITION中至少一项。
该过程中的主角flush tables with read lock, 其含义为Closes all open tables and locks all tables for all databases with a global read lock, 即在MySQL数据库Server层, 获取一个全局读锁.
那么配角flush no_write_to_binlog tables, 其含义为Closes all open tables, forces all tables in use to be closed, 起到加速flush tables with read lock操作完成的作用.