【问题标题】:verifying data consistency between two postgresql databases验证两个 postgresql 数据库之间的数据一致性
【发布时间】:2013-05-09 03:17:54
【问题描述】:

这特别是关于保持对使用各种复制解决方案的信心,您可以在不丢失数据的情况下故障转移到其他服务器。或者在主-主情况下,如果其中一个数据库不同步,您可以在合理的时间内知道。

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

具体要求:

  1. 我说的不仅仅是表结构。我想知道实际的记录数据是相同的,以便我知道记录是否已损坏或丢失(在这种情况下,我将使用最近的备份 + WAL 文件重新初始化坏数据库,然后再将其恢复进入游泳池)

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

  3. 我不认为需要实时检查(尽管它当然会很好)。每小时甚至每天都比没有好。

  4. 块级检查不起作用。这将是两个具有独立存储的数据库。

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

【问题讨论】:

  • 我首先想到的与数据库无关的想法是对两边的行进行哈希处理,并弄清楚如何比较 db1 和 db2 中每一行的哈希值。初始加载会很慢,但如果您逐步执行此操作,可能不会那么糟糕。
  • 这里有一个感兴趣的链接来扩展我之前的评论。 stackoverflow.com/questions/9607063/…

标签: postgresql replication data-consistency


【解决方案1】:

您可以检查两台机器上当前的 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 和 walreceiver 进程的帮助下进行检查:

[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

【讨论】:

    【解决方案2】:

    如果您正在寻找整个表格,您应该能够执行以下操作(假设表格很容易放入 RAM):

    SELECT md5(array_to_string(array_agg(mytable), ' '))
      FROM mytable order by id;
    

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

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

    【讨论】:

    • 当然ORDER BY需要进入array_agg()里面,否则这个查询根本不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-15
    • 2015-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多