【问题标题】:Postgresql skip transaction in logical replicationPostgresql 在逻辑复制中跳过事务
【发布时间】:2020-01-06 02:37:58
【问题描述】:

在我们公司,我们使用了逻辑复制(在服务器源和接收器上我们都有 Postgresql 10.5 版本),有时逻辑复制会因错误而关闭: 错误:重复键值违反唯一约束。

在 pg_replication_origin_status 我看到位置 remote_lsn(它在源上的位置,接收器可以到达)。我知道如何使用 pg_replication_origin_advance,而且我知道这个函数可能会跳过一些数据。有没有办法在remote_lsn之后获取下一个位置,这样数据不丢失?

【问题讨论】:

  • 欢迎来到 StackOverflow。我们很乐意为您提供帮助。为了提高您获得答案的机会,以下是一些提示:stackoverflow.com/help/how-to-ask
  • 你试过用PostgreSQL mailing lists检查吗?您要寻找的是 pgsql-general。核心开发人员监视该列表,听起来您可能遇到了复制错误。

标签: postgresql


【解决方案1】:

您是否真的确定是哪个表导致了这种情况。这通常是由在其表定义中使用序列的表引起的。 PostgreSQL 中不会复制序列。目的地可以尝试从头开始序列并为序列生成值 1。这是因为逻辑复制不会复制序列的值,因为序列的下一个值没有存储在表本身中。

解决方法:

  • 为数字使用外部来源,例如 zookeeper
  • 对不同的服务器使用不重叠的范围

【讨论】:

    【解决方案2】:

    这是因为 PostgreSQL 中序列的工作方式:

    从源头看这张表,有一个序列:

    src=# CREATE TABLE s (a serial PRIMARY KEY, b text);
    CREATE TABLE
    src=# INSERT INTO s (b) VALUES ('foo'), ('bar'), ('baz');
    INSERT 0 3
    src=# SELECT * FROM s;
     a |  b
    ---+-----
     1 | foo
     2 | bar
     3 | baz
    (3 rows)
    
    src=# SELECT currval('s_a_seq'), nextval('s_a_seq');
     currval | nextval
    ---------+---------
           3 |       4
    (1 row)
    

    创建序列 s_a_seq 是为了支持串行类型的 a 列。这会生成 s.a. 的自动递增值。现在让我们将它复制到 dst 中,并插入另一行:

    dst=# SELECT * FROM s;
     a |  b
    ---+-----
     1 | foo
     2 | bar
     3 | baz
    (3 rows)
    
    dst=# INSERT INTO s (b) VALUES ('foobaz');
    ERROR:  duplicate key value violates unique constraint "s_pkey"
    DETAIL:  Key (a)=(1) already exists.
    dst=#  SELECT currval('s_a_seq'), nextval('s_a_seq');
     currval | nextval
    ---------+---------
           1 |       2
    (1 row)
    

    糟糕,刚刚发生了什么?目的地尝试从头开始序列并为 a 生成值 1。这是因为逻辑复制不会复制序列的值,因为序列的下一个值没有存储在表本身中。

    解决方法

    如果你从逻辑上考虑,你不能在没有双向同步的情况下从两个地方修改相同的“自动增量”值。如果您确实需要在表的每一行中增加一个数字,并且需要从多个服务器插入到该表中,您可以:

    • 为号码使用外部来源,例如 ZooKeeper 或 etcd,
    • 使用不重叠的范围 - 例如,第一个服务器生成并插入 1 到 100 万范围内的数字,第二个服务器生成并插入 100 万到 200 万范围内的数字,依此类推。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-30
      • 1970-01-01
      • 1970-01-01
      • 2021-08-23
      • 2021-05-07
      • 1970-01-01
      • 2011-02-02
      相关资源
      最近更新 更多