gtid主从报错When@@SESSION.GTID_NEXT is set to a GTID

当@@SESSION.GTID_NEXT设置为GTID时,必须在COMMIT或ROLLBACK后显式设置为不同的值。报错信息显示@@SESSION.GTID_NEXT为'039a0c0c-9cee-11e6-922c-525400a9bf0e:324065731',可能由于未正确处理GTID_NEXT变量导致。文章将探讨故障原因并提供复现及解决方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

故障现象

gtid主从报错信息

When@@SESSION.GTID_NEXT is set to a GTID, you must explicitly set it to a differentvalue after a COMMIT or ROLLBACK. Please check GTID_NEXT variable manual pagefor detailed explanation. Current @@SESSION.GTID_NEXT is'039a0c0c-9cee-11e6-922c-525400a9bf0e:324065731'.


故障可能原因

1 enforce_gtid_consistency为OFF,主库执行create table as select * from xx;
2 myisam引擎表,主库执行insert delayed into xx values...
3 主从引擎不一致,主库innodb引擎一个事务中写入两条数据,传到从库的myisam引擎执行这个事务

原因分析

根本原因是每一个GTID需要与一个唯一的事务对应
针对原因1,create table as select * from xx会自动转换成row模式,这时会拆成crate table和insert两个事务,这时传到slave时,slave执行完crate以后,多出一个insert事务没有gtid,于是报错;
针对原因2,只有myisam引擎支持insert delayed语法,insert delay是异步写入,也就是一旦执行立即返回给客户端成功。mysql内部处理insert delay时,会将多个线程的insert合并后一起执行,但是只生成了一个GTID;于是传到slave后,由于是myisam表,从库的同样只能执行第一条SQL,于是报错
针对原因3,主库innodb执行一个事务,只产生一个gtid,myisam不支持事务,事务的第一条执行完以后,第二个sql就没有gtid,于是报错

复现方法

1和3很好复现,忽略,讲下复现2的方法

1 运行两个进程并发insert delayed to myisam表
root     16511 28347  4 17:05 pts/0    00:00:00 /bin/bash ./test_myisam_delayinsert1.sh
root     18763 28347  4 17:05 pts/0    00:00:00 /bin/bash ./test_myisam_delayinsert.sh
root     22925 28347  0 17:05 pts/0    00:00:00 grep test
其中脚本内容为
cat test_myisam_delayinsert.sh 
#!/bin/bash
while true
do
mysql -S /opt/udb/instance/mysql-5.6/573c430f-5d26-4ac3-85e5-a3a40adbb05b/mysqld.sock -uucloudbackup -pQXYM4DFKM0 xx -e "insert delayed into test_myisam values(123)"
done
2 等待复现后,查看报错提示的gtid号为97127
3 去主库解析GTID 97127的binlog内容,可以看到一个myisam表,这个GTID下面却有两条SQL,该binlog传到slave,执行完第一条,第二条肯定就报错了(注意进程1和进程2的SQL内容包含在一个GTID中)
SET @@SESSION.GTID_NEXT= '910ed792-8300-11e7-ae6f-6c92bf218a02:97127'/*!*/;
# at 218335
#170818 16:56:44 server id 168407287  end_log_pos 218405 CRC32 0x56926f4e       Query   thread_id=246690        exec_time=0     error_code=0
SET TIMESTAMP=1503046604/*!*/;
BEGIN
/*!*/;
# at 218405
#170818 16:56:44 server id 168407287  end_log_pos 218457 CRC32 0xdf1693fd       Table_map: `xx`.`test_myisam` mapped to number 104
# at 218457
#170818 16:56:44 server id 168407287  end_log_pos 218497 CRC32 0x2fb8234a       Write_rows: table id 104 flags: STMT_END_F


BINLOG '
zKuWWRP3sAkKNAAAAFlVAwAAAGgAAAAAAAEAAnh4AAt0ZXN0X215aXNhbQABAwAB/ZMW3w==
zKuWWR73sAkKKAAAAIFVAwAAAGgAAAAAAAEAAgAB//7qAAAASiO4Lw==
'/*!*/;
### INSERT INTO `xx`.`test_myisam`
### SET
###   @1=234 /* INT meta=0 nullable=1 is_null=0 */
# at 218497
#170818 16:56:44 server id 168407287  end_log_pos 218549 CRC32 0xf4e4d63a       Table_map: `xx`.`test_myisam` mapped to number 104
# at 218549
#170818 16:56:44 server id 168407287  end_log_pos 218589 CRC32 0x2e19d842       Write_rows: table id 104 flags: STMT_END_F


BINLOG '
zKuWWRP3sAkKNAAAALVVAwAAAGgAAAAAAAEAAnh4AAt0ZXN0X215aXNhbQABAwABOtbk9A==
zKuWWR73sAkKKAAAAN1VAwAAAGgAAAAAAAEAAgAB//57AAAAQtgZLg==
'/*!*/;
### INSERT INTO `xx`.`test_myisam`
### SET
###   @1=123 /* INT meta=0 nullable=1 is_null=0 */
# at 218589
#170818 16:56:44 server id 168407287  end_log_pos 218660 CRC32 0x4124e705       Query   thread_id=246690        exec_time=0     error_code=0
SET TIMESTAMP=1503046604/*!*/;
COMMIT

