PostgreSQL 9.0性能调校

978-7-115-30770-5
作者: 【美】Gregory Smith
译者: 吴骅周娟王学昌
编辑: 陈冀康

图书目录:

详情

本书是针对PostgreSQL 9.0的性能调校指南。全书共分为16章,分别介绍了PostgreSQL的各个版本、数据库硬件环境和基准评测、磁盘设置、数据库高速缓存、服务器配置、日常维护、数据库索引、查询优化、数据库活动和统计信息、监控与趋势预测、池化与高速缓存、扩展复制、数据分区等性能调校的方方面面,最后总结概括了应该避免的一些常见问题。

图书摘要

版权信息

书名:PostgreSQL 9.0性能调校

ISBN:978-7-115-30770-5

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。

• 著    [美] Gregory Smith

  译    吴 骅 周 娟 王学昌

  责任编辑 陈冀康

• 人民邮电出版社出版发行  北京市丰台区成寿寺路11号

  邮编 100164  电子邮件 315@ptpress.com.cn

  网址 http://www.ptpress.com.cn

• 读者服务热线:(010)81055410

  反盗版热线:(010)81055315


Copyright ©2010 Packt Publishing. First published in the English language under the title PostgreSQL9.0 High Performance.

AllRights Reserved.

本书由美国Packt Publishing公司授权人民邮电出版社出版。未经出版者书面许可,对本书的任何部分不得以任何方式或任何手段复制和传播。

版权所有,侵权必究。


PostgreSQL是一款功能强大而复杂的自由软件数据库系统,已经逐渐发展为一个为应用数据提供存储服务的日益成熟的数据库平台,并且获得越来越多的关注。

本书是针对PostgreSQL 9.0的性能调校指南,能够帮助读者加速PostgreSQL系统,并且避免一些可能导致系统缓慢的常见缺陷。全书共分为16章,分别介绍了PostgreSQL的各个版本、数据库硬件环境和基准评测、磁盘设置、数据库高速缓存、服务器配置、日常维护、数据库索引、查询优化、数据库活动和统计信息、监控与趋势预测、池化与高速缓存、扩展复制、数据分区等性能调校的方方面面,最后总结概括了应该避免的一些常见问题。

本书是涵盖了PostgreSQL 9.0性能调校和提升的各个话题,内容详尽,示例丰富,实用性强。本书适合PostgreSQL的高级数据库管理员、需要安装和使用PostgreSQL的技术人员以及对高级数据库内部构建和运作感兴趣的开发人员阅读。


从传统的企业数据库到最新的Web应用程序,PostgreSQL逐渐成为一个为应用数据提供存储服务的日益成熟的数据库平台。但要充分发挥PostgreSQL的性能却没那么容易。用户需要从一些经验法则入手,使用全方位的监控和维护来保障系统的正常运行,为故障排除提供相应的建议,为附加工具提供信息以便向那些无法尝试自行处理的核心数据库添加功能。

第1章“PostgreSQL版本”,介绍了PostgreSQL最近几个版本的性能提升情况,并通过新版本与稍早的版本之间的漏洞和执行速度的对比说明新版本的实用性。

第2章“数据库硬件”,讨论了服务器硬件环境当中的一些主要部件,包括处理器、内存和硬盘等,需要仔细选择可靠的数据库存储并平衡预算。尤其是当不小心使用了易失性回写缓存的磁盘控制器和驱动的时候,这将容易导致数据库的损坏。

第3章“数据库硬件基准评测”,主要讨论不同数据库硬件性能方面的量化标准,即在系统当中,内存和裸设备的速度究竟有多快?性能是否随着驱动器数量的增多成比例变化?

第4章“磁盘设置”,主要研究现行主流的文件系统选择方案,并对权衡硬盘中数据库布局的多种方式提出建议。此外,还讨论了一些常见的、有效的文件系统的调整问题。

第5章“数据库高速缓存内存”,研究数据库是如何存储在磁盘、内存当中,以及检查点进程如何保证双方的一致性。另外,还讨论了如何去具体查看数据库缓存的数据,以确认内存中所存储的数据与事先所期望的内容是否一致。

第6章“服务器配置调整”,介绍了postgresql.conf配置文件当中的一些重要设置选项,这些选项的含义以及如何去设置这些选项等内容。同时,还指出了一些会引起故障的设置。

第7章“日常维护”。本章首先解释PostgreSQL如何确定什么样的客户端能够显示什么样的数据信息。可见性信息存储的方法需要一个名为VACUUM的清理进程来妥善处理的重新利用剩余的空间的问题。此外,一些常见问题及针对的一般常见调整措施,以及始终运行auto vacuum的方法在本章中也有介绍。最后,本章介绍了数据库日志中数据量的调整方法,以及对结果进行查询日志分析来找出造成查询瓶颈的症结所在。

第8章“数据库基准评测”,研究如何从PostgreSQL所包含的pgbench测试程序中获得有用的基准测试结果。

第9章“数据库索引”,介绍在响应一个查询时,索引是如何能够减少读取数据块数量。这种方法可以用于彻底研究一些常见问题,诸如一个查询为什么会使用顺序扫描而不是使用一个功能强大的索引。

第10章“查询优化”,本章作为PostgreSQL优化器的指南,展示了根据用户需求以及数据库参数设置的不同,样例查询所采取的不同的执行方式。

第11章“数据库活动和统计信息”,介绍数据库内的统计信息,以及这些信息中,哪些有助于查找问题。此外,还讨论了查看索引活动和锁定行为的方法。

第12章“监控与趋势预测”,本章一开始就介绍如何使用基本的操作系统监控工具来确定数据库正在进行什么操作。接下来,给出可按照时间对信息进行图形化表示的趋势预测软件的相关建议。

第13章“池化与高速缓存”,说明了在同一时间内对数据库进行大规模连接的时候所遇到的问题与困难。提出两种类型的软件包的解决方案来解决这些问题:对请求进行更好的排序连接池以及可以回应用户请求而无需连接数据库的缓存。

第14章“扩展复制”,介绍解决跨越多个节点进行数据复制引起系统高负载的方法,典型的方法是一组只读的节点与单一的可写主节点进行同步。

第15章“数据分区”,探讨数据如何分区成有效的子集,这样查询就可以只对数据库的一小部分进行检索。讨论的方法包括标准单一节点数据库表分区以及使用与它相关的工具集PL/Proxy在多个节点之间建立分片数据库。

第16章“应该避免的一些常见问题”,主要讨论那些通常看起来会困扰那些数据库新手的PostgreSQL问题,例如,批量装载、对记录计数、外键处理等。本章最后回顾了从PostgreSQL 8.1版到9.0版的那些与性能相关的功能变化。有时候,避免一些常见的问题的最好方法是升级到新的版本,因为它可能再也不会出现那些问题。

要很好地利用本书,读者必须至少能够访问到一台允许在服务器执行查询的PostgreSQL客户端。如果是服务器管理员则更为理想。在http://www.postgresql.org/download/上提供了当前主流操作系统下的PostgreSQL完整客户端和服务器程序包的下载。

本书的所有例子都是在命令行下执行,通常运行于psql程序当中,这样可以使它们用于大多数的平台。它可以简单地执行很多操作,而不需要使用像pgAdminIII这样的面向PostgreSQL的GUI工具。

一些脚本是用bash脚本语言编写的。如果你使用的是Windows环境,可以在http://www.cygwin.com/cygwin获取套件,该套件提供在Windows环境下的类似bash的UNIX工具。

本书旨在帮助那些使用或计划使用PostgreSQL的中高级数据库管理员。其中部分内容对那些寻求构建或监控PostgreSQL安装的系统管理员以及对影响程序的高级数据库内部构造感兴趣的开发者也很有用。

在本书中,将会发现一些用来区分不同的信息所使用不同样式的字体。以下是这些样式的例子,并附有说明。

在文本中的代码单词表示如下:“如果正在对数据进行排序,那么work_mem参数将会决定何时允许这些排序在内存当中执行”。

