在不停机的情况下进行模式更改和将数据迁移到活动数据库的最佳做法?


43

如何在不停机的情况下对活动数据库进行架构更改?

例如,假设我有一个PostgreSQL数据库,该数据库的表包含各种用户数据(如电子邮件地址等),这些数据均与特定用户相关联。如果要将电子邮件地址移动到新的专用表中,则必须更改架构,然后将电子邮件数据迁移到新表中。如何在不停止写入原始表的情况下完成此操作?当然,当数据从旧表写入新表时,新数据将继续写入旧表并丢失,对吗?

我猜这个问题经常出现,但是我找不到任何标准的解决方案。

本文解决了这个问题,但是我并没有真正理解步骤3。他说要写入两个表,然后将旧数据从第一个表迁移到新表。您如何确保仅迁移旧数据?

(我在Heroku上使用PostgreSQL。)


2
Facebook 开发了一种针对MySQL 的工具
Nick Chammas 2012年

2
K. Scott Allen 在此处介绍了一种用于管理模式版本的系统。我创建了DbUpdater,这是一个用于版本感知模式部署的开源工具。更多信息-http: //www.tewari.info/dbupdater
ash 2012年

@NickChammas感谢您的分享。我对此有很多疑问。您能否建议一个更详细的教程,最好是一个视频,介绍诸如位日志,非聚集索引之类的内容,并回答-1的问题。与从源表复制到目标文件相比,如何将数据从源表中选择为外文件?直接表。2.复制阶段何时结束?这些只是我的几个问题,我才刚刚开始阅读。
Sandeepan Nath

@SandeepanNath-对不起,我不太熟悉Facebook的工具,因此无法为您提供更多资源。我读了关于它的公告并在几年前发表了评论,但我从未使用过它。
尼克·查马斯

Answers:


27

您几乎已经有了答案:

  1. 并行创建新结构
  2. 开始写两种结构
  3. 将旧数据迁移到新结构
  4. 只写和读新结构
  5. 删除旧列

对于第3步,在一个事务中使用如下代码:

插入尚不存在的内容:

INSERT INTO new_tbl (old_id, data)
SELECT old_id, data
FROM   old_tbl
WHERE  NOT EXISTS (SELECT * FROM new_tbl WHERE new_tbl.old_id = old_tbl.old_id);

同时更新已更改的内容:

UPDATE new_tbl
SET    data  = old.data
USING  old_tbl
WHERE  new_tbl.old_id = old_tbl.old_id
AND    new_tbl.data IS DISTINCT FROM old_tbl.data;

由于新数据在两个地方都相同,因此不会被触及。


在尝试了解您提出此答案的方案时,我有几个问题。1.代码更改是否将与数据库更改的开始一起部署?2.为什么需要写两个结构?3.为什么不能先提出新结构,然后再迁移现有数据,然后部署将填充新结构的代码更改?4.为什么需要找出不存在的内容(您的第一个查询)?您是否建议多次插入?
Sandeepan Nath

2
@SandeepanNath,回答您评论中的问题3:因为如果您(a)提出新结构,(b)将数据迁移到其中,(c)更改代码以将数据写入新结构而不是旧结构,则所有在步骤b和步骤c之间进行的数据更改将仅存在于结构中。问题是如何在不停机的情况下进行模式更改 再次仔细阅读此答案。
通配符
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.