我有一个包含 3GB 数据的 MySQL 表,在预生产过程中,创建新字段的 ALTER TABLE 大约需要 15 分钟。
该软件可以使用新字段或不使用新字段进行读写查询,因此我可以在不更改软件的情况下更新数据库。
问题:
有没有办法以“后台”之类的方式运行它,并让所有 CPU 周期首先处理“其他查询”,并且只有在有空闲 CPU 时才运行 ALTER?
在生产中执行“长修改表”的正确方法是什么?
答案1
CPU 很少是真正的瓶颈。通常是磁盘,缓冲池可用的内存量也是一个制约因素。
问题是,执行操作所需的资源ALTER TABLE
通常不是您的实际问题……事实上表很可能会在操作期间被锁定。
在 MySQL 中没有办法降低查询的优先级,但是如果有的话,它只会延长您的痛苦,因为表级锁会持续更长时间。
尝试这个:
ALTER TABLE t1
ADD COLUMN c2 BIGINT UNSIGNED NOT NULL AFTER c1,
LOCK=NONE,
ALGORITHM=INPLACE;
如果服务器不允许您这样做(这应该可以解决您的问题),那么错误消息应该会解释原因。
如果原因与外键有关,但您的ALTER
查询不会做任何事来扰乱外键完整性,那么您可以禁用那些会阻止您在没有锁的情况下进行就地更改的检查。
SET @@FOREIGN_KEY_CHECKS = 0; -- before ALTER
SET @@FOREIGN_KEY_CHECKS = 1; -- after ALTER
这确实不是禁用表上的外键约束。它只会免除您从当前连接运行的任何查询采取措施避免违反关系完整性的必要性。只要您没有做任何破坏关系完整性的事情,它就是一种安全的策略,但仅在您需要时才使用。
答案2
是的你可以。一个简单的谷歌搜索找到了这个答案在我们的姊妹 SE 网站上:https://stackoverflow.com/questions/24704086/low-priority-query-in-mysql
您可以根据执行的查询类型在查询中使用 LOW_PRIORITY 或 HIGH_PRIORITY:
INSERT [LOW_PRIORITY | HIGH_PRIORITY] INTO ... SELECT [HIGH_PRIORITY] * FROM ... UPDATE [LOW_PRIORITY] table ...