一个关于mysql innodb mvcc的测试

时间:2017-08-30 09:50:56

标签: mysql innodb mvcc

我现在正在学习InnoDB mvcc,我尝试了如下测试节目:

Mysql版本:

[root@mysql-test ~]# mysql --version
mysql  Ver 15.1 Distrib 5.5.52-MariaDB, for Linux (x86_64) using readline 5.1

表架构:

MariaDB [liruifeng]> show create table test_a;
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table  | Create Table                                                                                                                                          |
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------+
| test_a | CREATE TABLE `test_a` (
  `id` int(11) NOT NULL DEFAULT '0',
  `a` char(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

然后用这样的数据初始化:

MariaDB [liruifeng]> select * from test_a;
+----+------+
| id | a    |
+----+------+
|  1 | 1    |
|  2 | 2    |
|  3 | 3    |
+----+------+
3 rows in set (0.00 sec)

首先我在不同的终端开了两个会话,测试步骤显示为风箱:

T1:

MariaDB [liruifeng]> start transaction;
Query OK, 0 rows affected (0.00 sec)

MariaDB [liruifeng]> select * from test_a;
+----+------+
| id | a    |
+----+------+
|  1 | 1    |
|  2 | 2    |
|  3 | 3    |
+----+------+
3 rows in set (0.00 sec)

T2:

MariaDB [liruifeng]> insert into test_a values (4,4);
Query OK, 1 row affected (0.01 sec)

MariaDB [liruifeng]> select * from test_a;
+----+------+
| id | a    |
+----+------+
|  1 | 1    |
|  2 | 2    |
|  3 | 3    |
|  4 | 4    |
+----+------+
4 rows in set (0.00 sec)

T1:

MariaDB [liruifeng]> select * from test_a;
+----+------+
| id | a    |
+----+------+
|  1 | 1    |
|  2 | 2    |
|  3 | 3    |
+----+------+
3 rows in set (0.00 sec)

MariaDB [liruifeng]> update test_a set a = 444 where id = 4;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

MariaDB [liruifeng]> select * from test_a;
+----+------+
| id | a    |
+----+------+
|  1 | 1    |
|  2 | 2    |
|  3 | 3    |
|  4 | 444  |
+----+------+
4 rows in set (0.00 sec)

让我感到困惑的是,为什么t1可以在t1提交之前用t2更新行插入?我的tx_isolation级别是可重复读取的,为什么这个更新sql会起作用?

我的隔离节目如风:

MariaDB [liruifeng]> show variables like 'tx_isolation';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| tx_isolation  | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.00 sec)

感谢进步:)

2 个答案:

答案 0 :(得分:0)

REPEATABLE-READselect * from test_a;在t1 COMMITs之前会说同样的话。 UPDATE可以看到第4行但相同 SELECT的事实不是很奇怪,但有效。

答案 1 :(得分:0)

这很奇怪,在我使用auto-commit = false的实验中,由于插入条目上的记录X锁定,更新将被阻止。