[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Чем бэкапить?



On Mon, Nov 28, 2005 at 01:31:52PM +0300, Artem Chuprina wrote:
> А он incremental умеет?  Потом, судя по описанию, как-то не видно, чтобы
> он умел туда, куда мне надо.  NFS не устраивает по соображениям
> безопасности, partition - по соображениям равно отсутствия достаточного
> места и "все яйца в одну корзину", CD-R/CD-RW и даже DVD-R - поскольку
> под полный бэкап на одном точно места не хватит, а большее количество
> почти непременно потребует ручного вмешательства в процессе.

Насчет умеет ли incremental - вопрос на данный момент крайне сложный,
поскольку многие авторы думают, что "умеет" а на самом деле - нет. Для
начала вопрос - чем не устраивает gnu tar с опцией --listed-incremental.

А ниже я возьму на себя смелость запостить собственное видение вопроса
про алгоритм incremental backup. Текст сыроват, недописан и слегка
зануден :))))).


Мысли, в общем, давно известные, но знание сие как-то не слишком популярно по моим
наблюдениям. gnu tar пользует эти идеи, например, лет так 15. А вот здесь обсуждаются в том числе и эти
идеи 20 лет тому: 
http://groups.google.ru/group/net.bugs.usg/browse_thread/thread/154dc9013437fe2a/2da7ed60ec2e0b85?lnk=st&q=tar+newer+incremental+-gnu.*&rnum=23&hl=ru

Ну приступим...
С точки зрения стандарта POSIX файл
======= (http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_163)
Обьект, в который может производиться запись, чтение или и то, и другое. Файл имеет некоторые атрибуты,
включая права доступа и тип. Тип файла включает в себя обычный файл (regular file), файл символьного
устройства (character special file), файл блочного устройства (block special file), трубку (FIFO special
file), символьную ссылку (symbolic link), socket и каталог (directory).
=======

Все системные вызовы обращаются к файлу либо по пути к файлу, либо по файловому дескриптору, полученному
при открытии файла (опять же по пути к файлу).

======= (http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_266)
Pathname (Путь к файлу)
Строка символов используемая для идектификации файла. В контексте IEEE Std 1003.1-2001 путь к файлу может
содержать до {PATH_MAX} символов, включая нулевой символ в конце. Он содержит необязательный начальный
слэш, за которым следуют 0 или больше имен файлов, разделенных слэшами. Имя файла может содержать один
или более слэшей в конце. Несколько последовательных слэшей рассматриваются как один слэш.

======= (http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_169)
Имя файла (filename)
Имя, содержащее от 1 до {NAME_MAX} символов, используемое для названия файла. Символы, составляющие имя
могут быть выбраны из всего множества символов исключая слэш и нулевой байт. ....

======= (http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_128)
Каталог (Directory)
Файл, который содержит элементы каталога. Два элемента каталога не могут иметь одинаковое имя.

Элемент каталога (Directory Entry (or Link))
Обьект, который сопостовляет имя файла с файлом. Несколько элементов каталога могут сопостовлять имена
с одним файлом.
=======

Ну и, наконец, как это выглядит в виде дерева:

