GTID即全局事务ID(global transaction identifier),GTID其实是由server_uuid:transaction_id
组成的。其中server_uuid是一个MySQL实例的惟一标识,存放在数据目录的auto.cnf
文件下,transaction_id表明了该实例上已经提交的事务数量,而且随着事务提交单调递增,因此GTID可以保证每一个MySQL实例事务的执行(不会重复执行同一个事务,而且会补全没有执行的事务)。html
GTID集是一组全局事务标识符,以下所示:mysql
gtid_set: uuid_set [, uuid_set] ... | '' uuid_set: uuid:interval[:interval]... uuid: hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh h: [0-9|A-F] interval: n[-n] (n >= 1)
GTID集在MySQL服务器中以多种方式使用。 例如,gtid_executed
和gtid_purged
系统变量存储的值表示为GTID集。 此外,函数GTID_SUBSET()
和GTID_SUBTRACT()
须要GTID集做为输入。 当从服务器变量返回GTID集时,UUID按字母顺序排列,数值间隔按升序合并。web
GTID存储在mysql数据库中名为gtid_executed
的表中。 对于它表示的每一个GTID或GTID集合,该表中的一行包含原始服务器的UUID,以及该集合的起始和结束事务ID; 对于仅引用单个GTID的行,这两个最后两个值是相同的。sql
当slave禁用binlog时,mysql.gtid_executed
表使slave可以使用GTID,而且它能够在二进制日志丢失时保留GTID历史记录。数据库
当gtid_mode为ON或ON_PERMISSIVE时,GTID仅存储在mysql.gtid_executed表中,存储GTID的位置取决因而启用仍是禁用binlog:安全
若是禁用二进制日志记录(log_bin为OFF),或者若是禁用log_slave_updates,则服务器将属于每一个事务的GTID与表中的事务一块儿存储。 此外,该表能够按期压缩; 此状况仅不适用于复制中的master,由于在主服务器上,必须启用二进制日志记录才能进行复制。bash
若是启用了二进制日志记录(log_bin为ON),则不管什么时候轮询二进制日志或关闭服务器,服务器都会将写入先前二进制日志的全部事务的GTID写入mysql.gtid_executed
表。 这种状况适用于复制主服务器或启用了二进制日志记录的复制从服务器。服务器
若是服务器意外中止,则当前二进制日志中的GTID集不会保存在mysql.gtid_executed
表中。 在这种状况下,这些GTID会在恢复期间添加到表和gtid_executed
系统变量中的GTID集合中。session
启用二进制日志记录时,mysql.gtid_executed
表不会为全部已执行的事务提供GTID的完整记录。 该信息由gtid_executed
系统变量的全局值提供。app
命令RESET MASTER
将重置mysql.gtid_executed表。
启用GTID时,服务器会按期在mysql.gtid_executed
表上执行此类压缩。 经过设置gtid_executed_compression_period
系统变量,您能够控制压缩表以前容许的事务数,从而控制压缩率。 该变量的默认值为1000; 这意味着,默认状况下,在每1000次事务以后执行表的压缩。 将gtid_executed_compression_period设置为0能够防止执行压缩; 可是,若是执行此操做,您应该为gtid_executed
表可能须要的磁盘空间量的大幅增长作好准备。
【注意】:
启用binlog时,且不使用gtid_executed_compression_period的值,会在每一个binlog轮换时压缩mysql.gtid_executed表。
压缩前:
mysql> SELECT * FROM mysql.gtid_executed; +--------------------------------------+----------------+--------------+ | source_uuid | interval_start | interval_end | |--------------------------------------+----------------+--------------| | 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 37 | 37 | | 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 38 | 38 | | 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 39 | 39 | | 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 40 | 40 | | 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 41 | 41 | | 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 42 | 42 | | 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 43 | 43 | ...
压缩后:
+--------------------------------------+----------------+--------------+ | source_uuid | interval_start | interval_end | |--------------------------------------+----------------+--------------| | 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 37 | 43 | ...
mysql.gtid_executed
表的压缩由名为thread/sql/compress_gtid_table
的专用前台线程执行。 该线程未在SHOW PROCESSLIST的输出中列出,但能够将其视为performance_schema.threads
表中的一行,以下所示:
mysql> SELECT * FROM performance_schema.threads WHERE NAME LIKE '%gtid%'\G *************************** 1. row *************************** THREAD_ID: 26 NAME: thread/sql/compress_gtid_table TYPE: FOREGROUND PROCESSLIST_ID: 1 PROCESSLIST_USER: NULL PROCESSLIST_HOST: NULL PROCESSLIST_DB: NULL PROCESSLIST_COMMAND: Daemon PROCESSLIST_TIME: 1509 PROCESSLIST_STATE: Suspending PROCESSLIST_INFO: NULL PARENT_THREAD_ID: 1 ROLE: NULL INSTRUMENTED: YES HISTORY: YES CONNECTION_TYPE: NULL THREAD_OS_ID: 18677
thread/sql/compress_gtid_table
线程一般会休眠,直到执行了gtid_executed_compression_period
事务,而后唤醒以执行mysql.gtid_executed
表的压缩,如前所述。 而后它休眠直到另外一个gtid_executed_compression_period
事务发生,而后唤醒再次执行压缩,无限期地重复此循环。 禁用二进制日志记录时将此值设置为0意味着线程始终处于休眠状态且从不唤醒。
GTID的生命周期包括如下步骤:
gtid_purged
gtid_purged
系统变量(@@global.gtid_purged
)中的GTID集包含已在服务器上提交但在服务器上的任何二进制日志文件中不存在的全部事务的GTID。 如下类别的GTID在此集合中:
SET @@global.gtid_purged
明确添加到集合中的GTID服务器启动时,将初始化gtid_purged
系统变量中的GTID集。 每一个二进制日志文件都以事件Previous_gtids_log_event开头,该事件包含全部先前二进制日志文件中的GTID集(由前一个文件的Previous_gtids_log_event中的GTID和文件自己中每一个Gtid_log_event的GTID组成)。 最旧的二进制日志文件中的Previous_gtids_log_event的内容用于在服务器启动时初始化gtid_purged集,并在清除二进制日志文件时维护该集。
GTID使用master_auto_position=1
代替了基于binlog和position号的主从复制搭建方式,更便于主从复制的搭建。
类型 | ip | prot | server-id | 是否开启binlog | binlog格式 | log_slave_updates参数 |
---|---|---|---|---|---|---|
master | 192.168.56.100 | 3307 | 1003307 | log-bin = /data/mysql/mysql3307/logs/my3307_binlog | binlog_format = row | log_slave_updates=1 |
slave | 192.168.56.200 | 3307 | 2003307 | log-bin = /data/mysql/mysql3307/logs/my3307_binlog | binlog_format = row | log_slave_updates=1 |
server_id
: 设置MySQL实例的server_id,每一个server_id不能同样gtid_mode=ON
: MySQL实例开启GTID模式enforce_gtid_consitency=ON
:使用GTID模式复制时,须要开启参数,用来保证数据的一致性。log-bin
: MySQL必需要开启binloglog-slave-updates=1
:决定SLAVE从Master接收到更新且执行是否记录到SLAVE的binlog中binlog_format=ROW
: binlog格式为rowskip-slave-start=1
(可选): 当SLAVE数据库启动的时候,SLAVE不会启动复制1) 建立复制帐号
create user 'repl'@'%' identified by 'wanbin'; grant replication slave on *.* to 'repl'@'%';
2) master数据库利用xtrabackup备份至slave上
innobackupex --defaults-file=/etc/my3307.cnf -uroot -pmysql --stream=tar ./ |ssh root@mysqldb2 "cat - > /data/backup/dbback`date +%Y%m%d_%H%M%S`.tar"
mkdir dbback20181012_151213 tar -xvf dbback20181012_151213.tar -C dbback20181012_151213
innobackupex --apply-log /data/backup/dbback20181012_151213/
innobackupex --defaults-file=/etc/my3307.cnf --copy-back /data/backup/dbback20181012_151213/ chown -R mysql:mysql /data/mysql/mysql3307/data mysqld --defaults-file=/etc/my3307.cnf &
1)查看xtrabackup_info文件中的gtid信息 cat xtrabackup_info|grep binlog_pos binlog_pos = filename 'my3307_binlog.000002', position '2401', GTID of the last change '3a068bf8-cdeb-11e8-8176-080027b0b461:1-10' 2)查看slave已执行的gtid是否为空,若是不为空,须要执行reset MASTER进行清理,不然没法设置gtid。 root@localhost [(none)] 15:50:41>show master status \G; *************************** 1. row *************************** File: my3307_binlog.000002 Position: 234 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 3a068bf8-cdeb-11e8-8176-080027b0b461:1-10, ffe86a27-cdef-11e8-bb92-0800275b8a9a:1-2 1 row in set (0.00 sec) 3)执行reset master root@localhost [(none)] 15:50:52>reset master; Query OK, 0 rows affected (0.04 sec) root@localhost [(none)] 15:53:18>show master status\G *************************** 1. row *************************** File: my3307_binlog.000001 Position: 154 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 1 row in set (0.00 sec) 4)执行GTID_PURGED root@localhost [(none)] 15:56:32>set session sql_log_bin = 0; root@localhost [(none)] 15:56:53>set global gtid_purged='3a068bf8-cdeb-11e8-8176-080027b0b461:1-10'; root@localhost [(none)] 15:57:58>set session sql_log_bin = 1;
执行help change master to 能够获取change master to命令 CHANGE MASTER TO MASTER_HOST='192.168.56.100', MASTER_USER='repl', MASTER_PASSWORD='wanbin', MASTER_PORT=3307, master_auto_position=1;
start slave; #若是想分别指定启动线程,可使用以下命令 START SLAVE IO_THREAD; START SLAVE SQL_THREAD; #一样关闭命令: STOP SLAVE; #分别关闭命令: STOP SLAVE IO_THREAD; STOP SLAVE SQL_THREAD;
因为基于GTID的复制依赖于事务,所以在使用时不支持MySQL中可用的某些功能。本节提供有关使用GTID进行复制的限制和限制的信息。
使用GTID时,使用非事务性存储引擎(如MyISAM)对表的更新不能在与使用事务性存储引擎(如InnoDB)的表的更新相同的语句或事务中进行。
此限制是因为对使用非事务性存储引擎的表的更新与对同一事务中使用事务存储引擎的表的更新混合可能致使将多个GTID分配给同一事务。
当master和slave使用不一样的存储引擎用于同一个表的相应版本时,也会发生这样的问题,其中一个存储引擎是事务性的而另外一个不是。 还要注意,定义为在非事务性表上运行的触发器多是致使这些问题的缘由。
在刚刚提到的任何一种状况下,事务和GTID之间的一对一对应关系被破坏,结果是基于GTID的复制没法正常运行。
CREATE TABLE … SELECT对于基于语句的复制是不安全的。 使用基于行的复制时,此语句实际上记录为两个单独的事件 - 一个用于建立表,另外一个用于将源表中的行插入刚刚建立的新表中。 当在事务中执行此语句时,在某些状况下,这两个事件可能会接收相同的事务标识符,这意味着slave将跳过包含插入的事务。 所以,使用基于GTID的复制时不支持CREATE TABLE … SELECT。
使用GTID时(即,enforce_gtid_consistency系统变量设置为ON时),事务,过程,函数和触发器内不支持CREATE TEMPORARY TABLE和DROP TEMPORARY TABLE语句。 能够在启用GTID的状况下使用这些语句,但仅限于任何事务以外,而且仅使用autocommit = 1。
要防止执行会致使基于GTID的复制失败的语句,必须在启用GTID时使用–enforce-gtid-consistency选项启动全部服务器。
使用GTID时不支持sql_slave_skip_counter
。 若是您须要跳过事务,请使用master的gtid_executed变量的值; 有关详细信息,请参考
https://dev.mysql.com/doc/refman/5.7/en/replication-gtids-failover.html#replication-gtids-failover-empty
使用GTID时,不推荐使用CHANGE MASTER TO
语句的IGNORE_SERVER_IDS
选项,由于已经应用的事务会自动被忽略。 在启动基于GTID的复制以前,请检查并清除以前在相关服务器上设置的全部忽略的服务器ID列表。 能够为各个通道发出的SHOW_SLAVE_STATUS语句显示已忽略的服务器ID列表(若是有)。 若是没有列表,则Replicate_Ignore_Server_Ids
字段为空。
若是目标服务器的二进制日志中没有GTID,则能够将使用mysqldump建立的转储导入到启用了GTID模式的MySQL服务器中。
当服务器在启用全局事务标识符(GTID)的状况下运行时(gtid_mode = ON),请不要经过mysql_upgrade启用二进制日志记录(–write-binlog选项)。