[英]Postgres pg_dump dumps database in a different order every time
我正在編寫一個PHP腳本(也使用linux bash命令),它將通過執行以下操作來運行測試用例:
我正在使用PostgreSQL數據庫(8.4.2)...
1.)創建DB 2.)修改DB 3.)存儲DB的數據庫轉儲(pg_dump)
4.)通過執行步驟1.)和2.)進行回歸測試,然后進行另一個數據庫轉儲並將其(差異)與步驟3中的原始數據庫轉儲進行比較。)
但是,我發現pg_dump不會總是以相同的方式轉儲數據庫。 它每次都會以不同的順序轉儲。 因此,當我對兩個數據庫轉儲執行diff時,比較將導致兩個文件不同,當它們實際上是相同的時,只是以不同的順序。
我可以采用不同的方式來做pg_dump嗎?
謝謝!
這是一個方便的腳本,用於預處理pg_dump
輸出,使其更適合在版本控制中進行區分和存儲:
https://github.com/akaihola/pgtricks
pg_dump_splitsort.py
將轉儲拆分為以下文件:
0000_prologue.sql
:第一個COPY的所有內容 0001_<schema>.<table>.sql
NNNN_<schema>.<table>.sql
: 按第一個字段排序的每個表的數據 9999_epilogue.sql
:最后一次COPY之后的所有內容 表數據的文件已編號,因此可以使用所有文件的簡單排序連接來重新創建數據庫:
$ cat *.sql | psql <database>
我發現快速查看轉儲之間差異的一個好方法是在整個目錄中使用meld
工具:
$ meld old-dump/ new-dump/
在版本控制中存儲轉儲也可以很好地查看差異。 以下是如何配置git以在diffs中使用顏色:
# ~/.gitconfig
[color]
diff = true
[color "diff"]
frag = white blue bold
meta = white green bold
commit = white red bold
注意:如果已創建/刪除/重命名表,請記住在對新轉儲進行后處理之前刪除所有.sql
文件。
這里值得區分模式和數據。 模式以相當確定的順序轉儲,大多數對象按字母順序排列,受到對象間依賴性的約束。 在一些有限的情況下,訂單沒有完全約束,並且可能對外部觀察者來說是隨機的,但可能會在下一個版本中得到修復。
另一方面,數據以磁盤順序轉儲。 這通常是您想要的,因為您希望轉儲速度快,而不是使用大量的資源來進行排序。 您可能正在觀察的是,當您“修改數據庫”時,您正在執行更新,這將實際刪除舊值並在最后附加新值。 這當然會擾亂你的差異化戰略。
pg_comparator可能更適合您的工具 。
不可能強制pg_dump以任何特定順序轉儲數據,因為它以磁盤順序轉儲數據 - 這種方式要快得多。
您可以為pg_dump使用“-a -d”選項然后“排序”輸出,但數據中的換行將使排序的輸出無法使用。 但是對於基本的比較,無論是否有任何改變,都足夠了。
如果您只對架構感興趣:
您可以通過逐個使用這些選項的組合來執行diff表,一次只轉儲一個表的模式。 然后,您可以單獨比較它們,或者以已知順序將它們全部記錄到一個文件中。
-s, --schema-only dump only the schema, no data
-t, --table=TABLE dump the named table(s) only
要生成要提供給上面的表的列表,請查詢information_schema.tables
。
PostgreSQL行為不確定性並不罕見 - 可能是定時器觸發的重組過程或類似的事情發生在后台。 此外,我不知道有一種方法可以強制pg_dump在連續運行時重現相同的輸出。
我建議更改您的比較邏輯,因為它是您的行為不端的比較 - 它報告差異,而兩個轉儲表示相同的數據庫狀態。 這當然意味着一些額外的工作,但在我看來是解決問題的正確方法。
如果性能不如訂單那么重要,您可以使用:
COPY (select * from your_table order by some_col) to stdout
with csv header delimiter ',';
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.