【问题标题】:MySQL InnoDB row/table lock when performing ALTER执行 ALTER 时 MySQL InnoDB 行/表锁
【发布时间】:2019-08-10 16:28:44
【问题描述】:

我创建了一个如下所示的 sysbench 表,其中包含 25,000,000 条记录(大小为 5.7G):

Create Table: CREATE TABLE `sbtest1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `k` int(11) NOT NULL DEFAULT '0',
  `c` char(120) NOT NULL DEFAULT '',
  `pad` char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `k_1` (`k`)
) ENGINE=InnoDB AUTO_INCREMENT=25000001 DEFAULT CHARSET=latin1

然后直接使用ALTER语句在c上添加索引,更新表大概需要18分钟,如下图:

mysql> alter table sbtest1  add index c_1(c);
Query OK, 0 rows affected (18 min 47.32 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show create table sbtest1\G
*************************** 1. row ***************************
       Table: sbtest1
Create Table: CREATE TABLE `sbtest1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `k` int(11) NOT NULL DEFAULT '0',
  `c` char(120) NOT NULL DEFAULT '',
  `pad` char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `k_1` (`k`),
  KEY `c_1` (`c`)
) ENGINE=InnoDB AUTO_INCREMENT=25000002 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

在表更新过程的 18 分钟内,我尝试通过插入新记录在表上执行一些事务,并更新列 c 上的现有记录,令我惊讶的是,当我期望锁定来防止这种情况时,这一切都起作用了从发生。我一直明白,对 InnoDB 表(尤其是大表)执行 ALTER 可能会在整个过程中导致记录锁定,所以想知道为什么我无法毫无问题地执行插入和更新?

以下是关于我的服务器的一些信息:

mysql> show variables like '%isolation%';
+-----------------------+-----------------+
| Variable_name         | Value           |
+-----------------------+-----------------+
| transaction_isolation | REPEATABLE-READ |
| tx_isolation          | REPEATABLE-READ |
+-----------------------+-----------------+

mysql> select version()
    -> ;
+-----------+
| version() |
+-----------+
| 5.7.25-28 |
+-----------+

对我来说,现在似乎在 MySQL 5.7 中,可以直接运行 ALTER 语句而不用担心锁?这是一个准确的结论吗?

更新 当我尝试删除添加的索引 c_1 时,只用了不到一秒钟,这也让我感到惊讶,因为我预计这比实际添加索引需要更长的时间。我一直认为添加索引简单快捷,但删除或更新索引需要很长时间,因为必须更改整个表结构。所以有点迷茫???

【问题讨论】:

  • 不时重新评估你的信念很重要:-)
  • 哈哈,我喜欢。一定会用的。

标签: mysql innodb alter-table


【解决方案1】:

Adding secondary index 可以就地完成并允许并发 DML。

【讨论】:

  • 汉克斯。因此,锁定仅在您对列执行 ALTER 时发生,例如更改列数据类型而不是在添加或删除索引时?
  • 同一页面列出了所有锁定的操作,即不“允许并发 DML”。如上所述,某些列修改可以在没有锁定的情况下进行。如果有疑问,请将LOCK=NONE 添加到您的ALTER TABLE 语句中,看看是否有错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-14
  • 1970-01-01
相关资源
最近更新 更多