m6米乐安卓版下载-米乐app官网下载
1

postgresql故障恢复能力之检查点(checkpoint) -m6米乐安卓版下载

2021-06-01
1045

复习下前面的知识点:

1、缓冲区高速缓存(buffer cache)位于服务器的共享内存中,并且所有进程均可访问。在读取或更新数据时,进程将页面读入缓存。当页面位于缓存中时,我们在ram中使用它并保存数据到磁盘。

2、当遇到掉电等故障场景,所有 ram 内容丢失时,要在故障后恢复数据,pg必须维护一份预写式日志(wal),在故障恢复过程中通过重放wal日志进行数据恢复。

  • checkpoint

本文需要讨论的是,我们不知道在恢复期间从哪里开始重放 wal 记录。

方案一:

从头开始恢复,带来是问题是我们不一定保留了所有历史的wal日志记录(保留所有历史wal会占用大量磁盘空间),即使我们通过归档保留了所有的wal记录,恢复的时长也会难以接受。

方案二:

我们需要一个逐渐向前推进的时间点,我们可以从该时间点开始恢复(并可以安全地删除时间点以前的wal 记录),为此,pg引入了检查点(checkpoint)。

当执行checkpoint后,会确保检查点开始时所有脏的缓冲区都刷到磁盘上,此时checkpoint执行完成。后续我们可以使用checkpoint记录的开始时间作为开始恢复的点。

  •  checkpoint会执行多久

checkpoint执行后会带来大量的页面写入操作,为了避免大量的页面写入对i/o造成冲击,在检查点期间写入脏缓冲区的过程会分散为一段时间。该周期由checkpoint_completion_target控制,它是检查点间隔的一部分,默认为0.5,也就是说每个checkpoint需要在checkpoints间隔时间的50%内完成。

通常checkpoint_completion_target值会增加到 0.9 以获得更好的均匀性,postgresql 14版本中会将默认值修改为0.9。

  •  checkpoint执行过程

1、首先会对缓冲区中的脏页进行标记

 2、然后检查指针遍历所有缓存并将标记的脏页刷新到磁盘(页面不会从缓存中逐出,而只会写入磁盘)。

3、新的脏缓冲区不会被标记,并且检查指针不会写入它们。

4、创建检查点结束的 wal 记录,该记录包含检查点开始时间的 lsn。

5、更新控制文件信息($pgdata/global/pg_control)。

  • checkpoint 演示

1、创建一个表;它的页面将进入缓冲区缓存并变脏:

create extension pg_buffercache;
create table chkpt as select * from generate_series(1,10000) as g(n);
select count(*) from pg_buffercache where isdirty;
postgres=# select count(*) from pg_buffercache where isdirty;
count
-------
62
(1 row)

2、记住当前的 wal 位置

select pg_current_wal_insert_lsn();
pg_current_wal_insert_lsn
---------------------------
3/8a0b3810
(1 row)

3、手动执行检查点操作

checkpoint;
select count(*) from pg_buffercache where isdirty;
count
-------
0
(1 row)

4、看看检查点是如何反映在 wal 中的

select pg_current_wal_insert_lsn();
pg_current_wal_insert_lsn
---------------------------
3/8a0b38f8
(1 row)

可以看到lsn有更新,接下来用pg_waldump查看wal日志记录了哪些内容

查看当前lsn对应的wal日志文件

select file_name, upper(to_hex(file_offset)) file_offset from pg_walfile_name_offset('3/8a0b38f8');
file_name | file_offset
-------------------------- -------------
00000001000000030000008a | b38f8
(1 row)

/usr/local/pgsql/bin/pg_waldump -p usr/local/pgsql/data/pg_wal/ -s 3/8a0b3810 -e 3/8a0b38f8 00000001000000030000008a
----
rmgr: standby len (rec/tot): 50/ 50, tx: 0, lsn: 3/8a0b3810, prev 3/8a0b37d8, desc: running_xacts nextxid 58215 latestcompletedxid 58214 oldestrunningxid 58215
rmgr: xlog len (rec/tot): 114/ 114, tx: 0, lsn: 3/8a0b3848, prev 3/8a0b3810, desc: checkpoint_online redo 3/8a0b3810; tli 1; prev tli 1; fpw true; xid 0:58215; oid 34053;
multi 1; offset 0; oldest xid 479 in db 1; oldest multi 1 in db 12723; oldest/newest commit timestamp xid: 0/0; oldest running xid 58215; online

可以看到日志记录了checkpoint_online信息,checkpoint start的lsn在单词“redo”之后输出,这个位置对应checkpoint start时间最后一个wal记录。

5、查看控制文件信息,可知控制文件记录了最近的checkpoint点对应的lsn信息

pg_controldata -d usr/local/pgsql/data/ |egrep 'latest.*location'
latest checkpoint location: 3/8a0b3848
latest checkpoint's redo location: 3/8a0b3810
  • 故障后恢复

如果服务器出现故障,则在后续启动时,会通过查看pg_control控制
文件,查找与“关闭”不同的状态来检测此情况。在这种情况下进行自动恢复。

1、直接kill掉postgres主进程

2、查看控制文件database cluster state状态,没有发生变化

pg_controldata -d usr/local/pgsql/data/ |grep state
--------
database cluster state: in production

3、启动数据库,查看日志

pg_ctl -d /usr/local/pgsql/data/ start

 可知故障后,数据库从latest checkpoint's redo location开始恢复数据

  • 正常关闭后恢复

1、记录当前的lsn

select pg_current_wal_insert_lsn();
pg_current_wal_insert_lsn
---------------------------
3/8b0000a0
(1 row)


2、正常关闭数据库

 pg_ctl -d /usr/local/pgsql/data/ stop

3、查看控制文件database cluster state状态,可知正确记录了关闭状态

pg_controldata -d /usr/local/pgsql/data/ |grep state
database cluster state: shut down

4、查看wal日志, 拥有最终检查点的唯一记录(checkpoint_shutdown)

 /usr/local/pgsql/bin/pg_waldump -p /usr/local/pgsql/data/pg_wal/ -s 3/8b0000a0  00000001000000030000008b

5、再次启动数据库,可知数据库正常启动,无恢复操作


文章转载自,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论

关注
网站地图