1.主库事务未提交,其他事务/从库当前的现象(异步复制/半同步复制结果相同)
问题1: 当主库没有提交,binlog会发送嘛?从库会有什么变化?主库其他事务查询会有什么变化。
回答:
当主库使用start transaction开启事务后,进行了insert/delete/update操作,如果没有提交,其他事务不能查询到,从库的状态也不会改变。也没有收到binlog日志。
准备工作
测试环境:
10.1.1.1 3306 主库
10.1.1.1 3307
10.1.1.1 3308
数据库版本:MySQL 5.7.37
隔离级别:RR
测试表结构如下:
CREATE TABLE `t` (
`id` bigint(32) NOT NULL AUTO_INCREMENT,
`name` varchar(64) DEFAULT NULL,
`tt` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
)
当前库的数据和binlog日志
数据库名称:tm
表名称:t(没有数据,表为空)
创建表之后,当前的binlog日志信息
mysql> show master status;
+---------------+----------+--------------+------------------+----------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+----------------------------------------+
| master.000001 | 495 | | | ea1bd5d6xxxxxxx:1 |
+---------------+----------+--------------+------------------+----------------------------------------+
从库3307
mysql> show slave status \G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Log_File: master.000001
Read_Master_Log_Pos: 495
Relay_Log_File: relay-bin.000002
Relay_Log_Pos: 702
Relay_Master_Log_File: master.000001
从库3308
mysql> show slave status \G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Log_File: master.000001
Read_Master_Log_Pos: 495
Relay_Log_File: relay-bin.000002
Relay_Log_Pos: 702
Relay_Master_Log_File: master.000001
开始测试:
测试insert,插入数据后,rollback。
| 序号 | 3306 | 3306(其他事务) | 3307(从库开启事务) | 3308(从库未开事务) | |
|---|---|---|---|---|---|
| 1 | start transaction; 开启事务1 | ||||
| 2 | select * from t; 空表无数据返回 | start transaction; 开启事务2 | start transaction; 开启事务3 | ||
| 3 | insert into t values(NULL,'a',now()) | ||||
| 4 | select * from t; 返回主键为1的一条记录 | select * from t; 空表无数据返回 | select * from t; 空表无数据返回 | select * from t; 空表无数据返回 | select * from t; 空表无数据返回 |
| 5 | binlog日志还是master.000001,日志点是495 | 从库Read_Master_Log_Pos: 495 Relay_Log_Pos: 702 | 从库Read_Master_Log_Pos: 495 Relay_Log_Pos: 702 | ||
| 6 | rollback | ||||
| 7 | select * from t; 空表无数据返回 | select * from t; 空表无数据返回 | select * from t; 空表无数据返回 | select * from t; 空表无数据返回 | |
| 8 | binlog日志还是master.000001,日志点是495 | 从库Read_Master_Log_Pos: 495 Relay_Log_Pos: 702 | 从库Read_Master_Log_Pos: 495 Relay_Log_Pos: 702 | ||
| 9 | ls -lh master.000001 日志文件的时间没有变更 |
2.测试insert,插入数据后,commit
| 序号 | 3306 | 3306(其他事务) | 3307(从库开启事务) | 3308(从库未开事务) | |
|---|---|---|---|---|---|
| 1 | start transaction; 开启事务1 | ||||
| 2 | select * from t; 空表无数据返回 | start transaction; 开启事务2 | start transaction; 开启事务3 | ||
| 3 | insert into t values(NULL,'a',now()) | ||||
| 4 | select * from t; 返回主键为2的一条记录 | select * from t; 空表无数据返回 | select * from t; 空表无数据返回 | select * from t; 空表无数据返回 | select * from t; 空表无数据返回 |
| 5 | binlog日志还是master.000001,日志点是495 | 从库Read_Master_Log_Pos: 495 Relay_Log_Pos: 702 | 从库Read_Master_Log_Pos: 495 Relay_Log_Pos: 702 | ||
| 6 | commit | ||||
| 7 | select * from t; 返回主键为2的一条记录 | 事务2未提交,select * from t; 空表无数据返回 | 事务3未提交,select * from t; 空表无数据返回 | select * from t; 返回主键为2的一条记录 | |
| 8 | binlog日志master.000001,日志点是766 | 从库Read_Master_Log_Pos: 766 Relay_Log_Pos: 973,从库已经收到更改并应用 | 从库Read_Master_Log_Pos: 766 Relay_Log_Pos: 973,从库已经收到更改并应用 | ||
| 9 | commit; | commit; | |||
| 10 | select * from t; 返回主键为2的一条记录 | select * from t; 返回主键为2的一条记录 | |||
| 11 | ls -lh master.000001 日志文件的时间已经变更 |
3.update/delete 与insert的操作结果相同。
- 对于开启事务的情况,如果没有commit,其他事务是不可见更改的,其他从库也不可见更改。
- 主库开启事务,在没有commit的情况下,主库其他事务更改不可见,从库对更改也不可见。
- 主库开启事务,在commit的情况下,其他事务/从库有开启事务,则看不见变更后的值,且binlog也没有传送和应用到从库上。
- 主库开启事务,在commit的情况下,其他事务/从库没有开启事务,则可以见到变更后的值。