Ceph RBD删除后空间未释放?trash清理与对象回收实战指南

处理这种问题,我的第一反应是:先别急着扩容,也别怀疑删除操作失败。ceph df显示的空间没变化,十有八九是对象没被真正清掉,或者删除流程还没走完。标题里提到的“删除rbd的数据”,大概率是通过rbd rm或rbd trash系列命令完成的,但“删除”这个动作本身有好几层含义,每层没做彻底,都会让空间继续被占着。这篇文章就围绕我实际排查中的完整思路来写,从原理到命令,再到排障细节,尽量一次讲透。

1. 现象确认:空间没释放,卡在了哪个环节

先复现一下典型场景。你执行了类似这样的操作:

rbd rm --pool mypool myimage

命令输出正常,rbd ls mypool里也看不到这个镜像了。但执行ceph df一看,USED那一列纹丝不动,RAW USED 也没有什么变化。这时候很多人会以为删除失败或者有bug,其实大概率是删除流程没有真正走完。

在动手排查前,建议先把下面三条命令跑一遍,确认当前状态:

ceph df ceph osd df tree rbd trash ls --pool mypool --all

重点看rbd trash ls --all的输出。--all会把所有处于延迟删除状态、以及已经被删除但还未被清理的RBD镜像都列出来。如果这里能看到myimage,那问题就非常明确了:删除操作只是把镜像挪进了trash,并没有触发真正的对象清理。

为什么会这样?这是Ceph从Luminous版本开始引入的机制变化。早期版本执行rbd rm是真的直接删除所有对象,但这种方式有风险:一旦镜像正被客户端挂载使用,或者有快照、克隆依赖,删除就会报错甚至导致数据不一致。所以后来的设计改成两步走:

  1. 先标记删除,把镜像移入trash
  2. 后台异步执行清理

这个设计本身是为了安全,但也让很多刚上手Ceph的人困惑——明明“删了”,空间却没回来。

另外一个常见场景是误用了rados rm直接删对象。有些人会直接进pool里摸对象,然后执行rados rm删除看起来像镜像数据块的对象。这种操作不会更新RBD的元数据,trash里没有任何记录,但对象确实少了,最终会留下一堆孤儿对象,反而更难清理。后面我会单独讲孤儿对象的处理。

所以第一步的确认工作,就是把“删除方式”和“当前trash状态”弄清楚。你可以简单记一张对照表:

操作方式空间立即释放?是否进入trash后续需要处理
rbd rm(镜像无快照、无clone)通常延迟释放是执行 trash purge
rbd rm(镜像有快照)否是清理快照链后再purge
rbd rm(镜像有clone子镜像)否是先处理依赖,再purge
rados rm 手动删对象部分释放否需要孤儿扫描清理
rbd trash rm 手动清理是否无需额外操作

这张表基本上覆盖了我日常遇到的所有“空间没释放”的场景。你可以对照自己的操作路径,先确定属于哪一类,再往下走。

2. 核心机制:trash、延迟删除和依赖链

要理解为什么空间没释放,不能只停留在命令层面。Ceph RBD的删除链路设计,本质上是在“安全”和“即时回收”之间做取舍。我拆成几个关键机制来逐个说明。

2.1 trash机制:删除不是销毁

rbd rm执行后,镜像不会立刻被销毁,而是被打上“已删除”标记,移入pool的trash命名空间里。这个设计模仿了文件系统回收站的概念,目的是防止误删。rbd trash ls能看到这些镜像,它们的状态可能是removing、watched或者watcher。

这里有一个关键参数:rbd_trash_remove_delay。这个参数控制镜像进入trash后,至少要等多少秒才能被真正清理。默认值在某些版本里是0,但生产环境里很多团队会设置成1小时甚至24小时,用来给误操作留出恢复窗口。如果你在ceph config dump里看到了类似配置:

ceph config get client.rbd rbd_trash_remove_delay

输出值如果大于0,那即使你手动执行rbd trash purge,也需要等延迟时间过了之后才会真正清理。这个是很多排障过程中被忽略的点,明明命令执行了,空间却纹丝不动,就是因为在等待期。

2.2 延迟清理和watch状态

第二个机制是watch状态。RBD块设备在被客户端挂载时,客户端会对镜像维持一个watch通知机制。如果镜像正在被某个客户端使用,OSD层面上存在对应watcher,此时执行删除会进入“等待watcher断开”的状态。你会看到trash里的镜像状态变成watched。

这意味着,即使你执行了rbd trash purge,如果没有先断开客户端的连接(比如卸载文件系统、停止虚拟机),清理动作也会一直等下去。我在生产环境里踩过这个坑:有个云平台的虚拟机还在运行,底层RBD已经被管理员手动删掉了,结果trash清理持续了好几天,磁盘空间一直在告警。

