【问题标题】:Sorting postgresql database dump (pg_dump)排序 postgresql 数据库转储 (pg_dump)
【发布时间】:2011-01-13 08:41:12
【问题描述】:

我正在创建 pg_dumps、DUMP1 和 DUMP2。

DUMP1 和 DUMP2 完全相同,只是 DUMP2 以 DUMP1 的 REVERSE 顺序转储。

无论如何我可以对两个 DUMPS 进行排序,以便两个 DUMP 文件完全相同(使用差异时)?

我正在使用 PHP 和 linux。我尝试在 linux 中使用“排序”,但这不起作用...

谢谢!

【问题讨论】:

    标签: php linux postgresql sorting pg-dump


    【解决方案1】:

    解析转储可能不值得。

    将 DUMP2 恢复到临时数据库并以正确的顺序转储临时数据库会快得多。

    【讨论】:

    • 你能澄清一下你的意思吗?您是说将 DUMP 2 还原到临时数据库中,但是您能否澄清“以正确的顺序转储临时数据库”。谢谢!
    • 哦,你的意思是把DUMP2恢复到一个临时数据库,然后转储那个数据库……
    【解决方案2】:

    From your previous question,我假设您真正想做的是与数据库进行比较,看看它们是否相同,包括数据。

    As we saw there,pg_dump 的行为不会确定。一个文件与另一个文件相反的事实可能只是巧合。

    这是一种进行总体比较的方法,包括架构和数据。

    首先,比较架构using this method

    其次,通过以一致的顺序将数据全部转储到文件来比较数据。首先按名称对表进行排序,然后按主键列对每个表中的数据进行排序,从而保证顺序。

    下面的查询生成COPY 语句。

    select
        'copy (select * from '||r.relname||' order by '||
        array_to_string(array_agg(a.attname), ',')||
        ') to STDOUT;'
    from
        pg_class r,
        pg_constraint c,
        pg_attribute a
    where
        r.oid = c.conrelid
        and r.oid = a.attrelid
        and a.attnum = ANY(conkey)
        and contype = 'p'
        and relkind = 'r'
    group by
        r.relname
    order by
        r.relname
    

    运行该查询将为您提供一个语句列表,例如copy (select * from test order by a,b) to STDOUT; 将所有这些语句放在一个文本文件中,并通过 psql 为每个数据库运行它们,然后比较输出文件。您可能需要使用output settings to COPY 进行调整。

    【讨论】:

      【解决方案3】:

      我的解决方案是为 pg_dump 输出编写一个自己的程序。随意下载PgDumpSort,它按主键对转储进行排序。使用 512MB 的 java 默认内存,每个表最多可以处理 1000 万条记录,因为记录信息(主键值、文件偏移量)保存在内存中。

      您使用这个小的 Java 程序,例如与

      java -cp ./pgdumpsort.jar PgDumpSort db.sql
      

      你得到一个名为“db-sorted.sql”的文件,或者指定输出文件名:

      java -cp ./pgdumpsort.jar PgDumpSort db.sql db-$(date +%F).sql
      

      排序后的数据在“db-2013-06-06.sql”之类的文件中

      现在您可以使用 diff 创建补丁

      diff --speed-large-files -uN db-2013-06-05.sql db-2013-06-06.sql >db-0506.diff
      

      这允许您创建通常更小的增量备份。要恢复文件,您必须使用

      将补丁应用到原始文件
       patch -p1 < db-0506.diff
      

      (源代码在 JAR 文件中)

      【讨论】:

      • 太棒了,我只需要一种快速的方法来比较一些用于 QA 目的的 pre 和 post south 脚本数据库转储。快速简单,谢谢。在两个转储上运行,为孤儿搜索,立即保证我们不会级联任何数据。
      【解决方案4】:

      如果

      • 性能不如订单重要
      • 您只关心数据而不是架构
      • 并且您可以重新创建两个转储(您不必使用现有转储)

      您可以按如下确定的顺序转储 CSV 格式的数据:

      COPY (select * from your_table order by some_col) to stdout
            with csv header delimiter ',';
      

      COPY (9.5)

      【讨论】:

        【解决方案5】:

        这里有另一个解决问题的方法:https://github.com/tigra564/pgdump-sort

        它允许对 DDL 和 DML 进行排序,包括将 volatile 值(如序列值)重置为某些规范值以最小化产生的差异。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-03-26
          • 2011-01-11
          • 2015-06-29
          • 1970-01-01
          • 1970-01-01
          • 2021-02-05
          • 2011-07-22
          • 1970-01-01
          相关资源
          最近更新 更多