我最近在使用逻辑复制将 PostgreSQL 11 迁移到 PostgreSQL 15 时遇到了问题。
作为使用逻辑复制的缺点之一,序列数据不会在两个实例之间复制。 因此,如果数据库内部有任何序列,则有必要在使用新数据库之前修复它们。
为了修复序列,我一直在使用带有 select 的脚本,该脚本获取数据库中存在的所有序列,然后组装一个 SETVAL 命令,然后将其打印在数据库中。
不幸的是,我发现执行此操作的每个选择都仅选择列所拥有的序列。
是否有任何自动化方法来修复不属于列的序列?或者还有其他完全修复序列的方法吗?
看来我几乎能够复制 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 是否会有“真”或“假”,考虑到它的作用,我认为出于我的目的,尝试弄清楚这一点也没有多大意义。