春节前,稳定许久的 NAS 给我送了一个意外惊吓,让我平淡的生活又多了点刺激。
前两天 btrfs 存储池忽然故障,变成了只读。更换内存后重启了几次存储池自动修复了。
似乎是 btrfs 存储池的一部分数据存放在内存中的,而我的群晖型号不支持 ECC 内存。如果内存出现问题,存储池就有可能发生故障。
尽管自动修复后看上去数据并没有遭受太大损失,但 pgsql 数据库却遭遇了无法启动的问题。
一直在 /var/log/messages
文件中不断地输出相关信息:
2024-02-06T01:35:12+08:00 NAS coredump[3356]: Process postgres[3208](/usr/bin/postgres) dumped core on signal [6]. Core file [/volume1/@postgres.synology_avoton_1815+.42962.core.gz]. Cmdline [postgres: startup ]
2024-02-06T01:35:19+08:00 NAS coredump[3356]: Core file [/volume1/@postgres.synology_avoton_1815+.42962.core.gz] size [4084009]
进一步检查发现似乎是 pgsql 的部分数据文件损坏了,而 pgsql dump 的文件内也有类似 could not stat file "./base/81548/81918_vm": Input/output error
的错误信息。
在群晖系统中,pgsql 负责存储如 SynologyPhotos、DownloadStation、VideoStation 等服务的索引和历史数据,而这些都依赖于 pgsql-adapter.service
服务。
◢ 我观察了正常的 pgsql 数据库内容
root@NAS:/var/log# su - postgres
postgres@NAS:~$ psql
psql (11.11)
Type "help" for help.
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
----------------+----------------------------+-----------+------------+------------+-----------------------
download | DownloadStation | SQL_ASCII | C | C |
mediaserver | MediaIndex | UTF8 | en_US.utf8 | en_US.utf8 |
ong | SynologyApplicationService | SQL_ASCII | C | C |
postgres | postgres | SQL_ASCII | C | C |
synodrive | postgres | SQL_ASCII | C | C |
synoffice | office | SQL_ASCII | C | C |
synofoto | SynologyPhotos | UTF8 | C | C |
synoindex | MediaIndex | SQL_ASCII | C | C |
template0 | postgres | SQL_ASCII | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | SQL_ASCII | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
video_metadata | VideoStation | SQL_ASCII | C | C |
(11 rows)
postgres=# \c synofoto
You are now connected to database "synofoto" as user "postgres".
synofoto-# \dt
List of relations
Schema | Name | Type | Owner
--------+--------------------------------------+-------+----------------
public | acl_permission | table | SynologyPhotos
public | activity | table | SynologyPhotos
public | address | table | SynologyPhotos
public | administrative | table | SynologyPhotos
public | album | table | SynologyPhotos
public | aperture | table | SynologyPhotos
public | background_task | table | SynologyPhotos
public | burst_additional | table | SynologyPhotos
public | camera | table | SynologyPhotos
public | check_album_task | table | SynologyPhotos
public | cluster | table | SynologyPhotos
public | condition_album | table | SynologyPhotos
public | config | table | SynologyPhotos
public | delete_album | table | SynologyPhotos
public | delete_condition_album | table | SynologyPhotos
public | delete_item | table | SynologyPhotos
public | exposure_time | table | SynologyPhotos
public | face | table | SynologyPhotos
public | file_operation_error | table | SynologyPhotos
public | file_operation_task | table | SynologyPhotos
public | filter | table | SynologyPhotos
public | focal_length | table | SynologyPhotos
public | folder | table | SynologyPhotos
public | folder_operation_error | table | SynologyPhotos
public | folder_operation_task | table | SynologyPhotos
public | general_tag | table | SynologyPhotos
public | geocoding | table | SynologyPhotos
public | geocoding_info | table | SynologyPhotos
public | group_info | table | SynologyPhotos
public | index_queue | table | SynologyPhotos
public | iso | table | SynologyPhotos
public | item | table | SynologyPhotos
public | lens | table | SynologyPhotos
public | live_additional | table | SynologyPhotos
public | many_item_has_many_normal_album | table | SynologyPhotos
public | many_unit_has_many_administrative | table | SynologyPhotos
public | many_unit_has_many_general_tag | table | SynologyPhotos
public | many_unit_has_many_person | table | SynologyPhotos
public | metadata | table | SynologyPhotos
public | mobile_config | table | SynologyPhotos
public | normal_album | table | SynologyPhotos
public | notification | table | SynologyPhotos
public | one_filter_has_many_unit | table | SynologyPhotos
public | person | table | SynologyPhotos
public | person_group | table | SynologyPhotos
public | person_item_count | table | SynologyPhotos
public | person_migration_mapping | table | SynologyPhotos
public | photo_request | table | SynologyPhotos
public | search_timeline | table | SynologyPhotos
public | share | table | SynologyPhotos
public | share_permission | table | SynologyPhotos
public | takentime | table | SynologyPhotos
public | team_library_folder_has_many_sorting | table | SynologyPhotos
public | team_library_group_permission | table | SynologyPhotos
public | team_library_user_permission | table | SynologyPhotos
public | thumb_preview | table | SynologyPhotos
public | thumbnail | table | SynologyPhotos
public | unit | table | SynologyPhotos
public | user_flag | table | SynologyPhotos
public | user_info | table | SynologyPhotos
public | version_time | table | SynologyPhotos
public | video_additional | table | SynologyPhotos
public | video_convert | table | SynologyPhotos
(63 rows)
目前看重建数据库似乎不会影响到数据,但应该会导致如 DownloadStation 下载记录丢失,并且还需花费大量时间重新构建索引。
我在重建数据库后确认了下,我的 DownloadStation、VideoStation 恢复了初始状态,SynologyPhotos 的相册、分类等信息丢失缩略图也需要重新生成。
群晖官方提供了一个用于重建数据库的脚本,但地址已无法下载。
https://ftp.synology.com/support_web/Tools/script/pgsql_analyzer.sh
还好,互联网档案馆收录了这个地址,目前可以从下面的地址下载这个脚本文件:
https://web.archive.org/web/20220112183140if_/https://ftp.synology.com/support_web/Tools/script/pgsql_analyzer.sh
下载后上传到 NAS 中,使用 bash pgsql_analyzer.sh
-r 将会重建 pgsql 数据库。执行后需要重启 NAS。
2024年04月22日 更新:
pgsql_analyzer
脚本官方直连脚本:
curl -s https://supweb.synology.com/support_web/Tools/script/pgsql_analyzer.sh | sh -s -- -r
恢复数据耗费了 3 天,心累。目前 NAS 在炒豆子(重建索引)故障时插的内存条拿到另一台电脑上跑内存测试了,希望是内存故障引起的。不然 btrfs 存储真不敢用了😭
附 ChatGPT:在使用 btrfs 文件系统的服务器上,当没有 ECC 的内存出现故障时是否会影响 btrfs 内的数据?
在使用 btrfs 文件系统的服务器上,如果使用的是没有 ECC(Error-Correcting Code)功能的内存,并且这些内存出现故障,那么确实存在可能影响 btrfs 文件系统中数据的风险。因为 ECC 内存可以检测并修正内存中的一些错误,没有 ECC 的内存则缺乏这一层额外的保护措施。
当非 ECC 内存发生故障时,可能出现的问题包括:
- 丢失或损坏的数据:如果内存中保存的文件数据在写回磁盘之前发生错误,这些错误可能传递到文件系统并导致数据损坏。
- 文件系统结构损坏:内存中元数据的损坏可能会直接影响到文件系统的结构,导致无法挂载或错误地操作文件系统。
- 操作系统崩溃:某些内存错误可能导致操作系统的关键组件失败,这可能会引发系统崩溃或其他不稳定的行为。
- 未定义的行为:内存错误引发的行为很多是不预测的,这可能包括错误的系统计算、脚本执行错误,甚至是安静的数据损坏,这种损坏最为危险,因为它可能不会立即被检测到。
尽管 btrfs 提供了若干保护数据完整性的特性,如校验和、副本和快照,但这些特性通常是在数据已经被正确写入存储介质后才能发挥作用。如果内存发生故障并导致错误数据被写入,那么这些特性可能无法完全防止数据损坏。
因此,在不使用 ECC 内存的环境中,重要的防范措施应包括:
- 使用高品质的内存模块:尽管没有 ECC,高品质的内存模块仍旧能够提供相对较高的可靠性。
- 定期进行内存测试:使用如 Memtest86+ 等工具可以帮助检测内存中的错误。
- 定期备份:保持数据的定期备份是预防故障引起的数据丢失的关键策略。
- 监控系统日志:关注系统日志,如
/var/log/messages
,可能有助于早期检测内存问题的迹象。
总体上,没有 ECC 功能的内存确实增加了数据损坏的风险,特别是在文件系统如 btrfs 这样重度依赖内存操作的情况下。在无法使用 ECC 内存的情况下,应该通过上述措施来尽量减小风险。
厉害厉害,困扰我几个月的问题,在您这解决了,非常感谢
感谢博主,迅速解决问题!