【发布时间】:2019-01-23 08:21:23
【问题描述】:
我们的 Mysql(MariaDb) 数据库中有两个非常大的表。 Table_1 包含多对多映射。它有一个自动递增的主键和一个由两列组成的复合键。 Table_2 是指 Table_1 的主键。我们不想修复这个明显的设计错误,
- 在 Table_1 上使用复合主键
- 将两列添加到 Table_2
- 通过从 Table_1 复制数据来填充 Table_2 中的复合键,并在其上创建索引。
- 最好从两个表中删除自动递增的键列。
这些表有 ~300M 行,表的大小约为 10GB。我们需要在约 6 小时的服务窗口内进行这些更新。 我正在研究如何有效地做到这一点并在副本数据库上进行试验。到目前为止,我还没有尝试使用实际数据运行任何东西,因为普通脚本是不够的。 我不是经验丰富的数据库管理员。所以我需要一些光来完成这件事。 我的问题是什么是有效地做到这一点的最佳方法/技巧?
到目前为止我尝试过的事情
我了解了新的instant add column 功能,但我们的生产数据库使用的是较旧的 MariaDb 版本 10.0。
我已遵循this answer 中的建议,并在具有即时添加列支持的最新数据库版本上运行以下脚本(Alter 表是即时的)。该表有约 50M 行(原始的 1/6)。大约花了两个小时,这还不包括创建新索引。因此,这还不够。
SET join_buffer_size = 4 * 50 * 1024 * 1024; -- 50M keys of 4 bytes each
SET optimizer_switch='mrr=on,mrr_cost_based=off,mrr_sort_keys=on,optimize_join_buffer_size=on';
SET join_cache_level = 8;
UPDATE TABLE_2
JOIN TABLE_1 ON TABLE_1_Id = TABLE_2_FKT1_Id
SET
TABLE_2_KeyPart_1 = TABLE_1_KeyPart_1,
TABLE_2_KeyPart_2 = TABLE_1_KeyPart_2
也在考虑评估这个工具 https://www.percona.com/doc/percona-toolkit/2.2/pt-online-schema-change.html
【问题讨论】:
-
你可以使用分区吗?然后逐个分区?如果没有,这里有一个分块的想法:mysql.rjweb.org/doc.php/deletebig#deleting_in_chunks
-
感谢@DanielE 的建议。我们会调查的。
标签: mysql mariadb alter-table