2.3 快照链和clone依赖

第三个机制是快照和克隆。RBD创建快照以后,快照对象和当前镜像对象之间是有引用关系的。删除镜像时,如果快照还在,系统不会真正释放对象空间,因为快照还引用着这些对象。

更麻烦的是clone依赖。假设镜像A创建了快照snap_A,然后从这个快照clone出镜像B。这时候B是A的child,A的快照被B引用。删除A时,系统必须保证B仍然能读取A的快照数据。结果就是:A虽然被删除了,但A的快照对象会被保留,空间自然无法释放。

我曾经维护过一个测试环境,开发同事批量创建了一批克隆虚拟机,后来虚拟机删除了,但父镜像始终无法release空间,原因就是子镜像的引用关系没有解除。最终需要手动检查并解除clone关系,才算真正释放了空间。

2.4 理解object与PG的关系

最后要说一下底层存储模型。RBD镜像的每个数据块在Ceph中对应一个object,这些object根据pool的PG数量分布到各个OSD上。删除镜像的本质,是把这些object一个个删除掉。

但OSD删除对象后,对应的空间不会立刻返回“可用”。Ceph的OSD采取journaling和日志先写机制,删除操作需要完成日志提交、PG更新、副本同步等步骤。在大规模集群里,一次删除大量对象会产生很高的IO负载,如果OSD的Backfill或Recovery正在进行,这些删除操作会被延后。所以有时候你会看到,trash已经清空了,但空间还在缓慢变化,这就是后台在慢慢处理对象删除。

3. 实践操作:从trash清理到对象级检查

确认机制之后,就可以动手解决了。下面这组操作顺序,是我在多个集群上验证过的“标准排障流程”,用它基本能处理掉90%以上的“空间未释放”问题。

3.1 第一步:清理trash

先列出trash里的内容:

rbd trash ls --pool mypool --all

如果发现有镜像,先用rbd trash rm指定彻底删除某个镜像:

rbd trash rm --pool mypool myimage

如果你确定当前trash里所有镜像都不需要了,直接purge整个pool的trash:

rbd trash purge --pool mypool

注意,purge会删除该pool下trash里的所有镜像,操作前一定再确认一遍列表。

执行完后,立刻再看一遍trash列表,确认清空:

rbd trash ls --pool mypool --all

此时如果ceph df的空间开始变化,那就说明问题上文在第一步就解决了。

3.2 第二步:检查快照和clone

如果trash已经清空了,空间还是没释放,很大概率存在快照或clone依赖。

先查看pool下所有镜像:

rbd ls --pool mypool --long

对每一个镜像检查它的快照列表和children:

rbd snap ls --pool mypool myimage rbd children --pool mypool myimage --snap snapname

rbd children会列出依赖这个快照的所有子镜像。如果存在子镜像,你需要先处理子镜像,或者解除它们对这个快照的依赖,然后才能删除快照。

确认快照可以删后,执行:

rbd snap rm --pool mypool myimage@snapname

3.3 第三步:处理watcher

如果trash里的镜像状态一直是watched,先确认哪个客户端还在连接:

rbd status --pool mypool myimage

输出里会显示watcher的ip和进程。这时候有两个选择:

  • 正常卸载客户端(推荐):确认业务侧已经不再使用该设备,从虚拟机/容器里卸载或断开连接,watcher会自动消失。
  • 强制丢弃watcher(危险):只有当你非常确定客户端已挂死、不会再有IO时,才建议执行:
rbd watch reset --pool mypool myimage

这个命令会强制清除所有watcher,让删除流程继续。但如果有客户端实际上还在写数据,会造成数据损坏,务必谨慎。

3.4 第四步:定位孤儿对象

trash、快照、watcher都处理完了,空间还是没释放,那就要怀疑是不是有孤儿对象占着空间。这些对象可能是历史上用rados rm直接删对象造成的,也可能是一次异常中断的删除操作留下的。

查pool里的对象情况:

rados ls --pool mypool | head -n 20 rados du --pool mypool

rados du会给出每个对象的size信息,有助于判断哪些对象占了大量空间。

找到疑似孤儿对象后,先确认它不属于任何已知RBD镜像:

rados ls --pool mypool | grep -v rbd_data rados ls --pool mypool | grep rbd_data

RBD的块数据对象命名通常带有rbd_data前缀。如果一批rbd_data对象对应的镜像已经不存在了,那它们就是孤儿对象。对孤儿对象可以用以下命令删除:

rados rm -p mypool <object_name>

但这里我强烈建议不要手动一个个删,低效且容易误删。更稳妥的方式是用scrub机制让OSD自动清理:

