首页 > 数据库 > MySQL > MYSQL5.7-GTID概要翻译
18.1.3.1 GTID concept
1.GTID的生命周期
GTID当事务在coomit flush 阶段的时候会生产一个
GTID event,enent写入binlog,flush阶段最后会将整个事务的event提交给异步的dump线程,从库IO线程负责接受事务event,commit sync阶段进行OS sync写入binlog文件中。从库SQL apply这些事务event应用到从库,GTID写入从库binlog并落盘
2.译文
global transaction identifier 每一个事务提交的回收都会在主库上对应生成一个GTID,这个标识是唯一的,不仅是在主库唯一,是在所有的复制集间都是唯一的。 GTID = source_id:transaction_id mysqlbinlog --base64-output=DECODE-ROWS 或则在 SHOW BINLOG EVENTS的输出内容中可以看得到。 一旦使用了GTID我们不再需要从主库上获取任何本地信息,都是直接从复制数据流中获得。 GTID的生命周期包括以下几点: 1.事务在主库上执行然后提交 2.在二进制文件传到备库并写入备库的relay日志之后,备库读到gtid的值然后将它传给gtid_next,这即是告诉备库下一个事务需要使用这个gtid被记录到日志中。 3.备库会辨认这个gtid之前在自己记录事务日志的时候没有使用过,如果没有被使用过,slave会写下这个gtid,应用这个事务,然后写二进制日志。通过在处理事务之前首先检查事务的gtid, 这个不只确保了没有相同的gtid的事务被应用过,同时也确认了没有其他的会话已经读取了这个gtid只是没有提交关联的事务而已。换句话说,多个客户端是同时不允许应用相同的事务日志的。 4.因为gtid_next不为空,备库并不尝试为这个事务分配一个gtid而是写已经存好的值,这样的话,可以保证在主库获取gtid之后立即处理二进制日志中的事务。 如果二进制日志是disable,gtid会和对应的transaction一起存储到gtid_executed表里面去 如果log_bin=on,无论是日志切换或则数据库shutdown ,服务器都会将之前二进制日志鲜红的所有事务的gtid写进新的二进制日志。 如果服务器意外停止了,之前日志中的gtid没有被保存到gtid_executed中,这种情况下,恢复的时候会将其加入到表中以及系统参数gtid_executed中的。 gtid_executed会在reset master之后被重置 可以通过定期压缩几个事务记录到一条记录。通过设置 executed_gtids_compression_period 这个系统参数,可以控制几个事务写一次表,默认1000. 如果二进制日志开启了的话,这个参数是不生效的,每次日志切换的时候就会压缩这个表。 压缩表的线程是一个独立的前台线程,可以通过SELECT * FROM PERFORMANCE_SCHEMA.THREADS WHERE NAME LIKE '%gtid%'\G查看到。 18.1.3.2 使用GTID建立复制 1.如果已经开启了复制,先改成read-only状态,同步数据 2.停止所有的服务器 3.在GTID模式下重启所有的服务器,并配置好相应的配置。server_uuid必须存在以保证正确的运行 4.使用auto-positioning指定slave的master数据源,然后启动。 5.再次在所有服务器上开启读模式,让他们可以接受更新。 具体的步骤: 1、ysql> SET @@global.read_only = ON; 2、mysqladmin -uusername -p shutdown 3、shell> mysqld --gtid-mode=ON --enforce-gtid-consistency & ( --enforce-gtid-consistency这个选项是为了保证只有对GTID模式安全的语句才会被记录到日志中) 4、mysql> CHANGE MASTER TO MASTER_HOST = host, MASTER_PORT = port, MASTER_USER = user, MASTER_PASSWORD = password, MASTER_AUTO_POSITION = 1; 5、mysql> START SLAVE; 6、mysql> SET @@global.read_only = OFF;18.1.3.1 GTID concept global transaction identifier 每一个事务提交的回收都会在主库上对应生成一个GTID,这个标识是唯一的,不仅是在主库唯一,是在所有的复制集间都是唯一的。 GTID = source_id:transaction_id mysqlbinlog --base64-output=DECODE-ROWS 或则在 SHOW BINLOG EVENTS的输出内容中可以看得到。 一旦使用了GTID我们不再需要从主库上获取任何本地信息,都是直接从复制数据流中获得。 GTID的生命周期包括以下几点: 1.事务在主库上执行然后提交 2.在二进制文件传到备库并写入备库的relay日志之后,备库读到gtid的值然后将它传给gtid_next,这即是告诉备库下一个事务需要使用这个gtid被记录到日志中。 3.备库会辨认这个gtid之前在自己记录事务日志的时候没有使用过,如果没有被使用过,slave会写下这个gtid,应用这个事务,然后写二进制日志。通过在处理事务之前首先检查事务的gtid, 这个不只确保了没有相同的gtid的事务被应用过,同时也确认了没有其他的会话已经读取了这个gtid只是没有提交关联的事务而已。换句话说,多个客户端是同时不允许应用相同的事务日志的。 4.因为gtid_next不为空,备库并不尝试为这个事务分配一个gtid而是写已经存好的值,这样的话,可以保证在主库获取gtid之后立即处理二进制日志中的事务。 如果二进制日志是disable,gtid会和对应的transaction一起存储到gtid_executed表里面去 如果log_bin=on,无论是日志切换或则数据库shutdown ,服务器都会将之前二进制日志鲜红的所有事务的gtid写进新的二进制日志。 如果服务器意外停止了,之前日志中的gtid没有被保存到gtid_executed中,这种情况下,恢复的时候会将其加入到表中以及系统参数gtid_executed中的。 gtid_executed会在reset master之后被重置 可以通过定期压缩几个事务记录到一条记录。通过设置 executed_gtids_compression_period 这个系统参数,可以控制几个事务写一次表,默认1000. 如果二进制日志开启了的话,这个参数是不生效的,每次日志切换的时候就会压缩这个表。 压缩表的线程是一个独立的前台线程,可以通过SELECT * FROM PERFORMANCE_SCHEMA.THREADS WHERE NAME LIKE '%gtid%'\G查看到。 18.1.3.2 使用GTID建立复制 1.如果已经开启了复制,先改成read-only状态,同步数据 2.停止所有的服务器 3.在GTID模式下重启所有的服务器,并配置好相应的配置。server_uuid必须存在以保证正确的运行 4.使用auto-positioning指定slave的master数据源,然后启动。 5.再次在所有服务器上开启读模式,让他们可以接受更新。 具体的步骤: 1、mysql> SET @@global.read_only = ON; 2、mysqladmin -uusername -p shutdown 3、shell> mysqld --gtid-mode=ON --enforce-gtid-consistency & ( --enforce-gtid-consistency这个选项是为了保证只有对GTID模式安全的语句才会被记录到日志中) 4、mysql> CHANGE MASTER TO MASTER_HOST = host, MASTER_PORT = port, MASTER_USER = user, MASTER_PASSWORD = password, MASTER_AUTO_POSITION = 1; 5、mysql> START SLAVE; 6、mysql> SET @@global.read_only = OFF; 18.1.3.3 使用GTID实现故障切换以及扩展 几种不同的技术使用GTID 复制一个slave来实现扩展: 简单复制 拷贝数据以及事务到从库上 注入空事务 用gtid_purged排除事务 恢复GTID模式的slave 全局唯一标示加到mysql复制中为了实现简化数据流复制的日常管理以及特殊情况下的故障切换。 每个标示都唯一标示了部分组成一个二进制日志事件的事务,GTID在应用改变到数据库的过程中扮演了一个重要的角色。 服务器会自动跳过任何有已经被处理过的标示,这样对自动化的复制以及准确的故障切换很关键。 标示和构成事务的events的对应关系会记录在二进制日志中,这样会给从一个已有的服务器中拷取数据至一个新的服务器的过程中带来挑战。 为了在新的服务器上复制这些标示信息,在保持原有标示与实际的events之间的对应关系的情况下,从旧服务器上拷贝标示信息至新的服务器上显得至关重要了。 这对于恢复一个可以立即用于master角色的slave很有必要。 简单复制:最简单的复制所有的标示和事务的方法是建立一个主库的slave,然后再所有的服务器上都开启全局事务标示 一旦复制开始了,新的服务器会拷贝全部的主库所有的二进制日志,这样就可以获取到所有的关系gtid的信息。 这种方式是简单而有效的,但是要求slave去读取master的二进制日志,这个步骤有时候会很长一段时间使得备库追上主库, 所以这种方式不是很合适需要实现快速故障切换或则是快速恢复的场景。 拷贝数据和事务至slave上:回放所有的事务会比较消耗时间,会在建立slave的时候造成瓶颈。为了解决这个,数据的快照集,主库的二进制日志和全局事务信息对主库来说都很重要, 二进制日志是为了回放,回访完毕之后复制便可以开始了,使得slave成为剩下事务的当前镜像。 使用mysqldump的时候几个比较重要的参数列举如下: --master-data --set-gtid-purged --gtid-mode=ON 这种方法的优势在于基本上可以立即使用新的server,除了部分在创建快照或则恢复dump文件的时候还在提交事务需要从主库上获取外。 这意味着slave不是立即可用的,只是需要很短的一段时间以供备库追上主库的那一部分剩余的事务。 拷贝整个二进制日志一般会比从主库上读取整个事务历史执行记录要快。但是,由于文件大小以及其他的一些情景,不是所有情况下都能将这些文件拷贝至备库, 注入空事务:全局参数 gtid_executed 包括一套所有在主库上执行的事务。你可以在服务器上标记gtid_executed而不是在创建快照的时候拷贝二进制日志。在添加新的服务器至复制链上的时候, 为每个事务标示简单的提交一个空事务,像这样: SET GTID_NEXT='aaa-bbb-ccc-ddd:N'; BEGIN; COMMIT; SET GTID_NEXT='AUTOMATIC'; 一旦所有的事务标示都通过这种方式得以恢复,你必须flush和pruge备库的二进制日志,向这里这样,只是N是一个非0前缀的二进制文件名。 FLUSH LOGS; PURGE BINARY LOGS TO 'master-bin.00000N'; 你应该做这个操作为了阻止这台服务器执行错误的待会才会在主库上应用的事务,flush logs语句强制创建一个新的二进制日志文件,purge binary logs清除了空的事务,但是保留了他们的标示。 排除gtid_purge的事务:基于在创建了快照的服务器上的gtid_executed,你可以在备库上设置gtid_purge 恢复gtid模式下的slave:使用mysqlbinlog找到下一个event,也许是下一个日志文件的第一个event。 mysql> DELIMITER ; Restart replication from the correct position automatically: mysql> SET GTID_NEXT=automatic; mysql> RESET SLAVE; mysql> START SLAVE;
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/30018455/viewspace-2123864/ ,如需转载,请注明出处,否则将追究法律责任。