MySQL面试问题—复盘和测试

125 阅读3分钟

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。

序号33063306(其他事务)3307(从库开启事务)3308(从库未开事务)
1start transaction; 开启事务1
2select * from t; 空表无数据返回start transaction; 开启事务2start transaction; 开启事务3
3insert into t values(NULL,'a',now())
4select * from t; 返回主键为1的一条记录select * from t; 空表无数据返回select * from t; 空表无数据返回select * from t; 空表无数据返回select * from t; 空表无数据返回
5binlog日志还是master.000001,日志点是495从库Read_Master_Log_Pos: 495 Relay_Log_Pos: 702从库Read_Master_Log_Pos: 495 Relay_Log_Pos: 702
6rollback
7select * from t; 空表无数据返回select * from t; 空表无数据返回select * from t; 空表无数据返回select * from t; 空表无数据返回
8binlog日志还是master.000001,日志点是495从库Read_Master_Log_Pos: 495 Relay_Log_Pos: 702从库Read_Master_Log_Pos: 495 Relay_Log_Pos: 702
9ls -lh master.000001 日志文件的时间没有变更

2.测试insert,插入数据后,commit

序号33063306(其他事务)3307(从库开启事务)3308(从库未开事务)
1start transaction; 开启事务1
2select * from t; 空表无数据返回start transaction; 开启事务2start transaction; 开启事务3
3insert into t values(NULL,'a',now())
4select * from t; 返回主键为2的一条记录select * from t; 空表无数据返回select * from t; 空表无数据返回select * from t; 空表无数据返回select * from t; 空表无数据返回
5binlog日志还是master.000001,日志点是495从库Read_Master_Log_Pos: 495 Relay_Log_Pos: 702从库Read_Master_Log_Pos: 495 Relay_Log_Pos: 702
6commit
7select * from t; 返回主键为2的一条记录事务2未提交,select * from t; 空表无数据返回事务3未提交,select * from t; 空表无数据返回select * from t; 返回主键为2的一条记录
8binlog日志master.000001,日志点是766从库Read_Master_Log_Pos: 766 Relay_Log_Pos: 973,从库已经收到更改并应用从库Read_Master_Log_Pos: 766 Relay_Log_Pos: 973,从库已经收到更改并应用
9commit;commit;
10select * from t; 返回主键为2的一条记录select * from t; 返回主键为2的一条记录
11ls -lh master.000001 日志文件的时间已经变更

3.update/delete 与insert的操作结果相同。

  • 对于开启事务的情况,如果没有commit,其他事务是不可见更改的,其他从库也不可见更改。
  • 主库开启事务,在没有commit的情况下,主库其他事务更改不可见,从库对更改也不可见。
  • 主库开启事务,在commit的情况下,其他事务/从库有开启事务,则看不见变更后的值,且binlog也没有传送和应用到从库上。
  • 主库开启事务,在commit的情况下,其他事务/从库没有开启事务,则可以见到变更后的值。