======= (http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap04.html#tag_04_05)
Файлы в системе организованы в иерархическую структуру в которой все не конечные узлы - каталоги,
и все конечные узлы - файлы любых других типов. Поскольку несколько элементов каталога могут
ссылаться на один файл, данную иерархию правильно охарактеризовать как направленный граф.
=======

Можно заметить, что обращаясь к файлу по известному пути в 2 момента времени можно попасть в ситуацию,
когда во второй момент времени это окажется не тот файл. Допустим между первым и вторым обращениями 
старый файл стерли, а на "его место" с помощью сист. вызова rename перенесли другой, причем возможно с 
родительским каталогом (в последнем случае file timestamps от этой операции у файла не поменяются,
но это мы забежали вперед).

Насколько я понимаю именно для разрешения этой неприятности в стандарт введен file serial number
(более известный нам как inode number)
======= (http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_175)
Серийный номер файла (File Serial Number)

Уникальный в файловой системе идентификатор файла

Файловая система

Собрание файлов и их известных атрибутов. Оно предоставляет соответствие (name space) для серийных
номеров этих файлов.
=======

Таким образом для каждого файла при необходимости мы можем записать его file serial number и 
убедиться, что pathname указывает на тот же файл.

С другой стороны:

======= (http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap04.html#tag_04_07)
Обновление меток времени (timestamps) файла   

Каждый файл имеет три связанных с ним независимых значения времени
(timestamp): st_atime, st_mtime и st_ctime. st_atime ассоциировано с
моментами времени, когда происходит доступ к данным файла; st_mtime
ассоциировано с моментами времени, когда происходит модификация
данных файла; и st_ctime ассоциировано с моментами времени, когда
изменяется статус файла. Эти значения возвращаются в структуре
характеристик файла как описано в <sys/stat.h>.

Каждая функция или утилита в IEEE Std 1003.1-2001, которая читает или
пишет данные или изменяет статус файла указывает какие из
соответствующих временных полей должны быть "помечены для обновления"
   ...
=======

Для того, чтобы представить картину более детально в описании системных вызовов
описано какие конкретно из меток времени должны быть помечены для обновления при
успешном выполнении вызова.

Я собрал некоторые из этих данных в приведенную ниже таблицу (системные вызовы отбирались
на глазок из /usr/include/asm/unistd.h от glibc 2.2.3). Там, где обновляемые метки времени
зависят от параметров вызова поставлены *. 

+-------------------------------------------------------------------------------------------------------+
|         |   Помечаемые для обновления |                                                               |
|         |          timestamps         |                                                               |
|Сист.    |-----------------------------|                            Источник                           |
|вызов    |     для файла   | для родит.|                                                               |
|         |                 |  каталога |                                                               |
|---------+-----------------+-----------+---------------------------------------------------------------|
|chdir    |                 |           |www.opengroup.org/onlinepubs/009695399/functions/chdir.html    |
|---------| -               | -         |---------------------------------------------------------------|
|fchdir   |                 |           |www.opengroup.org/onlinepubs/009695399/functions/fchdir.html   |
|---------+-----------------+-----------+---------------------------------------------------------------|
|chmod    |                 |           |www.opengroup.org/onlinepubs/009695399/functions/chmod.html    |
|---------|ctime            | -         |---------------------------------------------------------------|
|fchmod   |                 |           |www.opengroup.org/onlinepubs/009695399/functions/fchmod.html   |
|---------+-----------------+-----------+---------------------------------------------------------------|
|chown    |                 |           |www.opengroup.org/onlinepubs/009695399/functions/chown.html    |
|---------|                 |           |---------------------------------------------------------------|
|fchown   |ctime            | -         |www.opengroup.org/onlinepubs/009695399/functions/fchown.html   |
|---------|                 |           |---------------------------------------------------------------|
|lchown   |                 |           |www.opengroup.org/onlinepubs/009695399/functions/chown.html    |
|---------+-----------------+-----------+---------------------------------------------------------------|
|close    | -               | -         |www.opengroup.org/onlinepubs/009695399/functions/close.html    |
|---------+-----------------+-----------+---------------------------------------------------------------|
|creat    |atime,ctime,mtime|ctime,mtime|www.opengroup.org/onlinepubs/009695399/functions/creat.html    |
|---------+-----------------+-----------+---------------------------------------------------------------|
|execve   |atime            | -         |www.opengroup.org/onlinepubs/009695399/functions/exec.html     |
|---------+-----------------+-----------+---------------------------------------------------------------|
|fcntl    | -               | -         |www.opengroup.org/onlinepubs/009695399/functions/fcntl.html    |
|---------+-----------------+-----------+---------------------------------------------------------------|
|ftruncate|                 |           |www.opengroup.org/onlinepubs/009695399/functions/ftruncate.html|
|---------|ctime,mtime      | -         |---------------------------------------------------------------|
|truncate |                 |           |www.opengroup.org/onlinepubs/009695399/functions/truncate.html |
|---------+-----------------+-----------+---------------------------------------------------------------|
|fstat    |                 |           |www.opengroup.org/onlinepubs/009695399/functions/fstat.html    |
|---------|                 |           |---------------------------------------------------------------|
|stat     | -               | -         |www.opengroup.org/onlinepubs/009695399/functions/stat.html     |
|---------|                 |           |---------------------------------------------------------------|
|lstat    |                 |           |www.opengroup.org/onlinepubs/009695399/functions/lstat.html    |
|---------+-----------------+-----------+---------------------------------------------------------------|
|fsync    |                 |           |www.opengroup.org/onlinepubs/009695399/functions/fsync.html    |
|---------| -               | -         |---------------------------------------------------------------|
|fdatasync|                 |           |www.opengroup.org/onlinepubs/009695399/functions/fdatasync.html|
|---------+-----------------+-----------+---------------------------------------------------------------|
|link     |ctime            |ctime,mtime|www.opengroup.org/onlinepubs/009695399/functions/link.html     |
|---------+-----------------+-----------+---------------------------------------------------------------|
|lseek    | -               | -         |www.opengroup.org/onlinepubs/009695399/functions/lseek.html    |
|---------+-----------------+-----------+---------------------------------------------------------------|
|mknod    |atime,ctime,mtime|ctime,mtime|www.opengroup.org/onlinepubs/009695399/functions/mknod.html    |
|---------+-----------------+-----------+---------------------------------------------------------------|
|mkdir    |atime,ctime,mtime|ctime,mtime|www.opengroup.org/onlinepubs/009695399/functions/mkdir.html    |
|---------+-----------------+-----------+---------------------------------------------------------------|
|mmap     | *               | -         |www.opengroup.org/onlinepubs/009695399/functions/mmap.html     |
|---------+-----------------+-----------+---------------------------------------------------------------|
|munmap   | -               | -         |www.opengroup.org/onlinepubs/009695399/functions/munmap.html   |
|---------+-----------------+-----------+---------------------------------------------------------------|
|msync    | *               | -         |www.opengroup.org/onlinepubs/009695399/functions/msync.html    |
|---------+-----------------+-----------+---------------------------------------------------------------|
|open     | *               | *         |www.opengroup.org/onlinepubs/009695399/functions/open.html     |
|---------+-----------------+-----------+---------------------------------------------------------------|
|pread    |                 |           |www.opengroup.org/onlinepubs/009695399/functions/pread.html    |
|---------|                 |           |---------------------------------------------------------------|
|read     |atime            | -         |www.opengroup.org/onlinepubs/009695399/functions/read.html     |
|---------|                 |           |---------------------------------------------------------------|
|readv    |                 |           |www.opengroup.org/onlinepubs/009695399/functions/readv.html    |
|---------+-----------------+-----------+---------------------------------------------------------------|
|pwrite   |                 |           |www.opengroup.org/onlinepubs/009695399/functions/pwrite.html   |
|---------|                 |           |---------------------------------------------------------------|
|write    |ctime,mtime      | -         |www.opengroup.org/onlinepubs/009695399/functions/write.html    |
|---------|                 |           |---------------------------------------------------------------|
|writev   |                 |           |www.opengroup.org/onlinepubs/009695399/functions/writev.html   |
|---------+-----------------+-----------+---------------------------------------------------------------|
|rename   |implementation   |ctime,mtime|www.opengroup.org/onlinepubs/009695399/functions/rename.html   |
|---------+-----------------+-----------+---------------------------------------------------------------|
|rmdir    | -               |ctime,mtime|www.opengroup.org/onlinepubs/009695399/functions/rmdir.html    |
|---------+-----------------+-----------+---------------------------------------------------------------|
|readlink | *               | -         |www.opengroup.org/onlinepubs/009695399/functions/readlink.html |
|---------+-----------------+-----------+---------------------------------------------------------------|
|readdir  |atime            | -         |www.opengroup.org/onlinepubs/009695399/functions/readdir.html  |
|---------+-----------------+-----------+---------------------------------------------------------------|
|readahead| ?               | ?         | -                                                             |
|---------+-----------------+-----------+---------------------------------------------------------------|
|symlink  | *               | *         |www.opengroup.org/onlinepubs/009695399/functions/symlink.html  |
|---------+-----------------+-----------+---------------------------------------------------------------|
|sendfile | ?               | ?         | -                                                             |
|---------+-----------------+-----------+---------------------------------------------------------------|
|unlink   | -               |ctime,mtime|www.opengroup.org/onlinepubs/009695399/functions/unlink.html   |
|---------+-----------------+-----------+---------------------------------------------------------------|
|utime    |ctime            | -         |www.opengroup.org/onlinepubs/009695399/functions/utime.html    |
+-------------------------------------------------------------------------------------------------------+

Итого 
модификация данных (помечаем mtime):
    - запись в файл (pwrite,write,writev,mmap);
    - изменение размера файла (truncate, open с флагом O_TRUNCATE);
    - создание элемента каталога (creat, link, open с созданием файла, mkdir, mknod);
    - удаление элемента каталога (rmdir, unlink);
    - изменение элемента каталога (rename),
доступ к данным (помечаем atime):
    - чтение из файла (read, pread, execve, mmap);
    - чтение каталога (readdir),
изменение атрибутов (помечаем ctime):
    - модификация данных (если помечаем mtime, то и ctime тоже);
    - изменение прав доступа (chmod, chown);
    - изменение mtime и atime вызовом utime.
    
При создании файла его timestamps помечаются для обновления все (creat, open с созданием файла, mknod,
mkdir).

Стоит особо остановиться на "implementation dependent" для переименовываемого файла (вызов rename) в
стандарте. Раньше было еще хуже. Раньше вообще не было указания, что какие-то из timestamp-ов 
переименовываемого файла могут помечаться. В linux 2.4 (как, видимо, и в большинстве других систем)
rename помечает для переименовываемого файла ctime.

Также мне лично показались непонятными объяснения для вызова symlink.

Теперь пусть у нас есть некоторая программа, которая должна делать что-то с изменившимися (в смысле
изменения данных, прав доступа или появления новых ссылок) файлами, которую мы запускаем периодически. 
Примером может служить backup, составление индекса по содержимому и, может быть, даже проверка на вирусы
(хотя в этом случае все сложнее, поскольку база антивируса у нас обновляется). У нас путь к файлу. 
Что нам нужно сделать, чтобы ответить на вопрос старый это файл, с которым ничего не происходило с момента
предыдущего запуска или измененный/новый файл? Мы видим, что глядя на ctime по отношению к моменту 
предыдущего запуска программы мы можем видеть были ли изменены атрибуты (включая данные) файла. А если
вызов rename у нас помечает для обновления ctime, то мы можем судить и о том переименовывали именно этот
файл. Остается убедиться в том не изменился ли путь к родительскому каталогу. А это мы можем сделать имея
файл, в котором сохранено соответствие между известными на момент предыдущего запуска программы путями к 
каталогам и inode numbers для них на тот момент. Все!

В заключение хочется заметить, что можно, конечно обойтись без запоминания соответствия между путями к
каталогам и их inode number, но ценой резкого ухудшения работы алгоритма. Для каталога, у которого
изменился ctime (а он меняется далеко не только при переименовании каталога) мы в этом случае не можем
с уверенностью сказать что файл остался прежним для любого пути, содержащего этот каталог, и нам придется
обрабатывать намного больше файлов.


WBR
Dmitri Ivanov



Reply to: