【発生条件】
PostgreSQL の TOAST テーブルのデータ破損に関連して発生します。
【原因】
ウィルス対策ソフトが PostgreSQL で利用するディレクトリを監視対象としている場合に、発生することがあります。
【回避方法】
ウィルス対策ソフトが PostgreSQL で利用するディレクトリを監視対象としている場合は、監視対象から除外していただくことで、回避することができます。
または、該当テーブルの REINDEX と VACUUM ANALYZE を定期実行することで、回避することができます。
【対応方法】
非同期タスクの処理で該当のエラーがすでに発生してしまった場合は、該当テーブルの REINDEX と VACUUM ANALYZE、および破損したデータを特定して削除することでエラーを解消できます。
その上で上記の回避方法により、以降のエラー発生を回避することができます。
以下に、該当テーブルの REINDEX と VACUUM ANALYZE、および破損したデータを特定して削除する手順を記載します。
1. システムデータベースのバックアップを取得します。
2. REINDEX を行います。
(1) 対象のtoastテーブルを特定します。
エラーメッセージから対象のtoastテーブルを特定します
【エラーメッセージ例】
===================
org.postgresql.util.PSQLException: ERROR: missing chunk number 0 for toast value 2859633 in pg_toast_112208
===================
上記メッセージの場合、「pg_toast_112208」が対象のtoastテーブルとなります。
(2) toastテーブルのリレーションテーブルを特定します。
【PSQL例】
===================
=> select 112208::regclass;
regclass
--------------------
im_async_task_info
===================
上記例では「pg_toast_112208」の「112208」からリレーションを特定しています。
(3) toastテーブルとリレーションテーブルをREINDEXします。
【PSQL例】
===================
=# GRANT usage ON schema pg_toast TO ユーザ; -- pg_toastへの権限をREINDEX実行ユーザに付与(スーパーユーザが実行)
===================
===================
=> REINDEX table pg_toast.pg_toast_112208; -- toastテーブルをREINDEX
=> REINDEX table im_async_task_info; -- im_async_task_infoをREINDEX
===================
3. リレーションテーブルに対してVACUUM と ANALYZE を行います。
【PSQL例】
===================
=> VACUUM ANALYZE im_async_task_info; -- im_async_task_info を VACUUM ANALYZE
===================
上記でエラーが発生する場合は次の手順に進みます。
エラーがなければ完了です。
4. 破損データの特定と削除を行う
(1) 2. で特定したリレーションテーブルのエラー行を特定します。
下記の例の場合は1件ずつSELECTを実行してエラー発生行を特定しています。
【PSQL例】
===================
=> SET client_min_messages TO notice; --コンソールに出力するための設定
=> DO $$
declare
v_rec record;
BEGIN
for v_rec in SELECT * FROM im_async_task_info ORDER BY message_id loop
RAISE NOTICE '%', v_rec.message_id;
end loop;
END;
$$
;
--エラーが発生した行のデータが破損している。
===================
(2) エラー発生行のデータと、関連データを削除します。
下記例では「im_async_task_info」と「im_async_task_info」に紐づく「im_async_context_info」を削除しています。
【PSQL例】
===================
=> DELETE FROM im_async_context_info WHERE identifier IN (SELECT context FROM im_async_task_info WHERE message_id = 'XXXXXX');
=> DELETE FROM im_async_task_info where message_id ='XXXXXX';
===================
(3) エラーが解消されたか確認します。
4-(1)を再度実行し、エラー行がないことを確認します。
エラー行がある場合は 4-(2)の通り削除を行います。
5. リレーションテーブルに対してVACUUMFULLを行います。
【PSQL例】
===================
=> VACUUMFULL im_async_task_info; -- im_async_task_info を VACUUMFULL
===================
以上で完了です。
-- 対象 ------------------------------------------------------------------------
iAP/Accel Platform/全アップデート
--------------------------------------------------------------------------------
FAQID:1163
非同期タスクの処理で「Caused by: org.postgresql.util.PSQLException: ERROR: missing chunk number XXXX for toast value XXXX in pg_toast_XXXX」というエラーが発生します。
