从 PostgreSQL 11 进行逻辑复制迁移后,修复 PostgreSQL 15 中的所有序列

Fixing all sequences in PostgreSQL 15 after migrating with logical replication from PostgreSQL 11

提问人:VKL 提问时间:8/30/2023 更新时间:10/10/2023 访问量:130

问:

我最近在使用逻辑复制将 PostgreSQL 11 迁移到 PostgreSQL 15 期间遇到了一个问题。

作为使用逻辑复制的缺点之一,序列数据不会在两个实例之间复制。 因此,如果数据库内部有任何序列,则有必要在使用新数据库之前修复它们。

为了修复序列,我一直在使用一个带有选择的脚本,该脚本获取数据库中存在的所有序列,然后组装一个 SETVAL 命令,然后将其打印到数据库中。

不幸的是,我发现执行此操作的每个选择都只选择列拥有的序列。

是否有任何自动化方法可以修复不属于列的序列?还是有其他方法可以完全修复序列?

数据库 PostgreSQL 迁移 顺序

评论

0赞 Richard Huxton 8/30/2023
通常,通过将其设置为或类似的东西来“固定”序列。如果序列不归列所有,则目标数据库无法确定“正确”值是什么。您需要从 v11 数据库转储/导出序列值并复制它们。max(column) + 1

答:

0赞 VKL 10/10/2023 #1

似乎我几乎能够复制pg_dump --data-only 在导出序列时所做的事情。

#!/bin/bash
port=$1
db=$2

query="select schemaname as schema,
       sequencename as sequence,
       start_value,
       last_value
from pg_sequences order by sequencename asc;
"

while read schema sequence start_value last_value
do
        if [ -z "$last_value" ]
        then
        echo "SELECT pg_catalog.SETVAL('${schema}.\"${sequence}\"', $start_value, true);"
        else
                echo "SELECT pg_catalog.SETVAL('${schema}.\"${sequence}\"', $last_value, true);"
        fi

done < <(psql -t -A -F" " -p ${port} ${db} -c "${query}")

此 bash 代码采用pg_sequences表中存在的所有序列,并使用 start_value 或 last_value 组合 setval 命令。选择哪一个取决于last_value值是否为空,因此它应该与start_value相同。唯一缺少的是弄清楚 setval 是否会有“真”或“假”,考虑到它的作用,我认为就我的目的而言,试图弄清楚这一点也没有多大意义。