我可以更改 mysql 外键引用的表而不锁定任何内容吗?

发布于 2024-10-30 16:27:11 字数 1138 浏览 1 评论 0原文

我们要运行大型架构迁移,并且不希望站点长时间停机,因此我们尝试即时执行此操作,并且不会对涉及的表进行读锁定。所涉及的表仅在一天中的特定时间写入,因此我们有一个可以承受写锁的窗口;但是,虽然许多 mysql 文档声称 ALTER TABLE 应该只写入锁定表,但根据我们的经验,任何重要的事情(例如添加索引读取)都会锁定它。

因此,我们必须手动进行迁移。我们通过以下过程取得了一些成功:

  1. CREATE TABLE new_mytable LIKE mytable;
  2. 将迁移应用到 new_mytable
  3. mysqldump -t mydb mytable > mytable.sql
  4. 使用 sed 更改 mytable.sql 以插入到 new_mytable 的正确列中
  5. mysql mydb mytable.sql
  6. mytable 上删除外键 - 它们不是由 CREATE TABLE ... LIKE ... 复制的
  7. 将外键添加到 new_mytable
  8. RENAME TABLE mytable TO old_mytable, new_mytable TO mytable
  9. 运行一些健全性检查
  10. 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:

  1. CREATE TABLE new_mytable LIKE mytable;
  2. apply the migration to new_mytable
  3. mysqldump -t mydb mytable > mytable.sql
  4. use sed to change mytable.sql to insert into the correct columns of new_mytable
  5. mysql mydb < mytable.sql
  6. drop foreign keys on mytable - they're not copied by CREATE TABLE ... LIKE ...
  7. add foreign keys to new_mytable
  8. RENAME TABLE mytable TO old_mytable, new_mytable TO mytable
  9. run a few sanity checks
  10. 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

稳稳的幸福 2024-11-06 16:27:11

前提是您知道如何更改表本身。

SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;

...Alter the tables and change the keys

SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;

Provided you know how to alter the tables themselves.

SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;

...Alter the tables and change the keys

SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文