![Raspberry Pi:文件系统写入文件,但重启后旧数据又恢复了](https://linux22.com/image/989271/Raspberry%20Pi%EF%BC%9A%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F%E5%86%99%E5%85%A5%E6%96%87%E4%BB%B6%EF%BC%8C%E4%BD%86%E9%87%8D%E5%90%AF%E5%90%8E%E6%97%A7%E6%95%B0%E6%8D%AE%E5%8F%88%E6%81%A2%E5%A4%8D%E4%BA%86.png)
好吧,这是在两个具有各自 8GB SD 存储卡的树莓派系统上发生的一个非常奇怪的问题:
简单的例子:当我将文件写入磁盘时,看起来文件已经写入。
我可以编辑一个文件vim test.dat
,在其中输入文本,然后保存。ll
将列出该文件。cat
将显示文件的内容。重新启动后,该文件将消失。
所以我认为发生的事情是,ubuntu 将文件写入 ubuntu 的磁盘缓存,但不会将文件提交到磁盘。用户空间程序可以继续读取文件并使用它们,但缓存会从 RAM 而不是磁盘返回目录列表和文件内容。因为重新启动后磁盘没有任何新数据。
另一个例子:
dd if=/dev/zero of=testfile.dat bs=1M count=1000
它创建了一个 1GB 大小的文件。ll 列出了该文件。df -h 显示磁盘上的数据已使用了 1GB 以上。但重启后文件就消失了,df -h 显示的是原来的可用空间。
有趣的事实:我知道 SD 卡的最大写入速度是 9MB/秒,当我使用笔记本电脑将磁盘映像 dd 到 SD 卡上时,我得到的就是这个速度。但是在树莓派中的 SD 卡上运行这个 dd 命令时,dd 报告的写入速度为 110MB/秒。不可能。这就是为什么我认为操作系统只是写入 RAM 而不是提交到磁盘。
第三个示例:我有一个脚本,可以编辑名为“interfaces”的文件,然后以 root 身份将其复制到 /etc/network/interfaces 文件,以更改设备的 IP。然后脚本重新启动。
#!/bin/bash
cp /var/project/scripts/interfaces /etc/network/interfaces
/sbin/reboot
重启后,设备仍使用旧的 IP 地址...奇怪...
第四个例子:树莓派运行一个 percona 数据库。我有一个包含 186 个条目的表。我截断了该表。使用 php 代码和 webmin 查看数据 - 表是空的,就像它应该的那样。重启后数据恢复了。真的……186 个条目。这让我很害怕。
我可能完全错了。有什么想法吗?
我一直在研究这个 ubuntu 安装,并在每次重大软件更新后通过克隆磁盘映像进行定期备份。我注意到了一些奇怪的事情(比如运行我的脚本后 IP 没有改变),但直到今天我才意识到这个问题,似乎我克隆的所有磁盘映像都出现了这个问题。它一定运行良好,直到某个时候,pi 上的 ubuntu 出了问题……
问题:我该怎么做才能让 ubuntu 写入 SD 卡?
答案1
似乎对我有帮助的是使用同步命令:
sync
来自帮助:
强制将改变的块写入磁盘,更新超级块。
换句话说,它会刷新文件系统缓冲区。但是,我认为当您sudo reboot
像我一样正确执行操作时,这不会有问题,因此同步可能对您不起作用。
我在安装 raspbian wheezy 时也遇到了类似的问题。它有一个 ext4 分区,其中包含只读文件系统。还有一个小型读写分区,其中包含一些配置文件,格式为 FAT32。当我更改配置文件然后拔掉电源插头重新启动时,更改不会持久。(请注意:如果没有只读 Pi,拔掉电源插头无论如何都不是明智之举)
答案2
我的三星 EVO 18G MicroSD 卡也存在同样的问题。很多人在树莓派论坛上讨论过这个问题:https://www.raspberrypi.org/forums/viewtopic.php?t=21330#p992573
最有可能的是 SD 卡已损坏。
答案3
我遇到了完全相同的问题。我通过以下步骤解决了此问题:
步骤1:
root=PARTUUID=
观察从之后指定的值/boot/cmdline.txt
:cat /boot/cmdline
就我而言,我发现了类似的东西
093bedcc-02
:boot=overlay console=tty1 root=PARTUUID=093bedcc-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
第2步:
root=PARTUUID=
使用上一步中的指定值查找 PATH (有关格式化输出的lsblk
更多详细信息,请阅读):man lsblk
lsblk -o NAME,FSTYPE,LABEL,UUID,PARTUUID,MOUNTPOINT,PATH
就我而言,我得到了如下信息:
NAME FSTYPE LABEL UUID PARTUUID MOUNTPOINT PATH mmcblk0 /dev/mmcblk0 ├─mmcblk0p1 vfat boot BC50-2AE4 093bedcc-01 /boot /dev/mmcblk0p1 └─mmcblk0p2 ext4 rootfs 9b87f948-9dc3-49e7-94fc-309bfabb1ac4 093bedcc-02 / /dev/mmcblk0p2
就我而言,我得到了小路值为
/dev/mmcblk0p2
。步骤3:现在通过在前面添加以下内容
root=PARTUUID=
来替换其 PATH 值(在我的情况下为/dev/mmcblk0p2
)root=
:root=/dev/mmcblk0p2
步骤4:最后使用以下命令重新启动系统:
sudo reboot