MySQL高可用实践
上QQ阅读APP看书,第一时间看更新

3.6 GTID限制

1. 涉及非事务存储引擎的更新

使用GTID时,一条语句或一个事务中,不能对非事务性存储引擎如MyISAM表和事务存储引擎(如InnoDB表)同时更新,因为这种混合引擎同时更新可能导致将多个GTID分配给同一个事务。下面两组命令都会报同样的错误。

错误信息:

在MySQL 8中,这个限制并没有多大影响,因为包括系统表在内都是InnoDB表,默认已经没有myisam表了,除非用户建表时显示定义。

2. CREATE TABLE ... SELECT语句

CREATE TABLE ...使用基于GTID的复制时不允许使用SELECT语句。当binlog_format设置为STATEMENT时,CREATE TABLE ... SELECT语句作为一个具有单一GTID的事务记录在二进制日志中。但如果使用ROW格式,则该语句将记录为具有两个GTID的两个事务。如果主服务器使用STATEMENT格式而从服务器使用ROW格式,则从服务器将无法正确处理事务,因此GTID不允许使用CREATE TABLE ... SELECT语句来防止出现这种情况。

3. 临时表

当binlog_format设置为STATEMENT,在服务器上启用GTID时,不能在事务、过程、函数或触发器内使用CREATE TEMPORARY TABLE和DROP TEMPORARY TABLE语句。如果设置了autocommit=1,则可以在使用GTID时在这些上下文之外使用它们。从MySQL 8.0.13开始,当binlog_format设置为ROW或MIXED且启用GTID时,允许在事务、过程、函数或触发器内使用CREATE TEMPORARY TABLE和DROP TEMPORARY TABLE语句。这些语句不会写入二进制日志,因此不会复制到从库。

要防止执行会导致基于GTID的复制失败的语句,必须在启用GTID时使用--enforce-gtid-consistency选项启动所有服务器。这会导致前面讨论的语句失败并显示错误。

4. 忽略服务器

使用GTID时,不推荐使用CHANGE MASTER TO语句的IGNORE_SERVER_IDS选项,因为已经应用的事务会自动被忽略。在启动基于GTID的复制之前,需要检查并使用CHANGE MASTER TO IGNORE_SERVER_IDS=()清除之前在相关服务器上设置的所有忽略的服务器ID列表。可以为各个通道发出的SHOW SLAVE STATUS语句显示被忽略的服务器ID列表。如果没有,则Replicate_Ignore_Server_Ids字段为空。

5. GTID模式和mysqldump

可以将使用mysqldump创建的转储导入到启用了GTID模式的MySQL服务器中,前提是目标服务器的二进制日志中没有重叠的GTID。