当前位置: 首页 > 科技观察

MySQL数据库主从技术GTID揭秘

时间:2023-03-23 11:36:55 科技观察

一、概述1.1GTID的概念GTID(globaltransactionidentifier)是mysqlMySQL-5.6.5支持的新特性之一。全局事务标识符不仅在源(主)服务器上是唯一的,而且在给定复制设置中的所有服务器中也是唯一的。也正是因为有这样一个特点,让mysql的主从复制变得更加简单和一致。它与源(主)服务器上提交的每个事务相关联,由服务器ID+事务ID组成。GTID=source_id:transaction_id,中间用“:”隔开,source_id用来标识原始服务器,通常是指server_uuid,由于GTID会传给slave,所以也可以理解为sourceID。transaction_id是当前服务器上提交的一笔交易的序号,一般是从1开始的自增序列,一个值对应一个交易。查看本机server_uuid的方法如下:mysql>showvariableslike'%uuid%';+----------------+-------------------------------------+|Variable_name|Value|+----------------+-------------------------------------+|server_uuid|f3d0a8b5-a657-11eb-a6e5-000c29dbd935|+------------+-----------------------------------+1rowinset(0.01sec)1.2GTID的工作原理1.当一个事务在主库端执行并提交时,会产生一个GTID记录在binlog日志中。2.binlog传给slave并存储到slave的relaylog中后,读取GTID的值,设置gtid_next变量,即告诉slave接下来要执行的GTID值。3、sql线程从relaylog中获取GTID,然后比较slave端的binlog是否有GTID。如果有表明GTID已经执行的事务,slave会忽略它。如果没有记录,slave会执行GTID的transaction。在执行之前,它会检查其他会话是否持有该GTID,以保证该GTID的事务不会被重复执行,并将该GTID记录到自己的binlog中。4.解析过程中会判断是否有主键。如果没有,就使用二级索引,如果没有,就进行全表扫描。1.3mysql.gtid_executed表GTID存放在mysql的gtid_executed表中。对于mysql服务器内部使用,此表中的一行代表每个GTID或GTID的集合,以及该集合的开始和结束事务ID;对于仅引用单个GTID的行,最后两个值相同。在mysql.gtid_executed中安装或升级MySQL服务器时,使用类似于以下的创建表语句创建表(如果它尚不存在):CREATETABLEgtid_executed(source_uuidCHAR(36)NOTNULL,interval_startBIGINT(20)NOTNULL,interval_endBIGINT(20)NOTNULL,PRIMARYKEY(source_uuid,interval_start))注意:与其他MySQL系统表一样,不要尝试自己创建或修改此表。GTID只有在gtid_mode为ON或ON_PERMISSIVE时才会存储在gtid_executed表中,而GTID的存储与mysql是否开启二进制日志密切相关。如果禁用二进制日志记录(log_binisOFF),或者如果使用log_slave_updates禁用二进制日志记录,则服务器将属于每个事务的GTID存储在具有该事务的表中。此外,该表会以用户可配置的速率定期压缩。这种情况仅适用于禁用了二进制日志记录或副本更新日志记录的副本。它不适用于复制源服务器,因为必须在源上启用二进制日志记录才能进行复制。如果启用二进制日志记录(log_bin为ON),每当二进制日志轮换或服务器关闭时,服务器会将写入先前二进制日志的所有事务的GTID写入mysql.gtid_executed表。启用二进制日志记录的复制源服务器或副本就是这种情况。如果服务器意外停止,则当前二进制日志文件中设置的GTID不会保存在mysql.gtid_executed表中。在恢复期间,这些GTID从二进制日志文件添加到表中。例外情况是在未启用二进制日志记录的情况下重新启动服务器。在这种情况下,服务器无法访问二进制日志文件来恢复GTID,因此无法启动复制。启用二进制日志记录后,mysql.gtid_executed表将不会保存所有已执行事务的GTID的完整记录。此信息由gtid_executed系统变量的全局值提供。始终使用@@GLOBAL.gtid_executed,它在每次提交后更新以表示MySQL服务器的GTID状态,而无需查询mysql.gtid_executed表。1.4mysql.gtid_executed表压缩随着时间的推移,mysql.gtid_executed表中可能会出现很多行,表会越来越大。为了节省空间,MySQL服务器mysql.gtid_executed使用了跨越事务标识符整个区间的一行通过如下替换每一行来定期压缩表:+--------------------------------------+----------------+------------+|source_uuid|interval_start|interval_end||-----------------------------------+----------------+------------||3E11FA47-71CA-11E1-9E33-C80AA9429562|37|43|...可以通过设置gtid_executed_compression_period系统变量来控制压缩率,默认为1000的值意味着默认情况下每1000个事务后将压缩表。将gtid_executed_compression_period设置为0根本不会执行压缩,并且gtid_executed应该准备好增加您的表可能需要的磁盘空间量,如果您这样做的话。mysql.gtid_executed表的压缩由名为thread/sql/compress_gtid_table的专用前台线程执行。SHOWPROCESSLIST的输出中没有列出该线程,但是可以在threads表中一行查看如下:mysql>SELECT*FROMperformance_schema.threadsWHERENAMELIKE'%gtid%'\GRESOURCE_GROUP:SYS_default**************************2.行******************************THREAD_ID:45NAME:thread/sql/compress_gtid_tableTYPE:FOREGROUNDPROCESSLIST_ID:6PROCESSLIST_USER:NULLPROCESSLIST_HOST:NULLPROCESSLIST_DB:NULLPROCESSLIST_COMMAND:DaemonPROCESSLIST_TIME:8757PROCESSLIST_STATE:SuspendingPROCESSLIST_INFO:NULLPARENT_THREAD_ID:1ROLE:NULLINSTRUMENTED:YESHISTORY:YESCONNECTION_TYPE:NULLTHREAD_OS_ID:7602RESOURCE_GROUP:SYS_default2rowsinset(0.01sec)二、GTID复制的优缺点2.1GTID优点1.更容易实现failover,不需要像以前那样去寻找log_file和log_pos。2.更容易搭建主从复制。3、比传统复制更安全。4、GTID连续无空洞,保证数据一致性,零丢失。2.2GTID限制1.不允许在同一个事务中对事务表和非事务进行DML操作,比如先更新innodb表,再在同一个事务中更新myisam表。因为GTID强制每个GTID对应一个事务,在同一个事务中同时操作innodbtable和myisam会产生两个GTID;2.CREATETABLE...SELECT语句是不允许的。首先,这个语句对于语句格式的binlog是不安全的;对于行格式的binlog,这条语句其实在binlog中记录了两个event,一个记录了create操作,一个记录了insert操作,那么有可能这两个操作对应同一个GTID,而当这两个相同GTID的events传到从库,从库会忽略相同GTID的insert操作,导致数据丢失;3.CREATETEMPORARYTABLE和DROPTEMPORARYTABLE不允许在事务中只能在事务内执行,autocommit=1;4、不支持sql_slave_skip_counter。如果需要跳过事务,可以使用下面的方法:set@@session.gtid_next='Transactiongtidtobeskipped'begin;commit;setsessiongtid_next=automatic;【小编推荐】这几天加了11000个star!谷歌必须推荐这个脚本工具一波大佬偷偷监控我的微信聊天...MicrosoftWindows10KB5003173更新安装失败因为没有新版本的Edge浏览器面试官:如何理解UDP和TCP?区别?应用场景?扬起开源的风帆,借官方认证考试之机,在NGINX领域脱颖而出

最新推荐
猜你喜欢