abl*_*igh 1 postgresql index crash
我正在努力解决Postgres的民间记忆问题。
听说很久以前在一个遥远的星系(Ubuntu 12.04下的PostgreSQL 8.4),PostgreSQL经常遇到一个问题,如果承载服务器的机器出现故障(例如内核崩溃),当机器重新启动时,Postgres将启动,但数据库上的索引可能已损坏。例如
SELECT foo FROM bar WHERE baz = 123
Run Code Online (Sandbox Code Playgroud)
会失败,因为上的索引bar.baz
会损坏。重新索引表修复了问题,但由于无法检测到此问题,而且这是在设备环境中(手头没有 DBA),本质上为了防止这种情况,有必要在重新启动时重新索引所有表,这会非常昂贵。因此(推理是这样的)如果手头没有 DBA,使用 Postgres 是不明智的,特别是在表很大且计算索引昂贵的环境中。
由于这种民间传说,在这种情况下首选 MySQL。
我依稀记得在 8.4 下看到过这个问题,所以我认为其中有一些道理。
我确信这也发生在 Ubuntu 14.0.4 下的 Postgres 9.3 上。我不知道它是否“经常”发生。它发生的系统正在运行(公认的旧)企业级 SAS 驱动器,该驱动器声称写入缓存已关闭,因此我认为这不是写入缓存问题。
如果情况仍然如此,我想我可以在网上找到比我能找到的更多的证据。
因此,我怀疑它可能已修复,或者可能是由于某些问题造成的postgresql.conf
(尽管检查表明只有 autovacuum 设置从默认值更改)。
在我最近知道的系统中(使用 9.3)没有使用 LVM。存储系统是 ext4,安装在具有默认属性的物理驱动器上。这个驱动器是一个(公认的老)企业 SAS 驱动器加上 SAS1068 PCI-X Fusion-MPT SAS 控制器,它sdparm
声称它没有打开写缓存,但这已经(据称)在不同供应商的多个驱动器上看到过等等。 ,虽然总是在 Ubuntu 上的 ext4 上。
fsync
处于默认状态(on
我相信)。
没有主/从配置——只有一个主——(所以这不是multixact
错误)。
表是使用默认索引创建的(没有花哨的哈希索引)。
Postgres 会定期更新到任何相关的 Ubuntu LTS 版本。最新的问题是在 14.04。
系统崩溃后手动重建索引是一项预期任务吗?
如果没有,是否曾经有过,什么时候改变过?
是否可以避免手动重新索引的需要?
TL;DR:除了 9.3.4 之前的 PostgreSQL 9.3 中的一个特定错误外,您修补至关重要,崩溃后的索引损坏是永远不会发生的,并且自 2001 年发布 PostgreSQL 7.1 以来从未发生过。
你得到的建议/民间传说是错误的。
听说很久以前在一个遥远的星系(Ubuntu 12.04下的PostgreSQL 8.4),PostgreSQL经常遇到一个问题,如果承载服务器的机器出现故障(例如内核崩溃),当机器重新启动时,Postgres将启动,但数据库上的索引可能已损坏。
除非您使用哈希索引,否则这种方式早于 8.4,被记录为不安全且不推荐。
索引的 WAL 日志记录是在 2001 年中期的黑暗遥远的过去引入的。PostgreSQL 在很长一段时间内都是崩溃安全的。这个建议是错误的。
MySQL 在 2009 年的 MySQL 5.5 中默认切换到崩溃安全(默认为 InnoDB 表)。在此之前,它的默认存储引擎 MyISAM 不是崩溃安全的,并且很容易损坏索引和表。所以你的民间传说不仅是错误的,而且是倒退的。
如果您在 8.4 下崩溃后出现损坏,则:
fsync=off
。随着时间的推移,出现了一些与索引相关的错误,但我所知道的所有其他错误都是次要的和/或难以触发的,很少有与崩溃恢复相关的。
9.3 的问题是不同的。这是一个非常具体的错误,我们都感到非常尴尬。当某些其他操作以特定顺序发生后,副本 PostgreSQL 服务器被提升为主服务器时,就会发生这种情况。这是一个非常糟糕的错误,因为它影响表的内容,而不仅仅是指数,所以这是非常重要的是你要补丁9.3.5或更高版本。要了解更多关于它的信息,您可能不想搜索“multixact bug”。
所以:
系统崩溃后手动重建索引是一项预期任务吗?
除非您使用哈希索引,否则手册特别希望您使用哈希索引。
如果没有,是否曾经有过,什么时候改变过?
PostgreSQL 7.1,早在 2001 年。
如果您阅读发行说明,您会发现偶尔的错误和错误修复,但除了前面提到的 9.3 中的 multixact 错误之外,没有什么太严重的。
是否可以避免手动重新索引的需要?
没做什么。恭喜,您不需要手动重新索引。
简单地:
fsync
设置为on
,默认full_page_writes
设置为on
,默认kill -9
让 postmaster 但没有其他进程删除postmaster.pid
并再次启动 PostgreSQL。如果您这样做并尝试防止损坏,最新版本甚至会检测到它。奖励积分,如果您: