注意

本文档适用于 Ceph 的开发版本。

故障排除

慢/卡顿的操作

有时CephFS操作会挂起。排查问题的第一步是找到导致操作挂起的问题。问题可能出现在三个地方

  1. 在客户端

  2. 在MDS中

  3. 连接客户端和MDS的网络中

首先,使用慢请求 (MDS)中的过程来确定客户端是否有卡顿的操作,或者MDS是否有卡顿的操作。

转储MDS缓存。MDS缓存的内容将用于诊断问题的性质。运行以下命令转储MDS缓存

ceph daemon mds.<name> dump cache /tmp/dump.txt

注意

不受systemd控制的MDS服务将文件dump.txt转储到运行MDS的机器上。受systemd控制的MDS服务将文件dump.txt转储到MDS容器中的一个tmpfs。使用nsenter(1)来定位dump.txt或指定另一个系统范围的路径。

如果MDS上设置了高日志级别,则dump.txt预计将包含诊断和解决导致CephFS操作挂起问题所需的信息。

慢请求 (MDS)

通过MDS主机运行以下命令,通过管理套接字列出当前操作

ceph daemon mds.<name> dump_ops_in_flight

识别卡住的命令并检查它们卡住的原因。通常,最后一个“事件”是尝试获取锁,或将操作发送到MDS日志。如果它正在等待OSD,请修复它们。

如果操作卡在特定的inode上,那么客户端可能持有功能,阻止其他客户端使用。这种情况可能是由于客户端试图刷新脏数据造成的,但也可能是因为您在CephFS的分布式文件锁代码(文件“能力”[“caps”]系统)中遇到了错误。

如果您已确定命令由于能力代码中的错误而卡住,请重新启动MDS。重新启动MDS可能会解决问题。

如果MDS上没有报告慢请求,并且没有迹象表明客户端行为异常,那么要么是客户端有问题,要么是客户端的请求没有到达MDS。

恢复期间卡顿

卡在up:replay

如果您的MDS卡在up:replay状态,那么日志可能非常长。MDS_HEALTH_TRIM集群警告的存在可能表明MDS在修剪其日志时尚未赶上。非常大的日志可能需要数小时来处理。无法避免这种情况,但您可以采取一些措施来加快处理速度

通过将MDS调试级别降低到0来暂时禁用MDS调试日志。即使使用默认设置,MDS也会记录一些消息到内存中,以防遇到致命错误时进行转储。您可以运行以下命令关闭所有日志记录

ceph config set mds debug_mds 0
ceph config set mds debug_ms 0
ceph config set mds debug_monc 0

请记住,当您将debug_mdsdebug_msdebug_monc设置为0时,如果MDS失败,将没有调试信息可用于确定发生致命错误的原因。如果您可以计算出up:replay何时完成,请在进入下一个状态之前恢复这些配置

ceph config rm mds debug_mds
ceph config rm mds debug_ms
ceph config rm mds debug_monc

加速重放后,计算MDS何时完成重放。检查日志重放状态

$ ceph tell mds.<fs_name>:0 status | jq .replay_status
{
  "journal_read_pos": 4195244,
  "journal_write_pos": 4195244,
  "journal_expire_pos": 4194304,
  "num_events": 2,
  "num_segments": 2
}

journal_read_pos达到journal_write_pos时,重放完成。在重放期间,写入位置不会改变。跟踪读取位置的进度以计算预期的完成时间。当重放日志的操作超过30秒时,MDS会发出MDS_ESTIMATED_REPLAY_TIME警告。警告消息包含日志重放完成的预计时间

mds.a(mds.0): replay: 50.0446% complete - elapsed time: 582s, estimated time remaining: 581s

避免恢复障碍

