对postgresql数据库转储进行排序(pg_dump)

时间:2010-02-05 02:10:35

标签: php linux postgresql sorting pg-dump

我正在创建pg_dumps,DUMP1和DUMP2。

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

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

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

谢谢!

5 个答案:

答案 0 :(得分:6)

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进行调整。

答案 1 :(得分:2)

我的解决方案是为pg_dump输出编写自己的程序。随意下载PgDumpSort,按主键对转储进行排序。由于记录信息(主键值,文件偏移量)保存在内存中,因此java默认内存为512MB,每个表最多可以使用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文件中)

答案 2 :(得分:0)

解析转储可能不值得。

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

答案 3 :(得分:0)

如果

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

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

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

请参阅COPY (9.5)

答案 4 :(得分:0)

尽管在2019年回答2010年发布的问题有点为时已晚,但这是该问题的另一种解决方案:https://github.com/tigra564/pgdump-sort

它允许对DDL和DML进行排序,包括将易失性值(如序列值)重置为一些规范值,以最大程度地减少差异。