ceph pg scrub <pgid>

或者对pool做一次深度scrub:

ceph osd pool scrub mypool

scrub会把内存中的对象信息和OSD上的实际对象做比对,发现多余对象后触发清理。这个方法比手动删更安全,不会破坏正常的RBD元数据。

4. 验证空间是否释放:别被ceph df的数字骗了

很多人反映,trash也清了,快照也删了,为什么ceph df看到的USED还是没变化?这里要搞清楚ceph df显示的数据层次。

4.1 区分总容量和实际使用

ceph df的输出有两大部分:GLOBAL行和POOL行。GLOBAL里的RAW USED表示整个集群所有OSD实际占用磁盘的大小,包括所有pool的对象、副本、内部元数据等。POOL行里的USED则只统计pool内的逻辑对象大小,不包含副本。

删除RBD镜像后,pool的USED会先下降,但RAW USED可能延迟变化。原因是OSD在完成删除对象操作后,还可能有一些额外开销,比如日志、内部元数据更新、wal文件等。这些不会瞬间全部反映到RAW USED里。

如果你想看更实时的变化,可以用:

ceph osd df tree

这个命令能看到每个OSD的具体使用量。删除操作触发后,你可以观察对应OSD的USED值是否在慢慢回落。如果某个OSD的USED始终不变,且trash和快照都已经处理完,那有可能存在PG分布不均的问题,或者OSD的删除队列被卡住了。

4.2 估算预期释放的空间

在删除前,可以通过镜像的size和快照数量来估算预期释放空间。

rbd info --pool mypool myimage

rbd info里的size是逻辑容量,并非实际占用。实际占用取决于镜像内部写入了多少数据块,以及副本数。估算公式是:

实际释放空间 ≈ 镜像实际数据量 × 副本数

比如一个镜像逻辑大小100G,实际写入50G,pool是3副本,则释放约150G。如果镜像包含多个快照,每个快照都有自己的对象,那要考虑快照占用的独立空间。

这里有一个容易踩坑的点:Ceph的压缩功能。如果pool启用了压缩(通常基于zstd),写进去的数据在底层可能小于逻辑数据量。这种情况下,释放的空间会比预期少。不要因此怀疑操作失败,先做数据量对比再下结论。

4.3 最终确认命令

排障结束后,我通常用一条组合命令做最终确认:

ceph df | grep mypool rbd trash ls --pool mypool --all rados du --pool mypool | tail -n 5

三条命令的输出应该同时满足:

  • trash列表为空
  • pool的USED明显下降
  • rados du的统计和pool USED基本一致

如果满足这些条件,那空间释放问题就是真正解决了。

5. 常见问题与避坑心得

这个主题我在群里和社区里被问过很多次,整理几个典型问题,当作排障速查表用。

5.1 为什么rbd trash purge执行了还是一样?

最常见原因就是延迟删除配置。先确认:

ceph config get client.rbd rbd_trash_remove_delay

如果值大于0,等到足够时间后空间才会释放。另外,如果trash里的镜像仍被watch,purge会跳过它,需要先处理watcher。

5.2rbd rm命令卡住不动?

这种情况通常发生在镜像正被使用,或者有大量快照。执行rbd rm时它会尝试停掉watch并通知所有客户端,如果客户端无响应,命令就会一直等。这时候先在trash里看镜像状态:

rbd trash ls --pool mypool

状态显示watched,就按前面说的处理watcher;显示removing,则检查后台是否有删除进程在跑:

ceph tell osd.* ceph_osd_pg_scrub

如果确认删除进程确实卡死,可以尝试重启相关OSD进程,让对象删除请求重新调度。不过在生产环境操作OSD前,一定要确认业务容忍度,优先在低峰窗口执行。

5.3 为什么删除后空间不升反降?

这种情况我也遇到过,通常不是删除导致,而是删除操作触发了大量对象的副本平衡。删除对象后,OSD会重新平衡分布,可能触发数据迁移或者backfill,期间磁盘写入会增加,导致USED看起来反而升高了。等平衡完成,空间才会正常回落。所以看到短时间内的上升,不用慌,观察一段时间。

5.4 关于对象命名空间的坑

RBD镜像在pool里不仅有数据对象,还有元数据对象。rbd ls看不到的隐藏命名空间里有rbd_directory、rbd_info、rbd_header等对象。手动清理时如果误删了这些元数据对象,RBD镜像会直接损坏。所以再次强调:不要手动用rados去删rbd_开头的对象。

5.5 恢复误删的RBD

trash机制的存在,让误删恢复成了可能。只要镜像还在trash里且未被purge,就可以通过以下命令恢复到原位置:

rbd trash restore --pool mypool myimage --image newname

