2.4 调整检查点和XLOG

目前为止,这一章已经提供深入洞察PostgreSQL如何写入数据,一般来说,XLOG是用来干什么的。考虑到这方面的知识,我们现在可以继续并学习我们能做些什么来使我们的数据库在复制和单台服务器运行的两种情况更加有效的工作。

2.4.1 理解检查点

在本章中,我们已经看到在数据可能到其它地方之前,它已经被写入到了XLOG。问题是,如果XLOG从未被删除,显然,在没有填满磁盘的同一时间,我们不会永远写到XLOG中。

要解决这个问题,XLOG必须在某一时刻被删除。这个过程就是所谓的检查点。

从这个问题所带来的主要问题是:什么时候XLOG可以被截断到某一特定的点?答案是:PostgreSQL把XLOG中所有的东西都放到存储文件中。如果XLOG中的所有更改也被放到数据文件中,XLOG才可以被截断。

[请记住,只写数据是没有价值的,我们还必须把数据刷新到数据表中。]

在某种程度上,XLOG可以被看作在有情况发生时,数据文件修理工。如果一切都被完全修复,修理指令就可以被放心地删除了。这就是在一个检查点期间所发生的。

2.4.2 配置检查点

对一致性来说,检查点是非常好重要的,但是它们对性能来说也是非常重要的。如果检查点配置不当,您可能会面临严重的性能下降。

当谈到配置检查点,下面是一些相关参数。请注意,所有这些参数可以在postgresql.conf 中进行更改:

checkpoint_segments = 3

checkpoint_timeout = 5min

checkpoint_completion_target = 0.5

checkpoint_warning = 30s

在下面的章节中,我们将看看这些变量:

关于段和超时

checkpoint_segments 和 checkpoint_timeout 将定义两个检查点之间的距离。检查点发生或者当我们用完段或者实际到了。

请记住,一个段通常是16MB,所以三个段意味着我们将每48MB做一个检查点。在现代硬件上,16MB是远远不够的。在一个典型的生产系统中,一个检查点256个间隔或者更高是完全可行的。

但是,当设置checkpoint_segments的时候,有一件事必须记在您的脑后:在崩溃的情况,PostgreSQL必须重放自从最后一个检查点的所有的更改。如果两个检查点之间的距离非常大,您可能会注意到,您的故障数据库实例需要很长的时间才能再次启动。为了可用性,这种情况应该避免。

[在崩溃之后,总会有性能与恢复时间之间的权衡;您必须平衡您相应的配置。]

checkpoint_timeout 也非常重要。它是两个检查点之间所允许的时间上线。不更改时间而无限制地增加checkpoint_segments是没有意义的。在大型系统中,对许多人来说,增加checkpoint_timeout已被证明是有意义的。

[在PostgreSQL中,您会发现,有一个事务日志的常数。不同于在其它数据库系统中,XLOG文件的数目和事务的最大尺寸没有关系;一个事务的大小可以很容易地超过两个检查点之间的距离。]

写或不写?

我们在本章已经知道,在COMMIT时,我们不能确定数据是否已经在数据文件。

因此,如果数据文件不必是一致的,为什么不改变数据写入的时间点?这正是我们使用checkpoint_completion_target可以做到的。这个思想是有一个指定检查点完成的目标,作为两个检查点之间的总时间的一部分。

现在让 我们讨论三个场景来说明checkpoint_completion_target的目的:

场景1-存储股市数据

在这个场景中,我们将存储道琼斯工业(DJIA)所有股票的最近行情。我们不想存储所有股票价格的历史,而是最近的,当前的价格。

考虑到我们正在处理的数据的类型,我们可以假设我们有一个由UPDATE语句决定的工作负载。

会发生什么?PostgreSQL必须一遍又一遍地更新相同的数据。鉴于一个事实,DJIA由30个不同的股票组成,数据量是非常有限的,并且我们的表也非常小。除此之外,价格可能每秒更新一次,或者更频繁。

