带有 Big Sur 的基于 ARM 的 M1 Mac 上的 Postgres 错误

问题描述

自从我获得了新的基于 ARM 的 M1 MacBook Pro,我就一直遇到严重且一致的 Postgresql 问题 (psql 13.1)。无论我使用 Rails 服务器还是 Foreman,我都会在浏览器和终端中收到错误,例如 PG::InternalError: ERROR: Could not read block 15 in file "base/147456/148555": Bad addressPG::Error (invalid encoding name: unicode)Error during failsafe response: PG::UnabletoSend: no connection to the server。奇怪的是,我经常可以反复刷新浏览器以使其正常工作(直到它们不可避免地再次出现)。

我知道与基于 ARM 的 M1 Mac 相关的所有配置挑战,这就是为什么我以多种方式多次卸载并重新安装从 Homebrew 到 Postgres 的所有内容(使用 Rosetta,不使用 Rosetta,使用 {{1 }} 命令,使用 Postgres 应用程序而不是 Homebrew 安装)。我在随机留言板上遇到了其他几个人,他们遇到了同样的问题(也在新的 Mac 上)并且没有任何运气,这就是为什么我不愿意相信这是一个驱动器损坏问题。 (我也多次运行磁盘工具急救检查;它说一切正常,但我不知道它有多可靠。)

我正在使用thoughtbot parity 将我的开发环境数据库与当前生产中的数据库同步。当我运行 arch -x86_64 brew 时,我在终端中看到数百行,看起来像下面的输出(这是在下载完成后立即但在继续创建认值、处理数据、序列集等之前)。我相信这是问题的根源,但我不确定解决方案是什么:

development restore production

有没有其他人遇到过这种情况?任何解决方案的想法将不胜感激。谢谢!

编辑:我能够在较旧的 MacBook Pro(也运行 Big Sur)上重现相同的问题,因此它似乎与 M1 无关,但可能与 Big Sur 相关。

解决方法

此问题的最终解决方法

在尝试了其他答案中的所有解决方法后,我仍然偶尔会收到此错误。即使在转储和恢复数据库、切换到 M1-native postgres、运行各种维护脚本等之后。

在对 postgresql.conf 进行大量修补后,唯一 可以无限期地可靠地解决此问题(此后未收到错误):

在 postgresql.conf 中,更改:

max_worker_processes = 8

max_worker_processes = 1

进行此更改后,我已在之前出错的数据库中抛出所有测试,并且一次未显示相同的错误。以前,我在大约 2000 万条记录的数据库上运行的提取例程在处理 1 到 200 万条记录后会出现错误地址错误。现在它完成了整个过程。

显然,减少并行工作线程的数量会降低性能,但这是我找到的唯一可靠且永久解决此问题的方法。

,

更新 #2:

WAL Buffer 等调整延长了错误间隔时间,但并没有完全消除它。最终使用 Homebrew 重新安装了新的 Apple Silicon 版本的 Postgres,然后对我现有的数据库执行 pg_dump(遇到错误)并将其恢复到新的安装/集群。

这是有趣的一点:pg_restore 未能恢复数据库中的索引之一,并在恢复过程中(否则已完成)注意到它。我的预感是该索引的损坏或其他问题导致了 Bad Address 错误。因此,我对这个问题的最终建议是执行 pg_dump,然后使用 pg_restore,而不是 pg_dump 来恢复数据库。 pg_restore 似乎已经标记了这个问题,而 pg_dump 没有,写入一个干净的数据库而没有错误的索引。

更新:

在尝试了多种解决方法后继续遇到此问题,包括完整的 pg_dump 和受影响数据库的恢复。虽然一些修复似乎延长了两次发生之间的时间(特别是增加共享缓冲内存),但没有一个被证明是永久性修复。

也就是说,对 postgres 邮件列表的更多挖掘表明,此“错误地址”错误可能与 WAL(预写日志)问题一起发生。因此,我现在在我的 postgresql.conf 文件中设置了以下内容,显着增加了 WAL 缓冲区大小:

wal_buffers = 4MB

并且从那以后就没有遇到过这个问题(再次敲木头)。

这会产生一些影响是有道理的,因为默认情况下 wal_buffer 大小与共享缓冲区大小成比例增加(如前所述,增加共享缓冲区大小提供了暂时的缓解)。无论如何,在我们确定导致此错误的原因之前,还可以尝试其他方法。


在 M1 MacBook Air 上偶尔会遇到这个确切的问题:ERROR: could not read blockBad Address 的各种排列。

我在 postgres 论坛上读到这个问题可能发生在虚拟机设置中。因此,我认为这是由 Rosetta 引起的。即使您使用的是通用版本的 postgres,您可能仍在使用 x86 二进制文件来处理某些附属进程(例如,在我的情况下使用 Python)。

无论如何,以下是解决问题的方法(到目前为止):reindexing the database

注意:您需要从命令行重新索引,而不是使用 SQL 命令。当我尝试使用 SQL 重新索引时,我一遍又一遍地遇到相同的 Bad Address 错误,并且重新索引从未完成。

当我使用命令行重新索引时,过程完成,Bad Address 错误没有再次出现(敲木头)。

对我来说,就是:

reindexdb name_of_database

一个 12GB 的数据库需要 20-30 分钟。我不仅不再收到这些错误,而且数据库似乎更容易启动。只希望在 Rosetta 中重复读/写/索引创建问题不会再次出现。我不确定为什么会这样……也许在 M1 Mac 上创建的索引容易损坏?也许索引因 Rosetta 交互而因写入或访问而损坏?

,

Big Sur Beta 11.3 中是否有可能修复了这个问题?

自从在我的 Mac mini M1(现在是 PostgreSQL 13.2)上使用 MacPorts 安装 PostgreSQL 13 以来,我一直遇到与 OP 相同的问题。

我会看到 could not read block 错误:

  1. 偶尔运行临时查询时
  2. 总是在用 R Markdown 编译一本书进行多次查询时
  3. 总是在我的主数据库上运行 VACUUM FULL 时(这台机器上的实例大约有 620 GB,相对于 {{1} } 需要)。

(到目前为止,我的“修复”是将我的 Mac 指向我在办公室角落运行的 Ubuntu 服务器,所以对我来说没有真正的问题。)

但是自从今天升级到 Big Sur Beta 11.3 以来,我已经设法做到了 2 和 3,没有出现错误(在升级前都失败了)。操作系统中是否有可能修复了这个问题?

,

我从 postgresql.conf 恢复了 postgresql.conf.sample(并重新启动了数据库服务器),从那时起它就运行良好。

待定,我在这里尝试了 wal_buffersmax_worker_processes,但没有帮助。我偶然发现了它,因为我尝试了很多我只需要回去的事情。我没有没有重新初始化整个数据库或类似的东西,只是配置文件。