Running Out of Disk Space in Production

(alt-romes.github.io)

113 points | by romes 4 days ago

17 comments

  • flanfly 4 hours ago
    A neat trick I was told is to always have ballast files on your systems. Just a few GiB of zeros that you can delete in cases like this. This won't fix the problem, but will buy you time and free space for stuff like lock files so you can get a working system.
    • layer8 2 hours ago
      Better fill those files with random bytes, to ensure the filesystem doesn’t apply some “I don’t actually have to store all-zero blocks” sparse-file optimization. To my knowledge no non-compressing file system currently does this, but who knows about the future.
      • freedomben 2 hours ago
        Yep, btrfs will happily do this to you. I verified it the hard way
        • kccqzy 2 hours ago
          Well btrfs supports compression so that’s understandable. However I personally prefer to control compression manually so it only compresses files marked by me for compression using chattr(1).
      • ape4 2 hours ago
        If I recall correctly:

            dd if=/dev/urandom of=/home/myrandomfile bs=1 count=N
        • fragmede 27 minutes ago
          bs=1 is a recipe for waiting far longer than you have to because of the overhead of the system calls. Better bs=N count=1
    • dspillett 3 hours ago
      Similarly, I always leave some space unallocated on LMV volume groups. It means that I can temporarily expand a volume easily if needed.

      It also serves to leave some space unused to help out the wear-levelling on the SSDs on which the RAID array that is the PV¹ for LVM. I'm, not 100% sure this is needed any more² but I've not looked into that sufficiently so until I do I'll keep the habit.

      --------

      [1] if there are multiple PVs, from different drives/arrays, in the VG, then you might need to manually skip a bit on each one because LVM will naturally fill one before using the next. Just allocate a small LV specially on each and don't use it. You can remove one/all of them and add the extents to the fill LV if/when needed. Giving it a useful name also reminds you why that bit of space is carved out.

      [2] drives under-allocate by default IIRC

    • dijit 2 hours ago
      I always called it a “bit-mass”. Like a thermal mass used in freezers in places where the power is not very stable.

      I knew I didn’t invent the concept, as there’s so many systems that cannot recover if the disk is totally full. (a write may be required in many systems in order to execute an instruction to remove things gracefully).

      The latest thing I found with this issue is Unreal Engines Horde build system, its so tightly coupled with caches, object files and database references: that a manual clean up is extremely difficult and likely to create an unstable system. But you can configure it to have fewer build artefacts kept around and then it will clear itself out gracefully. - but it needs to be able to write to the disk to do it.

      Now that I think about it, I don’t do this for inodes, but you can run out of those too and end up in a weird “out of disk” situation despite having lots of usable capacity left.

    • throw0101d 3 hours ago
      > A neat trick I was told is to always have ballast files on your systems.

      ZFS has a "reservation" mechanism that's handy:

      > The minimum amount of space guaranteed to a dataset, not including its descendants. When the amount of space used is below this value, the dataset is treated as if it were taking up the amount of space specified by refreservation. The refreservation reservation is accounted for in the parent datasets' space used, and counts against the parent datasets' quotas and reservations.

      * https://openzfs.github.io/openzfs-docs/man/master/7/zfsprops...

      Quotas prevent users/groups/directories (ZFS datasets) from using too much space, but reservations ensure that particular areas always have a minimum amount set aside for them.

      • throw0101d 1 hour ago
        Typo; link should be:

        * https://openzfs.github.io/openzfs-docs/man/master/7/zfsprops...

        Addendum: there's also the built-in compression functionality:

        > When set to on (the default), indicates that the current default compression algorithm should be used. The default balances compression and decompression speed, with compression ratio and is expected to work well on a wide variety of workloads. Unlike all other settings for this property, on does not select a fixed compression type. As new compression algorithms are added to ZFS and enabled on a pool, the default compression algorithm may change. The current default compression algorithm is either lzjb or, if the lz4_compress feature is enabled, lz4.

        * https://openzfs.github.io/openzfs-docs/man/master/7/zfsprops...

      • dizhn 2 hours ago
        Also if you VMs on a disk backed by ZFS it's trivial to extend those disks provided you actually do have space on the real disk. (Even automatic with LXC).
    • happycrappy 1 hour ago
      Interesting strategy, can't believe I've never heard of this one before.

      Would it be more pragmatic to allocate a swap file instead? Something that provides a theoretical benefit in the short term vs a static reservation.

    • HoldOnAMinute 1 hour ago
      Sounds like something straight out of Dilbert
    • fifilura 4 hours ago
      I did this too, but i also zipped the file, turns out it had great packing ratio!
      • saagarjha 4 hours ago
        Personally I just keep the file on a ramdisk so you can avoid having to fetch it from slow storage
        • 3form 2 hours ago
          Neat! I optimized for my own case, and I'm storing my ramdisk on SSD to gain persistence.
    • ninalanyon 4 hours ago
      This is why I never empty the Rubbish Bin/trash Can on my Linux laptop until the disk fills.
    • Chaosvex 3 hours ago
      Similar to the old game development trick of hiding some memory away and then freeing it up near the end of development when the budget starts getting tight.
    • dj0k3r 2 hours ago
      I did this recently, aka, docker images prune. Can confirm, saved the day.
    • omarqureshi 4 hours ago
      Surely a 50% warning alarm on disk usage covers this without manual intervention?
      • evil-olive 9 minutes ago
        > Surely a 50% warning alarm on disk usage covers this without manual intervention?

        surely you don't need a fire extinguisher in your kitchen, if you have a smoke detector?

        a "warning alarm" is a terrible concept, in general. it's a perfect way to lead to alert fatigue.

        over time, you're likely to have someone silence the alarm because there's some host sitting at 57% disk usage for totally normal reasons and they're tired of getting spammed about it.

        even well-tuned alert rules (ones that predict growth over time rather than only looking at the current value) tend to be targeted towards catching relatively "slow" leaks of disk usage.

        there is always the possibility for a "fast" disk space consumer to fill up the disk more quickly than your alerting system can bring it to your attention and you can fix it. at the extreme end, for example, a standard EBS volume has a throughput of 125mb/sec. something that saturates that limit will fill up 10gb of free space in 80 seconds.

      • theshrike79 4 hours ago
        Depends. A Kubernetes container might have only a few megabytes of disk space, because it shouldn't need it.

        Except that one time when .NET decides that the incoming POST is over some magic limit and it doesn't do the processing in-memory like before, but instead has to write it to disk, crashing the whole pod. Fun times.

        Also my Unraid NAS has two drives in "WARNING! 98% USED" alert state. One has 200GB of free space, the other 330GB. Percentages in integers don't work when the starting number is too big :)

      • coredog64 2 hours ago
        You don't want an alarm on a usage threshold, you want a linear regression that predicts when utilization will cross a threshold. Then you set your alarms for "How long does it take me to remediate this condition?"
      • jcims 4 hours ago
        If the alarms are reliably configured, confirmed to be working, low noise enough to be actioned, etc etc.

        And of course there's nothing to say that both of these things can't be done simultaneously.

      • dspillett 4 hours ago
        If the alarm works. And it actioned not just snoozed too much or just dismissed entirely.

        Defence in depth is a good idea: proper alarms, and a secondary measure in case they don't have the intended effect.

        • pixl97 3 hours ago
          Alarms are great, but when something goes wrong SSDs can fill up amazingly fast!
        • n4r9 3 hours ago
          Surely there are pitfalls either way. A ballast file can be deleted too readily, or someone could forget to re-add it.
        • jamiemallers 2 hours ago
          [dead]
    • bombcar 3 hours ago
      Some filesystems can be unable to delete a file if full. Something to be a bit worried about.
      • 6031769 1 hour ago
        Please name and shame those filesystems so that we will all be forewarned.
        • SAI_Peregrinus 24 minutes ago
          Any Copy-on-Write filesystem can run into this. There's always some way around it, but it can be problematic if you only have one device, can't remember the steps to fix a full filesystem, and can't look up the steps because you can't launch a browser without it trying to make some files!
    • jaapz 4 hours ago
      Love the simplicity and pragmatism of this solution
    • testplzignore 4 hours ago
      Would another way be to drop the reserved space (typically 1% to 5% on an ext file system)?
      • bombcar 3 hours ago
        Reserved space doesn't protect you against root, who is often the user to blame for the last used MB.
  • dirkt 2 hours ago
    If you run nginx anyway, why not serve static files from nginx? No need for temporary files, no extra disk space.

    The authorization can probably be done somehow in nginx as well.

    • aftbit 1 hour ago
      Yeah it's a bit odd to use a Haskell server to serve a static file which nginx then needs to buffer. You'd do much much better just serving the file out of nginx. You could authenticate requests using the very simple auth_request module:

      https://nginx.org/en/docs/http/ngx_http_auth_request_module....

    • kccqzy 1 hour ago
      Even if your authorization is so sophisticated that nginx cannot do it, a common pattern I’ve seen is to support a special HTTP response header for the reverse proxy to read directly from disk after your custom authorization code completes. This trick dates back to at least 2010. The nginx version of this seemed to be called X-Accel-Redirect from a quick search.
  • ilaksh 15 minutes ago
    I'm not sure that his problems are really over if a LOT of people were downloading a 2GB file. It would depend on the plan. Especially if his server is in the US.

    But maybe the European Hetzner servers still have really big limits even for small ones.

    But still, if people keep downloading, that could add up.

  • entropie 3 hours ago
    > I rushed to run du -sh on everything I could, as that’s as good as I could manage.

    I recently came across gdu (1) and have installed/used it on every machine since then.

    [1]: https://github.com/dundee/gdu

    • dizhn 1 hour ago
      gdu is really nice but ncdu, though slower, is very useful and is usually available on distro repos.
    • Neil44 2 hours ago
      I also discovered gdu recently. It's really good. It saves me running du -h --max-depth=1 | sort -h a million times trying to find where the space has gone while you're stressing about production being down.
    • NitpickLawyer 2 hours ago
      I use dust for this, but gdu looks nice, I'll give it a try. Thanks for sharing.
    • illusive4080 2 hours ago
      Have you used ncdu? I wonder how this compares.
  • gmuslera 1 hour ago
    Putting limits on folders where information may be added (with partitions or project quotas) is a proactive way to avoid that something misbehaves and fills the whole disk. Filling that partition or quota may still cause some problems, depending on the applications writing there, but the impact may be lower and easier to fix than running out of space for everything.
  • jollymonATX 29 minutes ago
    Never partition 100%. Simple solution here really and should be standard for every sysadmin. Like never worked with one that needed to be told this...
  • nottorp 28 minutes ago
    Didn't root used to have some reserved space (and a bunch of inodes) on file systems just for occasions like this?
  • bdcravens 2 hours ago
    I appreciate the last line

    > Note: this was written fully by me, human.

  • grugdev42 54 minutes ago
    You missed out point five.

    5. Implement infrastructure monitoring.

    Assuming you're on something like Ubuntu, the monit program is brilliant.

    It's open source and self hosted, configured using plain text files, and can run scripts when thresholds are met.

    I personally have it configured to hit a Slack webhook for a monitoring channel. Instant notifications for free!

  • renatovico 23 minutes ago
    Why not implement x send file ?
  • huijzer 2 hours ago
    > Plausible Analytics, with a 8.5GB (clickhouse) database

    And this is why I tried Plausible once and never looked back.

    To get basic but effective analytics, use GoAccess and point it at the Caddy or Nginx logs. It’s written in C and thus barely uses memory. With a few hundreds visits per day, the logs are currently 10 MB per day. Caddy will automatically truncate if logs go above 100 MB.

  • brunoborges 2 hours ago
    I remember a story of an Oracle Database customer who had production broken for days until an Oracle support escalation led to identifying the problem as mere "No disk space left".
    • AbraKdabra 2 hours ago
      Or NTP, if something is not working df -h and date are the first commands I input.

      It's always lupu... I mean NTP or disk space.

  • RALaBarge 1 hour ago
    Wait until you run out of inodes!
  • MeetRickAI 17 minutes ago
    [dead]
  • tcp_handshaker 3 hours ago
    [dead]
  • giahoangwin 2 hours ago
    [dead]