PostgreSQL Replication之第二章 理解PostgreSQL的事务日志(5)
2.5 XLOG的内部结构
我们将使用事务贯穿本书,并让您在技术层面上更深地洞察事情是如果工作的,我们已经增加了这部分专门处理XLOG的内部工作机制。我们会尽量避免前往下降到C级,因为这将超出本书的范围,但我们会为您提供希望足够深的见解。
2.5.1 理解XLOG记录
对XLOG所做的更改是基于记录的。这意味着什么?让我们假设您在给一个表添加一行数据:
test=# INSERT INTO t_test VALUES (1, 'hans');
INSERT 0 1
在这个例子中,我们正在插入一个含有两列的表。为了这个例子,我们要假定这两个列被索引。
记得我们之前了解到:XLOG的目的是为了保持这些数据文件安全。所以,这个操作将触发一系列的XLOG条目。首先,与表相关的数据文件将被写入。然后,索引相关的条目将被创建。最后一个COMMIT记录被发送到日志。
并不是所有的XLOG记录都是平等的:有各种类型的XLOG记录(例如,heap,btree,clog,storage,gin,以及standby 记录,仅举几例)。
XLOG记录向后链接。这样,每个入口指向文件中前面的条目。通过这种方式,我们可以完全相信,只要我们要到指向前一个条目的指针,我们就已经找到了记录的结尾。
使XLOG具有确定性
正如您所看到的,一个改变可以触发许多XLOG条目。对所有种类的语句来说,这都是真的;例如一个大的DELETE语句可以很容易造成上百万的变化。其原因是PostgreSQL不能简单地把SQL本身写入日志;它必须真实记录对表所做的物理改变。这是为什么?考虑一下下面的例子:
test=# DELETE FROM t_test WHERE id > random();
DELETE 5335
函数random每次被调用时,都产生不同的输出,因此,我们不能仅仅把SQL写入日志,因为如果在重放期间它被执行,这不能保证给我们提供相同的结果。
使XLOG可靠
在整个数据库实例中,XLOG本身是最关键和最敏感的部分之一。因此,我们必须采取特殊照顾,以确保做所有可能的事情来保护它。在崩溃的情况下,如果没有XLOG,数据库实例通常会遭遇不幸。
在内部,PostgreSQL采取特殊的预防措施来处理XLOG:
• 使用 CRC32 校验和
• 禁用信号
• 空间分配
首选,每条XLOG记录包含一个CRC32校验和。这允许我们检查日志在启动时的完整性。崩溃之前的最后一次写操作完全没有消息是完全可行的, 因此,一个校验和绝对有助于解决这个问题。校验和由PostgreSQL自动计算,并且用户没有必要关心这个明确的功能。
除了校验和,当写XLOG时,PostgreSQL将暂时禁用信号。这给了安全一些额外的级别,并在某种程度上降低了愚蠢的极端情况的可能性。
最后,PostgreSQL使用一个固定大小的XLOG。XLOG的大小由检查点段以及checkpoint_completion_target确定。
PostgreSQL事务日志大小的计算方法如下:
checkpoint_segments + wal_keep_segments + 1 files
重要的是,如果某个东西的大小是固定的,它很少用尽空间。
[在基于事务日志复制的情况下,如果事务日志无法存档,我们可以用尽XLOG目录的空间。]
您可以在下一个章节了解这个主题更多的内容。
2.5.2 LSN和共享缓冲区的交互
如果您要修复一个表,您必须确保按照正确的顺序修复表;如果一行数据在它实际产生之前被删除,这将是一场灾难。因此XLOG为您提供了所有改变的顺序。在内部,通过逻辑序列号(LSN)来反映这个顺序。对XLOG来说LSN是必不可少的。每个XLOG条目将被直接分配给一个LSN。
在前面的一个章节,我们已经讨论了一致性级别。synchronous_commit设置为off,即便XLOG记录还没有被刷新到磁盘,客户端也会获得一个OK。因为更改必须在高速缓存中反映,并且由于写XLOG必须在写数据表之前完成,系统必须确保并不是在共享缓存中的所有块都可以被立即写出来。LSN会保证,如果相应的变化已经写到了XLOG,我们只能从共享缓存把数据块写到数据文件。写入XLOG是根本,在崩溃后,违反了这个规则肯定会导致问题。
调试XLOG并把它们放在一起
既然我们已经知道了XLOG的基本工作原理,我们就可以把它们放在一起并研究一下XLOG。到了PostgreSQL9.2,工作原理如下:我们要从源代码编译PostgreSQL。在我们这样做之前,我们应该修改位于src/include/pg_config_manual.h的文件。在大约250行,我们可以取消WAL_DEBUG的注释并正常编译。这将允许我们设置一个称为wal_debug的客户端变量:
test=# SET client_min_messages TO log;
SET
test=# SET wal_debug TO on;
SET
除此之外,我们要设置client_min_messages,以确保日志消息会到达我们的客户端。
我们为我们的测试使用下面的表结构:
test=# \d t_test
Table "public.t_test"
Column | Type | Modifiers
--------+---------+-----------
id | integer |
name | text |
Indexes:
"idx_id"btree (id)
"idx_name"btree (name)
如果PostgreSQL已经正常编译(只有这样),我们将在屏幕上看到关于XLOG的信息:
test=# INSERT INTO t_test VALUES (1, 'hans');
LOG: INSERT @ 0/17C4680: prev 0/17C4620; xid 1009; len 36: Heap -
insert(init): rel 1663/16384/16394; tid 0/1
LOG: INSERT @ 0/17C46C8: prev 0/17C4680; xid 1009; len 20: Btree
- newroot: rel 1663/16384/16397; root 1 lev 0
LOG: INSERT @ 0/17C4700: prev 0/17C46C8; xid 1009; len 34: Btree
- insert: rel 1663/16384/16397; tid 1/1
LOG: INSERT @ 0/17C4748: prev 0/17C4700; xid 1009; len 20: Btree
- newroot: rel 1663/16384/16398; root 1 lev 0
LOG: INSERT @ 0/17C4780: prev 0/17C4748; xid 1009; len 34: Btree
- insert: rel 1663/16384/16398; tid 1/1
LOG: INSERT @ 0/17C47C8: prev 0/17C4780; xid 1009; len 12:
Transaction - commit: 2013-02-25 18:20:46.633599+01
LOG: XLOG flush request 0/17C47F8; write 0/0; flush 0/0
正如本章所述,PostgreSQL将先向表本身(heap)添加一行。然后XLOG包含所有与索引相关的条目。最后,添加一个提交记录。
总之,156字节已经能够成功写入XLOG;这远远超过了我们实际添加的数据。一致性,性能(各项指标)和可靠性都配备了价格标签。
2.6 总结
本章,您已经了解了PostgreSQL的事物日志的目的。我们已经广泛地讨论的磁盘上的数据格式和一些非常重要的主题,例如:一致性和性能。在下一章中,我们复制我们的第一个数据库时就会需要所有这些主题。
下一章将建立在您刚才学到的主题之上,重点关注即时恢复。目标是使PostgreSQL及时恢复到一个特定的时间点并提供好像后面的事务从来没有发生过的数据。
PostgreSQL Replication之第二章 理解PostgreSQL的事务日志(5)的更多相关文章
- PostgreSQL Replication之第二章 理解PostgreSQL的事务日志(4)
2.4 调整检查点和XLOG 目前为止,这一章已经提供深入洞察PostgreSQL如何写入数据,一般来说,XLOG是用来干什么的.考虑到这方面的知识,我们现在可以继续并学习我们能做些什么来使我们的数据 ...
- PostgreSQL Replication之第二章 理解PostgreSQL的事务日志(1)
在前面的章节中,我们已经理解了各种复制概念.这不仅仅是一个为了接下来将要介绍的东西而增强您的意识的理论概述,还将为您介绍大体的主题. 在本章,我们将更加接近实际的解决方案,并了解PostgreSQL内 ...
- PostgreSQL Replication之第二章 理解PostgreSQL的事务日志(3)
2.3 理解一致性和数据丢失 挖掘PostgreSQL事务日志而不考虑一致性是不可能的.在本章的第一部分,我们已经大体上解释了事务日志的基本思想.您已经知道,无需事先的日志改变的能力,使数据处于一种好 ...
- PostgreSQL Replication之第二章 理解PostgreSQL的事务日志(2)
2.2 XLOG和复制 在本章中,您已经了解到PostgreSQL的事务日志已经对数据库做了所有的更改.事务日志本身被打包为易用的16MB段. 使用这种更改集来复制数据的想法是不牵强的.事实上,这是在 ...
- PostgreSQL Replication之第一章 理解复制概念(1)
PostgreSQL Replication系列翻译自PostgreSQL Replication一书 在本章中,将会介绍不同的复制概念,您会了解哪些类型的复制对哪一种实用场景是最合适的. 在本章的最 ...
- PostgreSQL Replication之第一章 理解复制概念(3)
1.3 使用分片和数据分配 本节您将了解基本可扩展性技术,例如数据库分片.分片被广泛应用于高端系统并提供一个简单而且可靠的扩展设置方式来向外扩展.近年来,分片已经成为一种扩大专业系统规模的标准方式. ...
- PostgreSQL Replication之第一章 理解复制概念(2)
1.2不同类型的复制 现在,您已经完全地理解了物理和理论的局限性,可以开始学习不同类型的复制了. 1.2.1 同步和异步复制 我们可以做的第一个区分是同步复制和异步复制的区别. 这是什么意思呢?假设我 ...
- PostgreSQL Replication之第九章 与pgpool一起工作(6)
9.6 运行pgpool和流复制 pgpool也可以和除了语句级别的复制之外的流复制一起使用.一个完美的方案是使用PostgreSQL的板载复制和仅仅使用pgpool的负载均衡与连接池. 实际上,这样 ...
- PostgreSQL Replication之第九章 与pgpool一起工作(7)
9.7 处理故障转移和高可用 可以使用pgpool来解决的一些明显的问题是高可用性和故障转移.一般来讲,有使用pgpool或者不使用pgpool可以用来处理这些问题的各种方法. 9.7.1 使用Pos ...
随机推荐
- java基础之get和post的差别
上篇博文讲到HTTP协议,本篇介绍HTTP请求方法中get和post的差别: 首先,最明显的一点表象上的差别:GET 方式.将请求參数附加在url之后,POST将请求參数附加在请求头的最后 以下具体说 ...
- 每一个JavaScript开发者都应该知道的10道面试题
JavaScript十分特别.而且差点儿在每一个大型应用中起着至关关键的数据.那么,究竟是什么使JavaScript显得与众不同,意义非凡? 这里有一些问题将帮助你了解其真正的奥妙所在: 1.你能 ...
- 项目复习期总结3:CSS引入方式,凝视,命名规范,背景,行高,文本属性
文件夹: 1.CSS凝视的书写 怎么写?优点? 2.CSS引入方式 各种的优缺点 3.选择器的写法与选择器的优先级 4.CSS命名规范 5.背景,行高 6.文本(text与font开头)等全部属性 ...
- Objective-c 中如何重写父类的初始化方法
在我们的日常开发中我们经常会定义一些自己的子类继承一些UIKit 库中的类,那我们应该如何重写的这些初化方法呢?那我们先看看这些类有哪些初初化方法吧.(这里就用UIView为例) - (id)init ...
- 开发者了解NET的15个特性
NET 开发者了解的15个特性 本文列举了 15 个值得了解的 C# 特性,旨在让 .NET 开发人员更好的使用 C# 语言进行开发工作. ObsoleteAttribute ObsoleteAttr ...
- css文字换行问题white-space:pre-line或者white-space:pre-wrap,解决word-wrap:break-word解决不了的
想让文字换行必须要写的那几个css样式就略过了.当一行文字是数字或字母时或者数字字母组合时会出现不换行局面,这时候加个word-wrap:break-word:就基本可以解决但是有种情况是它解决不了的 ...
- dialog.setCancelable与setCanceledOnTouchOutside的区别
dialog.setCancelable(false); dialog弹出后会点击屏幕或物理返回键,dialog不消失 dialog.setCanceledOnTouchOutside(false); ...
- Python 计算相似度
#计算相似度 #欧式距离 # npvec1, npvec2 = np.array(det_a), np.array(det_b) # similirity=math.sqrt(((npvec1 - n ...
- 玩转图片上传————原生js XMLHttpRequest 结合FormData对象实现的图片上传
var form=document.getElementById("formId"); var formData=new FormData(form); var oReq = ne ...
- 【剑指Offer学习】【面试题47:不用加减乘除做加法】
题目:写一个函数,求两个整数之和,要求在函数体内不得使用+.-.×.÷四则运算符号. 解题思路 5 的二进制是101, 17 的二进制是10001 .还是试着把计算分成三步:第一步各位相加但不计进位. ...