Postgres 重新索引崩溃的民间传说

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。

我的理论

  1. 我依稀记得在 8.4 下看到过​​这个问题,所以我认为其中有一些道理。

  2. 我确信这也发生在 Ubuntu 14.0.4 下的 Postgres 9.3 上。我不知道它是否“经常”发生。它发生的系统正在运行(公认的旧)企业级 SAS 驱动器,该驱动器声称写入缓存已关闭,因此我认为这不是写入缓存问题。

  3. 如果情况仍然如此,我想我可以在网上找到比我能找到的更多的证据。

  4. 因此,我怀疑它可能已修复,或者可能是由于某些问题造成的postgresql.conf(尽管检查表明只有 autovacuum 设置从默认值更改)。

更多信息

  1. 在我最近知道的系统中(使用 9.3)没有使用 LVM。存储系统是 ext4,安装在具有默认属性的物理驱动器上。这个驱动器是一个(公认的老)企业 SAS 驱动器加上 SAS1068 PCI-X Fusion-MPT SAS 控制器,它sdparm声称它没有打开写缓存,但这已经(据称)在不同供应商的多个驱动器上看到过等等。 ,虽然总是在 Ubuntu 上的 ext4 上。

  2. fsync处于默认状态(on我相信)。

  3. 没有主/从配置——只有一个主——(所以这不是multixact错误)。

  4. 表是使用默认索引创建的(没有花哨的哈希索引)。

  5. Postgres 会定期更新到任何相关的 Ubuntu LTS 版本。最新的问题是在 14.04。

问题

  1. 系统崩溃后手动重建索引是一项预期任务吗?

  2. 如果没有,是否曾经有过,什么时候改变过?

  3. 是否可以避免手动重新索引的需要?

Cra*_*ger 6

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 下崩溃后出现损坏,则:

  • 您在 PostgreSQL、内核、文件系统等中遇到了错误(并非不可能,但也不太可能);
  • 您在修复写屏障支持之前使用 LVM,并且在您的文件系统上启用了屏障;
  • 你的存储子系统就 fsync() 向内核撒谎;或者
  • 您通过设置禁用了碰撞安全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。如果您这样做并尝试防止损坏,最新版本甚至会检测到它。
  • 创建索引时不要显式指定哈希索引。除非您要求,否则 PostgreSQL 永远不会使用哈希索引。

奖励积分,如果您:

  • 保持 PostgreSQL 合理更新,即应用点发布补丁
  • 如果您打算使用 SSD,请使用质量不错的 SSD,否则任何数据库都容易损坏。确保它们具有超级电容器或其他断电保护装置。