0

一連のPostgresデータベーステーブル名をループしてテーブルデータをダンプするシェルスクリプトを開発しています。例えば:

# dump data

psql -h $SRC_IP_ADDRESS -p 5432 -U postgres -c "BEGIN;" AWARE

do
 :
 pg_dump -U postgres -h $IP_ADDRESS -p 5432 -t $i -a --inserts MYDB >> \
 out.sql
done

psql -h $IP_ADDRESS -p 5432 -U postgres -c "COMMIT;" MYDB

ただし、データベースへの同時アクセスが心配です。Postgresにはデータベースロックがないため、(上記のようにpsqlを使用して)ループの周りにBEGINとCOMMITをラップしようとしました。これにより、psqlコマンドから次のようなエラーメッセージが表示されました。

WARNING:  there is no transaction in progress

これを達成する方法はありますか?そうでない場合、代替手段は何ですか?

ありがとう!

4

1 に答える 1

2

スクリプトには2つの主な問題があります。最初の問題は実用的です。トランザクションは特定のセッションの一部であるためpsql、トランザクションを開始して終了する最初のコマンドは実際には効果がありません。コマンドが完了するとトランザクションは終了し、後のコマンドはそれを共有しません。2番目の問題は概念的です。トランザクションXで行われた変更は、トランザクションXがコミットされるまでトランザクションYに表示されませんが、トランザクションXがコミットされるとすぐに、トランザクションYがまだ存在している場合でも、トランザクションYにすぐに表示されます。進捗。つまり、スクリプトがダンプ全体を1つのトランザクションで正常にラップしたとしても、ダンプはクエリ間で一貫性のない結果を表示する可能性があるため、違いはありません。(つまり、一連のをラップすることは無意味ですSELECTsトランザクション内。トランザクションは、1つ以上のDMLステートメント、UPDATEsまたはINSERTsまたはDELETEsが含まれている場合にのみ意味があります。)

ただし、テーブルのリストをループするためにシェルスクリプトは実際には必要ないため、むしろ、複数のフラグpg_dumpを渡すことで、一度にすべてのテーブル名を指定できます。-t

pg_dump -U postgres -h $IP_ADDRESS -p 5432 \
    -t table1 -t table2 -t table3 -a --inserts MYDB >> out.sql

また、ドキュメントによるとpg_dump「データベースが同時に使用されている場合でも一貫したバックアップを作成する」ため、トランザクションの設定について心配する必要はありません。

(ちなみに、-tフラグはglob表記もサポートしています。たとえば、-t table*名前が。で始まるすべてのテーブルに一致しtableます。)

于 2012-08-24T20:19:08.503 に答える