How to reclaim all/most free space from a sparsebundle on OS X

Solution 1:

Interesting!

From what I've heard, the sparse bundle divides the data into 8Mb bands. Changing the band size might just help, if you're lucky. I mean, you'll never get 100% reclaimed space, but maybe better than what you get now. (Depending on the data on the image etc.)

I did a dirty simple test with two 500Mb sparse bundles, one with 8Mb (default) band size, and one with 1Mb (smallest allowed size from what I can tell). I copied over 400mb of mp3 files and then removed every other file and then run hdiutil compact on their asses.

Size after compact
8Mb bands: 271Mb
1Mb bands: 215Mb

The command to convert your sparse bundle is

hdiutil convert src.sparsebundle -format UDSB -tgtimagekey sparse-band-size=2048 -o dst.sparsebundle

Band size is in the unit 512byte. So the above example sets the band size to 512 * 2048 = 1Mb. Just be careful if you're dealing with TimeMachine images or user home folder images etc. You're deviating from the Apple path :) Keep a fail safe backup!

As for defragmentation: I have a funny feeling it's just as fast (or faster!) to just use hdiutil to convert the sparsefile to a new sparse file with the same format. I think it tries to be smart about it. But I don't know.

(Note that defragmenting a sparse bundle just defragments the disk data, not the sparse bundle bands, unless it's a sparse bundle aware defragmentor. hdiutil convert does a band 'defragmentation' I believe.)

Solution 2:

I think the 90.4 GB possible is plain wrong. When I ran:

hdiutil compact *.sparsebundle

...it freed up 16 GB of space, which is roughly what I expected. Funnily enough it said roughly "800 GB possible" which is way more than the capacity of my HD. So I assume the second figure is just some (flawed) theoretical number.


Solution 3:

@Oscar pointed us in the right direction. But you don't need to convert to 1 MB and compact, hoping to regain space.

Instead, just copy your sparsebundle to another new sparsebundle. This, in turn, defrags the image for you. And at the same time you can change filesystem, size and even the bands.

Here's an example I did recently, converting my 20GB "code" image that i sync across devices.

$ hdiutil create -size 20g -type SPARSEBUNDLE \
-imagekey sparse-band-size=2048 -fs HFSX \
-volname code -attach ~/sync/images/code.sparsebundle

See all options with hdiutil create -help.

This command outputs:

/dev/disk3              GUID_partition_scheme
/dev/disk3s1            EFI
/dev/disk3s2            Apple_HFS                       /Volumes/code
created: /Users/eric/sync/images/code.sparsebundle

You can see the -attach option mounted it under /Volumes/code.

Note: I use HSFX for case-sensitive HFS+ because I sync my images to Linux as well and mount them. You'll most likely want to use HFS+ instead, since macOS is normally case-insensitive.

Now all I have to do is copy everything to my new sparsebundle:

$ cp -r /Volumes/IMG_CODE/ /Volumes/code/

And now to compare:

# old sparsebundle
$ du -h ~/sync/images/IMG_CODE.sparsebundle/
15.0G   /Users/eric/sync/images/IMG_CODE.sparsebundle/bands
15.0G   /Users/eric/sync/images/IMG_CODE.sparsebundle/

# new sparsebundle
$ du -h ~/sync/images/code.sparsebundle/
3.0G    /Users/eric/sync/images/code.sparsebundle/bands
3.0G    /Users/eric/sync/images/code.sparsebundle/

Yay. My 15GB sparsebundle is now 3GB, defragged, and bands changed!

Tags:

Mac Osx