我可以更改 mysql 外键引用的表而不锁定任何内容吗?
我们要运行大型架构迁移,并且不希望站点长时间停机,因此我们尝试即时执行此操作,并且不会对涉及的表进行读锁定。所涉及的表仅在一天中的特定时间写入,因此我们有一个可以承受写锁的窗口;但是,虽然许多 mysql 文档声称 ALTER TABLE 应该只写入锁定表,但根据我们的经验,任何重要的事情(例如添加索引读取)都会锁定它。
因此,我们必须手动进行迁移。我们通过以下过程取得了一些成功:
CREATE TABLE new_mytable LIKE mytable;
- 将迁移应用到
new_mytable
mysqldump -t mydb mytable > mytable.sql
- 使用 sed 更改
mytable.sql
以插入到new_mytable
的正确列中 mysql mydb
mytable.sql
- 在
mytable
上删除外键 - 它们不是由CREATE TABLE ... LIKE ...
复制的 - 将外键添加到
new_mytable
RENAME TABLE mytable TO old_mytable, new_mytable TO mytable
- 运行一些健全性检查
DROP TABLE old_mytable
正如我所说,所涉及的表仅在特定时间写入那天,所以我们确信数据保持一致 - 否则我们不会梦想尝试这样的事情。即便如此,我们还是遇到了问题。到目前为止,我们只在 FK 指向外面的桌子上进行过尝试。今天我在其他几张桌子引用的桌子上尝试了它。当我删除旧表时,我被告知外键约束失败,并且惊讶地发现引用表现在引用了旧表。
现在,我们可以删除 FK 并将它们重新添加到新的 FK 中,但这个过程本身就很脆弱;有很多表指向这个;重新添加密钥可能会给我们带来读锁。我们确信 - 确定 - 新表包含与第一个表相同的数据,因此最好更改这些 FK 的引用而不删除和添加它们。有没有一种方法可以操作数据库,以便更改现有的 FK 以引用新表?
We have a large schema migration to run, and we don't want the site to go down for ages, so we're trying to do it on the fly and without read locking the tables involved. The tables involved only get written to at specific times of the day, so we have a window in which we can afford to have write locks; but while a lot of the mysql docs claim ALTER TABLE
should only write lock tables, in our experience anything nontrivial such as adding an index read locks it.
So, we've had to do the migrations by hand. We've had some success with the following procedure:
CREATE TABLE new_mytable LIKE mytable;
- apply the migration to
new_mytable
mysqldump -t mydb mytable > mytable.sql
- use sed to change
mytable.sql
to insert into the correct columns ofnew_mytable
mysql mydb < mytable.sql
- drop foreign keys on
mytable
- they're not copied byCREATE TABLE ... LIKE ...
- add foreign keys to
new_mytable
RENAME TABLE mytable TO old_mytable, new_mytable TO mytable
- run a few sanity checks
DROP TABLE old_mytable
As I say, the tables involved only get written to at specific times of the day, so we're certain that the data stays consistent - otherwise we wouldn't dream of trying something like that. Even so, we've hit a problem. Until now, we've only tried it on tables where the FKs point outwards. Today I tried it on a table which was referred to by several other tables. When I dropped the old table, I was told that a foreign key constraint failed, and was horrified to see that the referring tables now refer to the old table.
Now, we could drop the FKs and re-add them to the new one, but the process is fragile enough as it is; there are a lot of tables pointing to this one; and re-adding the keys may give us read locks. We're certain - certain - that the new table contains all the same data as the first one, so what would be nice would be to change the referent of those FKs without dropping and adding them. Is there a way to manipulate the DB such that the existing FKs are altered to refer to the new table?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
前提是您知道如何更改表本身。
Provided you know how to alter the tables themselves.