Postgresql 如何处理热备份副本和服务器端游标问题

Postgresql 如何处理热备份副本和服务器端游标问题,postgresql,database-replication,database-cursor,Postgresql,Database Replication,Database Cursor,我有一个问题,我需要从副本PostgreSQL数据库中获取一次N表,并每天获取45天内编辑的所有行。复制副本被配置为热备用复制副本,其中对主数据库的更新会导致我的连接/事务被终止,并引发DatabaseError 我曾尝试使用命名服务器端游标,将迭代大小设置为100000,但问题仍然存在。我还将事务级别更改为可重复读取 我需要将SELECT*FROM表格结果写入Apache Avro文件,并将其移动到云存储。由于缺少磁盘空间,需要在迭代之间移动和删除这些文件,因此这会导致额外的时间来打开连接 如

我有一个问题,我需要从副本PostgreSQL数据库中获取一次N表,并每天获取45天内编辑的所有行。复制副本被配置为热备用复制副本,其中对主数据库的更新会导致我的连接/事务被终止,并引发DatabaseError

我曾尝试使用命名服务器端游标,将迭代大小设置为100000,但问题仍然存在。我还将事务级别更改为可重复读取

我需要将SELECT*FROM表格结果写入Apache Avro文件,并将其移动到云存储。由于缺少磁盘空间,需要在迭代之间移动和删除这些文件,因此这会导致额外的时间来打开连接

如何避免以下情况的任何建议:

ERROR 2019-02-01 15:51:25,317: DatabaseError occurred: Traceback (most recent call last):
  File "main.py", line 202, in export_data
    rows = cur.fetchmany(itersize)
  File "/home/userA/data-export/lib/python2.7/site-packages/psycopg2/extras.py", line 93, in fetchmany
    res = super(DictCursorBase, self).fetchmany(size)
TransactionRollbackError: terminating connection due to conflict with recovery
DETAIL:  User query might have needed to see row versions that must be removed.
HINT:  In a moment you should be able to reconnect to the database and repeat your command.
server closed the connection unexpectedly
    This probably means the server terminated abnormally
    before or while processing the request.
我也尝试过使用ApacheSqoop来完成这项工作,但最终还是遇到了同样的问题

with connection(connection_params=connection_params) as c:
    c.set_isolation_level(ISOLATION_LEVEL_REPEATABLE_READ)
    with cursor(connection=c, cursorname='{brand}_{database}_{tablename}'.format(brand=brand_name,database=db, tablename=table_name)) as cur:
        try:
            cur.itersize = 100000
            cur.execute(sql)
            results = []
            while True:
                rows = cur.fetchmany(100000)
                if not rows:
                   break
                for row in rows: 
          results.append(return_record(columns=list(row.keys()),row=row, cast_types=True))

            outputpath = './exports/file/test.avro'

            if writer(schemafile=schema_file, outputpath=outputpath, data=results):
              logging.info('Write finished, moving file {} to GCS'.format(outputpath))
              upload_failed += 1 if not upload_file(storage_config=config, filepath=outputpath) else upload_failed
            else:
              write_failed += 1
            counter += 1
            del results[:]
        except ValueError:
          logging.error('ValueError occurred: %s', traceback.format_exc()) 
          cli.report(traceback.format_exc())
        except (Exception, DatabaseError):
          logging.error('DatabaseError occurred: %s', traceback.format_exc())
          cli.report(traceback.format_exc())

此错误与查询无关,只与复制配置和查询持续时间有关

复制冲突发生在

  • VACUUM
    删除主服务器上的旧行版本,而备用服务器上长时间运行的查询可能仍然需要这些旧行版本

  • ACCESS EXCLUSIVE
    锁定主服务器与备用服务器上的查询冲突。这样的锁由
    更改表
    删除表
    截断
    创建索引
    集群
    和类似程序执行,但也可以在
    真空
    截断表末尾的空页时执行

  • 您正遭受第一个问题的困扰

    有两种补救办法:

  • 在待机状态下设置
    hot\u standby\u feedback=on
    。然后,在
    VACUUM
    期间,主服务器将不会删除待机状态下可能仍然需要的旧行版本。不利的一面是,如果繁忙表上的自动真空被阻止,这可能会导致主服务器上的表膨胀

  • max\u standby\u streaming\u delay
    设置为比您在待机状态下的最长查询长的值(或-1表示无穷大)。然后,主服务器上发生冲突的更改会流式传输到备用服务器,但更改的应用会延迟。这意味着备用设备可能会落后。这种技术也有助于解决上述第二类冲突


  • 您必须做出选择,但不要忘记所有方法都有不可接受的缺点。

    此错误与您的查询无关,只与您的复制配置和查询持续时间有关

    复制冲突发生在

  • VACUUM
    删除主服务器上的旧行版本,而备用服务器上长时间运行的查询可能仍然需要这些旧行版本

  • ACCESS EXCLUSIVE
    锁定主服务器与备用服务器上的查询冲突。这样的锁由
    更改表
    删除表
    截断
    创建索引
    集群
    和类似程序执行,但也可以在
    真空
    截断表末尾的空页时执行

  • 您正遭受第一个问题的困扰

    有两种补救办法:

  • 在待机状态下设置
    hot\u standby\u feedback=on
    。然后,在
    VACUUM
    期间,主服务器将不会删除待机状态下可能仍然需要的旧行版本。不利的一面是,如果繁忙表上的自动真空被阻止,这可能会导致主服务器上的表膨胀

  • max\u standby\u streaming\u delay
    设置为比您在待机状态下的最长查询长的值(或-1表示无穷大)。然后,主服务器上发生冲突的更改会流式传输到备用服务器,但更改的应用会延迟。这意味着备用设备可能会落后。这种技术也有助于解决上述第二类冲突


  • 你必须做出选择,但别忘了所有方法都有不可接受的缺点。

    谢谢Laurenz!这验证了我拥有的选项,这些选项有点有限,因为IT-OPS对底层基础设施设置进行任何更改都有一些阻力。但现在我对推动变革更有信心:)谢谢劳伦兹!这验证了我拥有的选项,这些选项有点有限,因为IT-OPS对底层基础设施设置进行任何更改都有一些阻力。但现在我对推动变革更有信心:)