验证两个postgresql数据库之间的数据一致性

验证两个postgresql数据库之间的数据一致性,postgresql,replication,data-consistency,Postgresql,Replication,Data Consistency,这特别是关于在使用各种复制解决方案时保持信心,以便能够在不丢失数据的情况下故障切换到另一台服务器。或者在主控情况下,您可以在合理的时间内知道其中一个数据库是否已失去同步 是否有任何工具可用于此目的,或者人们通常依赖复制系统本身来警告不一致性?我目前最熟悉postgresql主备用设置,但正在考虑使用PgPool之类的主备用设置。然而,由于该解决方案与PostgreSQL本身的直接联系较少(我的基本理解是,它提供应用程序将使用的连接,从而拦截各种SQL语句,然后将它们发送到池中的任何服务器),因此

这特别是关于在使用各种复制解决方案时保持信心,以便能够在不丢失数据的情况下故障切换到另一台服务器。或者在主控情况下,您可以在合理的时间内知道其中一个数据库是否已失去同步

是否有任何工具可用于此目的,或者人们通常依赖复制系统本身来警告不一致性?我目前最熟悉postgresql主备用设置,但正在考虑使用PgPool之类的主备用设置。然而,由于该解决方案与PostgreSQL本身的直接联系较少(我的基本理解是,它提供应用程序将使用的连接,从而拦截各种SQL语句,然后将它们发送到池中的任何服务器),因此我更多地考虑了实际验证数据一致性

具体要求:

  • 我说的不仅仅是桌子的结构。我想知道实际的记录数据是相同的,这样我就可以知道记录是否损坏或丢失(在这种情况下,我将使用最近的备份+WAL文件重新初始化坏数据库,然后再将其带回池中)

  • 数据库的大小顺序为30-50 GB。我怀疑原始的SELECT查询是否能很好地工作

  • 我认为没有必要进行实时检查(当然,这会很好)。每小时甚至每天都比没有好

  • 块级别检查不起作用。它将是两个具有独立存储的数据库


  • 或者这种类型的验证根本不现实?

    如果您要查找整个表,您应该能够执行类似的操作(假设一个表很容易放入RAM中):

    这将为您提供表上元组表示的哈希


    请注意,您可以按范围等进行细分。根据复制类型,您甚至可以按页面范围进行细分(对于流式复制)。

    您可以检查两台计算机上的当前WAL位置。。。 如果它们表示相同的值,则表示基础数据库彼此一致

    $ psql -c "SELECT pg_current_xlog_location()" -h192.168.0.10 (do it on primary host)
     pg_current_xlog_location 
    --------------------------
     0/2000000
    (1 row)
    
    $ psql -c "select pg_last_xlog_receive_location()" -h192.168.0.20 (do it on standby host)
     pg_last_xlog_receive_location 
    -------------------------------
     0/2000000
    (1 row)
    
    $ psql -c "select pg_last_xlog_replay_location()" -h192.168.0.20 (do it on  standby host)
     pg_last_xlog_replay_location 
    ------------------------------
     0/2000000
    (1 row)
    
    您还可以在walsender和WALSeceiver流程的帮助下进行检查:

    [do it on  primary] $ ps -ef | grep sender
    postgres  6879  6831  0 10:31 ?        00:00:00 postgres: wal sender process postgres 127.0.0.1(44663) streaming 0/2000000
    
    [ do it on standby] $ ps -ef | grep receiver
    postgres  6878  6872  1 10:31 ?        00:00:01 postgres: wal receiver process   streaming 0/2000000
    

    我想到的与数据库无关的第一个想法是对两边的行进行散列,并找出如何比较db1和db2中每一行的散列。这篇文章的初始加载速度会很慢,但如果你以增量的方式加载,那么继续下去可能不会太糟糕。这里有一个有趣的链接来扩展我之前的评论。当然,orderby需要进入数组_agg()的内部,否则这个查询将根本无法工作。
    [do it on  primary] $ ps -ef | grep sender
    postgres  6879  6831  0 10:31 ?        00:00:00 postgres: wal sender process postgres 127.0.0.1(44663) streaming 0/2000000
    
    [ do it on standby] $ ps -ef | grep receiver
    postgres  6878  6872  1 10:31 ?        00:00:01 postgres: wal receiver process   streaming 0/2000000