【问题标题】:Postgres errors on ARM-based M1 Mac w/ Big Sur带有 Big Sur 的基于 ARM 的 M1 Mac 上的 Postgres 错误
【发布时间】:2021-04-17 15:02:19
【问题描述】:

自从我有了基于 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,使用 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]";

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

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

【问题讨论】:

  • "Bad address" 是与EFAULT 相关联的消息,这意味着 postgres 将无效指针传递给read() 或类似的系统调用。这表明 postgres 或某些相关库中存在相当低级的错误,或者由于硬件故障、过热等导致内存损坏。
  • 谢谢,内特。有什么方法可以可靠地诊断是硬件问题还是低级 Postgres(或相关库)错误?
  • 我的 ARM MacBook Air 也有同样的问题,但并非始终如一。如果我重新启动 Postgres,错误不会弹出一段时间。在有原生 ARM 版本之前,这个问题很可能会一直存在。
  • 是的,在我的 M1 Mac Mini 上遇到了同样的问题。我通过自制软件安装了本机版本的 Postgres。
  • 我的 M1 Mini 也有同样的问题。本机和 x86。奇怪的是,重新启动 Postgres 似乎确实有时会使错误消失。

标签: macos-big-sur pg-restore apple-silicon postgresql-13 thoughtbot


【解决方案1】:

更新 #2:

WAL 缓冲区等调整延长了错误之间的时间,但并没有完全消除它。最后使用 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 交互,索引可能由于写入或访问而损坏?

【讨论】:

  • 谢谢你,@Ben Wilson。不幸的是,当我尝试重新索引时,我得到以下信息:“reindexdb:错误:数据库“database_name”的处理失败:错误:无法读取文件“base/16384/16600”中的块 22:错误地址”......我试过了运行它很多次,块数一直在增加。然后我重新启动 postgres 并再次尝试,它似乎做了一些事情(终端没有反馈表明发生了任何事情,这有时可能是个好消息)。但是,在 localhost:3000 中浏览了一些应用程序后,我又开始看到错误。
  • @carlhauck -- 嗯 -- 这与我在使用 SQL 语句时遇到的情况完全相同,例如:REINDEX DATABASE content_agg。但是,无论出于何种原因,使用命令行版本 (reindexdb NAME_OF_DB) 都可以正常工作并允许重新索引完成。要尝试的一件事:关闭您的 psql 实例,然后重新启动它并确保没有其他与数据库的连接(来自 Python、SQL GUI、Web 服务器等),然后尝试从命令行运行 reindexdb。
  • ——我用命令行和 SQL 语句再次尝试了多次,确保没有其他连接到数据库。仍然收到“错误地址”错误。
  • 感谢@Ben 的跟进,我真的很感激。我尝试将 shared_buffers 增加到 512MB,但这也没有改变任何东西……对我来说改变了什么是昨天我的雇主给我寄了一台基于 Intel 的 MacBook。它安装了 Catalina(我还没有更新到 Big Sur),并且在 Postgres 中一切都运行顺利,使用之前给我带来问题的相同数据库。抱歉,我知道这并不能解决其他遇到此问题的人的问题:/
  • 它在某种程度上与负载有关,因为我在常规开发过程中没有遇到这个问题,但它发生在自动化测试套件期间(它并行运行并且每秒左右重新创建数据库更长的时间) - 所以它要么与负载有关,要么与真空有关,还不确定
【解决方案2】:

明确的解决方法

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

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

在 postgresql.conf 中,更改:

max_worker_processes = 8

max_worker_processes = 1

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

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

【讨论】:

  • 很高兴知道,但这似乎更像是一种解决方法而不是修复方法。听起来 postgres 有一些比赛错误,如果比赛只有一个竞争对手,可以避免:)
  • 感谢 Nate - 调整了答案,因为它绝对是一种解决方法,而不是考虑到性能损失的修复。 FWIW,通过 psql 日志中的一些“无法映射动态共享内存段”错误,我被引导减少并行工作者。 M1 Mac 上的内存访问和 postgres 并行工作者显然有问题——这是这台机器唯一令人沮丧的地方。
【解决方案3】:

是否有可能在 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,相对于 VACUUM FULL 需要多长时间,错误会很快抛出)。李>

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

但是自从今天升级到 Big Sur Beta 11.3 以来,我已经成功地完成了 2 和 3 没有错误(升级前都失败了)。操作系统中的某些东西有可能解决了这个问题吗?

【讨论】:

  • 自从上述更新以来,我已经更频繁地使用我的数据库,我再也没有看到这个问题(之前真的无法使用)。
  • FWIW 在 MacBook Air M1 上的最新 Big Sur 更新后将 max_worker_processes 设置为 8 时,我仍然遇到此问题
  • 我真的从 每次 尝试特定任务(我的列表中的#2,意味着我只是指向我的 Ubuntu PostgreSQL)时看到这些问题,到从未看到问题(所以我现在只使用我的 Mac mini M1 实例)。我检查了,我也将max_worker_processes 设置为 8。所以谜团还在继续。 (我使用 MacPorts PostgreSQL,我的数据目录位于单独的硬盘上。)
【解决方案4】:

我从postgresql.conf.sample 恢复了postgresql.conf(并重新启动了数据库服务器),此后一切正常。

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

【讨论】:

    猜你喜欢
    • 2021-11-26
    • 2021-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-29
    • 2021-03-31
    • 2021-03-06
    • 2021-06-09
    相关资源
    最近更新 更多