【问题标题】:a test about mysql innodb mvcc关于mysql innodb mvcc的一个测试
【发布时间】:2017-08-30 09:50:55
【问题描述】:

我现在正在学习 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)

提前感谢:)

【问题讨论】:

  • 我在一个终端上看到START,那么另一个呢? autocommit 的值是多少?
  • @RickJames 是的,自动提交:)

标签: mysql innodb mvcc


【解决方案1】:

REPEATABLE-READ 表示select * from test_a; 会说同样的话,直到 t1 COMMITsUPDATE 可以看到第 4 行但 相同 SELECT 不能看到这一事实很奇怪,但有效。

【讨论】:

  • 因此,如果程序尝试使用诸如“a
  • UPDATE ... WHERE a<5 将锁定(在某种程度上)所有这些行。 WHERE a=5 只会锁定一行。通常,交易速度如此之快,以至于像这样的微妙问题都不是问题。生产系统需要几毫秒,而不是像 t1 和 t2 这样的语句之间的秒数。
【解决方案2】:

这很奇怪,在我使用 auto-commit = false 的实验中,更新会因为插入条目上的记录 X 锁定而阻塞。

【讨论】:

    猜你喜欢
    • 2016-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-04
    • 2013-02-20
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    相关资源
    最近更新 更多