关于 mysql innodb mvcc 的测试
a test about 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
table 架构:
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 水平是 repeatable 阅读,为什么这个更新 sql 有效?
我的隔离显示如下:
MariaDB [liruifeng]> show variables like 'tx_isolation';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tx_isolation | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.00 sec)
提前致谢:)
REPEATABLE-READ
表示 select * from test_a;
会在 t1 COMMITs
之前说同样的话。 UPDATE
可以看到第 4 行但 相同的 SELECT
不能看到这一事实很奇怪,但有效。
这很奇怪,在我使用 auto-commit = false 的实验中,由于插入条目上的记录 X 锁,更新将被阻止。
我现在正在学习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
table 架构:
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 水平是 repeatable 阅读,为什么这个更新 sql 有效?
我的隔离显示如下:
MariaDB [liruifeng]> show variables like 'tx_isolation';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tx_isolation | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.00 sec)
提前致谢:)
REPEATABLE-READ
表示 select * from test_a;
会在 t1 COMMITs
之前说同样的话。 UPDATE
可以看到第 4 行但 相同的 SELECT
不能看到这一事实很奇怪,但有效。
这很奇怪,在我使用 auto-commit = false 的实验中,由于插入条目上的记录 X 锁,更新将被阻止。