mysql> SELECT * FROM mysql.gtid_executed;
mysql.gtid_executed表是由MySQL服务器提供给内部使用的。它允许副本在副本上禁用二进制日志记录时使用GTIDs,并允许在二进制日志丢失时保留GTID状态。RESET MASTER命令,gtid_executed表将被清除。
服务意外停止的情况下,当前二进制日志文件中的gtid集不会保存在gtid_executed表。在恢复期间,这些gtid将从二进制日志文件添加到表中,以便可以继续复制。
3. gtid_executed
若MySQL服务器启用了二进制日志,则表mysql.gtid_executed的更新仅在二进制rotation时发生,因为发生重启等情况依旧可以通过扫描二进制日志判断得知当前运行的GTID位置。
简单来说,该表会记录当前执行的GTID
在MySQL 5.6中必须配置参数log_slave_updates的最重要原因在于当slave重启后,无法得知当前slave已经运行到的GTID位置,因为变量gtid_executed是一个内存值:
MySQL 5.7将gtid_executed这个值给持久化。采用的技巧与MySQL 5.6处理SQL thread保存位置的方式一样,即将GTID值持久化保存在一张InnoDB表中,并与用户事务一起进行提交,从而实现数据的一致性。
触发条件:
在binlog发生rotate(flush binary logs/达到max_binlog_size)或者关闭服务时,会把所有写入到binlog中的Gtid信息写入到mysql.gtid_executed表。
从库:如果没有开启log_bin或者没有开启log_slave_updates,从库在应用relay-log中的每个事务会执行一个insert mysql.gtid_executed操作。
常用命令
1. gtid设置
gtid_mode=ON #必选
enforce-gtid-consistency=true #必选
log-bin=mysql #5.6必选 5.7.5和它之后可选,为了高可用,最好设置
server-id=1 #开启log-bin的必须设置
log-slave-updates=ON # 5.6必选 5.7.5和它之后可选,为了高可用切换,最好设置ON
2. gtid跳过 gtid_next
stop slave;
set gtid_next='d74faa2d-5819-11e8-b248-ac853db70398:10603';
begin;commit;
set gtid_next='automatic';
start slave;
备注;该操作类似于sql_slave_skip_counter,只是跳过错误,不能保证数据一致性,需要人工介入,固强烈建议从机开启read_only=1
3. gtid清除gtid_pureged
命令的实际意义:因没有binlog信息(expire_logs_days),不考虑这些gtid确认和回滚。常用备份恢复,搭建从库的时候使用。
自动触发机制:flush,服务器重新启动
使用场景:
在副本上禁用二进制日志记录提交的复制事务的GTIDs。
写入二进制日志文件的事务的GTIDs,该文件现在已被清除。
通过语句set @@GLOBAL.gtid_purged显式添加到集合中的gtid。
mysqldump --set-gtid-purged=off/on 参数;
是否将GTID_PURGED’添加到输出中
4. gtid升级
pos升级gtid方式,条件允许建议重新搭建从库的方式。以下方式存在风险。
gtid_mode可选值
ON:完全打开GTID,如果打开状态的备库接受到不带GTID的事务,则复制中断
ON_PERMISSIV:可以认为是打开gtid前的过渡阶段,主库在设置成该值后会产生GTID,同时备库依然容忍带GTID和不带GTID的事务
OFF_PERMISSIVE:可以认为是关闭GTID前的过渡阶段,主库在设置成该值后不再生成GTID,备库在接受到带GTID和不带GTID事务都可以容忍。主库在关闭GTID时,执行事务会产生一个Anonymous_Gtid事件,会在备库执行:set @@session.gtid_next=‘anonymous’
OFF:彻底关闭GTID,如果关闭状态的备库收到带GTID的事务,则复制中断
从position模式切换到GTID模式:
1)在每个sever执行WARN模式:
这一步设置之后,使得所有事物都允许违反GTID的一致性
mysql>SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = WARN;
#这是第一个重要步骤. 您必须确保在进入下一步骤之前不会在错误日志中生成警告.
2)在每个sever执行ON模式:
以确保所有的事务都不能违反GTID一致性
mysql>SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = ON;
3)在每个sever执行OFF模式:
这一步表示,新的事务是匿名的,同事允许复制的事务是GTID或是匿名的
mysql>SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE;
#需要确保这一步操作在所有的服务器上执行
4)在每个sever执行ON模式:
这一步表示,新的事务是GTID的,同事允许复制的事务是GTID或是匿名的
mysql>SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE;
#需要确保这一步操作在所有的服务器上执行
5)在每个服务器上,等待状态变量ONGOING_ANONYMOUS_TRANSACTION_COUNT为零. 可以使用如下方式查询:
mysql>SHOW STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT';
#在所有从库上查询该状态,必须为0 才能进行下一步。该状态宝石已标示为匿名的正在#进行的事务数量,如果状态值为0表示无事务等待被处理
等待生成到步骤5的所有事务复制到所有服务器. 可以在不停止更新的情况下执行此操作:唯一重要的是所有anonymous transactions都被复制了.
6)GTID_MODE = ON在每所有服务器上执行:
mysql>SET @@GLOBAL.GTID_MODE = ON;
7)修改每个my.cnf文件:
gtid-mode=ON
ENFORCE_GTID_CONSISTENCY = ON
8)上面复制虽然配置了GTID模式,但还是基于Binlog方式的。可通过选项MASTER_AUTO_POSITION设置为1,把复制调整为基于GTID模式的复制,具体操作如下:
mysql>STOP SLAVE [FOR CHANNEL 'channel'];
mysql>CHANGE MASTER TO MASTER_AUTO_POSITION = 1 [FOR CHANNEL 'channel'];
mysql>START SLAVE [FOR CHANNEL 'channel'];
5. gtid 压缩 gtid_executed_compression_period
启用GTID时,服务器会定期在mysql.gtid_executed表上执行此类压缩。通过设置gtid_executed_compression_period系统变量,可以控制压缩表之前允许的事务数,从而控制压缩率。该变量的默认值为1000; 这意味着,默认情况下,在每1000次事务之后执行表压缩。
将gtid_executed_compression_period设置为0可以防止执行压缩; 但是,如果执行此操作,应该为gtid_executed表可能需要的磁盘空间量的大幅增加做好准备。
使用以下语句查询:
mysql> select thread_id,thread_os_id,name, processlist_command,processlist_statefrom `performance_schema`.threads where name like '%compress%';+-----------+--------------+--------------------------------+---------------------+-------------------+| thread_id |thread_os_id | name |processlist_command | processlist_state |+-----------+--------------+--------------------------------+---------------------+-------------------+| 26 |8024| thread/sql/compress_gtid_table |Daemon | Suspending |+-----------+--------------+--------------------------------+---------------------+-------------------+
备注:如发现 processlist_state 值一直是: "Compressing gtid_executed table"说明进行压缩。记录锁的内存从操作系统申请,所以当表gtid_executed不断增大时,最终会导致MySQL OOM。
6. binlog_gtid_simple_recovery
MySQL启动或重启时在搜索GTIDs期间迭代二进制日志文件的方式。就是为了初始化 gtid_executed , gtid_purged参数,扫描binlog 或则 event相关信息
MySQL 5.7.7或更老版本的二进制日志,需要在设置binlog_gtid_simple_recovery=FALSE,如果存在非gtid的binlog比较多的时候,会非常影响性能的。
限制
到目前为止已经发展完善,但存在一些场景是受限的。
1. create table xxx as select:
拆分成两部分:
create table xxxx like table;
insert into xxxx select *from table;
2. 临时表的限制
使用GTID复制模式:
1.不支持create temporary table 和 drop temporary table。
2.在autocommit=1的情况下可以创建临时表,
3.Master端创建临时表不产生GTID信息,所以不会同步到slave,但是在删除临时表的时候会产生GTID会导致,主从中断.
3.事务操作
涉及非事务性存储引擎的更新,非事务性存储引擎事务性存储引擎更新表则不能在同一条语句或同一事务中执行。
4.mysql_upgrade
GTID模式和mysql_upgrade。在启用全局事务标识符(GTIDs)的情况下运行时,不要通过mysql_upgrade(——write binlog选项)启用二进制日志记录。
5.sql_slave_skip_counter
传统模式的跳过postion方式gtid模式下不支持。
总结
1. gtid能不能做的更好。返回搜狐,查看更多
像并行复制的writeset一样 压缩机制
binlog内容能不能更简洁
gtid能不能实现物理级别的复制模式