下面的代码块的样式设置如下。

当需要引起对特殊代码段的注意时,我们将相关的行或条目设置为粗体显示,如下所示。

命令行内的输入或者输出加粗显示,如下所示。

我们一直欢迎读者的回馈。它可以让我们了解到用户对于这本书的看法,如喜欢什么而不喜欢什么。用户反馈有助于我们改进本书的的内容,而这将会获得更大的收获。

可以通过发送E-mail至feedback@packtpub.com提交反馈信息,请务必在邮件主题当中提及本书的书名信息。

如果你有需要或者想出版的图书,请在网站www.packtpub.com中的推荐信息表单(SUGGEST A TITLE)当中填写信息,或发送E-mail给我们。

如果你在某一领域内有专长,并且有兴趣将其写成书或参与书的编写,请查阅网站www.packtpub.com/authors的作者指南信息。

现在,你已经是Packt图书的用户,我们有许多的方式可以满足你的需求。

下载本书例子的代码

用户可以在Packt网站http://www.PacktPub.com下载以用户本人账号所购买的书籍中实例的代码。如果是在别处购买了本书,可以访问http://www.PacktPub.com/support并填写相关信息,将有电子邮件指引用户进行注册。

尽管我们非常仔细地确保内容的准确性,但错误是在所难免的。如果你发现我们书本中的错误(文本错误或者代码错误)并将错误反馈给我们,我们将非常感激。这样,你可以防止其他人也阅读到这个错误,并帮助我们在本书的后续版本中改进。如果你发现了任何的勘误内容,请访问http://www.packtpub.com/support,选择书本,点击链接errata submission form,输入具体的勘误内容。一旦你的勘误内容得到确认,你提交的内容将会上传至我们的网页或者增加到现有的勘误表中(列在勘误表一节的末尾)。在http://www.packtpub.com/support中可以通过选择主题查看现有的勘误表信息。

在Internet上各种媒体的版权材料盗版已经是层出不穷。而在Packt公司我们会严肃地对待版权和授权的保护,如果你在Internet上获取到我们著作的任何形式的非法拷贝,请立即向我们提供地址或网站名称,这样我们才能采取一些补救措施。

请通过copyright@packtpub.com与我们联系有关涉嫌盗版材料的链接。

我们真心感谢你对保护作者所提供的帮助,我们将有能力为你提供更有价值的内容。

你可以通过questions@packtpub.com与我们联系,如果你有任何关于本书的疑问,我们将竭尽全力处理你的问题。


PostgreSQL是“对象/关系”型数据库管理系统,它具有开放源码、支持多平台、免费使用等特点。它最初由美国加州大学伯克利分校计算机科学系开发和维护。因为来自于学术机构,它具有许多非常先进的、开创性的特性,这些特性现在已经被许多商业数据库系统所采用(如Informix)。目前PostgreSQL由一批自由软件爱好者维护,它的功能还在不断增强。

有关PostgreSQL的最新中文书仍关注于7.0的版本。在这10余年间,PostgreSQL版本经过了一个质的跨越,提供了诸多令人振奋的功能。所有涉及到的内容在本书当中都会有涉及。全书共分成16章内容。从相关的PostgreSQL版本到数据库基准评测,再到一些常见问题分析以及版本之间的更新内容对比等,这些内容都极具有参考价值。

本书针对正在使用或计划使用PostgreSQL的中高级数据库管理员。部分内容也会引起系统管理员的关注,包括建立或监控PostgreSQL安装等,对于开发人员,关心的则是影响应用程序设计的高级数据库内部组织。

本书的翻译由吴骅组织完成,参与本书翻译的还有王学昌、韩潼瑜、周娟、刘红军、王玲、郑正正、冯伟强、陶日然、李泽榆等人。全书由吴骅负责统一定稿。虽然译者多年从事DB2数据库的管理工作,但是本书对于译者来说也是一个全新的挑战,它介绍了大量的技术和特性,因此其中一些术语尚无固定的名称。由于水平有限,译文中的不当之处在所难免,恳请同行及各位读者朋友不吝赐教,联系方式wuhua@gxun.cn。

译者

2012年9月于相思湖畔


Gregory Smith是国际数据库专业服务公司2ndQuadrant的首席顾问,并且是公司在美国的第一个办事处的创始人。

编著PostgreSQL是他进军数据库性能调整教学领域的第二个扩展。在1995年,Greg(格里格)写了一本较小的免费电子书《Progress Performance FAQ》,主要内容是如何使Progress 4GL和相关数据库能够运行更快。2001年,他专注于PostgreSQL 7.0,一直关注复杂性问题,该数据库的发行版都能够解决这些问题。

从PostgreSQL 8.3开始,他对每个PostgreSQL版本都做出了贡献,添加附加的功能。他还为数据库编写了一些额外的工具集,目前包括有pgtune、pgbench-tools、peg和2warm等。

“我能够很好地专注于本书内容,完全是因为Simon Riggs和2ndQuadrant全球其他员工的支持。在过去一年中,发现并解决一些令人关注的问题,以及提供解决这些问题的资源,是2ndQuadrant员工为客户提供PostgreSQL性能改进服务的理念。

按照写作计划,在交付时要包含对一个新的主要数据库版本的支持,这是一件相当繁重的事情。没有家人(Judy、Jerry和Amanda)的支持,我不可能有为了这本书连续这么多个星期每星期都工作7天的时间。

最后,感谢PostgreSQL项目的众多参与者为这本书提供了很多的资料。在过去几年中,没有pgsql-performance和pgsql-hacker等邮件列表的共享精神,我也无法收集这样广泛的性能问题。无论是对自己问题的回答,还是仔细考虑回答别人的问题,这些邮件列表上的互动已经成为本书理念的关键。”


众所周知,PostgreSQL具有丰富的功能集和非常稳定的软件版本。其默认的安全配置既被安全人员称赞又因其复杂的学习过程而被诟病。SQL规范的一致性和数据完整性只允许通过严格的方式与数据库进行交互,这会使那些时常使用相对宽松的桌面数据库软件的用户感觉到非常不适应。但是所有的一切都有其自身一定的道理。

运行速度慢是另外一个让PostgreSQL出名的原因。时至今日,仍然有一些事实能证明这一点。往往有很多使用“正确的方法”数据库操作会比用其他的方法的操作需要更长的时间。例如,对于“2009年2月29日”这样一个日期而言,由于2009年不是闰年,因此这一天并没有任何意义。在实际生活中,不可能有这一天,而且也不会在这一天发生任何事。如果要让数据库向标准的日期字段中写入这个值,那确实可以,也很快速。或者,数据库可以检测这个日期是否能够有效存入目标字段,注意到在常规的日历里,没有这样的日期,它可以拒绝用户的修改。这样数据库执行的速度就稍微慢一些。PostgreSQL由一些不想抄近路做事的人设计,并且是为了这些人而设计,他们希望能够把事情做得更快和更简单。在用户只能通过一种方法来正确处理某个事物的情况下,那可能是惟一可用的方法。

然而,一旦进行了合理的实施之后,还可以回过头对它进行优化。在过去的几年中,这已经成为PostgreSQL的模式。PostgreSQL经常通过解决这些小问题来大幅提高数据库性能。其中一部分很好的设计远胜过更简单的方法,这当中由于复杂性的引入甚至付出了相当的开销。这是一种相当新的现象,一定程度上解释了为什么PostgreSQL相比其他竞争对手而言,是个速度较慢的数据库。

2005年11月,PostgreSQL发布了其8.1版本。该版本中包含了众多内部结构的改进,其中一些期望能够提高多个活动客户端在多处理器系统下的数据库性能。其结果是在处理沉重工作负荷时,数据库能力得到成比例的提高。在如今的硬件设备上进行的基准评测,突出地显示了其对先前版本的跨越。可以在http://suckit.blog.hu/2009/09/29/postgresql_history看到György Vilmos 对8.0版至8.4版的性能横向比较。它准确地显示了性能显著提升的程度。这些测试使用由http://sysbench. sourceforge.net/网站提供的sysBench基准评测软件的联机事务处理(OLTP)测试工具。