恢复文件系统时,请执行以下操作

  • 拒绝所有客户端重新连接。 将所有现有CephFS会话列入黑名单,导致所有挂载挂起或不可用

    ceph config set mds mds_deny_all_reconnect true
    

    MDS激活后,请记住撤消此操作。

    注意

    这不会阻止新会话连接。使用refuse_client_session文件系统设置来阻止新会话连接到CephFS。

  • 延长MDS心跳宽限期。 这样做会使系统避免在操作期间MDS“卡住”时替换它。有时MDS的恢复可能涉及比预期(从程序员的角度来看)更长的操作。当恢复完成时间已经比正常情况长时,这种情况更有可能发生(如果您正在阅读本文档,这很可能是您遇到的情况)。通过运行以下命令并延长心跳宽限期来避免不必要的替换循环

    ceph config set mds mds_heartbeat_grace 3600
    

    注意

    这会使MDS继续向监视器发送信标,即使其内部“心跳”机制在一小时内没有重置(没有跳动)。过去,这是通过mds_beacon_grace监视器设置实现的。

  • 禁用打开文件表预取。 在正常情况下,MDS在恢复期间会预取目录内容,以此来预热其缓存。在长时间恢复期间,缓存可能已经很热而且很大。如果缓存已经很热且很大,这种预取是不必要的,甚至可能是不受欢迎的。通过运行以下命令禁用打开文件表预取

    ceph config set mds mds_oft_prefetch_dirfrags false
    
  • 关闭客户端。 重新连接到新up:active MDS的客户端可能会在文件系统刚开始运行时对其造成新的负载。这通常是不希望的。在允许客户端连接到文件系统并恢复正常工作负载之前,通常需要进行维护。例如,如果恢复由于重放读取非常大的日志所花费的时间而持续很长时间,则建议加快日志修剪。

    客户端会话可以手动拒绝,或使用refuse_client_session可调参数,如下面的命令所示

    ceph fs set <fs_name> refuse_client_session true
    

    此命令的效果是阻止客户端与MDS建立新会话。

  • 不要调整max_mds。 在故障排除和恢复期间修改文件系统设置变量max_mds可能看起来是个好主意,但可能不是。修改max_mds可能会进一步破坏集群的稳定性。如果在此类情况下必须更改max_mds,请运行带有确认标志(--yes-i-really-mean-it)的命令来更改max_mds

  • 关闭异步清除线程。 卷插件会生成异步清除已删除或已删除子卷的线程。在故障排除或恢复期间,可以通过运行以下命令禁用这些清除线程

    ceph config set mgr mgr/volumes/pause_purging true
    

    要恢复清除,请运行以下命令

    ceph config set mgr mgr/volumes/pause_purging false
    
  • 关闭异步克隆线程。 卷插件会生成异步克隆子卷快照的线程。在故障排除或恢复期间,可以通过运行以下命令禁用这些克隆线程

    ceph config set mgr mgr/volumes/pause_cloning true
    

    要恢复克隆,请运行以下命令

    ceph config set mgr mgr/volumes/pause_cloning false
    

加速MDS日志修剪

MDS_HEALTH_TRIM警告表示MDS日志已变得过大。当MDS日志过大时,使用mds_tick_interval可调参数来修改“MDS心跳间隔”。“心跳”间隔驱动MDS中的各种维护活动,修改该间隔将通过确保更频繁地修剪MDS日志来减小其大小。

修改mds_tick_interval时,请确保没有显着的文件系统负载。有关减少CephFS负载的方法,请参阅避免恢复障碍

此设置仅影响处于up:active状态的MDSes。MDS在恢复期间不会修剪其日志。

运行以下命令修改mds_tick_interval可调参数

ceph config set mds mds_tick_interval 2

RADOS健康状况

如果CephFS元数据或数据池的一部分不可用,并且CephFS没有响应,则可能表明RADOS本身不健康。

在尝试查找CephFS中的任何问题之前,请解决RADOS的问题。请参阅RADOS故障排除文档

MDS

运行ceph health命令。slow requests are blocked消息表示MDS中存在任何挂起的操作。

显示failing to respond的消息表示客户端未能响应。

以下列表详细说明了操作挂起的潜在原因

  1. 系统过载。系统过载最可能的原因是活动文件集大于MDS缓存。

    如果您有额外的RAM,请增加mds_cache_memory_limit。特定的可调参数mds_cache_memory_limitMDS缓存大小中讨论。在对mds_cache_memory_limit可调参数进行任何修改之前,请完整阅读MDS缓存配置部分。

  2. 存在较旧的(行为不当的)客户端。

  3. 存在底层RADOS问题。请参阅RADOS故障排除文档

否则,您可能发现了一个新错误,应该报告给开发人员!

ceph-fuse调试

ceph-fuse是CephFS内核驱动程序的替代方案,用于在用户空间中挂载CephFS文件系统。ceph-fuse支持dump_ops_in_flight。使用以下命令转储正在进行的ceph-fuse操作以供检查

请参阅使用FUSE挂载CephFS文档。

调试输出

