Total Pageviews

Monday 16 October 2017

优化Ext4分区格式化后所占用的空间

这个 2T 硬盘的分区方案就是一个 Ext4 分区,当数据仓库盘用,于是我就用 GParted 格式化了,结果这一个过程花了差不多 8 分多钟,而且格式化后就已经使用了差不多 30G,太坑爹了吧。
我第一时间想到是 保留空间, 但经过我大胆假设小心求证后,得出结论,这个保留空间依然算在未使用里面的。保留空间意思是给 root 账户保留的空间,比如保留空间是 100M,当一个分区用得差不多后,剩下 100M 了,那么普通用户就无法继续建立新文件了,提示空间不足了。换到 root 账户后,就能继续使用这 100M。而格式化后这 30G,可是实打实的已经被使用掉。
可以知道这已使用空间是分配给索引区的,就是 inode(不清楚 inode 是什么 Google 去)和日志以及各种 Ext4 需要记录的信息。不过 30G,也太巨了吧,格式化一次要 8 分钟,感觉很不好。于是我就去研究一下原理,算不算浪费和有没有得优化空间。
在 STFW 和 RTFM,格式化了 n 次后,现在我格式化这个 2T 只需要半分钟,使用空间只占了 700 多 M,感觉良好。
好了,那么是什么原因导致格式化这个 2T 要 8 分钟,并一下用掉 30G 呢?答案是 inode 数量。在 Linux 的文件系统中,一个文件对应一个 inode。一个 inode 大小现在默认值是 256 字节。当然 256 字节是记录不了大文件所有数据地址的,于是有间接块,间接块就是……呃,总之就是
有多少个 inode 就能存多少个文件,无论文件有多大,而一个 inode 要 256 字节。
而 inode 数量是由格式化程序(这里就是 mkfs.ext4)根据自动算出来的。默认是 16K 一个 inode也就是说,就算你在这个分区全是 16K 小的文件,都有足够数量的 inode 使用。
但问题是,对于我这种拿来当仓库用的分区,不可能全是 16K 的文件呀,高清电影和光盘映像都是上 G 的东西了。上面说过,一个文件要 inode,就算这个分区都塞满了,肯定还有很多 inode 没被使用,明显是浪费掉了。
扯了这么多还是在个实际例子吧,就拿我这个 2T 新硬盘为例。格式化时会输出一些信息
$ sudo mkfs.ext4 -n /dev/sdc1 mke2fs 1.41.12 (17-May-2010) Filesystem label= OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) Stride=1 blocks, Stripe width=0 blocks 122101760 inodes, 488378368 blocks 24418918 blocks (5.00%) reserved for the super user First data block=0 Maximum filesystem blocks=4294967296 14905 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, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968, 102400000, 214990848 
看到有 122101760 个 inodes 吧,一个 inode 占256字节,那么换算成 M 单位是:(122101760 * 256) / (1024 ** 20 = 29810M,差不多 30G 啊!
警告!警告!严重警告! 上面的命令怎么多了个 -n 参数?-n 参数表示模拟运行,但不格式化,这样可以看不同的格式化参数会有什么效果。如果没有这个参数,那就真的格式化了。所以对有数据的分区测试时千万要记得加上 -n 参数!下面我都带上这个参数。
但是运行 mkfs.ext4 需要 root 权限,漏了 -n 太危险,可以用 tune2fs 查看文件系统各种信息。
sudo tune2fs -l /dev/sdc1 
Inode count 一行。
man 一下 mkfs.ext4,发现有两个参数可以制定 inode 数量
  • -i bytes-per-inode:多少个字节一个 inode
  • -N number-of-inodes:直接制定 inode 数量
默认 16k 一个 inode 相当于
sudo mkfs.ext4 -i 16384 -n /dev/sdc 
把这个数字加大了就行了,最好是 1024 的倍数。比如 1M,即 1048576 字节。
sudo mkfs.ext4 -i 1048576 -n /dev/sdc 
其实在 /etc/mke2fs.conf 定义了一些默认值,可以用 -T 来指定类型,比如 largefile 类型就是 1M 一个 inode,上一个命令相当于
sudo mkfs.ext4 -T largefile -n /dev/sdc 
还有一个 largefile4,4M 一个 inode。不过比 largefile 才少了 300M,对于 2T 来说小意思了,没必要省,万一小文件过多 inode 不够呢?
于是
$ sudo mkfs.ext4 -T largefile -n /dev/sdc1 mke2fs 1.41.12 (17-May-2010) Filesystem label= OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) Stride=1 blocks, Stripe width=0 blocks 1907840 inodes, 488378368 blocks 24418918 blocks (5.00%) reserved for the super user First data block=0 Maximum filesystem blocks=4294967296 14905 block groups 32768 blocks per group, 32768 fragments per group 128 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968, 102400000, 214990848 
还有 1907840 个 inode,可以保存 1907840 个文件,真够了,估计也难用满。(1907840 * 256) / (1024 ** 2) = 465M, 省出 29810 - 465 = 29345M,29G!十来部高清了。
格式化也只需半分钟,占用 700M 左右,因为还有日志其它什么的,过度优化没必要了,控制在 1G 内我觉得够了.
---------------------

