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)的更多相关文章

  1. PostgreSQL Replication之第二章 理解PostgreSQL的事务日志(4)

    2.4 调整检查点和XLOG 目前为止,这一章已经提供深入洞察PostgreSQL如何写入数据,一般来说,XLOG是用来干什么的.考虑到这方面的知识,我们现在可以继续并学习我们能做些什么来使我们的数据 ...

  2. PostgreSQL Replication之第二章 理解PostgreSQL的事务日志(1)

    在前面的章节中,我们已经理解了各种复制概念.这不仅仅是一个为了接下来将要介绍的东西而增强您的意识的理论概述,还将为您介绍大体的主题. 在本章,我们将更加接近实际的解决方案,并了解PostgreSQL内 ...

  3. PostgreSQL Replication之第二章 理解PostgreSQL的事务日志(3)

    2.3 理解一致性和数据丢失 挖掘PostgreSQL事务日志而不考虑一致性是不可能的.在本章的第一部分,我们已经大体上解释了事务日志的基本思想.您已经知道,无需事先的日志改变的能力,使数据处于一种好 ...

  4. PostgreSQL Replication之第二章 理解PostgreSQL的事务日志(2)

    2.2 XLOG和复制 在本章中,您已经了解到PostgreSQL的事务日志已经对数据库做了所有的更改.事务日志本身被打包为易用的16MB段. 使用这种更改集来复制数据的想法是不牵强的.事实上,这是在 ...

  5. PostgreSQL Replication之第一章 理解复制概念(1)

    PostgreSQL Replication系列翻译自PostgreSQL Replication一书 在本章中,将会介绍不同的复制概念,您会了解哪些类型的复制对哪一种实用场景是最合适的. 在本章的最 ...

  6. PostgreSQL Replication之第一章 理解复制概念(3)

    1.3 使用分片和数据分配 本节您将了解基本可扩展性技术,例如数据库分片.分片被广泛应用于高端系统并提供一个简单而且可靠的扩展设置方式来向外扩展.近年来,分片已经成为一种扩大专业系统规模的标准方式. ...

  7. PostgreSQL Replication之第一章 理解复制概念(2)

    1.2不同类型的复制 现在,您已经完全地理解了物理和理论的局限性,可以开始学习不同类型的复制了. 1.2.1 同步和异步复制 我们可以做的第一个区分是同步复制和异步复制的区别. 这是什么意思呢?假设我 ...

  8. PostgreSQL Replication之第九章 与pgpool一起工作(6)

    9.6 运行pgpool和流复制 pgpool也可以和除了语句级别的复制之外的流复制一起使用.一个完美的方案是使用PostgreSQL的板载复制和仅仅使用pgpool的负载均衡与连接池. 实际上,这样 ...

  9. PostgreSQL Replication之第九章 与pgpool一起工作(7)

    9.7 处理故障转移和高可用 可以使用pgpool来解决的一些明显的问题是高可用性和故障转移.一般来讲,有使用pgpool或者不使用pgpool可以用来处理这些问题的各种方法. 9.7.1 使用Pos ...

随机推荐

  1. 【转】Android 服务器之SFTP服务器上传下载功能 -- 不错

    原文网址:http://blog.csdn.net/tanghua0809/article/details/47056327 本文主要是讲解Android服务器之SFTP服务器的上传下载功能,也是对之 ...

  2. javascript系列-class8.BOM

    1.浏览器对象模型( browser object model )   什么是BOM?    提起BOM就不得不提起JavaScript的构成.ECMAScript为JavaScript的核心,但是要 ...

  3. Web开发中 前端路由 实现的几种方式和适用场景

    http://blog.csdn.net/xllily_11/article/details/51820909

  4. (七)日志采集工具sleuth--分布式链路跟踪(zipkin)

    微服务架构上通过业务来划分服务的,通过REST调用,对外暴露的一个接口,可能需要很多个服务协同才能完成这个接口功能,如果链路上任何一个服务出现问题或者网络超时,都会形成导致接口调用失败.随着业务的不断 ...

  5. Java Servlet 3.0 新特性

    Servlet 3.0 新特性概述 Servlet 3.0 作为 Java EE 6 规范体系中一员,随着 Java EE 6 规范一起发布.该版本在前一版本(Servlet 2.5)的基础上提供了若 ...

  6. svn创建分支的做法

    作者:朱金灿 来源:http://blog.csdn.net/clever101 1.  首先选择你要创建分支的工作目录,如下图: 2.选择要创建分支的路径.注释以及版本,选择HEADrevision ...

  7. day02变量

    一. 什么是变量? 变量:在程序运行过程中,值会发生变化的量.(与之相对应的,常量就是在程序运行过程中,值不会发生变化的量).无论是变量还是常量,在创建时都会在内存中开辟一块空间,用于保存它的值. 二 ...

  8. 服务器搭建域控与SQL Server的AlwaysOn环境过程(二) 搭建客户端节点 服务器

    1. 修改客户端服务器的计算机名,重启后,如果服务器属于克隆服务器,需要修改服务器SID,如果没有则调过这一步. 命令行方式:启动Windows2008进入系统后,打开“CMD窗口”并进入到" ...

  9. [HAOI2016]找相同字符(SAM+DP)

    感觉很水. 因为SAM上一个点的子树大小代表这个点所表示子串的出现次数. 建出广义后缀自动机之后.在\(parent\)树上跑\(DP\),维护\(size[i][1]\),和\(size[i][0] ...

  10. const int *a与int *const a,const int *const a的区别

    来源:https://blog.csdn.net/zhangheng837964767/article/details/33783511 关键问题点:const 属于修饰符 ,关键是看const 修饰 ...