崩潰恢復(fù)場景: 用例
下面我們在 PostgreSQL 的數(shù)據(jù)庫中,創(chuàng)建一個表,插入一些數(shù)據(jù)。
CREATE TABLE t (id integer, name text);
INSERT INTO t (id, name)
SELECT i, repeat('Pg', 32)
FROM generate_series(1, 1000000) AS s(i);
下面我們啟動一個事務(wù)塊,創(chuàng)建一個空表t1
,復(fù)制表t
創(chuàng)建一個新表t_copy
,并查看下表文件的存儲路徑。
BEGIN;
CREATE TABLE t1 ();
CREATE TABLE t_copy AS TABLE t;
SELECT pg_relation_filepath(name) AS path
FROM (VALUES ('t1'), ('t_copy')) AS t (name);
path
--------------
base/5/16389
base/5/16392
讓我們立即停止數(shù)據(jù)庫,模擬數(shù)據(jù)庫異常宕機(jī)的故障,再重新啟動數(shù)據(jù)庫服務(wù):
$ pg_ctl stop --mode=immediate
$ pg_ctl start
數(shù)據(jù)庫重新啟動后,手動觸發(fā)一次檢查點(diǎn):
CHECKPOINT;
檢查重啟前事務(wù)塊中新增的表文件:
$ ls -lh base/5/{16389,16392}
-rw------- 1 postgres postgres 0 Aug 18 17:43 base/5/16389
-rw------- 1 postgres postgres 97M Aug 18 17:44 base/5/16392
崩潰恢復(fù)場景: 內(nèi)部原理
下面是我們在 PostgreSQL 的事務(wù)中創(chuàng)建表文件時,崩潰恢復(fù)后出現(xiàn)表文件殘留問題的內(nèi)部原因:
- 1. PostgreSQL 在事務(wù)運(yùn)行的過程中,會在會話內(nèi)存中記錄創(chuàng)建的表文件。
- 2. 當(dāng)事務(wù)發(fā)生異?;蛘邎?zhí)行回滾操作時,會即時地清除這些表文件。
- 3. 當(dāng)事務(wù)異常中斷,如:磁盤不足引發(fā)的 PANIC 錯誤,系統(tǒng)發(fā)出的 OOM 內(nèi)存不足信號,或者發(fā)生軟件錯誤的擴(kuò)展插件,系統(tǒng)停電導(dǎo)致的服務(wù)器崩潰時,會話內(nèi)存中記錄的新增表文件會丟失,出現(xiàn)表文件殘留的問題。
Redrock Postgres 的解決方案
Redrock Postgres 在創(chuàng)建表文件時,會記錄撤消日志,當(dāng)正在連接的會話因?yàn)槟承┰虮恢兄购?,?shù)據(jù)庫重新啟動后會檢查這些異常中止的事務(wù)。數(shù)據(jù)庫會回滾這些異常中止的事務(wù),根據(jù)記錄的撤消日志清理殘留的表文件。
下面我們在 Redrock Postgres 的數(shù)據(jù)庫中,創(chuàng)建和上面相同的表,并插入同樣的數(shù)據(jù)。
CREATE TABLE t (id integer, name text);
INSERT INTO t (id, name)
SELECT i, repeat('Pg', 32)
FROM generate_series(1, 1000000) AS s(i);
下面我們啟動一個事務(wù)塊,創(chuàng)建一個空表t1
,復(fù)制表t
創(chuàng)建一個新表t_copy
,并查看下表文件的存儲路徑。
BEGIN;
CREATE TABLE t1 ();
CREATE TABLE t_copy AS TABLE t;
SELECT pg_relation_filepath(name) AS path
FROM (VALUES ('t1'), ('t_copy')) AS t (name);
path
--------------
base/5/16389
base/5/16392
讓我們立即停止數(shù)據(jù)庫,模擬數(shù)據(jù)庫異常宕機(jī)的故障,再重新啟動數(shù)據(jù)庫服務(wù):
$ pg_ctl stop --mode=immediate
$ pg_ctl start
數(shù)據(jù)庫重新啟動后,手動觸發(fā)一次檢查點(diǎn):
CHECKPOINT;
事務(wù)回滾的時候不會立即清理殘留的表文件,表文件的實(shí)際清理操作是在檢查點(diǎn)的過程中完成的。
檢查重啟前事務(wù)塊中新增的表文件:
$ ls -lh base/5/{16389,16392}
ls: cannot access 'base/5/16389': No such file or directory
ls: cannot access 'base/5/16392': No such file or directory
數(shù)據(jù)庫重新啟動后,回滾了異常中止的事務(wù),根據(jù)事務(wù)記錄的撤消日志清理了殘留的表文件。
轉(zhuǎn)自:https://mp.weixin.qq.com/s/98DnaCDJPcjFTS2JpxlRYg?
該文章在 2025/8/19 10:21:13 編輯過