充分利用磁盘空间,打开ext文件系统的保留区块

他的硬盘,有个分区一共有234G,但是只用了222G,就报满了,无法继续使用了。
其实这个问题,我不久前刚看过一下,只要你仔细看 mkfs.ext3 的man page,就可以知道原因了,其中有这么一句:

       -m reserved-blocks-percentage
              Specify the percentage of the filesystem blocks reserved for the
              super-user.   This  avoids  fragmentation, and allows root-owned
              daemons, such as syslogd(8), to continue to  function  correctly
              after non-privileged processes are prevented from writing to the
              filesystem.  The default percentage is 5%.
也就是说,ext文件系统,包括ext2、ext3、ext4都会默认预留5%的磁盘空间,留给root用户维护系统或者记录系统关键日志的时候使用,这也就是导致普通用户无法使用部分磁盘空间的原因了。
我个人觉得,这个选项用在根分区或者/var之类的分区,还是有一定的必要性的。但是如果是/home、/opt或者干脆是/data之类的数据分区,就显得有点多此一举了。而且,现在的磁盘空间越来越大,5%往往会有10多G,都可以存一部高清了。这么多空间浪费了,是不是太可惜了呢?
于是,就去找相关资料,看能可否在不格式化的情况下改变保留区块的大小。
吼吼找到了这个,比我想像得还要简单,甚至都不需要umount分区,就可以进行修改。
具体操作过程如下,已经加了详细注释:
#之前的保留区有 732463 块
lily@LLY:~$ sudo tune2fs -l /dev/sda7 | grep "Reserved block count"
Reserved block count:     732463
#已用空间+可用空间 和 总空间 相比,还少了近3个G
lily@LLY:~$ df
文件系统          1K-块      已用      可用 已用% 挂载点
/dev/sda7             57677500  47662588   7085060  88% /home
#调整:
lily@LLY:~$ sudo tune2fs -r 25600 /dev/sda7
tune2fs 1.41.9 (22-Aug-2009)
Setting reserved blocks count to 25600
#再来看看空间,哈哈
lily@LLY:~$ df
文件系统          1K-块      已用      可用 已用% 挂载点
/dev/sda7             57677500  47662584   9912516  83% /home
#确认调整成功
lily@LLY:~$ sudo tune2fs -l /dev/sda7 | grep "Reserved block count"
Reserved block count:     25600
看到了吧?就一眨眼的功夫,我就多了3G多的空间,哈哈。而且我还不是直接完全去掉保留区块呢,也留了百多兆以防不时之需呢,呵呵。
算了一下,吼吼那个3.4T的磁盘阵列,省出来的空间居然比我的整个硬盘都大。

 

 

 

No comments:

Post a Comment