在内部,情况是这样的:当第一个UPDATE到来时,PostgreSQL将获得一个块,放入内存并修改它。每一个后续的UPDATE将最有可能改变相同的块。从逻辑上讲,所有的写操作必须写到事务日志,但是在共享缓冲区中的缓存块发生了什么?一般的规则是:如果有许多UPDATE(分别对相同的块做更改),尽可能地把块保存在内存中是明智的;这将通过一个写多个变化更改来极大地增加避免I/O的可能性。

[如果你要增加在一个磁盘I/O有许多更改的肯能性,考虑降低checkpoint_complection_target。块将在内存中停留更长的时间,因此在写发生之前,很多变化可能进入相同的块。.]

该方案只是介绍,checkpoint_completion_target 为 0.05(或者5%)可能是合理的。

场景2-批量装载

在我们的第二个场景中,我们将加载1TB的数据到一个空表。如果你正在一次加载这么多的数据,再次命中你十分钟之前命中的数据块的可能性是多少?这个可能性基本上是0,在这种情况下,缓冲区没有一点写入,因为我们会很容易通过空闲以及等待I/O的发生而错过磁盘的容量。

在批量加载期间,我们要使用我们一直都有的所有的I/O能力。为了确保PostgreSQL立即把数据写出来,我们必须把checkpoint_completion_target的值增加到接近1。

场景3-I/O峰值和吞吐量方面的考虑

尖锐的剑锋可以杀死你,至少它们可以造成应该避免的严重的伤害。在你周围的真实世界中真实的东西在数据库世界中也是真实。

在这个场景中,我们要假设一个应用程序存储一个电话公司所谓的呼叫详细记录(CDRs)。你可以想象,很多写将会发生,并且人们一整天都在打电话。当然,会有人们在打电话时,立即有另外一个电话跟在后面,但我们也将见证好多人在一周之内只打一次电话。

从技术上将,这意味着有一个好机会,在共享内存中的块,它最近已经被更改了,将面临第二次或者第三次的更改,但是,我们也将对那些不再被访问的块做出巨大的更改。

这种情况我们该如何处理呢?晚点写出数据,以便尽可能多的更改将在之前已经修改过的页面上进行更改。但是,在检查点期间会发生什么呢?如果更改(在这种情况下,脏页)囤积了太长时间,检查点本身将会很激烈,很多块必须在很短的时间内被写入。这会导致所谓的I/O剑锋。在一个I/O剑锋,你会看到你的系统是繁忙的。这可能显示缺少响应时间,缺少响应时间可以被你的终端用户感受到。

这给问题增加了一个维度:可预测的响应时间。

让我们这样说吧:让我们假设你已经成功地使用了一段时间的网上银行。你很高兴。现在,一些人在你的网上银行找到了一个调整方法,这使得网上银行背后的数据库快了50%,但是,这增加了一个缺点:每天有两个小时,该系统不可达。显然,从性能的角度来说,吞吐量会比较好:

24 hours * 1 X < 22 hours * 1.5 X

但是,你的客户会开心吗?很显然,你不会。这是一个典型的用户案例,优化最大吞吐量并没有好处。如果你可以满足你性能需求,有均匀的响应时间而有一点小小的性能损失作为代价可能是明智的。在我们的银行的例子中,这将意味着你的系统是24×7运行而不是每天只运行22小时。

[如果你的互联网带宽比以前快10倍,你会频繁地支付你负担吗?显然,你不会。有时,它不是关于每秒多少事务的优化,而是你以最合理的方式处理一个预先定义的负载量的优化方法。]

同样的概念也适用于我们的电话应用程序。我们在检查点期间写所有的更改,因为这可能导致检查点期间的延迟问题。这对立即更改数据文件也没有好处(意思是:高的checkpoint_completion_target),因为我们会写得太多,太频繁。

这是一个你必须妥协的典型的例子,checkpoint_completion_target为0.5 可能在这种情况下是最好的注意。

结论

从三个例子中得出的结论是,没有适合所有用途的配置。为了得出一个好的可行的配置,你真的需要考虑一下你在处理的数据类型。对于许多应用,0.5的值已经证明刚刚好。

2.4.3 调整WAL缓冲区

