VPS 突然变成只读文件系统时,很多命令都会开始报错:
Read-only file system
cannot create temp file
failed to write pid file
systemd[1]: Failed to start ...
You are in emergency mode
这类问题不要急着反复重启。文件系统被内核重新挂成只读,通常是为了避免继续写入导致更严重的数据损坏。你真正要做的是:先判断还能不能安全备份,再确认是空间问题、inode 问题、挂载配置问题,还是磁盘/文件系统本身已经出错。
如果你现在还能 SSH 进去,先别改一堆配置;如果已经进 emergency mode,就通过控制台或救援模式操作。
先看根分区挂载状态:
findmnt /
mount | grep ' on / '
如果看到类似:
/ rw,relatime,...
说明根分区仍是读写。此时写不了文件,可能是磁盘满、inode 耗尽、目录权限、配额或应用自身问题。
如果看到:
/ ro,relatime,...
这里的 ro 就是 read-only,根分区已经被只读挂载。此时不要直接把问题当成普通权限错误。
同时检查空间和 inode:
df -h
df -i
如果是空间满,可以先看:VPS 硬盘满了怎么办?磁盘清理 + 扩容。如果空间还有但 inode 用完,看这篇:VPS 显示磁盘还有空间却写不了文件:inode 耗尽排查。
文件系统变只读时,应用日志经常只会告诉你“写失败”,真正原因在内核日志里。
dmesg -T | tail -n 100
journalctl -k --since "2 hours ago"
重点找这些关键词:
EXT4-fs error
Buffer I/O error
blk_update_request
I/O error
Remounting filesystem read-only
XFS ... metadata I/O error
如果出现 Remounting filesystem read-only,说明内核检测到文件系统或块设备异常后主动把它重新挂成只读。
日志排查不熟的话,可以先参考:VPS 日志怎么看:journalctl、systemctl、Nginx、应用日志。
很多教程会直接给:
sudo mount -o remount,rw /
这条命令不是不能用,但不能作为第一步。
如果只是一次临时挂载参数异常,remount 可能恢复写入;但如果底层磁盘或文件系统已经报错,强行写入可能扩大损坏。更稳的顺序是:
- 看
dmesg/journalctl -k是否有 I/O 或文件系统错误。 - 先备份还读得到的重要数据。
- 判断是否需要进入 rescue mode 做
fsck。 - 修复后再挂载读写。
只有在日志没有明显磁盘/文件系统错误、你确认风险可控时,才尝试:
sudo mount -o remount,rw /
如果命令失败,记下错误,不要连续反复执行。
只读状态有时反而是一个机会:系统暂时不能写,但还能读。先把关键数据拿出来。
优先备份:
- 数据库 dump 或数据目录
/var/www、应用上传目录/etc/nginx、/etc/systemd/system、应用配置.env、密钥、证书- 最近日志和排障截图
如果机器还能联网,可以用 rsync 拉走:
rsync -aHAX --numeric-ids /var/www/ user@backup-server:/backup/vps-www/
如果网络不稳定,先压缩关键目录到另一个已挂载的正常数据盘,或者用面板快照/云盘快照。备份策略可以参考:VPS 自动备份方案。
重启后进 emergency mode,很常见的原因是 /etc/fstab 配错了:
- 写了不存在的 UUID。
- 挂载了已经被删除的云盘。
- 文件系统类型写错。
- 网络盘或对象存储挂载失败,但没有
nofail。 - 手动加了数据盘后,启动顺序不稳定。
查看 fstab:
cat /etc/fstab
blkid
lsblk -f
如果发现某个非根分区的 UUID 不存在,可以先临时注释掉那一行,然后重启验证。
对于非关键数据盘,建议加上 nofail,避免一块附加盘挂载失败就把整台 VPS 卡进 emergency mode:
UUID=xxxx /data ext4 defaults,nofail 0 2
不要给根分区乱加 nofail。根分区挂不上,本来就应该停下来处理。
如果根分区已经报 ext4 错误,通常需要 fsck。但对正在挂载的根分区直接 fsck 是危险操作。
更稳的做法:
- 进入 VPS 服务商提供的 rescue mode / recovery mode。
- 找到根分区设备名。
- 确认它没有被挂载。
- 执行 fsck。
查看分区:
lsblk -f
blkid
假设根分区是 /dev/vda1:
sudo fsck -f /dev/vda1
如果是 XFS,不能用 ext4 的 fsck 修复方式:
sudo xfs_repair /dev/vda1
注意:不同服务商 rescue 环境里的设备名可能从 /dev/vda1 变成 /dev/sda1 或 /dev/nvme0n1p1。一定以 lsblk -f 为准,不要复制别人的设备名。
如果日志里有大量 I/O error,例如:
Buffer I/O error on dev vda
blk_update_request: I/O error
这不一定是你系统里某个配置写错,也可能是:
- 云盘底层异常
- 宿主机存储抖动
- VPS 节点故障
- 超售导致 I/O 长时间异常
- 云盘被服务商迁移或限速
这时要保留日志,尽快开工单。工单里不要只写“机器坏了”,最好带上:
dmesg -T | tail -n 100
journalctl -k --since "6 hours ago"
lsblk -f
findmnt /
如果你怀疑是邻居资源争用或磁盘抖动,可以对照:VPS 超售怎么判断:CPU 偷跑、磁盘抖动、邻居抢资源。
fsck 或 xfs_repair 完成后,先挂载检查:
sudo mount /dev/vda1 /mnt
ls /mnt
重点看:
/mnt/lost+found是否有大量文件- 数据库目录是否完整
- 应用上传目录是否完整
/etc/fstab是否已修正- 日志里是否还有新的 I/O error
如果能正常启动,也不要马上把流量切回来。先检查服务:
systemctl --failed
journalctl -p err -b
数据库类服务尤其要谨慎。MySQL、PostgreSQL、Redis 这类服务如果在文件系统异常期间被强行中断,可能还需要各自的数据一致性检查。
下面几种情况,不建议继续在原盘上硬修:
dmesg持续出现 I/O error。- fsck 修复后很快再次变只读。
- 关键数据库文件损坏,且没有可靠校验。
- 服务商确认存储节点异常。
- 这台机器已经多次进入 emergency mode。
这时更稳的路线是:
- 从快照或备份恢复到新 VPS。
- 校验业务数据。
- 切换 DNS 或反向代理入口。
- 保留旧机只读状态用于补取数据。
迁移思路可以参考:VPS 迁移指南:换服务商/换机房怎么少停机。
遇到 read-only file system 或 emergency mode,按这个顺序处理:
findmnt /看根分区是否ro。df -h和df -i排除空间满和 inode 耗尽。dmesg -T/journalctl -k找文件系统和 I/O 错误。- 能读数据时先备份关键目录。
- 检查
/etc/fstab、blkid、lsblk -f是否匹配。 - 不要在已挂载根分区上直接 fsck。
- 进入 rescue mode,对未挂载分区执行
fsck或xfs_repair。 - 修复后检查
systemctl --failed和错误日志。 - 如果 I/O error 持续,优先迁移,不要继续赌原盘。
VPS 变成只读文件系统,不是普通“权限不够”。它往往是系统在保护数据:要么磁盘/文件系统出错,要么启动挂载配置不一致,要么底层云盘已经不稳定。
正确处理顺序是:先看日志和挂载状态,能读就先备份,再修 fstab 或进 rescue mode 做文件系统检查。能恢复是好事,但只要 I/O error 反复出现,就不要把业务继续押在原盘上,尽快迁移到新机器。
