Бывало ли у вас такое, что Time Machine просто доводит до белого каления, когда нужно срочно закончить работу, а она начинает копировать какие-то дикие гигабайты непонятно чего? Недавно я столкнулся с этим. Понятно, что проблема была отнюдь не в Time Machine, а в рабочих файлах размером в десяток гигабайт и свежесписанных эпизодах зимней Олимпиады в iTunes. Но от этого было не легче, я смог разобраться с этим после окончания работы, а до этого постоянно жал на “Stop Backup” (сейчас я подумал, что вполне мог бы просто отключить запуск Time Machine при работе от аккумулятора и выдернуть питание – этот метод гораздо элегантнее).

Когда я освободился, то с помощью DaisyDisk нашёл пожирателей дискового пространства. Теперь моя конфигурация исключений для Time Machine такая:

Но в процессе размышлений я подумал, что неплохо было бы знать, что именно поместилось в бекап Time Machine – так можно хотя бы постфактум найти каталоги, содержимое которых не нужно было копировать, и добавить их в исключения.

Сказано – сделано. Я нашёл две очень полезных статьи – “X.5 Time Machine” и “List Files and Sizes in Last Time Machine Backup“. Во второй статье приведёны скрипты на Perl и Python, которые показывают файлы, помещённые в бекап Time Machine за последние два часа с указанием их размеров.

Выделенный жирным текстом путь к бекапу нужно подставить свой:

#!/usr/bin/env python

import commands
import os.path
import sys
from Foundation import NSDate

backupdir = "/Volumes/Time Machine Backups/Backups.backupdb/ole-mac"
time = NSDate.timeIntervalSinceReferenceDate() - 7200

if not os.path.exists(backupdir):
    raise Exception, "backupdir %s doesn't exist (need to mount backup volume?)" % backupdir

cmd = "mdfind -onlyin '%s' '_kTimeMachineOldestSnapshot > %s'" % (backupdir, time);
items = [(x, os.path.getsize(x)) for x in commands.getoutput(cmd).split("\n") if not os.path.isdir(x)]

def cmp(a, b):
    if b[1] < a[1]:
        return -1
    if b[1] == a[1]:
        return 0
    return 1

items.sort(cmp)

for item in items:
    print "%10d %s " % (item[1], item[0])

Скрипт выдаёт результаты в виде:

   3854336 /Volumes/Time Machine Backups/Backups.backupdb/ole-mac/2010-03-09-123057/Macintosh HD/Users/ctrld/Library/Preferences/com.apple.LaunchServices.QuarantineEvents
    930897 /Volumes/Time Machine Backups/Backups.backupdb/ole-mac/2010-03-09-123057/Macintosh HD/Users/ctrld/Library/Application Support/Speed Download/Speed Download Queue.plist
    385024 /Volumes/Time Machine Backups/Backups.backupdb/ole-mac/2010-03-09-123057/Macintosh HD/Users/ctrld/Library/Application Support/AddressBook/AddressBook-v22.abcddb
    281895 /Volumes/Time Machine Backups/Backups.backupdb/ole-mac/2010-03-09-123057/Macintosh HD/Users/ctrld/Library/Cookies/Cookies.plist
    274722 /Volumes/Time Machine Backups/Backups.backupdb/ole-mac/2010-03-09-122311/Macintosh HD/Users/ctrld/Library/Cookies/Cookies.plist
    198082 /Volumes/Time Machine Backups/Backups.backupdb/ole-mac/2010-03-09-123057/Macintosh HD/Users/ctrld/Library/Safari/History.plist
    197821 /Volumes/Time Machine Backups/Backups.backupdb/ole-mac/2010-03-09-122311/Macintosh HD/Users/ctrld/Library/Safari/History.plist

Результаты познавательны - например, я понял, что пора бы перестроить базу Launch Services, слишком много записей в базе данных SQLite com.apple.LaunchServices.QuarantineEvents.

К сожалению, утилита tms, которая делает то же самое и при этом гораздо более функциональна, сейчас не развивается и не запускается под Mac OS X 10.6.

Основой для поиска файлов является команда mdfind, ищущая в каталоге Time Machine файлы, которые были скопированы за последние 2 часа (7200 секунд):

$ mdfind -onlyin '/Volumes/Time Machine Backups/Backups.backupdb/ole-mac' '_kTimeMachineOldestSnapshot >  $time.now(-7200)'

К каждому файлу, помещаемому в Time Machine, добавляются метаданные, показывающие время помещения в snapshot:

$ xattr -l /Volumes/Time\ Machine\ Backups/Backups.backupdb/ole-mac/2010-03-09-123057/Macintosh\ HD/Users/ctrld/bin/cfcurl.pl
com.apple.metadata:_kTimeMachineNewestSnapshot:
00000000  62 70 6C 69 73 74 30 30 33 42 2D 63 C3 7F 00 00  |bplist003B-c....|
00000010  00 08 00 00 00 00 00 00 01 01 00 00 00 00 00 00  |................|
00000020  00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |................|
00000030  00 11                                            |..|
00000032

com.apple.metadata:_kTimeMachineOldestSnapshot:
00000000  62 70 6C 69 73 74 30 30 33 41 B1 3C 7C 48 00 00  |bplist003A.<|H..|
00000010  00 08 00 00 00 00 00 00 01 01 00 00 00 00 00 00  |................|
00000020  00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |................|
00000030  00 11                                            |..|
00000032

Тема разбора Time Machine интересна и я займусь этим в обозримом будущем.