我正在创建两个pg_dumps,DUMP1和DUMP2。
DUMP1和DUMP2完全相同,除了DUMP2是以与DUMP1相反的顺序转储的。
有没有办法对这两个DUMP进行排序,使得使用diff时这两个DUMP文件完全相同?
我正在使用PHP和Linux。我尝试在Linux中使用“sort”,但那行不通...
谢谢!
我正在创建两个pg_dumps,DUMP1和DUMP2。
DUMP1和DUMP2完全相同,除了DUMP2是以与DUMP1相反的顺序转储的。
有没有办法对这两个DUMP进行排序,使得使用diff时这两个DUMP文件完全相同?
我正在使用PHP和Linux。我尝试在Linux中使用“sort”,但那行不通...
谢谢!
根据您之前的问题, 我猜您想要做的是比较两个数据库是否相同,包括数据。
正如我们所看到的, 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
。COPY (select * from your_table order by some_col) to stdout
with csv header delimiter ',';
查看 COPY (v14)
这是解决问题的另一个方案:https://github.com/tigra564/pgdump-sort
它可以对DDL和DML进行排序,包括将易变值(例如序列值)重置为一些规范值以最小化结果差异。
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恢复到临时数据库中,然后按正确顺序转储临时数据库会快得多。