复制到 tmp table 自动增量改变 table

copy to tmp table which alter table on auto increment

我们遇到了 MySql (5.5.x) 的问题,希望您能帮助我们。 在白天的某个时候,我注意到一个状态为“copy to tmp table”的进程,以及这个查询:

ALTER TABLE `MyTableName` AUTO_INCREMENT=200000001

在此之后,所有其他查询都会获得“等待 table 元数据锁定”,并且所有查询都会冻结,并且不会进行任何处理。

我需要终止该进程,然后重新启动所有查询。

为什么?我该如何解决这个问题?

在 MySQL 5.5 中,像您 运行 这样的 ALTER TABLE 会复制整个 table。 table 越大,花费的时间就越多。特别是如果您的存储速度较慢。

你的 table 尺寸是多少(你可以从 SHOW TABLE STATUS LIKE 'MyTableName'\G 得到这个并查看 data_length + index_length)?

我刚刚在笔记本电脑上进行了测试。我在MySQL 5.5实例中填充了一个table,直到table的大小约为175MB。 运行 更改 table 以设置 auto-increment 值大约需要 5-6 秒。您的结果可能会有所不同,具体取决于您的服务器的功率和存储速度。

虽然 alter table 是 运行ning,但执行该操作的线程在 table 上持有一个 metadata lock,它会阻止所有其他查询,甚至 read-only SELECT 个语句。

ALTER TABLE 作为 MySQL 5.6 的一项功能在 2013 年得到改进。一些类型的改变被优化为完成“in-place”,因此如果没有必要,他们不必复制整个 table。更改 AUTO_INCREMENT 是这些操作之一。不管 table 有多大,如果你改变 table 来改变 AUTO_INCREMENT,它很快,因为它只改变 table 的一个属性,而不需要复制任何行数据。

https://dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl-operations.html

在MySQL 5.5 中,这些优化没有实现。所以 any alter table 需要很长时间,与 table.

的大小成正比

对于您的情况,我建议解决此问题的最佳方法是升级到较新的版本。 MySQL 5.5 超出其 end-of-life。甚至 MySQL 5.6 也将在 2021 年 2 月达到 end-of-life。是时候升级了。

如果无法升级,则应调查是哪个客户端在执行此 ALTER TABLE 语句。你说你在白天的某个时候注意到了它。追踪下来。在进程列表中,它会告诉您客户端主机 SQL 语句来自 运行。它还会告诉您他们登录的 MySQL 用户。您可能还需要搜索使用此数据库的任何应用程序或脚本的源代码。或者问问你的队友。

一旦找到正在执行此 ALTER TABLE 的客户端,请尝试将客户端 运行 执行此语句的时间更改为 ALTER TABLE不会阻止重要查询。或者询问负责的开发人员是否真的有必要如此频繁地更改 table?

问题可能是由于 服务器重新启动,因为 InnoDb 将最后一个 auto-increment 索引存储在内存中 在服务器重新启动时重新计算它 (InnoDB AUTO_INCREMENT Counter Initialization):

If you specify an AUTO_INCREMENT column for an InnoDB table, the table handle in the InnoDB data dictionary contains a special counter called the auto-increment counter that is used in assigning new values for the column. This counter is stored only in main memory, not on disk.

To initialize an auto-increment counter after a server restart, InnoDB executes the equivalent of the following statement on the first insert into a table containing an AUTO_INCREMENT column.

SELECT MAX(ai_col) FROM table_name FOR UPDATE;

InnoDB increments the value retrieved by the statement and assigns it to the column and to the auto-increment counter for the table. By default, the value is incremented by 1. This default can be overridden by the auto_increment_increment configuration setting.

If the table is empty, InnoDB uses the value 1. This default can be overridden by the auto_increment_offset configuration setting.

查看 mysql 日志并尝试找出服务器是否正在重新启动,导致 ALTER table 重置自动增量计数器。

尝试重新启动 mysql 服务器以查看是否出现此行为

如果是这种情况,您可以尝试:

In MySQL 8.0, this behavior is changed. The current maximum auto-increment counter value is written to the redo log each time it changes and is saved to an engine-private system table on each checkpoint. On a server restart following a normal shutdown, InnoDB initializes the in-memory auto-increment counter using the current maximum auto-increment value stored in the data dictionary system table.

  • 您可以尝试加快“复制到 tmp table”操作,skip copying to tmp table on disk mysql

参考资料

How to make InnoDB table not reset autoincrement on server restart?

https://serverfault.com/questions/228690/mysql-auto-increment-fields-resets-by-itself