删除ceph挂载卷中的数据后ceph空间没有释放


群晖卸载docker删除了docker文件夹 群晖删掉文件还占空间_ceph

有一个集群的ceph的存储空间被k8s的pod占满了,客户也不愿意扩容。现在就只能看可不可以删除一些不用的文件来释放一些存储空间,发现mysql占用的数据比较大,然后清理快40G的binlog,在容器中通过df -h查看已经是减少的了。但ceph df查看的使用率并没有变化,就很懵比~。由此引发了一些思考

文件系统是怎么删除文件的呢?

删除文件的过程:

以/var/log/messages这个文件为例,删除messages这个文件的过程大致如下:

  1. 找到/var/log/messages所在的inode
  2. 删除/var/log目录上有关messages的条目
  3. 空索引中/var/log/messages对应的inode数据(注意,不是删除inode,而是清空这个inode的数据),将此inode对应的位图改为空闲(如从1改为0)。事实上可以不清除数据,只将位图由1改为0,这样下次使用时会自动覆盖。
  4. 将/var/log/messages所占用的磁盘块重新标记为空闲。其实删除文件并不会对磁盘块做任何操作(清除数据),只会将相应的磁盘块的位图改为空闲,下次使用时仅仅只是覆盖现有磁盘块上的数据。如果没有在这些磁盘块上写入新文件,其数据仍然可以被找回来;但是一旦写入了新文件,就很难再找回原来的数据了。这就是为什么删除文件的过程相较其他操作要快得多。

群晖卸载docker删除了docker文件夹 群晖删掉文件还占空间_文件系统_02

由此可知,文件系统只是将文件头作一个已删除的标记,表明文件被删除了,即没有真正删除文件,只是标识删除。虽然文件系统知道这些block是未使用或者说可用的,但是底层的存储系统并不知道文件系统做的操作,会认为这些block仍在使用。

以这里mysql pod挂在的卷为例,它本身是稀疏格式的,也就是说它所占用objects会随着用户写入数据的增加而增加(Thin provision)。当用户删除数据以后,这些obejct不再使用,但并没有被释放。因为从Ceph的角度讲,它并不知道文件系统中发生的事情。

解决方法

SSD 具有一种称为 TRIM 的功能。从本质上讲,这是一种用于回收设备上未使用的块的方法,该块可能先前已被写入,但不再包含有效数据,因此可以返回到通用存储池以供重用。

Linux系统中都有一个命令 fstrim,就是作TRIM操作,可以用于普通SSD与NVMe

有两种方式可以触发Trim/Discard请求,一种是由文件系统自动完成,一种是用户通过执行命令来完成。

一、文件系统自动完成

  只要在挂载文件系统时指定discard参数即可,比如 mount -t ext4 -o discard  device mountpoint,这样在文件系统中删除文件后会自动触发Trim/Discard操作,在块设备上释放占用的空间。需要注意的是,mount的discard参数会导致文件系统性能下降,在并发删除大量小文件时变得很慢,因此需要根据具体场景选择合适的长发方式。

二、用户执行命令

  用户可以执行命令fstrim来触发Trim/Discard操作,采用这种方式mount文件系统时不需要discard参数。比如,fstrim -v mountpoint,就会释放对应块设备上不用的空间。

测试:

查看存储池

[root@zjjshen ~]# rados lspools
.rgw.root
images
volumestest
vms
k8s

创建一个卷并挂载到机器上

[root@zjjshen ~]# rbd create k8s/test --size 30G          #创建块设备
[root@zjjshen ~]# rbd info k8s/test 
rbd image 'test':
	size 30GiB in 7680 objects
	order 22 (4MiB objects)
	block_name_prefix: rbd_data.6cc18c6b8b4567
	format: 2
	features: layering, exclusive-lock, object-map, fast-diff, deep-flatten
	flags: 
	create_timestamp: Fri May 14 10:49:55 2021
[root@zjjshen ~]# rbd  feature disable k8s/test  exclusive-lock object-map fast-diff deep-flatten
[root@zjjshen ~]# rbd map k8s/test                    # 映射块设备
/dev/rbd13
[root@zjjshen ~]# mkdir /root/zjjshen                 # 创建挂载目录
[root@zjjshen ~]# mkfs.ext4 /dev/rbd13                # 格式化块设备
mke2fs 1.42.9 (28-Dec-2013)
Discarding device blocks: done                            
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=1024 blocks, Stripe width=1024 blocks
1966080 inodes, 7864320 blocks
393216 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=2155872256
240 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
	4096000

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: 
[root@zjjshen ~]# mount /dev/rbd13 /root/zjjshen/      # 挂载
[root@zjjshen ~]# df -h | grep zjjshen                 
/dev/rbd13       30G   45M   28G   1% /root/zjjshen
[root@zjjshen ~]# rbd du tstack_k8s/test          
NAME PROVISIONED   USED 
test       30GiB 240MiB

快速生成大文件

# 生成10G的file文件
[root@zjjshen ~]# cd /root/zjjshen
[root@zjjshen zjjshen]# dd if=/dev/zero of=file bs=1M count=10000        
10000+0 records in
10000+0 records out
10485760000 bytes (10 GB) copied, 3.39941 s, 3.1 GB/s
[root@zjjshen zjjshen]# du -sh file 
9.8G	file
[root@zjjshen zjjshen]# df -h | grep zjjshen
/dev/rbd13       30G  9.9G   19G  36% /root/zjjshen
[root@zjjshen zjjshen]# rbd du k8s/test
warning: fast-diff map is not enabled for test. operation may be slow.
NAME PROVISIONED  USED 
test       30GiB 10GiB

删除生成的文件,看rbd du是否有变化

[root@zjjshen zjjshen]# rm -rf file 
[root@zjjshen zjjshen]# df -h | grep zjjshen
/dev/rbd13       30G   45M   28G   1% /root/zjjshen
[root@zjjshen zjjshen]# rbd du k8s/test
warning: fast-diff map is not enabled for test. operation may be slow.
NAME PROVISIONED  USED 
test       30GiB 10GiB

可以看出,删除后ceph这边存储使用量是没有变化的

执行fstrim

[root@zjjshen zjjshen]# fstrim -v /root/zjjshen
/root/zjjshen: 10 GiB (10716344320 bytes) trimmed
[root@zjjshen zjjshen]# rbd du k8s/test
warning: fast-diff map is not enabled for test. operation may be slow.
NAME PROVISIONED   USED 
test       30GiB 240MiB

可以看出ceph查看的使用量已经减少了