基于 ARM 的 M1 Mac w/Big Sur 上的 Postgres 错误

Car*_*arl 24 pg-restore thoughtbot macos-big-sur postgresql-13 apple-silicon

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

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

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

pg_restore: dropping TABLE [table name1]
pg_restore: from TOC entry 442; 1259 15829269 TABLE [table name1] u1oi0d2o8cha8f
pg_restore: error: could not execute query: ERROR:  table "[table name1]" does not exist
Command was: DROP TABLE "public"."[table name1]";
pg_restore: dropping TABLE [table name2]
pg_restore: from TOC entry 277; 1259 16955 TABLE [table name2] u1oi0d2o8cha8f
pg_restore: error: could not execute query: ERROR:  table "[table name2]" does not exist
Command was: DROP TABLE "public"."[table name2]";
pg_restore: dropping TABLE [table name3]
pg_restore: from TOC entry 463; 1259 15830702 TABLE [table name3] u1oi0d2o8cha8f
pg_restore: error: could not execute query: ERROR:  table "[table name3]" does not exist
Command was: DROP TABLE "public"."[table name3]";
pg_restore: dropping TABLE [table name4]
pg_restore: from TOC entry 445; 1259 15830421 TABLE [table name4] u1oi0d2o8cha8f
pg_restore: error: could not execute query: ERROR:  table "[table name4]" does not exist
Command was: DROP TABLE "public"."[table name4]";
Run Code Online (Sandbox Code Playgroud)

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

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

Ben*_*son 7

对此的最终解决方法

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

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

在 postgresql.conf 中,更改:

max_worker_processes = 8
Run Code Online (Sandbox Code Playgroud)

max_worker_processes = 1
Run Code Online (Sandbox Code Playgroud)

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

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

  • 很高兴知道,但这似乎更像是一种解决方法,而不是解决方案。听起来 postgres 有一些比赛错误,如果比赛只有一名竞争对手,就可以避免:) (2认同)

Ben*_*son 2

更新#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 block并且Bad Address有各种排列。

我在 postgres 论坛中读到,虚拟机设置中可能会出现此问题。因此,我认为这是由 Rosetta 造成的。即使您使用的是通用版本的 postgres,您可能仍然使用 x86 二进制文件来执行某些辅助进程(例如,在我的例子中使用 Python)。

无论如何,这就是解决问题的方法(到目前为止):重新索引数据库

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

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

对我来说,这只是:

reindexdb name_of_database
Run Code Online (Sandbox Code Playgroud)

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