ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Linux文件系统全解:从VFS到inode,实战排查磁盘满与权限问题

Linux文件系统全解:从VFS到inode,实战排查磁盘满与权限问题 1. 从一次线上事故说起先说个真事。我前几年负责过一批 CentOS 7 服务器有天凌晨监控突然告警某台业务机的/分区使用率飙到 100%。登录上去一查df -h显示/已经满了但du -sh /*算下来总量却对不上——差了将近 30 个 G。折腾了大半夜最后才发现是有个进程写了个不断增长的临时大文件但文件已经被rm掉了所以du看不到而文件系统里的数据块迟迟没有被回收。这个锅说到底就是 Linux 文件系统的工作机制在背后起作用。这类问题几乎每个用 Linux 的人都会遇到一次。不管是刚接触 Linux 的新手还是写了几年代码的开发又或者是天天跟服务器打交道的运维只要你在 Linux 上干活文件系统就是绕不开的一层。它决定了你的数据怎么落盘、怎么读取、怎么保证一致性也决定了你遇到问题时该怎么排查。这篇文章我就想系统地聊一聊 Linux 文件系统。从架构原理到日常实操从命令细节到故障排查把根文件系统、VFS、挂载、权限、日志、常见坑这几个大块都过一遍。写的时候尽量用我实际踩过坑的经验来讲而不是干巴巴地堆概念。不管你是在学 Linux、准备面试、还是已经上生产环境救过火这篇应该都能给你一些参考。2. 文件系统整体架构与核心设计2.1 什么是文件系统文件系统通俗点说就是操作系统用来管理和存储文件的一套规则。它解决的核心问题就两个文件数据到底存在磁盘的哪些块上以及怎么把这些块组织成用户能看到的目录树 文件名 内容的结构。你可以把没有文件系统的磁盘想象成一个巨大的仓库里面全是大小相同的小格子每个格子都能装数据。问题是如果你不记录哪个格子存的是哪个文件的哪一段下次谁来都找不到想要的东西。文件系统就是那张仓储台账它记录文件名、大小、权限、存放位置、修改时间等等信息。不同的文件系统就是不同的记账方式有的账本简单粗暴有的账本花里胡哨但功能强大。Linux 里最经典的一句话是一切皆文件。普通文件是文件目录是文件设备是文件甚至进程间通信的管道和网络 socket 也都是文件。这句话背后站着的就是虚拟文件系统也就是 VFSVirtual File System。它是 Linux 文件系统的灵魂也是整个文件系统架构的顶层设计。2.2 VFS统一接口的抽象层VFS 是内核里的一个抽象层它不关心底层具体是什么文件系统只定义了一套统一的操作接口。你可以把它理解成 USB 接口标准——不管 U 盘内部是闪存颗粒还是别的什么存储介质只要它遵循 USB 协议插到电脑上就能用。VFS 对上层应用提供open()、read()、write()、close()这些标准的系统调用对下层各文件系统则要求它们实现对应的回调函数。所以你在 Linux 上写代码打开 ext4 的文件和打开 xfs 的文件用的系统调用是一模一样的。程序员不需要关心底层文件系统是哪个VFS 会帮你把请求分发到具体的文件系统实现上去。这就是为什么同一个cp命令既能拷贝本地磁盘文件也能拷贝挂载的 USB 设备文件甚至能通过网络文件系统操作远端文件。VFS 里还引入了四个核心对象的概念超级块对象super block描述整个文件系统的元信息、索引节点对象inode描述一个文件、目录项对象dentry描述路径中的一个组成部分、文件对象file描述进程打开的一个文件实例。这四者的关系可以简单理解成超级块是账本的封面inode 是账本里每个文件的条目dentry 是路径目录的查找缓存file 是当前正在记账的手头正在处理的单据。2.3 物理文件系统的多样性虽然 VFS 把接口统一了但底层物理文件系统之间差异还是非常大。Linux 上常见的几类ext 系列ext2、ext3、ext4。ext4 至今仍是很多发行版的默认文件系统支持最大 1EB 的文件系统大小和 16TB 的单文件支持日志journal、extents、延迟分配等特性。XFS高扩展性文件系统早年是 SGI 开发的现在 RHEL/CentOS 7 以上版本默认使用。它对大文件、大分区、高并发写入场景表现非常好。Btrfs被称为下一代文件系统支持写时复制CoW、快照、子卷、校验和等高级特性。这些年逐渐在 openSUSE、Fedora 等发行版中被广泛采用但稳定性争议一直存在。ZFS严格来说不是 Linux 内核原生文件系统但在 FreeBSD 和很多 NAS 系统中非常流行。功能强大集文件系统与卷管理于一身。tmpfs基于内存的临时文件系统数据放在 RAM 里速度飞快但重启就没了。/dev/shm和默认的/tmp在某些系统上就是 tmpfs。网络文件系统NFS、CIFS/SMB 等把远端存储挂载到本地目录。FUSE用户态文件系统框架像 sshfs、s3fs 这种都是基于 FUSE 实现的。选型时没有绝对的好坏。比如高并发小文件多的场景ext4 和 xfs 各有所长追求高级数据管理功能btrfs 和 zfs 更有优势只是临时放点共享内存储的数据tmpfs 是最快方案。关键是清楚自己业务对文件大小、并发量、数据安全性的要求再对照文件系统特性做选择。注意XFS 在 RHEL 系上有个坑——它不支持收缩shrink一旦分区创建时分配过大后期想缩小非常麻烦。ext4 虽然收缩也有限制但相比之下灵活一些。所以分区规划时要提前想清楚。2.4 inode 与目录的组织方式inode 是整个文件系统理解里最核心的概念之一但它经常被忽略。每个文件都有一个 inode里面保存了这个文件的元数据文件类型、权限、所有者、大小、时间戳、数据块指针。但有一个关键点——文件名不保存在 inode 里。文件名保存在目录文件中目录文件的本质就是一个文件名 - inode 号的映射表。所以移动文件和重命名文件在 Linux 里本质上是同一件事修改目录项里文件名到 inode 的映射关系文件数据本身根本不需要搬动。这就是为什么同一文件系统内mv的速度快到飞起而跨文件系统mv就变成拷贝 删除速度慢很多因为数据真的搬了。inode 的数量是有限的格式化时就会确定。如果你创建的都是一堆几 KB 的小文件哪怕磁盘空间还剩很多也可能先遇到 No space left on device而df -h显示空间明明充足。这时候要查的就是 inode 使用率。# 查看文件系统空间使用情况 df -h # 查看 inode 使用情况 df -i我遇到过某台跑定时任务的机器脚本每天生成上万个小日志文件过了几个月直接写不进去了就是 inode 被耗尽。解决办法是清理历史文件或者调整格式化参数增加 inode 密度。3. 文件系统创建与挂载实操3.1 分区、格式化、挂载三步走在 Linux 上从一块新磁盘到能正常使用要经历三个步骤分区或者不分区直接用整块盘、格式化创建文件系统、挂载到目录。第一步是分区。传统的做法是用fdisk或者parted。MBR 分区表是老古董了单盘只能支持到 2TB现在新磁盘基本都用 GPT。对于大多数服务器场景直接用整块磁盘建一个分区就够了没必要搞得花里胡哨。第二步是格式化。创建文件系统使用的命令是mkfs它本质上是 mkfs.ext4、mkfs.xfs 这些命令的统一入口。# 在 /dev/sdb1 上创建 ext4 文件系统 mkfs.ext4 /dev/sdb1 # 指定 inode 大小 mkfs.ext4 -I 256 /dev/sdb1 # 创建 xfs 文件系统指定块大小 mkfs.xfs -b size4k /dev/sdb1格式化之前要明确一个事mkfs 会清空分区上的数据。每次执行前确认这个分区是不是你真的要格式化的那个尤其在生产环境一个手滑数据就没了。我见过不止一次因为在多块磁盘的机器上敲错设备名导致事故的案例。第三步是挂载。mkdir -p /data mount /dev/sdb1 /data挂载的本质是把文件系统跟目录树上的某个目录关联起来。挂载完之后访问/data这个目录本质上就是在访问/dev/sdb1这个设备上的文件系统。mount命令不带参数时可以直接查看当前系统所有挂载点。3.2 /etc/fstab 配置系统启动时自动挂载手动挂载只是临时的重启就没了。要系统启动时自动挂载需要把挂载信息写进/etc/fstab。这个文件是启动时由 systemd 读取并处理的每行格式如下设备标识 挂载点 文件系统类型 挂载选项 是否备份 检查顺序举几个实际例子UUID8d5d1d4a-6c2f-4a4b-9c1c-4b6f3c9a5b2a /data ext4 defaults 0 2 /dev/mapper/vgdata-lvdata /data xfs defaults 0 0 tmpfs /tmp tmpfs defaults,noatime,mode1777 0 0有几个细节需要注意设备标识最好用 UUID 而不是 /dev/sdX。因为设备名可能会变比如你新插了一块盘原本来/dev/sdb的盘可能就变成了/dev/sdc。UUID 是文件系统创建时生成的一串唯一标识基本不会变。获取 UUID 用blkid。挂载选项里有个noatime建议生产环境加上。它的作用是不要每次读文件都更新访问时间戳能减少写 I/O提升性能。对很多业务来说atime 本来也没多大用处。每行的最后一列是 fsck 检查顺序根文件系统一般是 1其他文件系统是 2 或者 0。不想开机检查就写 0。配置/etc/fstab时还要留一个心眼如果写错了系统启动时会因为挂载失败卡住进入 emergency mode。为了避免这种情况验证 fstab 语法可以用mount -a它会尝试挂载所有 fstab 里尚未挂载的文件系统。如果报错说明你的配置有问题先改好再重启。3.3 根文件系统的核心地位根文件系统就是挂载在/上的文件系统。它是最特殊的一个因为它承担了系统启动时所有基础命令、库、配置、设备节点的承载任务。如果根文件系统损坏或者挂载失败系统是无法正常启动的。Linux 启动过程中内核被引导加载器加载后会解析启动参数里的root或rootUUID参数找到根文件系统所在的设备然后以只读方式挂载根文件系统接着初始化 systemdPID 1再切换到读写模式完成启动。日常维护中如果根文件系统满了系统会出现各种诡异的毛病服务无法创建临时文件、用户无法登录、cron 任务全部失败。所以监控根分区使用率是第一优先级。另外根文件系统不建议放大量业务数据尽量独立挂载/home、/var、/data这些目录隔离故障域。我在一台机器上习惯把重要的服务数据和系统盘分开不仅方便备份也能避免系统日志把磁盘挤爆进而导致整个系统不可用的情况。4. 权限、链接与文件属性细节4.1 权限模型和特殊权限位Linux 权限模型看起来简单就是属主/属组/其他 读/写/执行九位权限但实际使用中坑非常多。先把基本模型过一遍然后再讲几个容易忽略的地方。ls -l显示的第一列比如-rw-r--r--第一个字符是文件类型后面九位拆成三组属主u、属组g、其他用户o。每组三位分别是 r读、w写、x执行。但在现实场景中光靠这九位是不够的。比如用户要改密码/etc/shadow文件只有 root 能读写可普通用户执行passwd命令时为什么能修改它答案就是/usr/bin/passwd这个程序设置了SUID 特殊权限位。SUID 位如果设置在可执行文件上表现为属主权限位上的s比如-rwsr-xr-x。它作用是用这个程序执行时进程的有效用户 ID 变成文件属主通常是 root所以普通用户才能临时以 root 身份修改 shadow 文件。SUID 是个双刃剑如果系统里出现了不该有的 SUID 程序可能就意味着提权漏洞。检查方式# 查找所有 SUID 程序 find / -perm -4000 -type f 2/dev/null类似还有 SGIDs出现在属组权限位和 Sticky Bit其他用户权限位上的t典型例子是/tmp。Sticky Bit 的作用是在设置了它的目录里文件只能被文件属主、目录属主和 root 删除防止普通用户互相删文件。常用的设置方法# 添加 SUID chmod us /path/to/file # 添加 SGID chmod gs /path/to/dir # 添加 Sticky Bit chmod t /tmp4.2 硬链接与软链接的区别链接也是文件系统里高频概念。软链接symbolic link很好理解就是一个单独的文件内容存的是目标路径类似 Windows 的快捷方式。硬链接则不同它跟原文件共享同一个 inode本质上是同一个文件在目录树里有多个名字。硬链接的几个特性是面试和实际排查时容易考到的硬链接不能跨文件系统创建因为 inode 编号只在单个文件系统内有意义。硬链接不能链接目录防止目录树成环。删除其中一个硬链接名文件数据不会丢只有所有硬链接都被删了inode 才会被释放。软链接就灵活得多可以跨文件系统、可以指向目录、甚至可以指向不存在的路径。创建命令分别对应ln和ln -s。# 硬链接 ln /data/file /data/file_hardlink # 软链接 ln -s /data/file /data/file_softlink在实际运维中用软链接切换版本是很常见的操作。比如把 Java 的JAVA_HOME指向/usr/local/java/current而current是一个软链接指向具体的 JDK 版本目录升级时只需要改一下软链接即可。硬链接用得相对少但在备份场景中有些工具会利用硬链接做增量快照节省空间。4.3 文件时间戳与 ls -l 之外的细节文件系统里每个文件有三个时间戳atime访问时间、mtime修改时间内容被改、ctime状态改变时间权限、属主、链接数等元数据变化会更新。这里有个容易混淆的点ctime 不是创建时间。Linux 原生的 ext4 文件系统确实也有文件的创建时间crtime但标准命令不直接显示需要用statstat filename输出里 Birth 字段就是创建时间。诊断问题的时候区分 mtime 和 ctime 很有用。比如你怀疑某个文件被篡改mtime 可能被人为改回去了但 ctime 没法通过常规手段伪装所以可以看 ctime 来判断是否曾发生元数据变更。还有一个高频命令是touch它有两个参数比较实用touch -d指定修改时间touch -a只更新 atime。在测试和排查中经常用到。5. 日常文件操作命令与实用技巧5.1 检索、查看、分析文件的常用手段文件系统的日常操作无非是查看、查找、分析这几类。先看查看类。ls是最基础的但很多人不知道它有几个实用变体# 按时间排序 ls -lt # 按大小排序 ls -lS # 递归显示 ls -R # 显示带单位的大小 ls -lh查找文件是大头。find命令功能极其强大但参数多容易记混。我平时用得最多的几个组合# 按名字查找 find /data -name *.log # 按大小查找查找大于 1G 的文件 find /data -type f -size 1G # 按修改时间查找7 天内修改过的 find /data -type f -mtime -7 # 找到并批量删除 find /data -name *.tmp -delete # 找到并执行命令 find /data -name *.log -exec ls -lh {} \;grep是用来找文件内容的。主要参数就记几个-r递归、-n显示行号、-i忽略大小写、-v排除匹配行、-l只显示文件名。还有管道配合用的head、tail、less这些是面试常考的 Linux 常用命令也是日常排查的刀剑。查日志时我习惯这么用# 实时跟踪日志输出 tail -f /var/log/messages # 看日志最后 500 行并按关键字过滤 tail -n 500 /var/log/messages | grep -i error # 统计日志里某个关键字出现次数 grep -c timeout /var/log/app.log另外du和df必须分清楚。df查看文件系统维度的空间使用du查看目录维度的空间占用。排查磁盘满的问题时先用df -h定位是哪个挂载点满了再用du -sh逐层往下定位是哪个目录在占空间。# 查看当前目录下所有子目录的大小 du -sh * # 查看 1 级子目录的大小并按大小排序 du -sh * | sort -hr5.2 解压乱码与文件编码问题热搜词里有linux 解压文件乱码这是个非常经典的问题。原因多半是压缩包是在 Windows 系统上创建的文件名编码用了 GBK/GB18030而 Linux 默认用 UTF-8 解码于是中文文件名全变成乱码。不只是文件解压平时打开 Windows 传过来的文本文件也经常出现中文乱码。解决思路有两个。第一个是装一个支持编码转换的解压工具# 安装 unar yum install unar unar archive.zip # unar 会自动检测压缩包内部文件名编码并转换第二是用convmv对已经解压出来的乱码文件进行批量重命名修正convmv -f GBK -t UTF-8 --notest -r /path/to/dir我个人的经验是在 Windows 和 Linux 之间传文件除非必须用 zip 格式否则建议直接打成 tar.gztar 里文件名是以字节流存储的一般不涉及编码转换问题。如果非要 zip也尽量在打包时注意编码设置。5.3 I/O 性能与数据完整性核验排查文件系统性能问题首先看两个命令的输出iostat和iotop。# 查看磁盘 I/O 统计 iostat -x 1iostat -x输出里重点看%util设备忙绿程度、await平均 I/O 等待时间、svctm、r/s、w/s这些指标。如果%util接近 100%说明磁盘已经成为瓶颈。iotop则用来定位到底是哪个进程在疯狂读盘写盘跟top找 CPU 一样。# 实时查看各进程 I/O iotop -o数据完整性核验则聚焦在 checksum 上。对于重要文件可以定期生成和比对 checksum。常见的是md5sum、sha1sum、sha256sum。生产环境建议用sha256sum碰撞概率更低。# 生成校验和 sha256sum /data/important_file /root/checksum.sha256 # 校验 sha256sum -c /root/checksum.sha256如果文件系统本身支持 checksum 校验比如 btrfs 和 zfs日常使用中数据损坏也能被发现。而 ext4 默认不校验数据块内容jbd2 日志只校验元数据所以数据完整性要求高的场景要评估是否需要 ext4 开启 data journal或者直接用 btrfs/zfs。6. 常见问题与故障排查实录6.1 磁盘满了但找不到大文件这是运维中最经典的鬼故事场景df -h显示空间用完但du -sh /*加起来远小于总占用。原因基本就两类。第一类是前文说的文件被进程打开后又被rm删除了。文件系统里数据块还没释放因为进程还在持有文件句柄。Linux 下一切皆文件这种被删除但还被占用的情况解决办法是找到持有该文件的进程重启它或者让它关闭句柄# 列出所有被删除但仍被占用的文件 lsof L1从输出里能看到进程 PID 和删除文件路径。如果是日志文件被删一般是重启对应服务如果是数据库类应用可以先确认删除文件是不是误操作。如果进程不能重启也可以用/proc/pid/fd/文件描述符去恢复内容操作要快否则数据块一旦被覆写就没了。第二类是文件系统内部结构异常比如 ext4 的 reserved block预留块或者日志占用的空间异常。有些文件系统会为 root 保留一部分空间ext4 默认预留 5%普通用户不能写满但 root 可以。当普通用户报告磁盘满了root 登录却还能写入时就是这个预留机制在起作用。调小预留比例可以这样# 把 /dev/sdb1 的预留空间从 5% 调到 1% tune2fs -m 1 /dev/sdb16.2 文件系统只读与启动进入紧急模式文件系统突然变成只读read-only file system是服务器上非常吓人的故障因为它意味着任何写操作都失败。原因通常是内核检测到文件系统出现 I/O 错误或一致性错误为了保护数据主动将文件系统挂载为只读。遇到这种情况第一步是查看系统日志定位根因dmesg | tail -n 100 journalctl -b -p err日志里常见的有 I/O error、ext4-fs error、XFS corruption detected 等。如果是硬件问题磁盘坏道、掉盘要先换盘或处理硬件。如果是文件系统逻辑损坏可以尝试卸载后修复# 卸载 umount /data # ext4 文件系统检查修复 fsck.ext4 -f /dev/sdb1 # xfs 文件系统检查修复 xfs_repair /dev/sdb1注意fsck 和 xfs_repair 必须在文件系统未挂载的状态下执行。强行对已挂载的文件系统做 fsck 可能造成更严重的数据损坏。还有一种是系统启动时进入 emergency mode。除了 fstab 配置错误外/etc/fstab里某个挂载点设备不存在、UUID 写错、文件系统类型写错都可能触发。排查方法是进入 emergency mode 后先执行mount -a看具体报错然后针对错误修改 fstab修改完执行mount -a验证没问题后再重启。6.3 文件系统损坏与数据恢复的思路文件系统损坏是个大话题但实际运维中绝大多数损坏都是意外断电、意外拔盘、系统崩溃导致的。ext4 有日志所以一般断电后重启会自动回放日志恢复一致性。但如果元数据损坏严重就需要 fsck 深度清理。fsck 的交互模式会问一堆问题实际生产环境可以用-y参数自动回答 yesfsck.ext4 -y /dev/sdb1这会尽量修复但它也会把这些修复动作记录在 lostfound 目录里。这个目录里的文件是从损坏的目录结构中找回的数据文件名已经丢失通常只有 inode 号。这就是为什么重要数据一定要提前备份并且备份完要验证。数据恢复软件层面ext4 误删文件的恢复一直比较麻烦。如果文件刚删除且分区没怎么写入可以用 extundelete 试试# 以只读方式挂载源分区 mount -o ro,remount /dev/sdb1 extundelete /dev/sdb1 --restore-file /path/to/file但它的成功率随写入量急剧下降。真遇到误删数据更靠谱的方案是提前做好备份策略。我个人的习惯是重要的数据盘做每日快照数据库做定期全量 binlog 增量备份关键配置文件放到版本管理里跟踪。文件系统再强大也顶不住人为误操作备份才是最后的保命符。6.4 关于国产操作系统与文件系统适配的观察热搜里有个linux国产的词。这两年国产化替代提得多不少团队开始从 CentOS 迁移到银河麒麟、统信 UOS 这些国产 Linux 发行版。我自己在兼容性测试中的体会是这些发行版底层内核还是 Linux 内核文件系统层面主流的 ext4、xfs 都支持得很好日常使用不会因为文件系统适配出问题。但国产化替代真正要关注的坑往往在上层比如迁移后/etc/fstab里的设备标识、挂载选项、文件系统类型需不需要重新适配又比如原来用 CentOS 的 XFS 分区换到新系统里是否能正常识别。从实际测试来看ext4 的兼容性最好跨发行版基本无障碍。所以如果要做国产化替换数据盘尽量用 ext4 格式可以少踩很多坑。另外无论用哪个发行版养成好习惯都一样安装完系统第一时间确认磁盘分区和挂载布局是否合理设置好磁盘使用率告警再规划好备份和恢复演练。文件系统这层不出问题的时候你感觉不到它的存在一出问题就是大问题功夫要花在平时。7. 命令速查与面试重点整理7.1 高频命令速查表这里把我实际工作中使用频率最高的文件系统相关命令整理成一张表方便大家抄作业用途命令示例说明查看挂载信息mount/findmntfindmnt 输出更清晰支持树状查看文件系统空间df -hT-T 显示文件系统类型查看目录空间占用du -sh *先 cd 到目标目录再执行查看 inode 使用df -iinode 耗尽也会报空间不足查看块设备 UUIDblkid配置 fstab 前先查创建 ext4 文件系统mkfs.ext4 /dev/sdb1注意先确认设备名创建 xfs 文件系统mkfs.xfs /dev/sdb1xfs 不能收缩挂载文件系统mount /dev/sdb1 /data先创建的挂载点必须存在卸载文件系统umount /data有进程占用时用lsof定位自动挂载配置vim /etc/fstab修改后必须验证文件系统检查fsck.ext4 -f /dev/sdb1必须卸载后执行xfs 检查修复xfs_repair /dev/sdb1必须卸载后执行查看被删但仍占用文件lsof L1排查磁盘满必备实时查看进程 I/Oiotop -o需要 root 权限查看 I/O 统计iostat -x 1看 %util 和 await查找大文件find / -type f -size 1G结合 du 定位目录查看 inode 信息stat file能看创建时间查找 SUID 异常文件find / -perm -4000 -type f安全排查建议定期执行7.2 面试中文件系统相关的常见问题文件系统是 Linux 面试的高频考题。我整理几个常被问到的点1. inode 是什么inode 用完了怎么办inode 是文件的元数据索引节点存文件属性与数据块指针文件名不在 inode 里。inode 用完的处理清理无用小文件或者重新格式化时调大 inode 比例比如 mke2fs 的-i bytes-per-inode参数。2. 硬链接和软链接的区别硬链接共享 inode软链接是独立文件存储路径硬链接不能跨文件系统、不能链接目录删除原文件后软链接失效硬链接不受影响。3. 日志文件系统是干什么的日志journal机制保证文件系统在意外断电后能快速恢复一致性。以 ext4 为例它先把元数据操作记入日志再执行实际操作。崩溃后通过日志回放快速恢复到一致状态。代价是每次写操作多了一步日志写入会带来少量性能开销。4. 如何定位磁盘 IO 瓶颈是应用还是硬件先iostat -x 1看设备的%util和await。%util持续 95% 以上基本就是磁盘饱和。然后iotop定位具体进程。再结合pidstat -d看进程的读写速率从应用层判断是否有异常的大文件读写或随机小 IO。5. 文件系统损坏了怎么办优先止损将文件系统挂载为只读/立即卸载防止二次写入。然后检查硬件dmesg 看是否有 I/O error。确认无硬件问题后对未挂载的文件系统执行 fsck/xfs_repair。如果数据重要先尝试用 dd 做整盘镜像再恢复。6. Page Cache 和文件系统的关系是什么Linux 会把读写的文件内容缓存在 Page Cache 中。写文件时数据先写入 Page Cache 再异步刷盘这是写入快的原因但掉电可能丢数据。sync命令可以强制把 Page Cache 中的脏页写回磁盘。对数据一致性要求高的程序需要用 fsync/fdatasync 强制落盘。7.3 一个小技巧用 dd 快速测试磁盘性能判断一台新机器磁盘性能是否达标最简单粗暴的办法是用 dd 做一下快速读写测试# 写测试 dd if/dev/zero of/tmp/testfile bs1G count1 oflagdirect convfdatasync # 读测试 dd if/tmp/testfile of/dev/null bs1G count1 iflagdirectoflagdirect和iflagdirect可以绕过 Page Cache直接测试真实磁盘性能避免缓存干扰结果。生产环境测试完记得删掉临时文件。不过 dd 测出来的只是大块顺序读写的极限带宽不代表实际业务的随机 IO 性能更精确的测试要用 fio 这类工具。8. 结尾写了这么多最后说点掏心窝的话。Linux 文件系统这块内容非常庞杂刚接触时容易觉得又杂又抽象什么 VFS、inode、超级块、日志、挂载听起来都是术语堆砌。但用多了你会发现它本质上就只是在回答几个问题数据放哪里、怎么找到数据、怎么保证数据可靠、怎么组织数据让读写高效。这几个问题想通了大部分命令和概念都会自然串起来。我自己的学习路径是先掌握命令遇到问题再去翻原理。比如磁盘满了就搞清楚为什么文件删了空间还不释放看到 fsck 就跑就搞明白它到底在修什么。这样从现象到原理印象会深得多。最后提醒一句无论你用什么文件系统都没有绝对的安全。磁盘会坏操作会误断电会来。多做备份多做恢复演练多留个心眼。文件系统是在帮你管理数据但数据的最终安全责任永远在你自己身上。
返回列表