Postgresql日志系统的实现(九)

本文详细介绍了数据库恢复过程中涉及的关键步骤,包括控制文件读取、检查点记录处理、redo日志应用等,确保数据一致性的同时,提供了针对不同场景的恢复策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.3.3.3恢复过程步骤
    1.       读控制文件,如果有,则按照文件中的信息设置恢复参数。

2.       对控制文件中所写的系统状态进行判断,给出系统状态提示

3.       读出时间线历史记录中的时间线列表expectedTLIs,如果recoveryTargetTLI不在时间线列表expectedTLIs中,则系统出现故障。

4.       如果存在备份标记文件(备份标记文件是做基础备份时生成的,参见“在线备份(热备份)为什么要执行基础备份?”),读取备份标记文件中的备份标记,从备份标记定义的检查点读取检查点的记录到record中(说明:如果指定恢复某个备份标记“AAA”状态时的数据,则需要使用备份标记文件中指定的checkpoint指定的地方开始做redo,这样就避免了“AAA”状态之后,控制文件可能被多次再写入多个checkpoint所造成的与“AAA”状态不一致的情况发生)。

a)       如果record不空,则从record中的检查点记录处开始redo恢复,把参数InRecovery参数设置为true

b)       record为空,则说明系统出现错误。

5.       如果没有备份标记文件,读取控制文件中的最后一个检查点(表明用户默认要恢复到最近的checkpoint指定的位置),并把它的记录读到record中。

a)       如果record不空,读出了检查点记录的消息。

b)       record为空,找控制文件中倒数第二个检查点,并把它的记录读到record中。

c)       如果新的检查点记录record不为空,把参数InRecovery参数设置为true

d)       如果新的检查点记录record仍为空,则说明系统出现错误。

说明:(4)步与(5)步是同一个if判断,非此即彼。

6.       从上面各步骤中,一定会得到一个有效的检查点记录。把record记录中的值赋给一个检查点结构体变量checkPoint

7.       checkPointnextXidnextOid赋给共享缓冲区中的变量缓冲区ShmemVariableCachenextXidnextOid。把checkPoint的时间线ID赋给ThisTimeLineID

8.       checkPointredo指针和undo指针有效的情况下,把参数InRecovery参数设置为true

9.       在控制文件状态不是DB_SHUTDOWNED(系统正常关闭)时,把参数InRecovery参数设置为true

10.    如果恢复控制文件中的使用归档文件进行恢复的标志参数InArchiveRecovery为真,把参数InRecovery设置为true

11.    当参数InRecovery的值为true时,执行恢复。

a)       初始化恢复环境,启动各种需要恢复的资源(调用“RmgrTable[rmid].rm_startup();”)。

b)       设置需要redo的日志记录的起始位置,把起始位置处的日志记录读入record(初始record应该是离checkpoint最近的那个记录,应该从此record开始恢复,此处调用“ReadRecord”确认要开始恢复的第一条记录就是离checkpoint最近的那条记录)。

                                               i.  如果record不空,从record开始循环执行redo操作,处理完一条需要redo的记录(通过调用“RmgrTable[record->xl_rmid].rm_redo(EndRecPtr, record);”完成本条record对应的redo操作),然后继续读取下一条记录到record中。循环终止的条件是已经执行到了我们所要求的时间线的位置,或者已经把所有的日志记录中需要redorecord执行完毕。

                                            ii.  如果record为空,也就说明不需要进行redo操作。

c)       PG中只进行redo恢复操作,虽然定义了undo的扩展接口,但是各种资源的undo函数是空函数,也就是说,PG不实际进行undo操作,数据库的一致性的保持是由日志和数据的多版本并发控制和redo日志综合起来达到的。

12.    本次恢复结束之际,确定是否需要再设置一个新的时间线。如果是恢复到某个指定的时间点上而不是全部恢复,则生成一个新的时间线,以给本次系统运行时记载xlog使用。

13.    把恢复后的一些信息写到xlog对应个共享缓存“XLogCtl”中,以备在后来系统运行的过程中使用

14.    当参数InRecovery的值为true时,执行初始环境的清理工作(对应前面的恢复前环境初始化工作,通过调用“RmgrTable[rmid].rm_cleanup()”完成)。

15.    执行“CreateCheckPoint”,强迫恢复的内容刷到磁盘

16.    关闭恢复环境

17.    正式结束恢复操作,保存对应的信息到控制文件

18.    开始启动clogprepared transactions需要的资源或环境等内容,为恢复结束后、系统正常运行做准备工作

19.    恢复过程完全结束

### PostgreSQL Logger 系统日志进程的工作原理与配置 #### 工作原理概述 Logger系统日志进程负责收集来自`postmaster`进程、服务进程以及其他辅助进程的标准错误输出(stderr),并将这些数据写入到指定的日志文件中。这一过程由`SysLogger`子系统实现,其核心功能在于集中化管理和处理日志信息[^1]。 具体而言,当数据库运行过程中发生任何事件时,相关的信息会被发送至标准错误流。随后,`SysLogger`会捕获这些信息并将其持久化存储于磁盘上的日志文件中。这种机制不仅简化了日志管理流程,还提高了系统的可维护性和诊断能力。 #### 启动入口与初始化逻辑 `SysLogger`的启动是由主控进程`postmaster`完成的。一旦检测到参数`logging_collector`被设置为`on`,则会在服务器启动期间创建一个独立的`syslogger`进程来专门执行日志收集任务[^2]。此进程在整个生命周期内持续监听其他后台进程产生的日志消息,并按照预定义规则进行分类和保存。 #### 主要配置项及其作用 以下是几个常用的日志配置选项: - **`logging_collector`**: 控制是否启用日志收集器,默认关闭(`off`);如果希望利用内置的日志管理系统,则需显式设定为开启状态(`on`)。 - **`log_directory` & `log_filename`**: 定义日志文件所在的目录路径以及命名模式。例如,可以采用日期作为变量动态生成每日新日志文件名,如`postgresql-%Y-%m-%d.log`表示按年月日记录不同天数的数据[^3]。 - **`log_truncate_on_rotation`**: 当达到轮转条件(时间或者大小限制)时,决定是否现有旧日志内容再重新开始记录新的条目。 - **`log_rotation_age` 和 `log_rotation_size`**: 设置单个日志文件的最大存续时间和最大体积阈值,超过任一限定都会触发自动分割操作形成多个分片文件以便长期保留历史记录的同时保持高效访问性能。 ```sql -- 查看当前活动连接的状态信息示例查询语句 SELECT * FROM pg_stat_activity; ``` 上述SQL命令可用于监控实时在线用户的各项指标详情,包括但不限于所属数据库名称(datname)、客户端IP地址(client_addr)等字段展示各个session的具体行为特征。 #### 日志版本差异对比 值得注意的是,在PostgreSQL 10.0之前的发行版里,默认情况下所有类型的日志均统一放置在同一位置下;而自该版本起引入了一种更为灵活的新架构——允许区分对待各类别的日志类别分别存放于不同的子文件夹之中从而便于后续检索分析工作开展得更加便捷有效率[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值