测试场景:
在UPDATE操作提交后,脏块落盘前kill掉mogdb数据库,然后对UPDATE未落盘的脏块进行以下破坏操作,启动数据库可以正常RECOVER,数据未丢失。
1、用旧数据文件替换,可以启动
2、修改成错误的checksum,可以启动
3、数据块修改成错误的lsn,可以启动
4、dd一个数据块为0,可以启动
分析:
full_page_writes 打开时,每次checkpoint后第一次修改的块,会在wal中记录完整副本,recover时直接使用该副本重写数据文件中的块。
测试记录
[omm2@og01 ~]$ gsql
gsql ((MogDB 2.1.0 build 56189e20) compiled at 2022-01-07 18:47:53 commit 0 last mr )
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
omm2=# drop table t;
DROP TABLE
omm2=# create table t(id numeric,c varchar(100)) with (fillfactor=50);
CREATE TABLE
omm2=# insert into t select i,'test'||i from generate_series(1,1000)i;
INSERT 0 100
omm2=# checkpoint;
CHECKPOINT
select (select setting from pg_settings where name='data_directory')||'/'||pg_relation_filepath('t');
omm2=# select (select setting from pg_settings where name='data_directory')||'/'||pg_relation_filepath('t');
?column?
----------------------------------
/home/omm2/data/base/16385/73775
(1 row)
[omm2@og01 ~]$ cp /home/omm2/data/base/16385/73775 /home/omm2/data/base/16385/73775_old
[omm2@og01 ~]$
omm2=# select ctid,id from t;
ctid | id
--------+-----
(0,1) | 1
(0,2) | 2
(0,3) | 3
(0,4) | 4
(0,5) | 5
(0,6) | 6
(0,7) | 7
(0,8) | 8
(0,9) | 9
(0,10) | 10
(0,11) | 11
(0,12) | 12
(0,13) | 13
(0,14) | 14
(0,15) | 15
omm2=# update t set c='a' where id