在本章中,我们已经调整了一些重要的参数,例如,shared_buffers, fsync,等等。还有一个参数,但是,这可能会对性能产生重大的影响。参数 wal_buffers 被设计用来告诉PostgreSQL,用多少内存来记录目前还没有被写入磁盘的XLOG。所以,如果有人在注入大事务时,在COMMIT之前,PostgreSQL将不会把任何变化较小的表写到XLOG。请记住,在崩溃期间,如果一个未提交的事务丢失了,我们不需要在意它,因为COMMIT是在日常生活中唯一重要的事情。在COMMIT发生之前,这对使用较大的块写XLOG很有意义。这正是wal_buffers做的:除非在postgresql.conf中手动更改,它是一个自动调整的参数(用-1表示),在XLOG写回磁盘之前,它使得PostgreSQL花费3%的shared_buffers,但不超过16MB来保持XLOG。

[在老版本的PostgreSQL中,这个参数是64KB。对现代的机器来说 这么低的值是不合理的。如果你在运行一个老版本的PostgreSQL,可以考虑把wal_buffers增加到16MB。对合理大小的数据库实例来说,这通常是一个合理的值。]

PostgreSQL Replication之第二章 理解PostgreSQL的事务日志(4)的更多相关文章

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

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

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

    2.5 XLOG的内部结构 我们将使用事务贯穿本书,并让您在技术层面上更深地洞察事情是如果工作的,我们已经增加了这部分专门处理XLOG的内部工作机制.我们会尽量避免前往下降到C级,因为这将超出本书的范 ...

  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. 安装MYSQL错误“conflicts with file from package mysql-libs-*” 解决方法

    安装MYSQL的时候时: 错误现象: [root@localhost opt]# rpm -ivh MySQL-server-5.5.32-1.el6.x86_64.rpm Preparing... ...

  2. 云server之间实时文件同步和文件备份的最简单高效的免费方案

     分布于不同云计算中心的多台云server,通常须要进行文件同步.以满足业务的须要. 传统的文件同步方案,部署繁琐.同步实时性差.无法令人惬意. 端端Clouduolc,一款纯p2p方式的文件实时 ...

  3. win10+ubuntu双系统卸载ubuntu

    进入win10下载EasyUEFI,删除ubuntu的引导项.重启如果直接进入了win10,表示卸载成功了.然后可以格式化ubuntu的分区.

  4. bzoj4554: [Tjoi2016&Heoi2016]游戏(二分图匹配)

    4554: [Tjoi2016&Heoi2016]游戏 题目:传送门 题解: 一道很牛逼的匈牙利..和之前模拟赛的一道题有点相似(不过这题不用完美匹配) 我们可以把连续的行和列全部编号(如果之 ...

  5. JS冒泡事件 与 事件捕获

    JS冒泡事件 与 事件捕获 案例 <!DOCTYPE html> <html> <head> <title>冒泡事件</title> < ...

  6. iOS定义静态变量、静态常量、全局变量

    静态变量 当我们希望一个变量的作用域不仅仅是作用域某个类的某个对象,而是作用域整个类的时候,这时候就可以使用静态变量. staticstatic修饰的变量,是一个私有的全局变量.C或者Java中sta ...

  7. Python入门机器学习

    如何通过Python入门机器学习 我们都知道机器学习是一门综合性极强的研究课题,对数学知识要求很高.因此,对于非学术研究专业的程序员,如果希望能入门机器学习,最好的方向还是从实践触发. 我了解到Pyt ...

  8. Laravel-HTTP-验证

    Laravel-HTTP-验证 标签(空格分隔): php 第一种方式 **1 直接在controller里完成表单验证** **2 打印验证返回的错误信息 dd($errors)** 第二种方式 * ...

  9. direct2d: antialiasing and drawing a line with a 1 pixel stroke

    http://xboxforums.create.msdn.com/forums/t/61448.aspx I'm currently porting a number of custom MFC C ...

  10. STM8S103-STVD建立汇编代码项目

    转载:http://blog.csdn.net/u010093140/article/details/49983397 STVD本来就比较少人用,STVD汇编就更少人用了,不过STM8汇编我自己还是满 ...