这个测试给出了每秒处理事务数(TPS, Transactions Per Second)系统整体速度的数据值,可以在只读模式下或包含写入的模式下运行。在只读模式下,从8.0版本升级到8.1版本的性能提升4倍,而8.3版本的性能提升则再提高2倍左右。如表1-1所示。

表1-1

版 本

只读模式下TPS峰值

峰值状况下客户端数量

8.0.21

1256

4

8.1.17

5620

14

8.2.13

8109

18

8.3.7

13984

22

8.4.1

13546

22

在负载峰值情况下客户端数量的上升给出了数据库内部处理访问共享资源程度大小的一种思路。特别是8.1系列版本当中包含了一些重大的升级。而在写入模式下的性能改进与此类似,8.0版本到8.3版本之间性能几乎达到了8倍的增益,见表1-2。

表1-2

版 本

只读模式下TPS峰值

峰值状况下客户端数量

8.0.21

361

2

8.1.17

873

10

8.2.13

1358

14

8.3.7

2795

18

8.4.1

2713

12

在这些测试当中可以看出8.3版本到8.4版本性能有略微的降低,这是由于对数据库进行了细微的重新调整,以改善其在最糟糕情况下的性能。8.4版本中采集了更多的统计数据用于提高复杂索引的性能,并在测试中牺牲了部分不太重要排序的速度。第10章将会讲述更多关于这方面的详细内容。

尽管结果不会涵盖如此广泛的版本,但其他的测试结果也证实了性能的提升。可以很容易地看出,在2005年年底之前8.1版本交付的时候,之前所达成的关于PostgreSQL性能的结论是完全过时的。2008年8.3版本发布的时候,速度提升可以算是一个很大的飞跃。因此,8.3之前的版本并不能代表目前的性能,同时首选使用这个版本或者后续版本还有很多其他的原因。

1.1.1 选择部署的版本

如果用户有较老版本的PostgreSQL系统,并想让它运行得更快一些,因为新版本的这些令人瞩目的特性,首要的事情不是考虑如何调整设置,而是应该考虑升级到最新版本的可能性。如果用户正在实施一个新的项目,用户可以考虑最新的8.3版本。除了性能提升外,该版本还有一些影响到应用程序编码变化,用户可以更容易开始项目的实施,避免后期的改进。

第16章包含一个参考指南,其内容为从8.1版本至9.0版本当中每个主要的PostgreSQL版本所加入的与性能相关功能的介绍。用户可能会发现只有在最新版本里的功能能够引起他们的注意,因此强烈建议用户使用最新的版本。在本书中将会突出这些特定版本的变化。

1.1.2 升级到更新的主要版本

目前为止,从现有的PostgreSQL版本升级(例如从8.1.X版本升级到8.2.X版本)到最新的主要版本的惟一方法是dump转储和重载。使用新版本中的pg_dump和/或pg_dumpall程序将整个数据库的内容写入一个文件。采用这样的方法,如果有任何变更需要进行更新,那新的转储程序可以尝试处理它们。并不是所有的升级变更都会自动进行。随后,根据用户要转储的格式,可以运行它所生成的脚本或者是使用pg_restore程序来处理这个任务。pg_restore是在新版本的PostgreSQL中的一个较好的替代方案,具有并行存储的功能。

如果用户正在使用的操作系统并不允许用户在同一时间内运行多个PostgreSQL版本,例如现行的RedHat Linux的RPM包,在同一时间内同时安装一个老的PostgreSQL版本和一个新的PostgreSQL版本是很困难的。在PostgreSQL 9.0中,对这种情况所做的一些改进也在开发当中。因此在进行升级规划时,要将确认运行多个版本的可行性作为其中的一个部分。

转储数据需要一定的时间,恢复数据要花的时间更久。在这种情况下,数据库可能要暂停服务,这样才能保证没有其他的任何更改被写入到转储文件中。对于大型的数据库,停机的时间可能会很长而且是让人无法接受的。

在一些要求较高的环境中,数据库要求宕机时间为0,以达到7×24小时运行。在这种情况下,转储和重载是不适用的。直到最近,针对这种环境使用所进行的PostgreSQL升级,惟一有效的方法是Slony的复制。Slony是最受欢迎的解决方案,第14章有其更详细的介绍。Slony当中的一个功能就是用户可以不在所要进行复制的所有节点都运行相同版本的PostgreSQL。用户可以提取一个新的节点来运行新版本的PostgreSQL,等待复制完毕后,一旦与源相匹配,那么将其进行切换。

