使用AWS DMS迁移后,PostgreSQL主键序列丢失

问题描述 投票:0回答:2

我最近使用AWS Migration Service将自托管的Postgres数据库迁移到AWS RDS。 Postgres版本:10.6

我注意到我的所有主键都不再设置为“序列”,当我尝试手动添加序列时,它从1开始,而不是继续已经设置的计数。

我在数据库中使用Rails,所以我的sql技能非常低。我通常可以找到插入和更新的方法,但这不是我有很多经验的领域。

我的问题有两个部分:

  1. 如何修复单个表?在继续之前,我想了解并测试我正在做的事情。
  2. 有没有办法可以将此修复程序应用于我拥有的每个表而无需手动修改每个表?
postgresql amazon-rds
2个回答
1
投票

除非您遗漏了某些内容并且可以再次处理迁移(使用不同的参数?我从未使用AWS迁移服务,但我认为它应该保留列的serial-iness ...)您需要重新创建序列也是。


我大约一年前遇到过类似的情况,写了this answer on SO

这是它的要点:

CREATE SEQUENCE foo_a_seq OWNED BY foo.a;
SELECT setval('foo_a_seq', coalesce(max(a), 0)) FROM foo;
ALTER TABLE foo ALTER COLUMN a SET DEFAULT nextval('foo_a_seq'); 

这将创建一个序列foo_a_seq,其nextvalmax(或foo.a,如果没有1记录)的foo值高一个。

我还继续设置Function以快速应用于所有需要的表/列:

CREATE OR REPLACE FUNCTION make_into_serial(table_name TEXT, column_name TEXT) RETURNS INTEGER AS $$
DECLARE
    start_with INTEGER;
    sequence_name TEXT;
BEGIN
    sequence_name := table_name || '_' || column_name || '_seq';
    EXECUTE 'SELECT coalesce(max(' || column_name || '), 0) + 1 FROM ' || table_name
            INTO start_with;
    EXECUTE 'CREATE SEQUENCE ' || sequence_name ||
            ' START WITH ' || start_with ||
            ' OWNED BY ' || table_name || '.' || column_name;
    EXECUTE 'ALTER TABLE ' || table_name || ' ALTER COLUMN ' || column_name ||
            ' SET DEFAULT nextVal(''' || sequence_name || ''')';
    RETURN start_with;
END;
$$ LANGUAGE plpgsql VOLATILE;

像这样使用它:

SELECT make_into_serial('foo', 'a');

1
投票

在@a_horse_with_no_name指向正确的方向并与AWS聊天之后,我能够回答我自己的问题,至少在您使用AWS数据库迁移服务(DMS)时。

问题是,DMS只关注数据本身,而不是模式(这对我来说似乎是一个主要的疏忽,特别是如果你使用相同的数据库技术但这是另一个问题)。因此,架构本身不会迁移。文档并没有真正说明这一点。

要解决此问题:

  1. 停止(如果它仍然存在)现有的AWS DMS迁移
  2. 删除现有的迁移数据库,并创建要使用的新空模式
  3. 按照此处的步骤https://docs.aws.amazon.com/SchemaConversionTool/latest/userguide/CHAP_Installing.html安装和设置Amazon Schema Conversation Tool(SCT)
  4. 一旦连接到两个数据库,请按照此处的步骤https://docs.aws.amazon.com/SchemaConversionTool/latest/userguide/CHAP_Converting.html“转换”您的模式(我为此数据库执行了整个“公共”模式,以确保涵盖所有内容
  5. 创建或修改AWS DMS迁移,确保目标表准备模式=“TRUNCATE”并禁用目标数据库上的外键。如果修改,请确保在被要求“恢复”时不恢复

我尚未测试的是如何处理我正在迁移实时数据库的事实。因此,迁移完成后,目标数据库上的序列可能已过时。我相信我可以稍后进入SCT并只迁移序列,但我还没有测试过。

© www.soinside.com 2019 - 2024. All rights reserved.