将 UNIQUE 键添加到正在接收 INSERTs/DELETEs 的大型现有 MySQL table
Adding a UNIQUE key to a large existing MySQL table which is receiving INSERTs/DELETEs
我有一个非常大的 table(数千万行),需要将 UNIQUE 索引添加到 table 上的列。我知道 table 确实包含该键的重复值,我需要清理这些值(通过将 rows/resetting 列的值删除为我可以自动生成的唯一值)。一个优点是已经复制的行不再被修改。
考虑到我可能会使用 Percona pt-osc 工具并且 table 上有连续的 deletes/inserts,执行这样的更改的正确方法是什么?我的计划是:
- 添加代码以确保不再插入重复 ID。可能我需要暂时为此添加一个单独的 table,因为我希望数据库为我而不是应用程序强制执行此操作 - 所以插入到 "shadow table" 中,并在事务中与我一起使用唯一索引main table,回滚所有尝试插入重复值的插入
- 通过删除
$current_pkey_value
以下主键范围内的所有无效列值来回填 table
- 然后添加索引,用pt-osc切换table
有什么我遗漏的吗?
因为我们使用 pt-online-schema-change
,所以我们使用触发器来执行从现有 table 到临时 table 的同步。该工具实际上为此有一个特殊的配置键 --no-check-unique-key-change
,它将完全满足我们的需要 - 同意执行 ALTER TABLE 并设置触发器,如果发生冲突,INSERT .. IGNORE
将被应用,并且使用现在唯一值的第一行将在同步期间在插入中获胜。对我们来说,这是一个很好的权衡,因为我们看到的所有重复都是数据竞争的结果,而不是价值生成过程中的实际冲突。
我有一个非常大的 table(数千万行),需要将 UNIQUE 索引添加到 table 上的列。我知道 table 确实包含该键的重复值,我需要清理这些值(通过将 rows/resetting 列的值删除为我可以自动生成的唯一值)。一个优点是已经复制的行不再被修改。
考虑到我可能会使用 Percona pt-osc 工具并且 table 上有连续的 deletes/inserts,执行这样的更改的正确方法是什么?我的计划是:
- 添加代码以确保不再插入重复 ID。可能我需要暂时为此添加一个单独的 table,因为我希望数据库为我而不是应用程序强制执行此操作 - 所以插入到 "shadow table" 中,并在事务中与我一起使用唯一索引main table,回滚所有尝试插入重复值的插入
- 通过删除
$current_pkey_value
以下主键范围内的所有无效列值来回填 table
- 然后添加索引,用pt-osc切换table
有什么我遗漏的吗?
因为我们使用 pt-online-schema-change
,所以我们使用触发器来执行从现有 table 到临时 table 的同步。该工具实际上为此有一个特殊的配置键 --no-check-unique-key-change
,它将完全满足我们的需要 - 同意执行 ALTER TABLE 并设置触发器,如果发生冲突,INSERT .. IGNORE
将被应用,并且使用现在唯一值的第一行将在同步期间在插入中获胜。对我们来说,这是一个很好的权衡,因为我们看到的所有重复都是数据竞争的结果,而不是价值生成过程中的实际冲突。