《PostgreSQL 9.0性能调校》一一2.2 可靠的控制器及磁盘安装

本节书摘来自异步社区出版社《PostgreSQL 9.0性能调校》一书中的第2章,第2.2节,作者: 【美】Gregory Smith,更多章节内容可以访问云栖社区“异步社区”公众号查看。

2.2 可靠的控制器及磁盘安装

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,后续还有相关讲述。

2.2.1 回写缓存

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

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

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

图标

如果用户的系统采用回写缓存,系统崩溃引起回写缓存内的内容丢失,那么PostgreSQL数据库存储在该磁盘上的数据会变得不可用。用户会发现即使专家介入重启数据库,检查那些数据损坏也会变得非常困难。
考虑到用户已经提交事务的情况。新事务可能会分布在磁盘的两个数据块上。现在,假设其中有一个在系统故障前写入磁盘,而另一个则没有。此时数据库就会处于一种损坏的状态下:事务中的一个数据块没在它本来要存在的另一个块中。

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

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

操作系统写缓存,这个缓存大小很容易就能够达到GB的规模。通常情况下,要存储数据到磁盘时,可以强制使用数据块上的“同步”操作将缓存中的数据清空。在POSIX(包含所有类似UNIX的系统)系统中,这称为fsync或fdatasync调用。在一些情况下,同步模式可以直接写,而实际上是由fsync进行操作的高效写入。在配置文件postgresql.conf当中的wal_sync_method设置控制所使用的方法,这也可以两个都不用,来提高速度而不是提高安全性。
磁盘控制器写缓存。在很多RAID控制器的板卡以及类似SAN的外部存储内部上都会发现写缓存。卡上缓存大小一般为128MB到512MB不等,而SAN中的缓存大小则以GB为单位。通常情况下,控制器可以变为以完全直写式模式下进行操作,尽管这种操作将会比较缓慢。但在默认情况下,用户通常会发现它们工作于回写模式。那些能够在控制器缓存当中容纳的写入的数据被保存于此处,当操作系统收到写操作已完成后,板卡将在后续的时间内将数据清空。要在电源中断后保持这种写操作,板卡需要配备电池。这种组合被称为电池后备的写入高速缓存(BBC、BBWC;battery-backed write cache)。
磁盘驱动器写缓存。所有的SATA和SAS磁盘都带有8MB到32MB不等的写缓存。这些缓存不是永久的:如果电源中断,缓存内保存的任何数据都会丢失,通电情况下可一直为回写缓存。
用户如何保证这些有可能会丢失数据的回写缓存内的数据安全?有以下几个注意事项。

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

一些较好的RAID控制器会在电池停止正常工作的情况下自动禁用回写模式。如果性能在一台旧的服务器上突然下降,那多半可能是由于此原因。
另外,不要忘记每一个UPS的电池也有失效的时间。这就有更多的理由让用户在电源失效的时间内逐个关掉服务器,而不是乐观地保持服务器运行直到电源重新可用。

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

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

image

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

2.2.2 直写式缓存的性能影响

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

image

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

如果用户有一个7200转/分的硬盘驱动器,在启用回写高速缓存的任何情况下,没有哪个单独的客户端提交事务的速度可以超过120个/秒。
RAID阵列中有多少块硬盘,或者在用户的软件中如何进行配置都无关紧要。重要的是用户的硬件必须带有电池,启用非易失性回写缓存,才能安全突破限制。

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

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

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

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值