df和du命令:Linux磁盘管理初步

Linux磁盘管理好坏直接关系到整个系统的性能问题,Linux磁盘管理常用三个命令为 df、du 和 fdisk。

  • df:列出文件系统的整体磁盘使用量(Disk Free)
  • du:检查磁盘空间使用量(Disk Usage)
  • fdisk:用于磁盘分区(???)

直译过来,df 是磁盘空闲,du 是磁盘占用,
至于 fdisk 本文不讨论。(有人说前面的 f 意思是 f*** —— 这只是一个笑话)



在讲之前,先补充一点 Linux 文件系统的知识。(我记得之前有过相关的文章,具体参见我的 “Linux 背景知识” 系列博文)

学习 “这方面” 知识,始终离不开三点

  • 磁盘
  • 文件
  • 数据

下面就随便谈谈上面提及的 “三点” 重要的知识体系。

任何文件系统中的数据都分为存储数据和元数据两类,存储数据就是实际存在于文件中用户需要的数据信息,比如一幅画、一首诗,或者一个电话号码,而元数据(metadata),它是 “描述数据的数据”,作为存储数据敲定的先决条件,终端用户并不关心元数据本身的内容。这些信息包括访问权限、文件拥有者以及文件数据块的分布信息(inode)等等。举个例子你就懂了。

要创建一个数据表,在 SQL 中写

CREATE TABLE DEMO {
	LastName varchar(255),
	FirstName varchar(255),
	Address varchar(255)
}

这里创建了三个数据列,它们的数据类型都是 varchar 类型,且最大长度为 255 个字节。

LastName FirstName Address
木星
火星

在这个例子中,存储数据是张三、李四,他们的个人信息,而元数据就是为了创建这个表所做的事先准备,也就是张三和李四等一众用户的各种属性的属性,即这里的 varchar 类型和 255 字节。 处理文件之实际情况比这复杂一些,但是万变不离其宗。元数据也被称为 “中介数据”、“中继数据”,这些名字都是一个意思。我们说 “格式化文件系统” 或者 “建立文件系统”,实际上就是向那块存储空间写入特定的初始化元数据的过程。

大部分 Unix 文件系统种类具有类似的通用结构,即使细节有些变化。其中心概念是超级块(superblock)、i节点(inode)、数据块(data block)、目录块(directory block)和间接块(indirection block)。超级块包括文件系统的总体信息,比如大小(其准确信息依赖文件系统);i节点包括除了名字外的一个文件的所有信息,名字与i节点数目一起存在目录中,目录条目包括文件名和文件的i节点数目;i节点包括几个数据块的数目,用于存储文件的数据。i节点中只有少量数据块数的空间,如果需要更多,会动态分配指向数据块的指针空间。这些动态分配的块是间接块;为了找到数据块,这名字指出它必须先找到间接块的号码。

再讲讲磁盘或硬盘。硬盘是磁盘的一种,除此之外还有软盘。在说分区的时候,“磁盘” 和 “硬盘” 的概念通常混为一谈。“磁盘分区” 或 “硬盘分区” 的说法都是可以的。这样说:“计算机中存放信息的主要的存储设备就是硬盘,但是硬盘不能直接使用,必须对硬盘进行分割,分割成的一块一块的硬盘区域就是磁盘分区”。文件和数据都是逻辑上的概念,而硬盘或者说磁盘,则是在物理上真实存在的。


df 命令的特点

  • 直接从文件的元数据的块(可认为就是 super block)中获取信息,速度很快
  • 只能展示整个磁盘的信息,较为准确

du 命令的特点

  • 遍历指定的所有文件(文件树),累加求和,速度较慢
  • 可以展示目录级别的信息,较不准确

关于第二点,解释如下

1. 由于正在运行的进程可以保持已删除的文件打开,这意味着该部分空间仍由 df 保留和查看,但是 du 不能在目录树中看到该文件的引用,因此无法看到这些保留块。

2. du 命令采取遍历文件树的手段进行空间大小计算,由于存在不可读文件和硬链接等情况,该命令可能无法读取所有文件,至于 df 命令直接从元数据中获取信息就没有这样的尴尬。

df 命令固然好,既准确又快速,但是缺点是只能读取一整个磁盘空间。du 命令虽然慢,还不太准确,却也是日常必备之磁盘管理命令,因为它针对指定目录。具体问题具体对待(日常中 du 命令其实用的更多)。

[email protected]:~$ df --help
Usage: df [OPTION]... [FILE]...
Show information about the file system on which each FILE resides,
or all file systems by default.

Mandatory arguments to long options are mandatory for short options too.
  -a, --all             include pseudo, duplicate, inaccessible file systems
  -B, --block-size=SIZE  scale sizes by SIZE before printing them; e.g.,
                           '-BM' prints sizes in units of 1,048,576 bytes;
                           see SIZE format below
  -h, --human-readable  print sizes in powers of 1024 (e.g., 1023M)
  -H, --si              print sizes in powers of 1000 (e.g., 1.1G)
  -i, --inodes          list inode information instead of block usage
  -k                    like --block-size=1K
  -l, --local           limit listing to local file systems
      --no-sync         do not invoke sync before getting usage info (default)
      --output[=FIELD_LIST]  use the output format defined by FIELD_LIST,
                               or print all fields if FIELD_LIST is omitted.
  -P, --portability     use the POSIX output format
      --sync            invoke sync before getting usage info
      --total           elide all entries insignificant to available space,
                          and produce a grand total
  -t, --type=TYPE       limit listing to file systems of type TYPE
  -T, --print-type      print file system type
  -x, --exclude-type=TYPE   limit listing to file systems not of type TYPE
  -v                    (ignored)
      --help     display this help and exit
      --version  output version information and exit

