问题现象
上周RDS组同事反馈了一个问题:
对RDS高可用实例进行主从切换时,主上设置super_read_only后,show master status记录了对应的Binlog文件及偏移位置pos1。从上等待复制线程完成所有relay-log回放后,show slave status获取slave此时执行到主上Binlog文件及偏移位置pos2,发现pos2>pos1,似乎数据不一致了,非常奇怪。此时从已经被重建,但还主还在,获取了主上pos1~pos2的Binlog信息。结果是一个xa commit。
问题定位
莫非xa commit不受super_read_only控制吗?于是做了个实验:
XA事务场景
session 1:
mysql>create database xatest;
Query OK, 1 row affected (0.01 sec)
mysql>use xatest;
Database changed
mysql>create table xatable (a int primary key);
Query OK, 0 rows affected (0.00 sec)
mysql>xa start '1';
Query OK, 0 rows affected (0.00 sec)
mysql>insert into xatable values (1);
Query OK, 1 row affected (0.01 sec)
mysql>xa end '1';
Query OK, 0 rows affected (0.00 sec)
session 2:
mysql>set global super_read_only=on;
Query OK, 0 rows affected (0.00 sec)
session 1:
mysql>xa prepare '1';
Query OK, 0 rows affected (0.00 sec)
mysql>xa commit '1';
Query OK, 0 rows affected (0.01 sec)
看起来super_read_only确实对xa事务操作没用。不过在xa事务还处于活跃状态时不能在同一个session下设置super_read_only。进一步测试发现如果在
mysql>insert into xatable values (1);
Query OK, 1 row affected (0.01 sec)
之前设置了super_read_only,那么insert是无法执行的,这个逻辑没有问题。
普通事务场景
进一步测试了普通事务的场景:
session 1:
mysql>set global super_read_only=off;
Query OK, 0 rows affected (0.00 sec)
mysql>begin;
Query OK, 0 rows affected (0.00 sec)
mysql>insert into xatable values (11);
Query OK, 1 row affected (0.00 sec)
session 2:
mysql>set global super_read_only=on;
Query OK, 0 rows affected (0.00 sec)
session 1:
mysql>commit;
ERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement
session 2:
mysql>set global super_read_only=off;
Query OK, 0 rows affected (0.00 sec)
session 1:
mysql>commit;
Query OK, 0 rows affected (0.00 sec)
普通事务的commit被super_read_only所阻挡。符合预期。
问题反馈
进一步测试了其他xa事务命令,基于测试结果,显然super_read_only无法阻止xa事务操作命令。
给官方反馈了该问题,已被确认。
问题挺简单,修复也容易,不过影响还是比较大的。对于使用MySQL XA事务的业务容易掉坑里。