次のスクリプトを実行しています。
pg_restore tmp/latest.backup --verbose --clean --no-acl --no-owner --dbname hub_development --jobs=12
これはしばしば次のエラーで失敗します:
error: could not find block ID 4584 in archive -- possibly due to out-of-order restore request, which cannot be handled due to lack of data offsets in archive
pg_restore: error: a worker process died unexpectedly
このエラーは、インデックス、主キーなどが必要なテーブルに、インデックスがないことを意味します。たとえば、複数のコアなしで実行すると、予想どおり、users
テーブルは次のようになります。
Table "public.users"
Column | Type | Collation | Nullable | Default
--------------------+-----------------------------+-----------+----------+-----------------------------------
id | integer | | not null | nextval('users_id_seq'::regclass)
created_at | timestamp without time zone | | not null |
updated_at | timestamp without time zone | | not null |
email | character varying | | not null |
confirmation_token | character varying(128) | | |
name | character varying | | not null | ''::character varying
user_type | character varying | | |
encrypted_password | character varying(128) | | |
remember_token | character varying(128) | | |
Indexes:
"users_pkey" PRIMARY KEY, btree (id)
"index_users_on_email" btree (email)
"index_users_on_remember_token" btree (remember_token)
Referenced by:
TABLE "project_feedback_users" CONSTRAINT "fk_Rails_08af49ba47" FOREIGN KEY (user_id) REFERENCES users(id)
TABLE "client_reviews" CONSTRAINT "fk_Rails_8fc606dbea" FOREIGN KEY (user_id) REFERENCES users(id)
with複数のコアを実行すると、テーブルは次のようになります。
hub_development=# \d users
Table "public.users"
Column | Type | Collation | Nullable | Default
--------------------+-----------------------------+-----------+----------+-----------------------------------
id | integer | | not null | nextval('users_id_seq'::regclass)
created_at | timestamp without time zone | | not null |
updated_at | timestamp without time zone | | not null |
email | character varying | | not null |
confirmation_token | character varying(128) | | |
name | character varying | | not null | ''::character varying
user_type | character varying | | |
encrypted_password | character varying(128) | | |
remember_token | character varying(128) | | |
これに基づいて、テーブル自体を作成したのと同じワーカーがインデックスと外部キーの追加にも責任を負っていないこと、2番目のワーカーが最初のワーカーの前に実行しようとしていること、そしてこれが私が観察したエラーの原因であるという結論に達しました。
--jobs=12
フラグを削除すると、スクリプトは正常に機能します。最悪の場合の修正は、単純にそれを行うことです。
ただし、私自身の教育では、順不同の復元要求を回避しながら、複数のコアを使用してDB復元を並列化する機能を維持するソリューションがあるかどうか知りたいです。
このエラーは、アーカイブにデータオフセットがないため、順不同の復元リクエストを処理できないことを示しています。これらのデータオフセットを追加すると、私が説明した方法で問題が解決しますか?もしそうなら、私はそれについてどうしますか、そうすることには不利な点がありますか?
私はDB管理者ではないため、ここでの知識は限られています。質問に答えるのに十分な情報を提供できなかった場合は、お知らせください。
Postgresのローカルバージョンは12.1で、データはRails Herokuでホストされているアプリからのものです。ここにheroku pg:info
の結果があります:
=== HEROKU_POSTGRESQL_BRONZE_URL, DATABASE_URL
Plan: Standard 0
Status: Available
Data Size: 3.38 GB
Tables: 44
PG Version: 11.5
Connections: 22/120
Connection Pooling: Available
Credentials: 1
Fork/Follow: Available
Rollback: earliest from 2020-01-10 18:17 UTC
Created: 2019-10-29 18:20 UTC
Region: us
Data Encryption: In Use
Continuous Protection: On
Maintenance: not required
Maintenance window: Wednesdays 18:00 to 22:00 UTC
Add-on: postgresql-metric-02684
pg_dump
が出力ファイルを検索できない場合(通常、出力がどこかにパイプされていることを意味します)、特定のメタデータで出力ファイルを更新できず、警告なしにダンプから除外します。 PostgreSQL 12のpg_restore -j
ロジックを変更すると、そのデータに依存するようになり、データが利用できない場合はpossibly due to out-of-order restore request
エラーが発生します。
-f
フラグを使用してpg_dumpを実行し、出力用のファイルを指定できる場合は、正しいメタデータを含むダンプファイルを取得します。その変更を行うためのpg_dump
の実行方法を制御できない場合は、PostgreSQL 12以降で並列復元を実行できません。
私は関連する場所でこの動作の一部を文書化するためにパッチをアップストリームに提出したので、うまくいけば、それが将来の人々にとってそれほど謎ではないでしょう。出力ファイルがシークをサポートする場合にのみ書き込まれる追加のメタデータは、pg_dump
コード内のコメント以外に文書化されていないため、ほとんどのユーザーにとっては少し謎です。
一見すると、pg_dumpがEOFに達したファイルシステムの問題のようです。
しかし、あなたは--jobs = 12なしでそれがうまくいくと言います。次に、これは同期の問題のように見えますが、他の人が報告することでもっと頻繁に現れるはずです。 (私は--jobs = 2で実験します。)
私の推測では、それはOSに関係しています。おそらく、開いているファイルの最大数に達しています(通常、/ var/log/messagesを調べますが、Herokuを使用しています)。最大オープンファイルの詳細については、以下を参照してください。 https://www.postgresql.org/docs/12/kernel-resources.html#id-1.6.5.6.5
私はこの問題を抱えていました。私にとっての解決策は、開発で古いバージョンのpostgresを使用することでした。本番サーバーは9.xまたは10.xを使用していましたが、postgres 12.xを使用して復元しようとしました。 10.xへのダウングレードがうまくいきました。