年齡回收類問題
更新時間 2025-02-05 09:37:34
最近更新時間: 2025-02-05 09:37:34
分享文章
本頁介紹天翼云TeleDB數據庫年齡回收類問題。
事務回卷問題
問題描述
當事務未能正常回收持續一段時間,庫年齡達到上限后。
報錯如下,此時數據庫還可以訪問,但不允許寫入:
ERROR: database is not accepting commands to avoid wraparound data loss in database "xxx"
HINT: Stop the postmaster and vacuum that database in single-user mode
可能影響
- 如果CN主節點年齡回卷,那么這個CN主節點會變成只讀狀態;
- 如果某個DN主節點年齡回卷,那么寫入到這個DN主節點數據SQL會報錯。
解決步驟
- 執行SQL,檢查引起年齡回收問題的庫:
SELECT datname, age(datfrozenxid) FROM pg_database where age(datfrozenxid)>200000000;
- 連接年齡回卷的庫,執行SQL,檢查引起年齡回收問題的表;
SELECT pg_namespace.nspname as schema_name,relname, age(relfrozenxid) as xid_age,
pg_size_pretty(pg_table_size(pg_class.oid)) as table_size
FROM pg_class,pg_namespace
WHERE pg_namespace.oid=pg_class.relnamespace and age(relfrozenxid)>200000000 and
relfrozenxid != 0
order by age(relfrozenxid) desc;
- 控制臺停止該節點;
- 手動啟動節點(指定報錯提示中的數據庫)進入單用戶模式
postgres --single -D ./ xxx(database)
- 手動執行vacuum或vacuum full回收問題表,如遇到報錯,需要先解決相應報錯;
- ctrl+d退出單用戶模式,控制臺啟動該節點。
年齡回收沖突問題
問題描述
年齡回收時,報沖突錯誤,如:
ERROR: tuple cannot be frozen now, please try later xid 802439820 cutoff xid 958123080
committs 25144982436271 RecentDataTs 25144852436271
RecentGlobalXmin 1058123080 RecentGlobalDataXmin 1058123080k
可能影響
表年齡回收失敗,長時間可能會導致表膨脹嚴重,影響性能,甚至會導致事務回卷,節點進入只讀狀態。
解決步驟
- 先檢查并清理一些長事務SQL,長期執行未結束的SQL;
- 執行以下命令,減少年齡差,縮小年齡回收范圍:
set vacuum_defer_freeze_min_age to 1000000;
- 再嘗試回收。
表元數據錯誤導致年齡回收失敗問題
問題描述
表年齡回收時,報錯如下:
ERROR: catalog is missing xx attribute(s) for relid xxx
可能原因
表年齡回收失敗,長時間可能會導致表膨脹嚴重,影響性能,甚至會導致事務回卷,節點進入只讀狀態。
解決步驟
參考文檔先修復元數據不一致問題,然后再嘗試回收。
toast表元數據錯誤導致年齡回收失敗問題
問題描述
toast表年齡回收時,報錯如下:
ERROR: catalog is missing xx attribute(s) for relid xxx
可能原因
表年齡回收失敗,長時間可能會導致表膨脹嚴重,影響性能,甚至會導致事務回卷,節點進入只讀狀態。
解決步驟
設置set allow_force_ddl=on;后再嘗試回收。
臨時表殘留導致年齡回收失敗問題
問題描述
臨時表其它進程無法訪問,有殘留臨時表時,無法手動回收這些臨時表年齡。
可能影響
表年齡回收失敗,長時間可能會導致表膨脹嚴重,影響性能,甚至會導致事務回卷,節點進入只讀狀態。
解決步驟
需要將臨時表所屬的schema 強制刪除,如:
drop schema if exists pg_temp_xx cascade;
操作前需要確認當前無業務訪問,所有臨時表都可以清理。
template0庫年齡回收問題
問題描述
年齡需要回收前,需要先連接template0庫,該庫默認不可連接,嘗試連接會報錯:
FATAL: database "template0" is not currently accepting connections
可能影響
template0庫有年齡問題需要回收,但template0庫不可連接。
解決步驟
- 需要修改為template0庫可連接,需要先將teledb用戶參數allow_dml_on_datanode修改為on,允許該用戶在DN上執行DML語句:
alter role teledb set allow_dml_on_datanode to on;
- 再連接所有CN、DN主節點,將template0修改為可連接:
update pg_database set datallowconn=true where datname='template0';
- 連接需要回收年齡的節點,執行vacuum回收命令。
- 還原設置,連接所有CN、DN主節點,將template0修改為不可連接:
update pg_database set datallowconn=false where datname='template0';
- 還原設置,連接CN主節點,將teledb用戶參數allow_dml_on_datanode修改為off:
alter role teledb set allow_dml_on_datanode to off;