我正在创建 pg_dumps、DUMP1 和 DUMP2。
DUMP1 和 DUMP2 完全相同,只是 DUMP2 以 DUMP1 的 REVERSE 顺序转储。
无论如何我可以对两个 DUMPS 进行排序,以便两个 DUMP 文件完全相同(使用差异时)?
我正在使用 PHP 和 linux。我尝试在linux中使用“排序”,但这不起作用......
谢谢!
我正在创建 pg_dumps、DUMP1 和 DUMP2。
DUMP1 和 DUMP2 完全相同,只是 DUMP2 以 DUMP1 的 REVERSE 顺序转储。
无论如何我可以对两个 DUMPS 进行排序,以便两个 DUMP 文件完全相同(使用差异时)?
我正在使用 PHP 和 linux。我尝试在linux中使用“排序”,但这不起作用......
谢谢!
从您之前的问题中,我假设您真正想做的是与数据库进行比较,看看它们是否相同,包括数据。
正如我们在那里看到的,pg_dump 的行为不会是确定性的。一个文件与另一个文件相反的事实可能只是巧合。
这是一种可以进行总体比较的方法,包括架构和数据。
首先,使用此方法比较架构。
其次,通过以一致的顺序将数据全部转储到文件中来比较数据。首先按名称对表进行排序,然后按主键列对每个表中的数据进行排序,从而保证顺序。
下面的查询生成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 为每个数据库运行它们,然后比较输出文件。您可能需要将输出设置调整为COPY
.
我的解决方案是为 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 文件中)
解析转储可能不值得。
将 DUMP2 恢复到临时数据库并以正确的顺序转储临时数据库将会快得多。
如果
您可以按如下确定的顺序转储 CSV 格式的数据:
COPY (select * from your_table order by some_col) to stdout
with csv header delimiter ',';
参见副本 (9.5)
这是该问题的另一种解决方案:https ://github.com/tigra564/pgdump-sort
它允许对 DDL 和 DML 进行排序,包括将 volatile 值(如序列值)重置为一些规范值以最小化结果差异。