在没有任何停机时间的情况下在 PostgresSQL 中将 `int` 迁移到 `bigint`?

jef*_*unt 5 postgresql database-migration downtime

我有一个数据库,它将遇到Basecamp 在 11 月著名的整数耗尽问题。我有几个月的时间来弄清楚该怎么做。

是否有无需停机的主动解决方案来迁移这种色谱柱类型?如果是这样,那是什么?如果没有,这只是解决停机时间并尽可能迁移色谱柱的问题吗?

就是这篇文章足够的,假设我已经好几天/几周执行迁移现在之前我不得不这样做时,我的id跑出来了?

Lau*_*lbe 8

使用逻辑复制

使用逻辑复制,您可以在主数据库和备用数据库中拥有不同的数据类型。

使用 复制架构pg_dump -s,更改副本上的数据类型,然后开始逻辑复制。

复制完所有数据后,将应用程序切换为使用备用。

对于零停机时间,应用程序必须能够重新连接和重试,但这始终是这种情况下的要求。

为此,您需要 PostgreSQL v10 或更高版本,以及您的数据库

  • 不应修改架构,因为不会复制 DDL。
  • 不应使用序列(SERIALIDENTITY),因为不会复制最后使用的值


Lau*_*lbe 5

针对 v10 之前的数据库的另一种解决方案,其中所有事务都很短

  • bigint向表中添加一列。

  • 创建一个BEFORE触发器,每当添加或更新行时设置新列。

  • 运行一系列更新,将新列设置为旧列IS NULL。保持这些批次较短,这样就不会锁定太久,也不会出现太多死锁。确保这些事务运行,session_replication_role = replica这样它们就不会触发触发器。

  • 更新所有行后,CONCURRENTLY在新列上创建唯一索引。

  • USING为您刚刚创建的索引添加唯一约束。那会很快。

  • 执行切换:

    BEGIN;
    ALTER TABLE ... DROP oldcol;
    ALTER TABLE ... ALTER newcol RENAME TO oldcol;
    COMMIT;
    
    Run Code Online (Sandbox Code Playgroud)

    那会很快。

您的新专栏没有NOT NULL设置。如果没有长时间的侵入性锁定,这是无法完成的。但您可以添加检查约束IS NOT NULL并创建它NOT VALID。这已经足够好了,您稍后可以在不中断的情况下验证它。

如果存在外键约束,事情就会变得更加复杂。您必须删除这些并NOT VALID为新列创建外键。