<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>磁盘 on 寻 Mi 处</title>
        <link>https://blog.mibase.top/tags/%E7%A3%81%E7%9B%98/</link>
        <description>Recent content in 磁盘 on 寻 Mi 处</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh</language>
        <lastBuildDate>Mon, 26 Oct 2026 19:45:00 +0800</lastBuildDate><atom:link href="https://blog.mibase.top/tags/%E7%A3%81%E7%9B%98/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>df 说盘满了，du 加起来却只有一半，那二十多个 G 去哪了</title>
            <link>https://blog.mibase.top/p/df-du-mismatch/</link>
            <pubDate>Mon, 26 Oct 2026 19:45:00 +0800</pubDate>
            <guid>https://blog.mibase.top/p/df-du-mismatch/</guid>
            <description>&lt;img src=&#34;https://blog.mibase.top/p/df-du-mismatch/cover.jpg&#34; alt=&#34;Featured image of post df 说盘满了，du 加起来却只有一半，那二十多个 G 去哪了&#34; /&gt;&lt;p&gt;周日晚上快十一点，手机震了一下，Uptime Kuma 的推送：Gitea 挂了，HTTP 502。&lt;/p&gt;&#xA;&lt;p&gt;我当时躺在床上刷东西，本来想着明天再说，但是又想到这台机子上除了 Gitea 还跑着我的 RSS、一个自己写的书签服务，还有这个博客的评论后端（虽然现在评论已经关了），拖到明天总觉得心里不踏实，就爬起来开了电脑。&lt;/p&gt;&#xA;&lt;p&gt;机器是年初在某家小厂买的，2 核 2G，40G 的系统盘，Debian 12。便宜，一年一百出头，所以我对它的期待一直很低，只要别动不动就挂就行。&lt;/p&gt;&#xA;&lt;h2 id=&#34;先是个很普通的开头&#34;&gt;先是个很普通的开头&#xA;&lt;/h2&gt;&lt;p&gt;ssh 上去之后第一反应当然是看 Gitea 为什么挂：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;systemctl status gitea&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;journalctl -u gitea -n &lt;span class=&#34;m&#34;&gt;50&lt;/span&gt; --no-pager&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;日志里一堆 &lt;code&gt;no space left on device&lt;/code&gt;，往 sqlite 里写不进去，起不来。&lt;/p&gt;&#xA;&lt;p&gt;行吧，盘满了。这种事不算稀奇，小机器上日志、docker 镜像、apt 缓存，哪个都能吃掉几个 G。我顺手 &lt;code&gt;df -h&lt;/code&gt;：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Filesystem      Size  Used Avail Use% Mounted on&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/dev/vda1        40G   38G     0 100% /&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;tmpfs           987M     0  987M   0% /dev/shm&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;注意这个 Avail 是 0，Used 是 38G，加起来不到 40，是因为 ext4 默认给 root 留了 5% 的保留块。这个我知道，不是问题。&lt;/p&gt;&#xA;&lt;p&gt;问题在后面。&lt;/p&gt;&#xA;&lt;p&gt;我习惯性地进根目录跑一下 du，找大头：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; /&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;du -xh --max-depth&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; 2&amp;gt;/dev/null &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sort -h &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; tail&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;等了一会儿，结果：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;310M    ./opt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;1.1G    ./usr&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;1.4G    ./home&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2.3G    ./var/lib   （这是我后面单独看的）&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;5.8G    ./var&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;14G     .&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;整个根分区 du 出来才 14G。df 说用了 38G。&lt;/p&gt;&#xA;&lt;p&gt;差了二十四个 G，这就不对了。&lt;/p&gt;&#xA;&lt;h2 id=&#34;第一个怀疑挂载点底下藏了东西&#34;&gt;第一个怀疑：挂载点底下藏了东西&#xA;&lt;/h2&gt;&lt;p&gt;遇到 df 比 du 大很多的情况，我脑子里最先蹦出来的是挂载遮盖。&lt;/p&gt;&#xA;&lt;p&gt;大概是这么回事：假如 &lt;code&gt;/data&lt;/code&gt; 本来是个单独的目录，里面已经写了一堆文件，后来你又把另一块盘挂到 &lt;code&gt;/data&lt;/code&gt; 上，那原来目录里的文件并没有消失，只是被新挂上去的文件系统盖住了，&lt;code&gt;ls&lt;/code&gt; 看不到，&lt;code&gt;du&lt;/code&gt; 也扫不到，但它们依然占着根分区的空间。&lt;/p&gt;&#xA;&lt;p&gt;我之前真干过这事，是在另一台机子上，数据盘忘了挂，服务先起来了，往 &lt;code&gt;/data&lt;/code&gt; 里写了几个 G，后来补挂了盘，那几个 G 就成了幽灵。&lt;/p&gt;&#xA;&lt;p&gt;所以先看这台机子有哪些挂载：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;findmnt -lo TARGET,SOURCE,FSTYPE &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep -v -E &lt;span class=&#34;s1&#34;&gt;&amp;#39;proc|sys|cgroup|tmpfs|devpts|mqueue&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;TARGET                 SOURCE         FSTYPE&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/                      /dev/vda1      ext4&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/boot/efi              /dev/vda15     vfat&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/var/lib/docker/overlay2/....   overlay&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;除了 docker 的 overlay 就没有别的了，我这台机子压根没挂过别的盘。&lt;/p&gt;&#xA;&lt;p&gt;不过我还是想确认一下，因为&amp;quot;我记得没有&amp;quot;这种话在运维里最不可靠。有个办法是把根分区再 bind 挂载一次，这样挂载点底下的东西就能看到：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;mkdir /mnt/rootcheck&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;mount --bind / /mnt/rootcheck&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;du -xsh /mnt/rootcheck&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;umount /mnt/rootcheck&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;bind mount 出来的是根文件系统本身，不带子挂载，所以被遮住的内容会露出来。结果是 14G，和之前一样。&lt;/p&gt;&#xA;&lt;p&gt;这条路排除了。&lt;/p&gt;&#xA;&lt;h2 id=&#34;第二个怀疑inode&#34;&gt;第二个怀疑：inode&#xA;&lt;/h2&gt;&lt;p&gt;df 有两个维度，一个是块，一个是 inode。有时候块没满但是 inode 用光了，同样报 &lt;code&gt;no space left on device&lt;/code&gt;。不过这次 &lt;code&gt;df -h&lt;/code&gt; 里块本身就是满的，按理说和 inode 无关，但我还是顺手看了一眼：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;df -i /&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Filesystem      Inodes  IUsed   IFree IUse% Mounted on&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/dev/vda1      2621440 412873 2208567   16% /&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;16%，很健康。&lt;/p&gt;&#xA;&lt;p&gt;这里说一句题外话，我以前遇到过一次真的是 inode 耗尽的，是某个 PHP 应用的 session 目录里堆了上百万个几百字节的小文件，&lt;code&gt;df -h&lt;/code&gt; 看一半空着，就是写不进去。那种情况下 &lt;code&gt;ls&lt;/code&gt; 那个目录都能卡半分钟。这次不是。&lt;/p&gt;&#xA;&lt;h2 id=&#34;第三个怀疑docker&#34;&gt;第三个怀疑：docker&#xA;&lt;/h2&gt;&lt;p&gt;du 我加了 &lt;code&gt;-x&lt;/code&gt;，意思是不跨文件系统。docker 的 overlay2 虽然在 &lt;code&gt;/var/lib/docker&lt;/code&gt; 下面，但它自己的 merged 目录是 overlay 挂载，&lt;code&gt;-x&lt;/code&gt; 会跳过它们，但 &lt;code&gt;/var/lib/docker/overlay2//diff&lt;/code&gt; 这些层本身是普通目录，是会被统计到的。所以 docker 的镜像和层其实已经算在那个 14G 里了。&lt;/p&gt;&#xA;&lt;p&gt;保险起见我还是问了一下 docker 自己：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker system df&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;TYPE            TOTAL   ACTIVE   SIZE      RECLAIMABLE&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Images          9       6        3.2GB     1.1GB (34%)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Containers      7       6        412MB     0B&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Local Volumes   5       4        1.9GB     310MB&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Build Cache     0       0        0B        0B&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;加起来五六个 G，对得上，也远远凑不够那 24G。&lt;/p&gt;&#xA;&lt;p&gt;容器的 json 日志呢？&lt;code&gt;/var/lib/docker/containers/*/*-json.log&lt;/code&gt;，这个也是 docker 目录下的普通文件，du 会算。我又单独 &lt;code&gt;ls -lh&lt;/code&gt; 了一遍，最大的是 Uptime Kuma 的，80 多 M。不是它。&lt;/p&gt;&#xA;&lt;p&gt;到这里我已经折腾了二十来分钟了，有点烦。&lt;/p&gt;&#xA;&lt;h2 id=&#34;想起来一件事&#34;&gt;想起来一件事&#xA;&lt;/h2&gt;&lt;p&gt;我坐在那儿盯着屏幕，忽然想起上个周末干过的一件事。&lt;/p&gt;&#xA;&lt;p&gt;有个小爬虫脚本，抓一些我关注的站点的更新，用 &lt;code&gt;nohup python3 crawl.py &amp;gt; crawl.log 2&amp;gt;&amp;amp;1 &amp;amp;&lt;/code&gt; 挂在后台跑。上周末我发现 crawl.log 已经长到好几个 G 了（脚本里有个 debug 输出忘了关，每抓一个页面就把整个 HTML 打一遍），我当时看了一眼，想着反正不重要，直接：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;rm ~/crawl/crawl.log&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;然后就去干别的了。&lt;/p&gt;&#xA;&lt;p&gt;没有重启脚本。&lt;/p&gt;&#xA;&lt;p&gt;这在 Linux 下是个经典的坑，但我居然自己踩了。&lt;code&gt;rm&lt;/code&gt; 删的只是目录项，也就是文件名到 inode 的那条链接。只要还有进程打开着这个文件，inode 和它的数据块就不会被释放，进程照样往里写，只是你再也在任何目录里找不到这个文件了。&lt;/p&gt;&#xA;&lt;p&gt;所以 du 看不见它，因为 du 是顺着目录树往下走的，目录树里已经没有这个名字了。df 看得见，因为 df 问的是文件系统，文件系统知道这些块还被占着。&lt;/p&gt;&#xA;&lt;p&gt;这就解释了为什么两边对不上。&lt;/p&gt;&#xA;&lt;h2 id=&#34;验证一下&#34;&gt;验证一下&#xA;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;lsof&lt;/code&gt; 有个选项专门找这种东西，&lt;code&gt;+L1&lt;/code&gt; 的意思是列出链接数小于 1 的已打开文件，也就是已删除但还开着的：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;lsof +L1 2&amp;gt;/dev/null &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; head&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;COMMAND   PID USER   FD   TYPE DEVICE   SIZE/OFF NLINK     NODE NAME&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;python3  1873 zhou    1w   REG  254,1 24831209472     0   915487 /home/zhou/crawl/crawl.log (deleted)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;python3  1873 zhou    2w   REG  254,1 24831209472     0   915487 /home/zhou/crawl/crawl.log (deleted)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;SIZE 那一列 24831209472，除以 1024 三次，23.1G。&lt;/p&gt;&#xA;&lt;p&gt;就是它。后面还跟着一个很显眼的 &lt;code&gt;(deleted)&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;p&gt;fd 1 和 fd 2 是标准输出和标准错误，当初重定向的时候 &lt;code&gt;2&amp;gt;&amp;amp;1&lt;/code&gt; 让它们指向了同一个文件。所以同一个文件开了两次，lsof 列出两行，但占的空间只有一份，不要重复加。&lt;/p&gt;&#xA;&lt;p&gt;一周的时间，这个脚本往一个我以为已经不存在的文件里写了二十三个 G。我现在回头想想，那个 debug 输出的量大得有点离谱，可能当时那个站点对爬虫做了什么重定向循环，脚本一直在重试。反正这是另一个问题了。&lt;/p&gt;&#xA;&lt;h2 id=&#34;怎么处理&#34;&gt;怎么处理&#xA;&lt;/h2&gt;&lt;p&gt;有两个办法。&lt;/p&gt;&#xA;&lt;p&gt;最直接的是把进程杀了。进程一退出，所有 fd 关闭，内核发现这个 inode 没有任何引用，就会释放空间。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;kill&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;1873&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;但是我这次想先试试不杀进程的做法，原因也没什么，就是想验证一下，顺便以后遇到不能随便杀的进程也有个预案。&lt;/p&gt;&#xA;&lt;p&gt;Linux 的 &lt;code&gt;/proc//fd/&lt;/code&gt; 下面有这个进程所有打开的文件描述符，每一个都是一个符号链接，即便指向的文件已经被删除，通过这个链接依然能访问到它。所以可以直接把它截断：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;: &amp;gt; /proc/1873/fd/1&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;那个冒号是 shell 的空命令，加上重定向就是把文件截成 0 字节。也可以用 &lt;code&gt;truncate -s 0 /proc/1873/fd/1&lt;/code&gt;，效果一样。&lt;/p&gt;&#xA;&lt;p&gt;跑完之后马上 &lt;code&gt;df -h&lt;/code&gt;：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/dev/vda1        40G   14G   24G  38% /&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;空间一下就回来了。&lt;/p&gt;&#xA;&lt;p&gt;这里有个要注意的点。我截断的是 fd 1，但 fd 2 指向同一个文件，同一个 inode。如果进程是用 &lt;code&gt;O_APPEND&lt;/code&gt; 打开的（shell 的 &lt;code&gt;&amp;gt;&lt;/code&gt; 重定向其实不是，它是 &lt;code&gt;O_TRUNC&lt;/code&gt;，不带 append），那截断之后写入位置会回到文件末尾，也就是新的 0；但如果不是 append 模式，进程内部的文件偏移量还停在原来 23G 的位置，下一次写入的时候会从 23G 那里开始写，文件系统会产生一个稀疏文件，大小显示还是 23G，但实际块占用很小。&lt;/p&gt;&#xA;&lt;p&gt;我这次用的是 &lt;code&gt;&amp;gt;&lt;/code&gt;，没带 append，所以其实就是后面那种情况。我又跑了一次 &lt;code&gt;ls -l /proc/1873/fd/1&lt;/code&gt;，大小显示又变回了几百兆，因为脚本还在继续写，偏移量不对，形成了空洞。实际占的磁盘块不多，所以空间没有问题，但这个文件的&amp;quot;表面大小&amp;quot;会很吓人。&lt;/p&gt;&#xA;&lt;p&gt;说得有点绕。总之如果要长期这么做，应该用 &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; 重定向启动脚本，这样 truncate 完了偏移量会自己跟到文件末尾。&lt;/p&gt;&#xA;&lt;p&gt;我最后还是把那个脚本杀掉了，没打算留着它，重新启动的时候改成了：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nohup python3 crawl.py &amp;gt;&amp;gt; ~/crawl/crawl.log 2&amp;gt;&lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;顺便把那个愚蠢的 debug 输出删了。&lt;/p&gt;&#xA;&lt;h2 id=&#34;gitea-还是没起来&#34;&gt;Gitea 还是没起来&#xA;&lt;/h2&gt;&lt;p&gt;空间回来之后我 &lt;code&gt;systemctl restart gitea&lt;/code&gt;，还是起不来，报 &lt;code&gt;database disk image is malformed&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;p&gt;这个我一点都不意外，sqlite 在写到一半磁盘满了，很可能把库写坏了。&lt;/p&gt;&#xA;&lt;p&gt;好在 Gitea 每天凌晨有个备份，是我之前随手加的 cron，用 &lt;code&gt;gitea dump&lt;/code&gt; 打包到 &lt;code&gt;/home/zhou/backup/&lt;/code&gt;。去看了一下，昨天凌晨的包是正常的，3.1M。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;systemctl stop gitea&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cp /var/lib/gitea/data/gitea.db /var/lib/gitea/data/gitea.db.broken&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sqlite3 /var/lib/gitea/data/gitea.db &lt;span class=&#34;s2&#34;&gt;&amp;#34;PRAGMA integrity_check;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;输出了一大堆 &lt;code&gt;*** in database main ***&lt;/code&gt; 和 &lt;code&gt;Page xxx: btree page is out of order&lt;/code&gt; 之类的，确实坏了。&lt;/p&gt;&#xA;&lt;p&gt;我先试了一下 &lt;code&gt;.recover&lt;/code&gt;：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sqlite3 gitea.db.broken &lt;span class=&#34;s2&#34;&gt;&amp;#34;.recover&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sqlite3 gitea.db.recovered&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;恢复出来的库能打开，&lt;code&gt;integrity_check&lt;/code&gt; 也是 ok。但我不太敢直接用它，因为 &lt;code&gt;.recover&lt;/code&gt; 对丢失的页面是尽力而为，我没法确认有没有悄悄丢了行。最后还是选了稳一点的做法，用昨天的备份还原，然后把昨天备份之后的提交让自己的几个仓库重新 push 一遍（仓库本身是文件系统里的 git 目录，不在 sqlite 里，没有损坏，只是 issue、评论这些元数据可能丢了一天的内容）。&lt;/p&gt;&#xA;&lt;p&gt;查了一下，实际上我昨天到今天没有开过 issue，所以什么都没丢。运气。&lt;/p&gt;&#xA;&lt;p&gt;十二点过十分的时候 Gitea 重新能打开了。&lt;/p&gt;&#xA;&lt;h2 id=&#34;之后加的两样东西&#34;&gt;之后加的两样东西&#xA;&lt;/h2&gt;&lt;p&gt;这事之后我加了两样东西，都不复杂。&lt;/p&gt;&#xA;&lt;p&gt;第一个是磁盘告警。Uptime Kuma 能做 push 类型的监控，我就写了个很短的脚本放在 cron 里，每五分钟跑一次，用量超过 85% 就不推送心跳，Kuma 那边超时就会告警：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#!/bin/bash&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;used&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;df --output&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;pcent / &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; tail -1 &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; tr -dc &lt;span class=&#34;s1&#34;&gt;&amp;#39;0-9&amp;#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$used&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; -lt &lt;span class=&#34;m&#34;&gt;85&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    curl -fsS -m &lt;span class=&#34;m&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://kuma.example.com/api/push/xxxxxxxx?status=up&amp;amp;msg=&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;used&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;%25&amp;#34;&lt;/span&gt; &amp;gt;/dev/null&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;之前我只监控了服务能不能访问，等到服务挂了磁盘早就满了。这次从报警到发现原因其实还算快，但本来可以更早的，一周前它就开始涨了。&lt;/p&gt;&#xA;&lt;p&gt;第二个是给后台脚本一个正经的归宿。以后这类东西一律写成 systemd 的 service，日志交给 journald，journald 本身有大小限制（&lt;code&gt;SystemMaxUse&lt;/code&gt;），不用我再操心。&lt;code&gt;nohup&lt;/code&gt; 加重定向这种做法，我以前觉得方便，现在觉得它方便的地方恰好就是它危险的地方，因为它没有任何人替你管那个文件。&lt;/p&gt;&#xA;&lt;h2 id=&#34;顺便记一下以后的排查顺序&#34;&gt;顺便记一下以后的排查顺序&#xA;&lt;/h2&gt;&lt;p&gt;下次再遇到 df 和 du 对不上，我大概按这个顺序来：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;code&gt;lsof +L1&lt;/code&gt;，最快，一条命令，十有八九是它&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;df -i&lt;/code&gt;，看是不是 inode&lt;/li&gt;&#xA;&lt;li&gt;bind mount 一下根，看挂载遮盖&lt;/li&gt;&#xA;&lt;li&gt;再去翻 docker、日志这些&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;我这次顺序反了，先去查了挂载和 docker，最后才想起来 lsof。其实如果当时多想一秒，就应该先怀疑&amp;quot;有没有什么东西在往已经没有名字的地方写&amp;quot;，毕竟 du 看不到的东西，本质上就只有那么几类。&lt;/p&gt;&#xA;&lt;p&gt;另外那个被我 rm 掉的 crawl.log，名字至今还躺在我 shell 的 history 里，&lt;code&gt;rm ~/crawl/crawl.log&lt;/code&gt; 那一行，我现在每次 ctrl+r 都能看到它，像个纪念碑。&lt;/p&gt;&#xA;</description>
        </item></channel>
</rss>
