注意
本文档适用于 Ceph 的开发版本。
高级:元数据修复工具
警告
如果您不具备 CephFS 内部结构的专业知识,在使用任何这些工具之前,您需要寻求帮助。
这里提到的工具既可以修复问题,也容易造成损坏。
在尝试修复文件系统之前,必须确切了解文件系统出了什么问题。
如果无法获得集群的专业支持,请咨询 ceph-users 邮件列表或 #ceph IRC/Slack 频道。
注意
在对 Ceph 文件系统使用元数据修复工具之前,它必须处于离线状态。如果文件系统在线时调用这些工具,它们会报错。如果任何恢复步骤未能成功完成,请勿继续运行任何其他恢复步骤。如果任何恢复步骤失败,请通过邮件列表、IRC 频道和 Slack 频道寻求专家帮助。
导出日志
在尝试任何危险操作之前,请运行以下命令复制日志
cephfs-journal-tool journal export backup.bin
如果恢复过程没有按预期进行,备份的日志将派上用场。MDS 日志可以通过从备份的日志导入来恢复到其原始状态
cephfs-journal-tool journal import backup.bin
从日志中恢复目录项
如果日志损坏,或者由于任何原因 MDS 无法重放它,请尝试运行以下命令恢复文件元数据
cephfs-journal-tool event recover_dentries summary
默认情况下,此命令对 MDS 秩 0 执行操作。将选项 --rank=<n> 传递给 cephfs-journal-tool 命令以对其他秩执行操作,或者传递 --rank=all 以对所有 MDS 秩执行操作。
此命令将日志中所有可恢复的 inode 和目录项写入后端存储,但前提是这些 inode 和目录项的版本高于后端存储中的现有内容。日志中任何丢失或损坏的区域将被跳过。
除了写入目录项和 inode 之外,此命令还会更新每个 in MDS 秩的 InoTables,以指示任何写入的 inode 号码现在正在使用中。在简单的情况下,这将导致完全有效的后端存储状态。
警告
不能保证后端存储的最终状态是自洽的,之后需要进行在线 MDS 擦洗。日志内容不会被此命令修改。在恢复了您可以恢复的内容之后,单独截断日志。
截断日志
使用以下形式的命令截断任何损坏或 MDS 无法重放的日志
cephfs-journal-tool [--rank=<fs_name>:{mds-rank|all}] journal reset --yes-i-really-really-mean-it
当文件系统有或曾经有多个活动 MDS 守护程序时,使用 --rank 选项指定文件系统和 MDS 秩。
警告
重置日志将导致元数据丢失,除非日志数据已通过其他方式(例如 recover_dentries)提取。重置日志可能会在数据池中留下孤立对象,并可能导致重新分配已写入的 inode,从而导致文件系统出现故障(错误等)。
MDS 表格清除
并非所有 MDS 表格都必须在恢复过程中重置。如果相应的 RADOS 对象丢失(例如,由于某些 PG 丢失)或者表格与 RADOS 后端中存储的元数据不一致,则需要重置 MDS 表格。要检查丢失的表格对象,请运行以下形式的命令
会话表
rados -p <metadata-pool> stat mds0_sessionmap
Inode 表
rados -p <metadata-pool> stat mds0_inotable
快照表
rados -p <metadata-pool> stat mds_snaptable
注意
sessionmap 和 inotable 对象是按 MDS 秩划分的(对象名称带有秩号 - mds0_inotable、mds1_inotable 等)。
即使表对象存在,它也可能与 RADOS 后端中存储的元数据不一致。然而,如果元数据确实不一致或损坏,在不使文件系统在线的情况下很难检测到不一致性。在这种情况下,MDS 会将自己标记为 down:damaged。要重置单个表格,请运行以下形式的命令
会话表
cephfs-table-tool 0 reset session
SnapServer
cephfs-table-tool 0 reset snap
InoTable
cephfs-table-tool 0 reset inode
上述命令对特定 MDS 秩的表格进行操作。要对处于 in 状态的所有 MDS 秩进行操作,请将上述命令中的 MDS 秩替换为 all,如下所示
会话表
cephfs-table-tool all reset session
SnapServer
cephfs-table-tool all reset snap
InoTable
cephfs-table-tool all reset inode
注意
重置会话表后,重新挂载或重启所有 CephFS 客户端。
MDS 映射重置
当文件系统的 RADOS 内状态(即元数据池的内容)得到一定程度恢复后,可能需要更新 MDS 映射以反映元数据池的新状态。使用以下命令将 MDS 映射重置为单个 MDS
ceph fs reset <fs name> --yes-i-really-mean-it
运行此命令后,MDS 秩 0 以外的任何 RADOS 内状态都将被忽略。这意味着运行此命令可能会导致数据丢失。
fs reset 命令和 fs remove 命令的效果有所不同。fs reset 命令将秩 0 保持在 active 状态,以便下一个 MDS 守护程序在声明该秩时使用现有的 RADOS 内元数据。fs remove 命令将秩 0 保持在 creating 状态,这意味着磁盘上现有的根 inode 将被覆盖。运行 fs remove 命令将使任何现有文件成为孤立文件。
从丢失的元数据对象中恢复
根据哪些对象丢失或损坏,您可能需要运行额外的命令来重新生成对象的默认版本。
如果根 inode 或 MDS 目录 (~mdsdir) 丢失或损坏,请运行以下命令
根 inode(“/”和 MDS 目录)
cephfs-data-scan init
运行此命令通常是安全的,因为它会跳过生成根 inode 和 mdsdir inode(如果它们存在)。但是,如果这些 inode 损坏,则必须重新生成它们。可以通过尝试使文件系统重新在线来识别损坏(此时 MDS 将转换为 down:damaged,并附带一条适当的日志消息 [在 MDS 日志中] 指向加载根 inode 或 mdsdir inode 时可能出现的问题)。另一种方法是使用 ceph-dencoder 工具来解码 inode。这一步涉及更多。
最后,您可以根据数据池的内容重新生成丢失文件和目录的元数据对象。这是一个三阶段过程
扫描所有对象以计算 inode 的大小和 mtime 元数据
cephfs-data-scan scan_extents [<data pool> [<extra data pool> ...]]扫描每个文件的第一个对象以收集此元数据并将其注入元数据池
cephfs-data-scan scan_inodes [<data pool>]检查 inode 链接并修复发现的错误
cephfs-data-scan scan_links
如果数据池包含许多文件或非常大的文件,scan_extents 和 scan_inodes 命令可能需要很长时间。
要加快运行 scan_extents 或 scan_inodes 的过程,请运行多个工具实例
确定工作程序数量,并为每个工作程序传递一个范围 0-(worker_m - 1) 内的数字(即“零到 worker_m 减 1”)。
以下示例展示了如何同时运行四个工作程序
# Worker 0
cephfs-data-scan scan_extents --worker_n 0 --worker_m 4
# Worker 1
cephfs-data-scan scan_extents --worker_n 1 --worker_m 4
# Worker 2
cephfs-data-scan scan_extents --worker_n 2 --worker_m 4
# Worker 3
cephfs-data-scan scan_extents --worker_n 3 --worker_m 4
# Worker 0
cephfs-data-scan scan_inodes --worker_n 0 --worker_m 4
# Worker 1
cephfs-data-scan scan_inodes --worker_n 1 --worker_m 4
# Worker 2
cephfs-data-scan scan_inodes --worker_n 2 --worker_m 4
# Worker 3
cephfs-data-scan scan_inodes --worker_n 3 --worker_m 4
重要的是,确保所有工作程序都完成了 scan_extents 阶段,然后任何工作程序才能进入 scan_inodes 阶段。
完成元数据恢复过程后,您可能需要运行清理操作以删除恢复期间生成的辅助数据。使用以下形式的命令运行清理操作
cephfs-data-scan cleanup [<data pool>]
清理阶段可以运行多个实例以加快执行速度
# Worker 0
cephfs-data-scan cleanup --worker_n 0 --worker_m 4
# Worker 1
cephfs-data-scan cleanup --worker_n 1 --worker_m 4
# Worker 2
cephfs-data-scan cleanup --worker_n 2 --worker_m 4
# Worker 3
cephfs-data-scan cleanup --worker_n 3 --worker_m 4
注意
scan_extents、scan_inodes 和 cleanup 命令的数据池参数是可选的,通常工具能够自动检测池。不过,您可以覆盖此设置。scan_extents 命令要求指定所有数据池,但 scan_inodes 和 cleanup 命令仅要求您指定主数据池。
已知限制和陷阱
灾难恢复过程可能耗时且艰巨。恢复步骤必须按照上面详述的精确顺序执行,并格外小心,以确保清楚地理解每一步中的失败。您必须能够绝对确定是否可以安全地继续。如果您确信自己可以应对这些挑战,请在尝试灾难恢复之前研究此限制和陷阱列表
数据扫描命令无法估算其操作完成所需的时间。提供此类估算的功能正在开发中。请参阅 https://tracker.ceph.com/issues/63191 了解详细信息。
在 CephFS 客户端开始使用文件系统之前,进行恢复后进行文件系统擦洗非常重要。
一般来说,我们不建议在出现故障时更改任何与 MDS 相关的设置(例如
max_mds)。灾难恢复目前是一个手动过程。有一个通过灾难恢复超级工具实现恢复自动化的计划。请参阅 https://tracker.ceph.com/issues/71804 了解详细信息。
一个众所周知的技巧(被一些社区用户使用)是在 MDS 由于日志过长而卡在
up_replay状态时使用灾难恢复过程(尤其是recover_dentries步骤)。在 MDS 重放日志花费较长时间时急于调用recover_dentries之前,请考虑尝试按照 恢复期间卡住 中详述的步骤加快日志重放速度。
使用备用元数据池进行恢复
警告
此过程尚未经过广泛测试。除非有充分理由不这样做,否则我们建议使用上面详述的恢复过程来恢复文件系统。应非常小心地执行此过程。
如果现有的 CephFS 文件系统损坏且无法运行,则可以创建一个新的元数据池,并尝试将损坏且无法运行的文件系统的元数据重新构建到新池中,同时保留旧元数据。这可用于进行更安全的恢复尝试,因为现有的元数据池不会被修改。
警告
在此过程中,多个元数据池将包含指向同一数据池的数据。必须极其小心,以避免在这种情况下更改数据池的内容。恢复完成后,存档或删除损坏的元数据池。
关闭现有文件系统,以防止对数据池进行任何进一步的修改。卸载所有客户端。卸载所有客户端后,使用以下命令将文件系统标记为失败
ceph fs fail <fs_name>注意
此处的
<fs_name>和下面指的是原始的、损坏的文件系统。创建一个恢复文件系统。此恢复文件系统将用于恢复损坏池中的数据。首先,文件系统将为其部署一个数据池。然后,您将把一个新的元数据池附加到新的数据池上。然后,您将把新的元数据池设置为由旧数据池支持。
ceph osd pool create cephfs_recovery_meta ceph fs new cephfs_recovery cephfs_recovery_meta <data_pool> --recover --allow-dangerous-metadata-overlay
注意
您可以在以后重命名恢复元数据池和文件系统。
--recover标志可防止任何 MDS 守护程序加入新的文件系统。为文件系统创建初始元数据
cephfs-table-tool cephfs_recovery:0 reset sessioncephfs-table-tool cephfs_recovery:0 reset snapcephfs-table-tool cephfs_recovery:0 reset inodecephfs-journal-tool --rank cephfs_recovery:0 journal reset --force --yes-i-really-really-mean-it使用以下命令从数据池重建元数据池
cephfs-data-scan init --force-init --filesystem cephfs_recovery --alternate-pool cephfs_recovery_metacephfs-data-scan scan_extents --alternate-pool cephfs_recovery_meta --filesystem <fs_name>cephfs-data-scan scan_inodes --alternate-pool cephfs_recovery_meta --filesystem <fs_name> --force-corruptcephfs-data-scan scan_links --filesystem cephfs_recovery注意
上述每个扫描过程都会扫描整个数据池。这可能需要很长时间。请参阅上一节了解如何将此任务分配给多个工作程序。
如果损坏的文件系统包含脏日志数据,则可以使用以下形式的命令进行恢复
cephfs-journal-tool --rank=<fs_name>:0 event recover_dentries list --alternate-pool cephfs_recovery_meta恢复后,某些恢复的目录将具有不正确的统计信息。确保参数
mds_verify_scatter和mds_debug_scatterstat设置为 false(默认值),以防止 MDS 检查统计信息ceph config rm mds mds_verify_scatterceph config rm mds mds_debug_scatterstat注意
验证配置是否未全局设置或使用本地
ceph.conf文件设置。允许 MDS 守护程序加入恢复文件系统
ceph fs set cephfs_recovery joinable true运行正向 scrub 来修复递归统计信息。确保您有一个正在运行的 MDS 守护程序并发出以下命令
ceph tell mds.cephfs_recovery:0 scrub start / recursive,repair,force建议您尽快从恢复文件系统迁移任何数据。在恢复文件系统运行时不要恢复旧文件系统。
注意
如果数据池也损坏,某些文件可能无法恢复,因为与其关联的回溯信息丢失了。如果任何数据对象丢失(由于数据池上丢失了放置组等问题),则恢复的文件将在丢失数据的位置包含空洞。