深入理解缓冲区(十四)

4.2.2        日志缓存的管理方式

日志缓存的管理,主要依赖于如下结构:

typedef struct XLogCtlData

{

       /* Protected by WALInsertLock: */

       XLogCtlInsert Insert;    //标识插入位置

 

       /* Protected by info_lck: */

       XLogwrtRqst LogwrtRqst;    //标识刷出请求的位置,请求未必已经被执行

       XLogwrtResult LogwrtResult;    //标识刷出结果的位置,已经刷出日志的位置

       uint32            ckptXidEpoch;       /* nextXID & epoch of latest checkpoint */

       TransactionId ckptXid;

       XLogRecPtr   asyncXactLSN; /* LSN of newest async commit/abort */

       uint32            lastRemovedLog; /* latest removed/recycled XLOG segment */

       uint32            lastRemovedSeg;

 

       /* Protected by WALWriteLock: */

       XLogCtlWrite Write;

 

       /*

        * These values do not change after startup, although the pointed-to pages

        * and xlblocks values certainly do.  Permission to read/write the pages

        * and xlblocks values depends on WALInsertLock and WALWriteLock.

        */

       char    *pages;                   /* buffers for unwritten XLOG pages */    //要写出的日志信息

    //注意,日志信息,大小不同,指针指向不同的块,实际上,放的主要是数据缓存块的信息,这样,恢复时,不是以记录为单位恢复,而是以数据库运行态中的实际的“数据块”(数据缓存中的以块为单位的信息)做恢复。不好之处是,可能使得日志文件中的信息量很大。基于逻辑信息(SQL语句)和基于物理信息(数据块)做恢复,是个争论点。教科书上,通常讲到REDO日志的时候,只会使用“前映像”和“后映像”指代恢复的单位,不明确说出恢复的单位,这是讲原理和工程实现之间的差别所在。

       XLogRecPtr *xlblocks;         /* 1st byte ptr-s + XLOG_BLCKSZ */

       int                  XLogCacheBlck;    /* highest allocated xlog buffer index */

       TimeLineID    ThisTimeLineID;

       TimeLineID    RecoveryTargetTLI;

 

       /*

        * archiveCleanupCommand is read from recovery.conf but needs to be in

        * shared memory so that the bgwriter process can access it.

        */

       char        archiveCleanupCommand[MAXPGPATH];

 

       /*

        * SharedRecoveryInProgress indicates if we're still in crash or archive

        * recovery.  Protected by info_lck.

        */

       bool        SharedRecoveryInProgress;

 

       /*

        * recoveryWakeupLatch is used to wake up the startup process to

        * continue WAL replay, if it is waiting for WAL to arrive or failover

        * trigger file to appear.

        */

       Latch             recoveryWakeupLatch;

 

       /*

        * During recovery, we keep a copy of the latest checkpoint record here.

        * Used by the background writer when it wants to create a restartpoint.

        *

        * Protected by info_lck.

        */

       XLogRecPtr   lastCheckPointRecPtr;

       CheckPoint     lastCheckPoint;

 

       /* end+1 of the last record replayed (or being replayed) */

       XLogRecPtr   replayEndRecPtr;

       /* end+1 of the last record replayed */

       XLogRecPtr   recoveryLastRecPtr;

       /* timestamp of last COMMIT/ABORT record replayed (or being replayed) */

       TimestampTz recoveryLastXTime;

 

       slock_t           info_lck;         /* locks shared variables shown above */

} XLogCtlData;

 

       日志缓存管理的方式,主要是如下算法(方法)构成:

       日志缓存,由8k大小的共享缓存构成(8k不准确,可以查看XLOGShmemSize理解更为精确)。日志缓存,有个“元信息”块,就像数据缓冲区的“BufferDesc”一样,有个“XLogCtlData”描述了日志缓冲区的使用情况。

       日志缓存,是个固定大小的区域(如下图左侧,2个方块,代表的是同一个日志缓冲区),而日志文件,是个线性连续不断的文件(如下图右侧,使用了3个方块表示日志文件,但日志文件根据日志号连续标识,可以看作是一个线性增长的文件序列),如何以固定区域的一块内存对应外存的线性文件,是我们需要掌握的问题。

 

深入理解缓冲区(十四) - 那海蓝蓝 - 那海蓝蓝的博客
 


       对于日志缓存而言(如上图左侧),其大小是固定的,内存总是要外外存小,这样,以有限的内存映射无限的外存文件,则必须循环使用内存。其用法,有点像我们学习过的“循环数组”。

1.         内存日志缓存,其大小固定

2.         内存日志缓存中存放的日至块,大小不固定。(图示的左侧的日志缓存中的小块,看起来均匀,但实际上,其中存放的日志信息的大小是不一样的)

3.         当内存日志缓存中有足够的空间(每次存放日志信息的时候,主要要比较空余空间大小),则可以把信息放到日志缓存中

4.         当日志缓存没有足够的空间,则需要写出(调用XLogWrite)一些信息到日志文件,以便重复利用日志(循环使用)

5.         当日志缓存写到尾部且空间不足时,除了要刷出一部分数据外,还要注意,从日子缓存头部刷出信息后要被重复利用

6.         日志缓存的信息是线性刷出的,这样日志文件中的信息必然是连续的(连续通过“LSN”这样的东西表示,可以通过PageGetLSN函数入手追踪LSN,实则是日志的ID和文件中的偏移的组合标识,日志ID对应一个日志文件,偏移则标识了文件内的位置,这样就唯一标识了一个物理位置)

7.         日志缓存到日志文件,是单项的,只写不读,对IO的影响不大

8.         特别需要注意阅读代码的地方是:跨页写(调用XLByteInPrevSeg函数之处)、日志文件的切换(写满后怎么再写到下一个文件,XLogWrite函数中如何调用XLogFileClose和XLogFileInit和XLogFileOpen函数)

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值