这个操作实际执行过,恢复后镜像数据完整可用。这也是为什么我不建议你一上来就purge,如果只是确认误删,先restore比重建虚拟机恢复数据要靠谱得多。

6. 遗留细节:pool级配置和长期优化建议

处理完当前问题后,建议从机制层面做一些长期调整,减少未来再遇到同类问题的概率。

对于测试环境或临时项目使用的pool,可以将延迟删除时间设置为0,让删除操作立即清理:

ceph config set client.rbd rbd_trash_remove_delay 0

对于生产环境,建议保留延迟删除时间,比如1小时或24小时。误操作时有后悔药可以吃,不差这几个小时的空间。同时把trash巡检加入日常监控脚本,定期检查是否有堆积的trash项目。

对克隆使用比较多的场景,建议在删除父镜像前,先产出完整的clone依赖清单,并制定逐层删除计划。这可以通过脚本实现,一句话总结就是:先删子、再删父、最后清trash。

好在Ceph的这套机制都是从数据安全角度出发的,虽然让我多排查了很多次,但至少没出现过误删无法恢复的事故。以我个人维护集群的经验,处理这类问题最大的成本不是命令不会敲,而是定位不到阻塞点。只要按照trash → watch → 快照 → 孤儿对象这条链路走,大部分问题都能快速收尾。

相关新闻

艺术院校计算机基础课教改:分层教学与案例驱动实践

艺术院校计算机基础课教改:分层教学与案例驱动实践

简介&#xff1a;这份资源是面向艺术类院校计算机基础课教师与教学研究者的教学探讨文档&#xff0c;围绕艺术院校学生文化基础薄弱、偏重感性思维、喜欢动手却抵触理论等特点&#xff0c;分析计算机基础课程在专业设置、教学目标与应用方式上的特殊性&#xff0c;并针对学生水…

2026/10/22 11:53:06 阅读更多 →
艺术手作项目全流程:从灵感立项到量产售卖的实操指南

艺术手作项目全流程:从灵感立项到量产售卖的实操指南

开始做手作项目之前&#xff0c;我一直被一个问题卡住&#xff1a;为什么同样一堆材料&#xff0c;别人做出来像艺术品&#xff0c;我做出来只能算手工活。后来我想明白一件事——真正值钱的从来不是某个单一技法&#xff0c;而是“艺术”与“工艺”的串联能力。artcraft 这个词…

2026/10/22 12:26:09 阅读更多 →
计及光伏逆变器快速无功响应的配电网分布式电源优化配置

计及光伏逆变器快速无功响应的配电网分布式电源优化配置

做配电网规划这些年&#xff0c;我见过太多这样的case&#xff1a;设计院把光伏接入方案算得清清楚楚&#xff0c;容量、位置、潮流全部满足标准&#xff0c;结果一到夏天的中午&#xff0c;10千伏馈线电压直接冲到107%&#xff0c;逆变器纷纷离网&#xff0c;调度只能让光伏降…

2026/10/22 12:26:23 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年&#xff0c;我大部分时间都在跟浏览器标签页打交道&#xff0c;直到第一次把桌面应用跑起来&#xff0c;才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词&#xff0c;最开始是在某段时间频繁出现在同事的讨论里&#xff0c;一个用HTML…

2026/10/22 10:18:38 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介&#xff1a;亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档&#xff0c;主要面向智能锁安装人员、终端用户及售后维护者&#xff0c;帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件&#xff0c;大小4.37MB&#xff0c;内容结构清晰&#xff…

2026/10/22 11:01:53 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统&#xff0c;整车要求空载跑到8m/s&#xff0c;电机转速已经拉到额定点&#xff0c;驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令&#xff0c;转速纹丝不动&#xff0c;三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/22 9:44:47 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年&#xff0c;用它写过嵌入式驱动、做过游戏服务端&#xff0c;也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词&#xff0c;我其实挺感慨的——这门语言的难点从来不是语法多&#xff0c;而是知识点之间的耦合太深…

2026/10/22 10:42:00 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介&#xff1a;亚太天能T109滑盖智能锁产品说明书以PDF格式发布&#xff0c;适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开&#xff0c;先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能&#xff0c;再给出完整安装步骤&…

2026/10/22 10:40:08 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历&#xff1a;翻开源码注释、论文摘要或者一份专业报告&#xff0c;每个字都认识&#xff0c;连在一起却像天书。想找人聊聊&#xff0c;身边要么没人懂&#xff0c;要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型&#xff0c;几秒钟之后&a…

2026/10/22 10:56:37 阅读更多 →

日新闻

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/22 1:47:45 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/21 21:32:28 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/22 5:12:39 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 21:50:56 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 21:51:55 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 16:24:48 阅读更多 →