现在,有一种新方法可以不需要任何的复制软件,该程序起初称为pg_migrator(见http://pgfoundry.org/projects/pg-migrator/),可以不需要转储和重载操作来完成从8.3版本到8.4版本的升级。这个过程称为就地升级(in-place upgrading)。用户需要进行仔细的测试,在PostgreSQL的功能中既有已知的限制也有一些未知的不太受欢迎的相关特性。要确保仔细阅读升级工具的文档。从PostgreSQL 9.0开始,这个模块包含在核心数据库中,并且名称更改为pg_upgrade。由于所有就地升级都会有些风险并需要进行仔细的测试,因此在很多情况下,pg_upgrade可以带用户从8.3版本或8.4版本升级到9.0或更高的版本。

PostgreSQL开发社区目前决定将就地升级功能应用于未来的版本中。现在,TB以及更大数据量规模的PostgreSQL的安装已经很普遍,因此升级时只使用转储和重载是不实际的。

1.从更早的版本升级到PostgreSQL 8.3+

8.3版本的主要内部变化是从更早版本进行升级当中不需要转储整个数据库并进行重载到更新的版本。这让8.3版本成为其发展史上的重要里程碑。与8.2版本相比较,不仅仅速度上快很多,一旦用户使用了8.3版本,从此就可以使用就地升级功能了。

从早期版本升级到PostgreSQL8.3或后续版本是比较困难的。部分较老的应用程序依赖于非字符型数据类型,被透明转换成TEXT类型,因为多种原因,这个特性在8.3版本中被删除,更多信息请浏览http://www.postgresql.org/docs/8.3/static/release-8-3.html

虽然升级数据库版本总是有可能会引入新的问题,尤其是对早期版本编写的应用程序升级到8.3版本或更高版本时。这也许可通过手动添加回被删除的自动类型转换功能来有解决这个问题。在http://petereisentraut.blogspot.com/2008/03/readding-implicit-casts-in-postgresql.html有一个具体的实例。然而在应用程序中固化这个特性的替代方法是使用更强大和可持续的方法。较老的特性因为其会导致莫名其妙的应用程序问题而被取消。如果用户将其添加回来,就需要对每一个新的PostgreSQL版本做其他额外的添加步骤。关于这个主题和执行主要版本的PostgreSQL升级会遇到的问题,可以浏览http://blog.endpoint.com/2010/01/postgres-upgrades-ten-problems-and.html以获取更多信息。

2.次要版本的升级

从8.4.1版本升级到8.4.2版本之类次要版本升级不需要使用转储/重载或使用类似pg_ upgrade的工具。只需要停止服务器,安装新版本,然后对现有的服务器数据文件运行新的数据库二进制更新。部分用户不愿意进行此类升级,以免数据库内的改动会让正在运行的程序产生问题。在PostgreSQL中不会产生这种情况。PostgreSQL项目的规则在http://www.post gresql.org/support/versioning描述得很清楚。

虽然升级多少都会有些风险,PostgreSQL次要版本仅修复经常碰到的安全性和数据损坏错误,以减少升级的风险。PostgreSQL社区认为不升级比升级的风险高。

在PostgreSQL次要版本升级当中,永远不会找到会破坏应用程序的任何一种不可预期的修改。漏洞、安全和损坏性修复总会以一种最小化引入外部可视的行为变化几率的方式被执行。如果是无法避免的话,那么将会在发行说明当中详细地去解释其中的原因以及建议的解决方案。在其中将会发现一些细微的问题,这是由于某些已解决的缺陷所带来的,这甚至会在一个次要版本的更新之后得到彻底解决。从PostgreSQL邮件列表当中不难发现某个问题的报告已经在兼容该版本的一些最新的次要版本更新当中被解决,因此升级到该版本是使所有这些问题消失的主要需求。

1.2 使用PostgreSQL还是其他数据库

当然也有其他的数据库解决方案会执行得好一些。例如,PostgreSQL缺失了一些在TPC-H测试套件当中较为复杂的查询能够得到较好执行的功能(具体内容详见第8章)。因此,与一部分商业数据库相比较而言它不适用于运行在较大规模的数据仓库应用程序当中。如果用户需要进行类似TPC-H包含的高负载查询时,就可能会发现诸如Oracle、DB2、SQL Server等数据库仍然有值得付出的性能上的优势。目前也有一些由PostgreSQL衍生出来的版本,包含了能够适用于数据仓库和类似的大型系统的功能。例如,Greenplum、Aster Data和Netezza。

对于某些类型的Web应用程序而言,用户只能通过PostgreSQL所不允许的对数据完整性的功能进行剪裁的方法以获得一些可接受的性能表现。这些程序可能在类似MySQL这样的并不严格的数据库或者严格度最小的SQLite中表现得很好。与相对成熟的数据仓库市场所不同的是,这种类型的应用程序设计还是经常使用的。在本书编写之时,有关基于键值(key-value-based)的NoSQL环境(包括CouchDB、MongoDB和Cassandra)越来越受欢迎。如果对处理此类键/值存储相关的高级查询的运行时间不怎么敏感时,那么这些方法可以很容易地超越那些传统的数据库。

但对于很多在这两个极端之间的那些“正常的”数据库用例来说,PostgreSQL的性能在8.3版本当中达到了这样的一种程度:其情况很可能是在数据库成为限制因素之前需要面对的硬件或应用程序设计的限制。此外,某些PostgreSQL的传统优势,如处理复杂查询以及其深度的可编程性,这些都将继续存在。

1.3 PostgreSQL工具

如果用户习惯于数据库厂商提供的那些针对数据库本身的完整工具集,这些工具集所涵盖的范围从服务器管理到应用程序开发,那么PostgreSQL可能无法满足这部分用户的需求。与很多成功的开源项目一样,PostgreSQL视图持续专注于一些它所擅长的功能。这也就是开发社区所指的PostgreSQL核心:主要的数据库服务器,相关的工具可以作为数据库本身的一个部分进行开发。当有新的功能提出时,如果它们可能被建立和发布在“核心外”,这是首选的方式。这种方式尽可能地保持数据库核心是持续性的,也就是允许这些外部的项目发布为自己的更新,而不需要与主要的数据库发布计划进行同步。

成熟的PostgreSQL部署应该能够识别众多的各自具有其特定目的附加工具,这些都需要整合到数据库核心服务器中以形成一个完整的系统。

1.3.1 PostgreSQL contrib

用户也许没必要安装PostgreSQL核心的contrib模块部分(其命名是根据它们所存储的目录名称)。这些可选的工具与标准工具包一同发布,但在用户的系统上默认可以不进行安装。contrib代码作为PostgreSQL核心的一部分进行维护与发布,但不要求服务器进行操作。

从代码质量的角度上看,contrib模块在其测试时并没有遵守那么高的标准。主服务器包含对每个功能的深度回归分析测试,这会涉及在数量庞大的系统中去搜寻错误。可选的contrib模块并没有得到在相同级别上的测试覆盖。然而,代码本身是由同一个开发团队进行维护,其中的一些模块极其受欢迎,并且经过用户的良好测试。

查看所有可用的contrib模块的列表,请浏览http://www.postgresql.org/docs/current/static/ contrib.html

1.发现系统中的contrib模块

检查是否安装有contrib模块的方法是去查看pgbench程序是否可用。pgbench是少数那些安装了完整程序的contrib组件工具的其中之一,而不仅仅是用户可使用的脚本。在UNIX中,检查pgbench是否安装的例子如下所示。

在大多数Linux系统中,如果用的是RPM或者DEB包安装的PostgreSQL,可选的postgresql- contrib包中包含所有的contrib模块以及与它相关的安装脚本。如果尚未安装相关功能的话,就需要使用yum、apt-get或者类似的机制来添加安装包。在Solaris系统中,这个包的名称为SUNWpostgr-contrib

如果用户不能确定在其系统中PostgreSQL contrib模块安装的位置,那可以使用文件系统工具进行搜索。在许多类UNIX系统中,locate和find命令一样能够很好地达到目的。在Windows系统中,在开始菜单中可以找到文件搜索工具。例如,用户要搜索在下一章要谈到的内存分配的文件pg_ buffercache.sql,以下是在部分平台下,该文件所在的位置的说明。

2.从源码安装contrib模块

在一些平台下,当用户的服务器环境符合相应的先决条件,则可以使用源码安装PostgreSQL作为一种简单的练习。相关详细信息请参考:http://www.postgresql.org/docs/current/static/install-procedure.html

在构建主要服务器的代码后,用户还需要自行编译诸如pg_buffercache之类的contrib模块。以下是一个相关的实例,在该例当中假设用户的PostgreSQL目标路径为/usr/local/postgresql,并且目录source是用户放置源代码的目录(本实例不作为典型或者推荐用户使用的目录结构),如下所示。

在contrib目录中运行make/make install命令可以构建并安装所有的contrib模块。请注意其中的一些更广泛的源代码构建的需求。uuid-ossp模块就是一个更具挑战性的自行编译的模块实例。

3.使用contrib模块

虽然一些诸如pgbench的contrib程序可以直接执行,但那些安装在数据库中的工具大多数都是为了向其添加额外的功能。

例如,要将模块pg_buffercache安装到一个名为abc的数据库中,则要在命令行下使用如下命令。

用户可以使用图形化用户界面管理工具pgAdmin III替代命令行来完成工作。它是捆绑在Windows平台下的PostgreSQL工具,以替代命令行方法。具体使用方法如下。

使用以下的查询可以快速检测任意类型的系统中所安装的模块。

如果返回任意值,则表明该模块已安装。注意pg_buffercache只能由数据库超级用户安装和使用。

1.3.2 pgFoundry

PostgreSQL相关的项目的官方站点是pgFoundry:http://pgfoundry.org/

pgFoundry只是存放PostgreSQL软件的主机,除了文件分发之外还提供诸如邮件列表和错误追踪的功能。许多最流行的PostgreSQL附加程序都可以在那里找到。

尽管有时会由从事PostgreSQL核心的同一批人维护pgFoundry,但其代码质量时常会有显著变化。保持项目良好进行的一个方法是注意定期和最近的发布版本。

1.3.3 其他一些与PostgreSQL相关的软件

除了PostgreSQL核心自带的程序之外,诸如contrib模块以及pgFoundry提供的软件等,还有很多的程序能够让PostgreSQL更加易用和强大。在网络上都能找到这些资源。为需求本身选择正确的包实际上有很多选择。

本书中,很多很有用的程序都会被重点提出,用户可以尽早了解所提供的简短列表。这是构建大型开源项目的标准方法,用户可以得到一个基本的系统运行环境并随后在需要的时候去添加额外的的组件。

对那些安装任何软件都要经过审批和QA周期的企业文化来说,这样做是比较困难的。为了提高在这种环境下用户成功安装PostgreSQL的几率,在早期就引进这一概念是很重要的。在后期需要往较小的数据库核心中附加程序来添加组件,很明显在刚开始的时候不需要全部组件。

1.4 PostgreSQL应用程序扩展生命周期

虽然每一个应用程序都有其独特的发展方向,但是我们也会发现有必要作为使用PostgreSQL数据库的应用程序的一些共同技术变得更为频繁。本书中的章节分别关注这一过程的常见方面。运行数据库服务器的步骤一般如下。

(1)决定服务器运行的硬件条件。理想情况下,用户将测试能够满足预期条件的硬件。

(2)建立数据库磁盘的布局:RAID级别、文件系统以及硬盘上可能的表/索引的布局。

(3)优化服务器配置。

(4)监控服务器性能和查询执行的情况。

(5)提高查询执行的效率,或创建索引以帮助加速。

(6)由于很难仅通过调整服务器来达到承受更多工作负荷,取而代之的是通过引入连接池以及高速缓存来减少对这方面的担忧。

(7)将数据复制到多个服务器,同时分布读取这些数据。

(8)将较大的表分区为片段。最终,实际上一个比较大的表可能需要被分割,以便能够同时写入到多个服务器当中。

此过程不是按部就班的。用户反复多次对服务器参数进行优化。这可能会出现在决定购买较新的硬件的情况下,而不是开始那些需要重新设计应用程序复制或分区操作工作。部分设计可能会在从最开始的阶段整合缓存到设计当中。其中重要的是需要意识到有很多的选项可选,并且去采集足够的有关系统能够达到的性能极限,以决定哪些变化是有帮助的数据。

1.5 作为实践的性能优化

提高数据库性能与其他领域一样,有其专门的术语。下面是本书中要用到一些术语或短语。

在通常情况下,性能调优工作中比较令人关注的一个原则就是,用户无法指明应用程序在移除当前瓶颈之前会陷入哪一个瓶颈。假设某个系统运行的情况不能像用户预期的那样快,用户通常会去猜测当前的瓶颈在哪,或者下一个瓶颈又会是什么情况。这是很浪费时间的。用户最好能够进行性能测定,分析系统运行较慢的部分,用来确定原因以及指导相关的修改。

例如,用户已经知道应该提高的shared_buffers值,这个值用来调整缓冲数据库读和写时所使用的内存大小。这通常有些积极作用,但用户也有可能会遇到潜在的负面效果。需要指出哪一个应用程序会受到影响,这种变化是否会提高或降低性能,在服务器上运行的小设置能不能够进行预测。这是混沌理论的一种:在开始条件下即使是微小的变化,也将会引起非常不同的结果。例如,一个小小的度的变化,也会影响服务器数以百万计的决策。同样的,如果shared_buffers设置的值过小,会有部分参数不能像预期的那样良好运行,例如,在它们控制数据库检查点的情况下。

鉴于用户在绝大多数情况下无法预测将会发生的事,所以更倾向于用户进行深度的监控和变更控制。从应用程序到数据库服务器再到硬件,尽可能多地进行监控。这里引入一个有针对性的变化。尝试去量化具体的差异并且意识到某些用户所拒绝采用的修改不一定总是一直处于不积极状态之下。将瓶颈移到别的地方,用户就会发现在突然陷入下一个限制因素前,某些参数其实是无关紧要的。

在专注于PostgreSQL性能的邮件列表中,当用户没有做任何分析就推断其根本原因来证明他们的理论时,通常对此会有种通俗的表达:那就是“少说多做gprof”。虽然gprof可能不是每个性能问题要选择的工具,但是鉴于与其他一般的监控工具相比,它更多的是一种代码分析工具,用户在推断根本原因之前尽可能多的进行分析的做法是合理的。用户也需要进行推断来证实所期望的变化。

另一种在本书中反复和出现的原则就是:用户必须要把性能问题研究系统化。不能因为服务器是从名牌厂家购买的,就假设会运行得很快,基准评测是独立的组件。不要将数据库性能测试与应用程序级别的测试一同启动。首先运行那些可以与其他测试内容进行对比的综合的数据库性能测试。这样,当用户运行的应用程序不可避免地慢时,此时用户知道自身的硬件已经运行在预期的性能之内,并且数据库本身也良好运行。一旦用户的系统上线运行,需要做一些基本的不可能将系统拖垮的操作以查找出性能上的问题,例如,硬件速度的测试。

若用户部署的每台服务器都按照一些通用的方法进行测试的话,那么它会有更好的结构。接下来的章节将讲述测试相关内容。因为用户不是“唯器材是用”,这并不意味着用户可以跳过类似磁盘性能测试的这部分内容。用户在构建新的系统时应当经常进行此类工作——这是去获得最基本情况的惟一方法,而不管是否操作的这些行为在标准范围内抑或有些错误的操作。

1.6 小结

PostgreSQL在近5年中取得了长足的发展。在建立了坚实的数据库基础后,众多开发人员向其添加了很多附加功能,在最近发布的版本中,所添加的功能和性能改进得到了很大提高。最新的PostgreSQL 9.0版本所添加的功能,使得复制和读取扩展比之前的版本变得更容易,人们期望能进一步加速这种适用于数据库的应用程序类型。

 译者注:关于TCP-H基准评测一些相关信息的简介请参见http://www.db2cert.com/bencandy.php?fid=44&id=22/


本章旨在帮助用户在做计划购买并运行PostgreSQL服务器的时候能够更好地对开支做些优先级方面的考虑。如果用户已经有了正在运行的数据库服务器,可以跳过本章直接参考第3章以及第8章当中的部分内容。最后,用户可能会反复多次采用本章所讲述的一些技术。例如,用户要对服务器进行基准评测,其磁盘运行缓慢,那么本章的内容会给用户提出一些意见,如更换什么硬件能够提高它的性能表现。更换硬件后,重新进行测试。重复进行直到性能表现能与预期相同为止。

在生产环境中使用诸如PostgreSQL等开源数据库的一个原因是,用户本要花在软件授权上的每一分钱,都可以用在更好的硬件上。在用户的预算当中需要权衡的有三个主要部件:CPU、内存和包含相关磁盘控制器及重要部件的磁盘。

目前,在售的每个CPU内部都集成有至少两个、甚至多达八个核心,核心的数量能反映出大多数的数据库应用程序的一些优势。在决定使用哪一种CPU解决方案能够满足用户的数据库应用需求时,需要考虑两个基本的问题。

1.选哪一种处理器系列?

目前,Intel和AMD都推出了各种类型的64位产品线可供选择,当然也有一些其他市场占有率不太高的产品可供选择(Itanium、SPARC等)。

2.需要更多的核心还是更快的核心?

这些选择在某些时候会比用户所想象得要复杂。目前,Intel在处理器与系统的RAM之间的传输速度更快,因此在单个处理器核心的速度上处于领先地位,但处理器和相关的部件也更加昂贵。AMD作为其竞争对手,提供更廉价的处理器核心,它们的服务器处理器设计能够使每个核心最大程度地利用内存。如果用户要选择更廉价的核心,那么AMD在这方面更适合。当用户要将两个以上的物理CPU安装在同一台服务器中时,AMD在多插槽配置当中也有可用的最快的处理器的辉煌历史。

要指出用户的数据库应用类型更适合于哪种CPU方案(多核还是更快的核心),最好方法是使用类似top的工具监控目前现有服务器。如果每一个CPU所运行的进程数量不多,那么对于这种类型的工作负荷则使用速度更快的核心会更好。这种情况经常在以批处理的方式运行大量查询的情况下发生,例如,在大批量的数据需要进行排序形成报表时。但是相反地,如果所有的CPU都与并发进程处于活动状态,那么用户需要的可能是更多核心的CPU。这些情况在具有大量用户的应用程序中,例如,数据库支持的Web应用程序等很常见。

如果用户没有从对运行中的系统监控中得到好处,那么可以尝试通过记录数据库的局限性来推断用户处于的状况。PostgreSQL不允许将一个查询分配到多个核心,而在其他数据库中,称其为并行查询并予以支持。也就是说,用户要求在执行任意一个查询或较少数量的查询尽可能得快,那唯一的办法就是将其按照次序分配给最快的核心。

另外一种情况是,在用户需要优先装载或导出数据的时候,使用更快的核心是更好的方法。COPY是PostgreSQL最好的数据导入方法,该方法很容易(但不经常)受到CPU性能的限制,这可能会成为操作的瓶颈。虽然它可以将输入文件分割成若干个小片段,并使用并行的方法去装载这些文件,但是必须自行去创建或者获得,而不是那些服务器所了解的能够为用户自动创建的内容。使用pg_dump工具导出一个数据库的副本在某些系统上是另外一个可以受限于CPU的例子。

给应用优先配置多少内存,实际上由工作中需要处理的最常见操作的数据集大小决定。一般的,加大内存能够显著提高性能。在以下情况下,可以不用这个方法来提供更好的服务。

常见的情况下更多内存有助于经常访问那些能够容纳较大数量的数据,而不是较小的那些。这种情况的发生比用户所预想的更为频繁,这是因为需要存储数据库B-树索引,即在内存当中无法适应整个表或甚至仅仅是索引的话,那么尽可能存储更多的一部分索引就意味着基于索引的数据查找会很显著地加速。将位于树结果顶端的那些最常使用的数据块进行缓存也会有助于在不能将所有叶子节点放入内存的情况下的处理。

一旦用户有程序在运行,PostgreSQL缓冲区高速缓存当中用户通常可以有更多有关内存是如何使用的信息(在操作系统中也可以查看),并且可以看到哪些数据能保存。本书中关于使用pg_buffercache的章节将会讲述如何监控这种数据。

虽然在数据库服务器中用户经常遇见的是CPU成为该系统瓶颈的情况,但是绝对可能会碰到磁盘成为系统瓶颈的时候,特别是在系统中只有一块或两块硬盘的情况下比较明显。几年前,在硬盘上有两个基本的选择,一个是较为便宜的通常在桌面环境使用的ATA(也就是IDE)驱动器,另一个是在服务器上使用的SCSI驱动器。

这两个技术目前已经得到发展,在配置数据库服务器时,目前选择倾向于使用串行ATA(SATA)或者串行连接SCSI(SAS)。在两种接口之下,可能会发现其所使用的几乎是相同的驱动器,甚至磁盘控制器可以附加任意一种磁盘。结合这两个之间的微小性能差距,在它们之间做选择比之前更难。

每种技术当中参数都被进行了简单的比较,当下的一些详细信息如下所示。

一般情况下,用户会发现在相似规格的情况下,单个SAS硬盘的速度会比SATA硬盘要快。特别是由于SAS磁盘更快的机械性能,其随机I/O上的寻道性能会更好,有时磁盘的传输速率也更快。此外,由于SAS驱动器已支持类似更长的命令队列等高级特性,因此更有可能的是操作系统将有匹配支持去充分利用这些特性。

1.RAID

廉价冗余磁盘阵列(RAID,Redundant Array of Inexpensive Disk)方法是解决单个磁盘驱动器在处理性能和可靠性上的局限性问题上的标准方法。一个RAID阵列会将多块磁盘纳入一组磁盘集当中将其视作一个单独的磁盘,这些磁盘通常具有相同的配置。其所产生的效果要么性能提高,要么可靠性提高,或者两者都有提高。在某些情况下,写入阵列的奇偶校验(parity)信息计算能够带来额外的可靠性。奇偶校验是数据校验的一种方式,它能够在信息丢失的情况下进行重组。从空间的角度来看,使用奇偶校验的RAID级别在驱动器故障存在的前提下写入数据方面是有效的,但是奇偶校验计算开销将会显著影响数据库应用程序。

较为常见的RAID阵列的基本形式包括如下的几种类型。

为了公平公正地去比较磁盘的性能,需要考虑大多数系统都将会有个来自多个磁盘(如RAID阵列)的裸性能(net performance)。由于SATA磁盘相对便宜一些,因此同样预算情况下所采购到的SATA磁盘会比SAS多一些。如果确信应用程序在负载分散于更多磁盘之上会得到更快的响应速度,那么单位成本内购买的更多东西必将会导致系统整体速度的加快。需要注意的是,这里的上限通常是服务器的物理硬件所决定的。因此在环境当中只有这么多的存储机架或者控制器端口可用的情况下,扩大机箱可能会花费更多的成本。在那些更小数量、更为快速的驱动器的情况下很容易发现使用SAS是一种更好的方法。这也就是为什么如下的做法很重要:不断对硬件及数据库进行基准评测,以得到在磁盘数量增加情况下的改进状况。

2.驱动器错误处理

购买廉价的SATA硬盘,并从它们那得到比较好的性能,也不一定意味着用户会将其使用在数据库服务器中。因为不论用户的系统运行速度多快,硬盘驱动器一旦发生故障后服务器会都不可用。

确保硬盘驱动器操作可靠性的第一步是能够准确地报告磁盘所面对的错误情况。这可以通过两种机制进行错误报告:在读和写操作期间所报告的错误代码,以及使用SMART协议来报告磁盘状态。SMART提供磁盘的各类信息,例如温度和其他自测结果。

当发现错误数据的时候,消费级的SATA驱动器配置成积极的自动重试并尝试去修复该错误。这样做是有一定道理的,因为通常围绕该数据的只有一个副本存在,而且是需要花费相当长的一段时间去重试,而不是去报告数据丢失。不过经常会发现在某个数据库环境的RAID配置中,用户可能不需要这样操作。如果这样,可能会引起超时,而在一般情况下RAID控制器很难进行处理。与其相反的是,用户会希望磁盘能够及时报告错误,这样才能使用一个或者多个磁盘备份替换。这种形式错误处理的变通通常是SATA驱动器标识为“enterprise”或“RAID edition”与常规形式驱动的主要区别。以某种形式标记的驱动器将会迅速报告错误,这在其他非RAID的版本当中则不会如此处理。购买企业版的SATA硬盘驱动器以获得可靠的服务器错误处理操作弥补了它们与SAS型号之间的价格差距。这也可能在驱动器固件当中被调整。可以从http://en.wikipedia.org/wiki/TLER查看关于此方面驱动器功能的更多详细信息。

一般来说,所有的SAS磁盘将有助于返回错误信息而不是尝试去自行修复,以使数据得以重建。下一节中关于Metwork Appliance可靠性研究的部分会对这一主题给出更多的额外信息,相关链接请参见:http://storagemojo.com/2007/02/26/netapp-weighs-in-on-disks/

 

为数据库使用外部存储

因为USB和火线桥接芯片用于进行连接和相关联的驱动程序的限制,使用USB或者火线连接的外部设备很难报告其SMART和其他错误信息。它们也由于相似的原因不能处理写缓存的问题。用户在数据库中应该避免使用这些连接方法的外部磁盘。在这点上,使用新的外部SATA接口(eSATA)的外部存储技术要好一些,因为它们与直接连接到SATA设备的方式不同。

3.硬盘驱动器可靠性研究

一般来说,预期的可靠性也是要优先考虑的重要事情。在过去几年,共发布三个关于大规模磁盘驱动器的研究成果。

http://research.google.com/archive/disk_failures.pdf

http://www.cs.cmu.edu/~bianca/fast07.pdf

http://www.usenix.org/event/fast08/tech/full_papers/bairavasundaram/bairavasundaram.pdf (详细版本)或 http://www.usenix.org/publications/login/2008-06/openpdfs/ bairavasundaram.pdf(简短版本)。

在Google和卡内基梅隆的研究成果中没有偏向于描述SCSI/SAS系列磁盘更为可靠。但威斯康辛大学麦迪逊分校和Network Appliance公司的研究则暗示“SATA磁盘相对于光纤通道磁盘具有更高数量级的校验和不匹配概率”。综合以上观点,在SAS下的错误处理要强于类似的SATA磁盘。因为它们都比较昂贵,不论其中哪一种提高错误处理的方法,要付出的费用都会根据用户的商业环境对可靠性的需求而变化。对用户正在运行的数据库,这种情况则不尽相同。具有单一主数据库和多个从数据库的系统显然会倾向于使用主数据库中表现更好的组件。

用户会发现任意一种连接类型都有可靠和不可靠的的磁盘驱动器。最佳的做法是只部署在市场上发售的时间够长,并且实际客户对其故障率满意的磁盘驱动器。使用更新技术的新型驱动器通常会比经过实践证明的稍微旧的产品要容易失效,因此用户找不到任何可靠的调查结果,这就成了需要进行质疑的原因。

4.驱动器固件与RAID

在一些磁盘阵列配置当中,所有的磁盘需要有相同版本的固件,以保证其可靠性。SATA磁盘面向用户定期进行驱动器固件的大幅更新,有时产品型号并不变更。在一些情况下,一旦用户更新了驱动器固件,那么很可能不能恢复到早期的版本,而新更换的驱动器可能不能运行较老的固件。即使相同型号的硬盘还在市面上销售,用户也不能通过更换损坏的硬盘来解决问题。

如果用户购买的是SAS驱动器,或者是面向企业的SATA驱动器的RAID,这些驱动器具有较为稳定的固件版本。这也是制约其最大存储容量落后于用户需求的原因之一。一旦用户在市场上购买了最新最大容量的驱动器后,就会知道新的驱动器技术的不可靠是多么危险。但公平地说,市场上出现的新技术都是经过了彻底检验的。面向商业的版本例如SAS版本,硬件和与其相关的固件稳定,价格也更贵。对于厂商来说,在新型驱动器版本发布时保持固件的修订版本的稳定相对容易一些,因为用户所使用的beta版本已经修正了很多可能的缺陷。

5.SSD

目前市场上出现的最新的驱动器技术是固态硬盘(SSD),也称为闪存磁盘。它们不需要任何移动部件就可以提供对数据的永久性存储。其性能可以大大超过需要移动部件的磁盘,特别是对磁盘寻址有要求的应用程序——通常是数据库并且要更高可靠性的情况。

目前有三个主要因素制约数据库对SSD技术的使用。

鉴于 SSD 的擦除机制,用户必须要为那些将会持续很长时间的操作配备写入缓存(通常几个KB大小的,匹配闪存单元块大小)。写入操作将会被缓存,直到整个数据块处于排队状态,然后会在写入新数据时擦除闪存。

虽然容量比较小,但这些对于回写高速缓存,以及针对数据库使用的所有潜在数据损坏问题的设计仍然是有效的(具体详细信息将会在本章随后内容当中进行讨论)。某些SSD当中包含一个电容或者是类似电池后备机制来处理这些问题,这些问题很少会出现但仍然会实际存在。

直到SSD制造商能够获得更好的描述什么样条件下设备当中的写缓存会被丢失之前,该技术对于数据库使用来说仍然是一种未知的风险,并应该谨慎对待。数据丢失的窗口期以及由此所造成的数据库损坏的可能性都很小,但是往往都会存在。通常也不能通过使用具有其自身电源后备支持的控制器卡来解决此问题。在许多情况下,当前的这一代存储卡根本谈不上是SSD。即使它们能够如此,SSD可能也不会接受并且使用与正常驱动器所使用的同样的命令来禁用其写入高速缓存。这是因为一个正常运行的写入高速缓存对于驱动器长久使用方面是非常重要的。

这是PostgreSQL性能最重要的一个方面也是最容易受忽视的方面。现在很多硬件都不那么重视磁盘控制器。

因此不要被现状所迷惑。当涉及到向一个数据库中提交信息的时候,循环使用的磁盘介质(即使是诸如SSD之类的闪存介质)都有些任何软件所无法克服的限制。

1.硬件RAID和软件RAID

在部署一个RAID阵列时,用户需要用一些专用的硬件才能完成。现在,包括Windows和Linux等在内操作系统都包含有软件RAID工具,使用户可以不需要使用主板上的额外磁盘控制器来完成操作。

硬件RAID有几个好处。在一些软件RAID安装中,例如Linux环境下,用户需要小心系统在任意一种磁盘失效情况下,都有可能导致无法启动。硬件RAID卡的BIOS通常已经考虑到这种情况。当更换故障硬盘后,硬件RAID卡也可以自动进行重建。

磁盘失效后,如果它们开始将损坏的数据发送到主板,那么在处理过程中可以卸下整个系统。硬件RAID控制器倾向于测试这种方法,而主板的驱动器控制器则不一定。

除了成本过高以外,硬件RAID的缺点就是当控制器失效时,用户使用其他的控制器也不能访问到该驱动器。在这种情况下,SNIA所提供的RAID磁盘数据格式(DDF, Raid Disk Data Format)就是一种新兴的存储RAID元数据标准,但目前尚未获得控制卡厂商的良好支持。

在众多系统中,硬件RAID最大优点是其对可靠写缓存支持。有关这部分内容将会在本章后续内容详细描述。

2.一些推荐的磁盘控制器

市面上有很多种磁盘驱动器都不能很好地应用于数据库。下面列出几个众所周知的在PostgreSQL部署时能够较好运行的产品。

Areca阵列卡的驱动深度依赖用户所使用的操作系统,因此用户需要仔细检查。例如,在Linux系统下,用户要针对系统内核做一些测试才能确保驱动正确,因为这个驱动并没有经过大量的内核测试。不过在2.6.22内核下,PostgreSQL负载较重的用户可以较好地使用这块卡。

通常情况下,上述列表当中目前售价最便宜的一块控制卡大约需要300美元。如果找到一块比该售价更为便宜的控制卡的话,那么它不大可能运行得很好。这些卡当中的大多数都被成为假RAID(Fake RAID)。这些卡实际上并不会包含一个专门的存储处理器,这是价格大幅度上升的影响因素之一。

与其他上述控制卡不同的是,假RAID卡是使用系统当中的CPU来处理这些任务。从性能的角度来看,这并不一定是什么坏事情,但是最好是直接使用一个简单的操作系统RAID(如Linux甚至是Windows所提供的)。假RAID往往是漏洞百出的,包含低质量的驱动程序以及不能被移植到另一种类型RAID控制器的担忧。同时,这些控制器也没有电池后备的高速缓存。在许多情况下,这是另外一个值得付出的重要组成部件。

假RAID卡的著名提供商包括Promise以及HighPoint。此外,用户会在大多数主板上找到对RAID的支持,如Intel的RAID,这也是属于假RAID的范畴。虽然Intel也提供了一些真正的RAID卡设备,同时也制造用于以上提到的那些控制卡的I/O处理器芯片。

即使有硬件RAID可以考虑使用,但也不可能会去直接推荐某一块具体的卡,因为在企业的采购预算里可能会减少对这些的选择。如果用户喜欢购买HP的产品,而实际上Areca的阵列卡可能更适合;那么用户最好要知道P800是一块很不错的卡,而E200因为太慢,连前面列出的列表里都没有它,这就足够了。同样地,用户如果与DELL有个大的采购合同,那最后可能惟一现实的选择是采用PERC6或者H700/800产品。有许多面向商业需求已经决定了哪些硬件产品可以使用,因此,比上述所列的产品可选择面就更小。

3.附加存储——SAN和NAS

用户通过主板或功能卡将服务器直接连接硬盘,硬盘与机箱不分离,这样的方式成为直接附加存储(DAS,Direct-Attached Storage)。另一种方法是使用外部接口,通常是光纤通道或者以太网,使用存储区域网络(SAN,Storage Area Network)或者网络附加存储(NAS,Network Attached Storage)来容纳数据库的磁盘。SAN和NAS的硬件比DAS要贵得多,并且在复杂方式下更容易管理。除此之外,两者之间的比较有些争议。

还有一些外部驱动器阵列可以通过使用SAS或eSATA线缆进行附加,因此尽管在技术上,它们处于服务器机箱的外部,它们仍然还是直连存储方式。DELL公司的PowerVault是较为常用和廉价的产品,已知可以扩展连接192块DAS驱动器。

SAN或者NAS相比直接存储有如下一些很明显的优势。

不过,这里也会有些潜在的缺陷存在。

如果用户要以合理的价位达到性能要求,那么最好选择直连存储。如果用户需要SAN或NAS,需要考虑的因素更多的是价格而不是性能表现。

如果用户采用了本书推荐的磁盘基准评测方法的话,那么就能够很快确定结果为SAN销售周期的一个必要组件取得良好的性能。考虑到它们的价格,如果在系统完全交付之前进行一些基准评测的话,就可以使那些提供商的SAN产品去执行一部分操作作为销售当中的一部分内容。在标准方式下其结果是不可能会有争议的。这可以避开需要聘请外部顾问的需求,取而代之的是使用提供商内部的资源。

PostgreSQL使用预写式日志(WAL,Write-Ahead Log)来写入数据以使数据库或硬件失效时能保存数据。这与其他数据库的日志缓存和REDO日志类似。数据库文档包含WAL的实施方法详见:http://www.postgresql.org/docs/current/static/wal.html

以下内容引用自该文档。

WAL主要的概念是改变数据文件(表和索引所在的)只能在这些变更被记录后才能进行的情况,也就是说,日志记录描述的是那些被刷新至永久存储的变更。

这个过程确保用户的应用程序如果接收一个COMMIT事务,该事务是作用在永久性存储之上,在即使有故障的情况下也不会丢失。这满足了ACID(原子性、一致性、隔离性、持久性:Atomicity、Consistency、Isolation、Durability)当中的持久性,同时也满足数据库的要求。

WAL实施当中最复杂的部分就是“刷新到永久存储”。本章花了几页的内容来讲述WAL,后续还有相关讲述。

服务器当中的CPU和内存都比磁盘的速度快。因此,系统都是等待磁盘响应,特别是数据要写出时,会大幅降低系统的性能。系统在转移到下一个任务之前等待磁盘完成写操作被称为直写式缓存(write-through cache)。虽然数据会被临时保存在内存缓存中,直到所有数据都写入物理磁盘,任何写入应用程序请求都不被视作完成。

使其执行更快的常见解决方法就是在程序执行写操作与磁盘之间引入一种不同类型的写缓存。回写缓存(write-back cache)就是这种将数据拷贝到内存,然后控制请求写入操作的应用程序返回信息。这些写入操作由回写缓存设计所规定的在未来的某个时间随后进行异步处理。在数据实际写到磁盘上之前可能有几分钟时间。

当PostgreSQL向WAL当中写入信息,以及有些时候在写入常规数据库文件的时候,这些信息必须是“刷新到永久存储”使数据库的崩溃故障防范机制能够奏效。用户的回写缓存表明写操作已完成时会发生什么,它真的完成了么?人们将这些现象称为“lying drives”,并且其结果可能会很糟。

如果用户的系统采用回写缓存,系统崩溃引起回写缓存内的内容丢失,那么PostgreSQL数据库存储在该磁盘上的数据会变得不可用。用户会发现即使专家介入重启数据库,检查那些数据损坏也会变得非常困难。

考虑到用户已经提交事务的情况。新事务可能会分布在磁盘的两个数据块上。现在,假设其中有一个在系统故障前写入磁盘,而另一个则没有。此时数据库就会处于一种损坏的状态下:事务中的一个数据块没在它本来要存在的另一个块中。

当与WAL有关的所有数据块都已经被正确写入,数据库WAL会在故障后修正这些错误。但WAL保护只在其能够获取信息是否已经被正确写入磁盘的可靠信息时起作用,在“撒谎”的回写缓存当中并不对其进行报告。

1.回写缓存的来源

使用写入缓存来填充服务器时,用户需要知道以下信息。

用户如何保证这些有可能会丢失数据的回写缓存内的数据安全?有以下几个注意事项。

2.磁盘控制器监控

用户具有电池后备的高速缓存的RAID控制器板卡时,可能会希望能够监控板卡,以确认磁盘何时会失效。然而用户在使用这种技术的时候,监控控制器电池的健康状况对维持可靠的数据库系统同样重要。如果电池失效并且用户使用的是回写模式,用户写入的信息则不安全。类似的,如果用户的电源失效,用户应该在电源失效的几分钟内将数据库服务器关闭并保持这个状态。通过UPS或其他的类似机制整合电源监控应该成为用户数据库服务器配置的一部分,以便断电时能够按顺序关闭服务器。考虑到控制器电源的目的是保护用户免受类似有人碰掉电源等意外断电的损失。虽然厂商主张控制器电池能够维持一天左右的时间,但用户实际上不会觉得这多出的中断时间是安全的,特别是在电池老化和没有太多电量的,以及部分控制器电池一开始容量就不大的情况下。用户应只将电池作为电源中断后若干分钟内的保护工具。务必要进行测试,而不是盲目地相信厂商的参数:数据最终还是要依赖这些设施进行保障。

一些较好的RAID控制器会在电池停止正常工作的情况下自动禁用回写模式。如果性能在一台旧的服务器上突然下降,那多半可能是由于此原因。

另外,不要忘记每一个UPS的电池也有失效的时间。这就有更多的理由让用户在电源失效的时间内逐个关掉服务器,而不是乐观地保持服务器运行直到电源重新可用。

3.禁用磁盘写缓存

如果用户的阵列卡没有禁用所有驱动器的写缓存,或正在使用的是软件RAID,用户则需要自行关闭缓存。最好的判断方法就是使用驱动器厂商所提供的工具来检查是否有可能去修改默认的写缓存状态。

此外,用户也可以使用软件方法达成此目标。以下是Linux系统下检查写缓存的例子,具体操作顺序是关闭写缓存、确认变更生效、再打开写缓存,如下所示。

对于数据库使用来说,只有-W 0的配置才会是完全安全的。在PostgreSQL的WAL文档当中为其他操作系统推荐了类似的命令。

如果用户没有电源后备的写入高速缓存,那么就不能利用某些基于内存的缓存来加速fsync写,数据库提交的性能将会很差。最差的情况是用户将会拥有一个在每条语句执行后要执行一个提交动作的客户端。硬盘驱动器是如何运作的实际情况意味着磁盘每转一圈执行一次写操作。表2-1是目前常见的驱动器的速度的测量值,以及最大的事务提交率。

表2-1

转 速

旋转时间(ms)

最大提交事务数/秒

5400

11.1

90

7200

8.3

120

10000

6.0

166

15000

4.0

250

重要的是要意识到这能够限制在什么样的程度之上。

如果用户有一个7200转/分的硬盘驱动器,在启用回写高速缓存的任何情况下,没有哪个单独的客户端提交事务的速度可以超过120个/秒。

RAID阵列中有多少块硬盘,或者在用户的软件中如何进行配置都无关紧要。重要的是用户的硬件必须带有电池,启用非易失性回写缓存,才能安全突破限制。

有部分PostgreSQL安装使用RAID控制器板卡就是为了这个目的,在简单磁盘捆绑JBOD,Just a Bunch of Disks模式当中提供BBWC功能,即在控制器中没有采用任何RAID。有时候磁盘会被直接使用,其他的顶层软件RAID与硬件RAID相比有一定的优势。

如果用户的客户端不止一个,那么每个事务提交需要做的操作更多。如果用户的客户端的数量很大,并且定期提交事务,那么每秒提交事务的数量大于500个的情况很常见,这是因为每一次刷新磁盘写入操作也将会包括其他客户端的排队等候提交的请求。另一个普遍的方法是将提交整合成更大的块,可能同时发送1000个记录,而不是单独提交,以减少提交延迟的影响。

另一种不使用写缓存来加速系统的方法就是异步提交。这将在第6章中进行讲述。

架设一台高性能的数据库服务器是项艰苦的工作。在众多的质量等级和相应的成本开销下有许多独立的部件可用。也有许多的小细节需要用户做出正确决定,否则将有数据损坏的风险。幸运的是,用户不需要从零开始。一般的,知名的产品都有较好的性能表现,并且可靠性也较高,用户可以对数据库服务器做一个合理的预算。但也要对结果进行用户自身的基准评测。在运行中的数据库中,错误的配置也可以很容易破坏好的设备。


相关图书

相关文章

相关课程