日志缓存的管理,主要依赖于如下结构:
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函数)
分享到:
相关推荐
本文主要以《深入理解计算机》3.38题为例,详细地介绍了该题目的解题过程,主要目的是利用程序缓冲区溢出以达到改变程序的输出(攻击程序)。 要解决这类题目,需要对过程调用的栈帧变化、指令的作用有较深入的了解...
经典缓冲区溢出攻击源代码,包含详细的分析文档,不可多得的 <br>资源,对于理解缓冲区溢出原理以及汇编语言有很好的帮助。《 <br>深入理解计算机系统》一书中使用到的例子,我将这个例子进行 <br>了详细的...
本文从根本上讲解了scanf函数的应用,以及输入时键盘缓冲区的数据形式,相信读完之后你会对scanf有更深一层次的认识。
深入理解程序设计.使用Linux汇编语言...., 文件处理及缓冲区分析;, 记录读写及修改;, 通过测试及错误处理打造健壮程序;, 程序共享;, 内存布局及处理;, 计算机的计数原理;, 程序优化(时机、位置及方式)。
应大家要求上传。可嵌入到工程上的C语言实现的内存泄漏检查代码!!!!!!!!!!深入理解LINUX内存管理学习笔记。常见的内存错误。以及缓冲区缓冲区溢出攻击:原理,防御及检测,并给出全部代码以及ppt
这就是"等待队列".(有多种原因可以让进程进入TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE状态, 如等待缓冲区被填充, 等待 锁被释放等, 于是就构造一个链表, 链表中的进程都在等待同一事件的产生.).解Linux内核正版...
在java中,所有实例域、静态域和数组元素存储在堆内存中,堆内存在线程之间共享(本文使用“共享变量”这个术语代指实例域,静态域和数组...它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化。 。。。。。。
缓冲区溢出学习的入门教程,深入浅出,非常容易理解。比较详细,从基础讲起,用实例分析,适合新手入门学习。
2. 增加了很多关于由算术运算溢出以及缓冲区溢出造成安全漏洞的内容。 3. 更详细讲述了处理器对异常的发现和处理。 4. 描述了基于Intel Core i7处理器的存储器层次结构,还增加了固态硬盘的内容。 5. 强调并发性...
以android4.1代码为基础,综合了网络上的内容,加入了自己的一些理解。 目录: Activity的启动与GSurface的创建 Activity与...共享内存缓冲区同步策略 SurfaceView实现原理分析 特殊的应用——Chromium
笔者在最近项目的开发中需要使用到“屏幕双缓冲”技术,“屏幕双缓冲”是GUI客户端中最经常使用的一种技术,但是这种技术在iPhone平台似乎很少被人使用到,网上的资料基本很难找到,这点让笔者很是不解.
一般情况下,由键盘输入的字符并没有直接送入程序,而是被存储在一个缓冲区当中。下面这篇文章主要给大家介绍了关于C语言中输入输出流与缓冲区的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
种攻击,目的就在于:当程序没有对缓冲区溢出做足够防范时,立交 攻击者可能会如何利用这些安全漏洞 ;通过实验,能更好的理解写 出安全的程序的重要性,也能了解到一些编译器和操作 ;以及系统 提供的帮助改善...
1) ByteArrayInputStream:把内存中的一个缓冲区作为InputStream使用 2) StringBufferInputStream:把一个String对象作为InputStream 3) FileInputStream:把一个文件作为InputStream,实现对文件的读取操作 4) ...
ByteBuf内存池设计可以实现缓冲区的重用,提高性能。灵活的TCP参数配置能力可以满足不同的用户场景。并发优化包括volatile的大量、正确使用,CAS和原子类的广泛使用,线程安全容器的使用,以及通过读写锁提升并发...
对于一个刚刚入门的php程序员来说,php缓冲区是几乎透明的。在他们心目中,一个echo print_r 函数,数据便会‘嗖’的一声飞到浏览器上,显示出来。我也一直如此单纯地认为。 其实,在技术的世界里,向来都是由简单到...
先决条件在深入研究缓冲区溢出之前,您应该熟悉: 基本的 C/C++ 理解。 Linux 权限。 基本装配知识。 GDB 和程序内存分配(堆栈、帧)。 GNU 项目调试器(又名 GDB)特别有用,因为我不会详细介绍如何使用它,如果您...
在进行毕业设计、课程设计或大作业时,选择具备学习借鉴价值的项目可以帮助你理解和应用所学知识,同时也可以通过修改和扩展来实现其他功能。 通过参与实际项目,你可以应用所学的理论知识,深入了解软件开发或其他...
并发控制-生产者-消费者问题实验报告