要从ceph-fuse获取更多调试信息,请在前台列出当前操作,同时记录到控制台(-d),启用客户端调试(--debug-client=20),并为发送的每条消息启用打印(--debug-ms=1)。

ceph daemon -d mds.<name> dump_ops_in_flight --debug-client=20 --debug-ms=1

如果您怀疑潜在的监视器问题,请通过运行以下形式的命令同时启用监视器调试(--debug-monc=20

ceph daemon -d mds.<name> dump_ops_in_flight --debug-client=20 --debug-ms=1 --debug-monc=20

内核挂载调试

诊断和修复内核客户端问题的第一步是确定问题出在内核客户端还是MDS中。如果内核客户端本身损坏,损坏的证据将存在于内核环缓冲区中,可以通过运行以下命令进行检查

dmesg

找到相关的内核状态。

慢请求

不幸的是,内核客户端不提供管理套接字。但是,如果客户端上的内核启用了debugfs,则可以使用类似于管理套接字的接口。

/sys/kernel/debug/ceph/中找到一个名称类似于28f7427e-5558-4ffd-ae1a-51ec3042759a.client25386880的文件夹。该文件夹包含可用于诊断慢请求原因的文件。使用cat查看其内容。

这些文件描述如下。对于诊断慢请求最有用的是mdsc(当前对MDS的请求)和osdc(当前对OSD的正在进行的IO操作)文件。

  • bdi: 关于Ceph系统(脏块、写入等)的BDI信息

  • caps: 内存中和已使用的文件“caps”结构计数

  • client_options: 转储提供给CephFS挂载的选项

  • dentry_lru: 转储当前内存中的CephFS目录项

  • mdsc: 转储当前对MDS的请求

  • mdsmap: 转储当前的MDSMap世代和MDSes

  • mds_sessions: 转储当前与MDSes的会话

  • monc: 转储监视器中的当前映射,以及持有的任何“订阅”

  • monmap: 转储当前监视器映射世代和监视器

  • osdc: 转储当前对OSD的正在进行的IO操作(即文件数据IO)

  • osdmap: 转储当前的OSDMap世代、池和OSD

如果数据池处于NEARFULL状态,则内核CephFS客户端将切换到同步写入。同步写入非常慢。

断开连接+重新挂载的文件系统

由于CephFS具有“一致性缓存”,当网络连接长时间中断时,MDS会强制逐出(并列入黑名单)集群中的客户端。发生这种情况时,内核客户端无法安全地写回脏(缓冲)数据,这会导致数据丢失。但是:请注意,这种行为是适当的,并且遵循POSIX语义。客户端必须重新挂载才能再次访问文件系统。这是默认行为,但可以通过recover_session挂载选项覆盖。请参阅“mount.ceph”手册页的“选项”部分

如果dmesg的输出包含以下内容,则您处于这种情况

[Fri Aug 15 02:38:10 2025] ceph: mds0 caps stale
[Fri Aug 15 02:38:28 2025] libceph: mds0 (2)XXX.XX.XX.XX :6800 socket closed (con state OPEN)
[Fri Aug 15 02:38:28 2025] libceph: mds0 (2)XXX.XX.XX.XX:6800 session reset
[Fri Aug 15 02:38:28 2025] ceph: mds0 closed our session
[Fri Aug 15 02:38:28 2025] ceph: mds0 reconnect start
[Fri Aug 15 02:38:28 2025] ceph: mds0 reconnect denied

挂载

挂载5错误

mount 5错误表示MDS服务器滞后或MDS服务器崩溃。

确保至少有一个MDS正在运行,并且集群处于active + healthy状态。

挂载12错误

带有消息cannot allocate memory的挂载12错误表示Ceph客户端版本和Ceph存储集群版本之间存在版本不匹配。使用以下命令检查版本

ceph -v

如果Ceph客户端版本低于Ceph集群版本,请升级客户端

sudo apt-get update && sudo apt-get install ceph-common

如果这未能解决问题,请卸载、自动清理和自动删除ceph-common软件包,然后重新安装它以确保您拥有最新版本。

动态调试

CephFS内核驱动程序的动态调试允许启用或禁用调试日志记录。内核驱动程序日志写入内核环缓冲区,可以使用dmesg(1)实用程序进行检查。默认情况下禁用调试日志记录,因为启用调试日志记录可能导致系统变慢和I/O吞吐量下降。

对CephFS模块启用动态调试。

请参阅: https://github.com/ceph/ceph/blob/master/src/script/kcon_all.sh

注意:运行上述脚本会为CephFS内核驱动程序、libceph和内核RBD模块启用调试日志记录。要为特定组件(例如,CephFS内核驱动程序)启用调试日志记录,请运行以下形式的命令

echo 'module ceph +p' > /sys/kernel/debug/dynamic_debug/control

要禁用调试日志记录,请运行以下形式的命令

echo 'module ceph -p' > /sys/kernel/debug/dynamic_debug/control

内存日志转储

当日志级别设置为小于10时,可以通过设置mds_extraordinary_events_dump_interval来转储内存日志。mds_extraordinary_events_dump_interval是发生异常事件时转储最近内存日志的间隔(秒)。

异常事件包括以下内容

  • 客户端逐出

  • 未收到监视器的信标ACK

  • 内部心跳丢失

内存日志转储默认禁用。这可以防止生产环境默认情况下出现日志文件膨胀。

运行以下两个命令以启用内存日志转储

  1. ceph config set mds debug_mds <log_level>/<gather_level>
    

    log_level设置为小于10的值。将gather_level设置为大于10的值。当这两个值都设置后,内存日志转储即启用。

  2. ceph config set mds mds_extraordinary_events_dump_interval <seconds>
    

    启用内存日志转储后,MDS会每隔mds_extraordinary_events_dump_interval秒检查是否有异常事件发生。如果发生任何异常事件,MDS会将包含相关事件详细信息的内存日志转储到Ceph MDS日志中。

注意

当设置了更高的日志级别(log_level大于或等于10)时,没有理由转储内存日志。较低的收集级别(gather_level小于10)不足以收集内存日志。这意味着debug_mds中日志级别大于或等于10或收集级别小于10会阻止启用内存日志转储。在这种情况下,如果发生故障,您必须在启用上述命令之前将mds_extraordinary_events_dump_interval的值重置为0

通过运行以下命令禁用内存日志转储

ceph config set mds mds_extraordinary_events_dump_interval 0

升级后文件系统无法访问

注意

您可以通过在升级前运行此过程来避免operation not permitted错误。截至2023年5月,似乎这里讨论的operation not permitted错误发生在Nautilus(含)之后的升级中。

如果

您拥有由ceph fs new命令创建(意味着它们不是使用默认值创建的)数据和元数据池的CephFS文件系统

或者

您拥有现有的CephFS文件系统,并且正在升级到Nautilus之后的主要新版Ceph

那么

为了使文档中说明的ceph fs authorize...命令按文档所述运行(并避免在进行文件I/O或类似的安全相关问题时,所有用户除client.admin用户外都出现“操作不允许”错误),您必须首先运行

ceph osd pool application set <your metadata pool name> cephfs metadata <your ceph fs filesystem name>

ceph osd pool application set <your data pool name> cephfs data <your ceph fs filesystem name>

否则,当OSD收到读取或写入数据(不是目录信息,而是文件数据)的请求时,它们将不知道要查找哪个Ceph文件系统名称。池名称也是如此,因为主要版本中的“默认值”本身已从

data pool=fsname
metadata pool=fsname_metadata

更改为

data pool=fsname.data and
metadata pool=fsname.meta

所有挂载都使用client.admin的任何设置都没有遇到这个问题,因为admin密钥提供了全面的权限。

一个临时的解决方案是将挂载请求更改为“client.admin”用户及其关联的密钥。一个不那么极端但半解决的方案是将用户的osd能力更改为仅caps osd = "allow rw"并删除tag cephfs data=....

禁用卷插件

在某些情况下,可能需要禁用卷插件以防止其余Ceph集群受到损害。有关详细信息,请参阅:禁用卷插件

报告问题

如果您确定了特定问题,请尽可能详细地报告。特别重要的信息

  • 客户端和服务器上安装的Ceph版本

  • 您是使用内核客户端还是FUSE客户端

  • 如果您使用的是内核客户端,内核版本是多少?

  • 有多少客户端参与,进行何种类型的工作负载?

  • 如果系统“卡顿”,是影响所有客户端还是只有一个客户端?

  • 任何ceph健康消息

  • Ceph日志中因崩溃产生的任何回溯

如果您确定找到了错误,请在错误跟踪器上提交。对于更一般的问题,请写信给ceph-users邮件列表

由 Ceph 基金会为您呈现

Ceph 文档是由非营利性 Ceph 基金会 资助和托管的社区资源。如果您希望支持这项工作和我们的其他努力,请考虑 立即加入