Rho*_*ros 0 postgresql write-ahead-logging
我曾经问过性能问题,人们会告诉我 PostgreSQL 自动将足够小的表完全保存在 RAM 中,以免给 HDD 带来压力,从而实现“小表”的超快读写,即很少更容易适合可用 RAM(或分配给 PG 的内容)的行。
这对我来说很有意义,让我很高兴,因为我可以在并行运行的脚本之间有效地进行通信,而不会给我可怜的 HDD/SSD 带来压力并堵塞所有资源。
但后来我突然想到:这怎么可能?PG 怎么可能将一个表全部保存在 RAM 中,无论它有多小,而不会丢失数据完整性?
如果它不是一直写入永久存储,如果突然断电,或者软件崩溃,或者在运行时发生其他一些灾难,它怎么可能恢复?我想得越多,这对我来说就越不重要。
我能想到的唯一答案是:不,它实际上并没有这样做。如果 PG 从不(或很少)将数据写入永久存储,我看不到任何可能的方式来避免丢失数据。
如果这是可能的,但只有在为表格或设置启用某种标志后,我才想知道该标志/设置。我想为仅包含“内部通信”数据的表启用此功能,该数据类型除了作为主动运行脚本的“公共数据存储”之外没有任何价值。
由于预写日志(WAL),这是可能的:
简而言之,WAL 的核心概念是对数据文件(表和索引所在的位置)的更改必须仅在这些更改被记录后写入,即在描述更改的日志记录已刷新到永久存储之后。如果我们遵循这个过程,我们不需要在每次事务提交时将数据页刷新到磁盘,因为我们知道在发生崩溃的情况下我们将能够使用日志恢复数据库:任何尚未应用的更改可以从日志记录中重做数据页。
它是 Postgres 架构的核心组件,默认情况下是打开的。您可以配置几个参数,如手册一章WAL 配置中的说明。
还要考虑手册中有关可靠性的基础知识。
PostgreSQL 将经常/最近使用的数据保存在shared_buffers 中。它并不专门针对小表。每个页面都单独处理。来自大表或索引的频繁访问的页面与来自以相同频率访问的小表的页面一样有可能在shared_buffers中找到。
有两种方法可以保护此数据。另一个答案已经描述了 WAL。另一种机制是检查点。在检查点时,shared_buffers 中的所有脏数据都会写入磁盘,并最终同步。但是,shared_buffers 中的副本不会失效,它只是被标记为干净。所以它仍然在那里,如果再次需要它,就不需要再次读取。
因此,如果所有数据都保存在shared_buffers中,这意味着该页面只需要读取一次,并且只需要在每个检查点(默认为5分钟)被弄脏时写入一次(只写入一次,无论如何很多次都被弄脏了)。但每次更新时,更改也必须写入 WAL 流中。
如果表被标记为未记录,那么对这些表的更改不再需要添加到 WAL,并且在检查点,数据不会写出,除非它是“关闭”检查点。在事务结束时,提交记录仍然会写入 WAL,但如果事务中更改的每个表都未记录,则提交记录不需要立即同步到磁盘。
| 归档时间: |
|
| 查看次数: |
88 次 |
| 最近记录: |