<think>嗯...用户这次的问题非常具体啊,涉及到MySQL的两个深层错误:SSL记录层失败(167772473)和session_track_gtids事务冲突。看来用户在配置MySQL路由时遇到了棘手的安全连接问题。用户提到"SSLroutinesrecordlayerfailuretls_err:167772473"这个错误代码167772473需要重点关注。查过资料发现,这通常对应OpenSSL的SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN错误,意味着证书验证环节出了致命问题。而另一个错误"session_track_gtidscannotbesetduringongoingtransaction"明显是事务状态冲突,用户可能在不恰当的时机修改变量。考虑到用户提到"mysqlroutingerror",应该是在使用MySQLRouter时出现的组合错误。这里需要分两个层面处理:首先是SSL证书链的完整性验证,包括客户端是否信任服务器证书;其次是事务管理规范问题,需要检查session_track_gtids的修改时机。上次对话历史提到系统指令要求技术回答遵循特定格式,所以这次在解决方案里要特别注意:1)SQL语句用反引号包裹2)配置参数保持原始拼写3)证书路径这类关键信息用$...$标注。不过用户看起来是资深DBA,可以直接给专业方案不用过多基础解释。用户似乎很着急,错误提示直接复制粘贴过来的,连标点符号都没调整。应该是在生产环境遇阻了,需要快速可操作的解决方案。特别要注意提醒用户先在测试环境验证CA证书配置方案,毕竟错误的证书操作会导致服务中断。</think> 这个组合错误涉及 **SSL连接失败** 和 **MySQL事务状态冲突**,通常发生在使用MySQL Router或客户端连接时。以下是分步解决方案: --- ### 一、解决 SSL记录层失败(`tls_err:167772473`) 此错误表明SSL/TLS握手失败,常见原因及修复方法: 1. **证书验证失败** - **检查证书链完整性**:确保服务端证书包含完整CA链 ```bash openssl s_client -connect mysql_server:3306 -showcerts > chain.pem ``` - **客户端添加CA证书**:在客户端配置文件中指定可信CA ```ini [client] ssl-ca = /path/to/ca.pem ``` *注:路径替换为实际CA证书路径* 2. **协议/密码套件不兼容** - **升级OpenSSL**:确保客户端/服务端使用OpenSSL 1.1.1+ - **强制TLSv1.2+**(在MySQL配置中): ```ini [mysqld] tls_version = TLSv1.2,TLSv1.3 ``` 3. **证书域名不匹配** - 检查证书SAN(Subject Alternative Name)是否包含服务器域名 - 测试连接跳过验证(仅测试用): ```bash mysql --ssl-mode=VERIFY_IDENTITY --ssl-ca=ca.pem -h host ``` --- ### 二、解决 `session_track_gtids` 事务冲突 此错误因在**事务中修改系统变量**导致: 1. **检查事务边界** ```sql SHOW SESSION STATUS LIKE 'Com_commit'; -- 确认是否有未提交事务 ``` 2. **修正操作顺序** ```sql /* 错误示例(事务内修改变量) */ START TRANSACTION; SET SESSION session_track_gtids = ALL_GTIDS; -- 触发错误 COMMIT; /* 正确操作 */ SET SESSION session_track_gtids = ALL_GTIDS; -- 先设置变量 START TRANSACTION; -- 再开启事务 ... -- 业务操作 COMMIT; ``` 3. **应用层检查** - 在代码中确保修改变量时无活跃事务 - 框架如JDBC需检查`autoCommit=false`状态 --- ### 三、MySQL Routing错误处理 若使用MySQL Router,需同步调整: 1. **Router配置验证** ```ini [routing:failover] ssl_mode = PREFERRED # 改为VERIFY_CA或VERIFY_IDENTITY ssl_ca = /router/ca.pem ``` 2. **重启Router前清理状态** ```bash mysqlrouter --bootstrap user@host:port --directory /tmp/router --conf-use-sockets ``` --- ### 关键检查点总结 | 问题类型 | 检查项 | 修复工具 | |---------|-------|---------| | SSL失败 | 证书链完整性 | `openssl verify -CAfile ca.pem server-cert.pem` | | | TLS协议版本 | MySQL的`tls_version`参数 | | GTID冲突 | 事务状态 | `SHOW PROCESSLIST` | | | 变量修改时机 | 应用层事务控制器 | > **操作建议**:<br/> > 1. 先在测试环境验证CA证书配置方案[^1] <br/> > 2. 使用`SET GLOBAL general_log=1`捕获精确错误发生位置<br/> > 3. 对于生产环境,建议通过`ALTER INSTANCE RELOAD TLS`动态重载证书[^2] [^1]: MySQL官方证书配置文档:https://dev.mysql.com/doc/refman/8.0/en/creating-ssl-rsa-files.html [^2]: 动态重载TLS说明:https://dev.mysql.com/doc/refman/8.0/en/alter-instance.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值