Display values are in units of the first available SIZE from --block-size,
and the DF_BLOCK_SIZE, BLOCK_SIZE and BLOCKSIZE environment variables.
Otherwise, units default to 1024 bytes (or 512 if POSIXLY_CORRECT is set).

The SIZE argument is an integer and optional unit (example: 10K is 10*1024).
Units are K,M,G,T,P,E,Z,Y (powers of 1024) or KB,MB,... (powers of 1000).

FIELD_LIST is a comma-separated list of columns to be included.  Valid
field names are: 'source', 'fstype', 'itotal', 'iused', 'iavail', 'ipcent',
'size', 'used', 'avail', 'pcent', 'file' and 'target' (see info page).

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
Full documentation at: <http://www.gnu.org/software/coreutils/df>
or available locally via: info '(coreutils) df invocation'
[email protected]:~$ du --help
Usage: du [OPTION]... [FILE]...
  or:  du [OPTION]... --files0-from=F
Summarize disk usage of the set of FILEs, recursively for directories.

Mandatory arguments to long options are mandatory for short options too.
  -0, --null            end each output line with NUL, not newline
  -a, --all             write counts for all files, not just directories
      --apparent-size   print apparent sizes, rather than disk usage; although
                          the apparent size is usually smaller, it may be
                          larger due to holes in ('sparse') files, internal
                          fragmentation, indirect blocks, and the like
  -B, --block-size=SIZE  scale sizes by SIZE before printing them; e.g.,
                           '-BM' prints sizes in units of 1,048,576 bytes;
                           see SIZE format below
  -b, --bytes           equivalent to '--apparent-size --block-size=1'
  -c, --total           produce a grand total
  -D, --dereference-args  dereference only symlinks that are listed on the
                          command line
  -d, --max-depth=N     print the total for a directory (or file, with --all)
                          only if it is N or fewer levels below the command
                          line argument;  --max-depth=0 is the same as
                          --summarize
      --files0-from=F   summarize disk usage of the
                          NUL-terminated file names specified in file F;
                          if F is -, then read names from standard input
  -H                    equivalent to --dereference-args (-D)
  -h, --human-readable  print sizes in human readable format (e.g., 1K 234M 2G)
      --inodes          list inode usage information instead of block usage
  -k                    like --block-size=1K
  -L, --dereference     dereference all symbolic links
  -l, --count-links     count sizes many times if hard linked
  -m                    like --block-size=1M
  -P, --no-dereference  don't follow any symbolic links (this is the default)
  -S, --separate-dirs   for directories do not include size of subdirectories
      --si              like -h, but use powers of 1000 not 1024
  -s, --summarize       display only a total for each argument
  -t, --threshold=SIZE  exclude entries smaller than SIZE if positive,
                          or entries greater than SIZE if negative
      --time            show time of the last modification of any file in the
                          directory, or any of its subdirectories
      --time=WORD       show time as WORD instead of modification time:
                          atime, access, use, ctime or status
      --time-style=STYLE  show times using STYLE, which can be:
                            full-iso, long-iso, iso, or +FORMAT;
                            FORMAT is interpreted like in 'date'
  -X, --exclude-from=FILE  exclude files that match any pattern in FILE
      --exclude=PATTERN    exclude files that match PATTERN
  -x, --one-file-system    skip directories on different file systems
      --help     display this help and exit
      --version  output version information and exit

Display values are in units of the first available SIZE from --block-size,
and the DU_BLOCK_SIZE, BLOCK_SIZE and BLOCKSIZE environment variables.
Otherwise, units default to 1024 bytes (or 512 if POSIXLY_CORRECT is set).

The SIZE argument is an integer and optional unit (example: 10K is 10*1024).
Units are K,M,G,T,P,E,Z,Y (powers of 1024) or KB,MB,... (powers of 1000).

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
Full documentation at: <http://www.gnu.org/software/coreutils/du>
or available locally via: info '(coreutils) du invocation'

先讲讲 df 命令

df和du命令:Linux磁盘管理初步

df和du命令:Linux磁盘管理初步
如你所见,df 命令第一列代表文件系统对应的设备文件的路径名(磁盘上的分区),第二列给出分区包含的数据块的大小,之后分别是已用和可用的磁盘数据块数目,两列之和之所以不等于第二列是因为缺省的每个分区都留了少量空间供系统管理员使用(防止空间满了的情况,用管理员权限解决问题)。Mounted on,即挂载点。

使用 -t 参数,显示指定类型磁盘

df -t ext3

df和du命令:Linux磁盘管理初步
事实上,在日常生活或工作中使用更多的是 du 命令(虽然它很慢),因为它在目录层次上显示磁盘使用情况。

df和du命令:Linux磁盘管理初步
给出先要查看的文件,它会自动递归的进行搜索,也就是说也会显示该目录的子目录,以及子目录的子目录……

df和du命令:Linux磁盘管理初步
使用 -h 参数,将输出结果改造为美观可读的形式,改变的是第一列的单位。

du -h ./temp

df和du命令:Linux磁盘管理初步

如果你只是想要获取该目录(不关心目录的子目录)的磁盘占用情况,使用 -s 参数

du -sh ./temp

df和du命令:Linux磁盘管理初步
前面说过,du 命令在目录层次上解决问题,如果想要查看文件的话,请加上 -a 参数

du -ah ./temp

df和du命令:Linux磁盘管理初步
下面是一个综合应用。使用 --exclude 参数排除指定类型文件,--max-depth 参数指定向下搜索深度,使用 -c 参数在输出末行给出指定目录的总磁盘占用(鸡肋选项)。

df和du命令:Linux磁盘管理初步
df和du命令:Linux磁盘管理初步

初学者重点掌握du命令。