在非同步任务的处理中发生了错误「Caused by: org.postgresql.util.PSQLException: ERROR: missing chunk number XXXX for toast value XXXX in pg_toast_XXXX」。

 
【触发条件】
该问题的发生与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.步确定的关系表错误行。
 
  在以下示例中,逐个执行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
这篇文章有帮助吗?
0 人中有 0 人觉得有帮助
由 Zendesk 提供技术支持