墨墨导读:对于MySQL GTID,经过多年的磨炼已经很稳定了,作为position方式的延伸,在如今使用环境中带来了很多方便。本文分享GTID技术点的汇总。 MySQL复制不管用那个方式,都离不开binlog方式进行的。GTID作为position方式的延伸,在如今使用环境中带来了很多方便。下面一步一步的把gtid相关的知识点复习一下。 基础 先了解复制的基本原理: 1. MySQL复制方式 master用户写入数据,生成event记到binary log中. slave接收master上传来的binlog,然后按顺序应用,重现master上的操作。 2. 日志记录上position方式和GTID方式区别 直观图对比:
3. GTID优势
冷门功能:接口 这类接口MySQL初期是为了通过开发接口,解决执行状态和复制延迟的跟踪准备的。但现在基本不适用。 1. FUNCTION
参考:https://dev./doc/refman/5.7/en/gtid-functions.html 2. API 跟踪gtid从库接受的情况,返回值:成功的为零。发生错误时非零。
网上分析案例: DROP TABLE IF EXISTS test.t1; CREATE TABLE test.t1 (i INT, f FLOAT); --enable_session_track_info SET @@SESSION.session_track_schema=ON; SET @@SESSION.session_track_system_variables='*'; SET @@SESSION.session_track_state_change=ON; USE information_schema; SET NAMES 'utf8mb4'; SET @@SESSION.session_track_transaction_info='CHARACTERISTICS'; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; SET TRANSACTION READ WRITE; START TRANSACTION; SELECT 1; INSERT INTO test.t1 () VALUES(); INSERT INTO test.t1 () VALUES(1, RAND()); COMMIT; shell> mysqltest < testscript DROP TABLE IF EXISTS test.t1; CREATE TABLE test.t1 (i INT, f FLOAT); SET @@SESSION.session_track_schema=ON; SET @@SESSION.session_track_system_variables='*'; -- Tracker : SESSION_TRACK_SYSTEM_VARIABLES -- session_track_system_variables -- * SET @@SESSION.session_track_state_change=ON; -- Tracker : SESSION_TRACK_SYSTEM_VARIABLES -- session_track_state_change -- ON USE information_schema; -- Tracker : SESSION_TRACK_SCHEMA -- information_schema -- Tracker : SESSION_TRACK_STATE_CHANGE -- 1 SET NAMES 'utf8mb4'; -- Tracker : SESSION_TRACK_SYSTEM_VARIABLES -- character_set_client -- utf8mb4 -- character_set_connection -- utf8mb4 -- character_set_results -- utf8mb4 -- Tracker : SESSION_TRACK_STATE_CHANGE -- 1 SET @@SESSION.session_track_transaction_info='CHARACTERISTICS'; -- Tracker : SESSION_TRACK_SYSTEM_VARIABLES -- session_track_transaction_info -- CHARACTERISTICS -- Tracker : SESSION_TRACK_STATE_CHANGE -- 1 -- Tracker : SESSION_TRACK_TRANSACTION_CHARACTERISTICS -- -- Tracker : SESSION_TRACK_TRANSACTION_STATE -- ________ SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; -- Tracker : SESSION_TRACK_TRANSACTION_CHARACTERISTICS -- SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; SET TRANSACTION READ WRITE; -- Tracker : SESSION_TRACK_TRANSACTION_CHARACTERISTICS -- SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; SET TRANSACTION READ WRITE; START TRANSACTION; -- Tracker : SESSION_TRACK_TRANSACTION_CHARACTERISTICS -- SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; START TRANSACTION READ WRITE; -- Tracker : SESSION_TRACK_TRANSACTION_STATE -- T_______ SELECT 1; 1 1 -- Tracker : SESSION_TRACK_TRANSACTION_STATE -- T_____S_ INSERT INTO test.t1 () VALUES(); -- Tracker : SESSION_TRACK_TRANSACTION_STATE -- T___W_S_ INSERT INTO test.t1 () VALUES(1, RAND()); -- Tracker : SESSION_TRACK_TRANSACTION_STATE -- T___WsS_ COMMIT; -- Tracker : SESSION_TRACK_TRANSACTION_CHARACTERISTICS -- -- Tracker : SESSION_TRACK_TRANSACTION_STATE -- ________ ok 参考: 判断方式 1. 如何判断复制方式GTID 还是 pos Show slave status 查看Auto_Position字段。0是pos 方式, 1是gtid方式。 gtid变更为pos方式: change master to master_auto_position=0; 2. 当前执行gtid信息 mysql> SELECT @@GLOBAL.GTID_EXECUTED; +----------------------------------------------+ | @@GLOBAL.GTID_EXECUTED | +----------------------------------------------+ | 39d0a7f2-702c-11ea-92a0-000c29b9a76d:1-46534 | +----------------------------------------------+
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
常用命令 1. gtid设置 gtid_mode=ON #必选 2. gtid跳过 gtid_next stop slave; 备注;该操作类似于sql_slave_skip_counter,只是跳过错误,不能保证数据一致性,需要人工介入,固强烈建议从机开启read_only=1 3. gtid清除gtid_pureged 命令的实际意义:因没有binlog信息(expire_logs_days),不考虑这些gtid确认和回滚。常用备份恢复,搭建从库的时候使用。 使用场景:
mysqldump --set-gtid-purged=off/on 参数; 4. gtid升级 pos升级gtid方式,条件允许建议重新搭建从库的方式。以下方式存在风险。
从position模式切换到GTID模式: 1)在每个sever执行WARN模式: mysql>SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = WARN; 2)在每个sever执行ON模式: mysql>SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = ON; 3)在每个sever执行OFF模式: mysql>SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE; 4)在每个sever执行ON模式: mysql>SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE; 5)在每个服务器上,等待状态变量ONGOING_ANONYMOUS_TRANSACTION_COUNT为零. 可以使用如下方式查询: mysql>SHOW STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT'; 等待生成到步骤5的所有事务复制到所有服务器. 可以在不停止更新的情况下执行此操作:唯一重要的是所有anonymous transactions都被复制了. 6)GTID_MODE = ON在每所有服务器上执行: mysql>SET @@GLOBAL.GTID_MODE = ON; 7)修改每个my.cnf文件: gtid-mode=ON 8)上面复制虽然配置了GTID模式,但还是基于Binlog方式的。可通过选项MASTER_AUTO_POSITION设置为1,把复制调整为基于GTID模式的复制,具体操作如下: mysql>STOP 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_state from `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相关信息 限制 到目前为止已经发展完善,但存在一些场景是受限的。 2. 临时表的限制 3.事务操作 4.mysql_upgrade 5.sql_slave_skip_counter 总结 1. gtid能不能做的更好。
2. gtid的技术点的汇总图。 |
|