challenge админам (наведение порядка в бэкапах) (наведение порядка в "бэкапах")

Обсуждение настройки и работы сервисов, резервирования, сетевых настроек и вопросов безопасности ОС.

Модераторы: SLEDopit, Модераторы разделов

maksimnov
Сообщения: 3

challenge админам (наведение порядка в бэкапах)

Сообщение maksimnov »

Суть проблемы:

Есть 3 винчестера по 500Г каждый, на них типа бэкапов, но не архивы, а просто нужные файлы в разных каталогах (на каждом винте больше 50.000 файлов разного размера). Теоретически каждый файл должен был быть дублирован на двух разных дисках, а на практике там 3 большие свалки. Некоторые файлы в одном экземпляре; некоторые как нужно; некоторые по 2, но на одном и том же диске; некоторые на каждом из 3х.

Всего там есть порядка 300Г уникальных файлов. И теперь нужно привести все это в порядок, но в ручную и месяца разбираться не хватит, нужно как то автоматизировать.

В итоге должно получиться: два винта по 300Г файлов (т.е. по 1 копии каждого файла на каждом из двух дисков) и один чистый.



p.s. купить еще 2 и устроить свалку №4 - №5 просьба не предлагать.

p.p.s. пока у самого нет умных идей. Может как то составить списки файлов "имя,размер,md5" и потом как то их обрабатывать. Структура каталогов не важна, системы там нет, но "родительские" для файлов нужно бы сохранить.
Спасибо сказали:
Аватара пользователя
arkhnchul
Сообщения: 2284
Статус: Толчковый инженер
ОС: Debian, Fedora

Re: challenge админам (наведение порядка в бэкапах)

Сообщение arkhnchul »

В итоге должно получиться: два винта по 300Г файлов (т.е. по 1 копии каждого файла на каждом из двух дисков) и один чистый.

man find, man md5sum. Находим все файлы на всех дисках, попутно считаем хэш, пишем в текстовик или в базу md5 и оригинальное полное имя. Выдергиваем уникальные md5, переносим файлы куда надо, дубликаты сносим. Все.
Ну, то есть, не все. Потом организуем человеческую систему бэкапа, чтобы данный вопрос более не возникал.
Losing is fun!
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4824
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: challenge админам (наведение порядка в бэкапах)

Сообщение SLEDopit »

arkhnchul писал(а):
02.04.2012 15:38
man find, man md5sum. Находим все файлы на всех дисках, попутно считаем хэш, пишем в текстовик или в базу md5 и оригинальное полное имя. Выдергиваем уникальные md5, переносим файлы куда надо, дубликаты сносим. Все.
Есть готовые решения. fdupes всякие. Если лень со скриптами заморачиваться.
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
maksimnov
Сообщения: 3

Re: challenge админам (наведение порядка в бэкапах)

Сообщение maksimnov »

Хорошо бы сохранить каталоги где сами файлы, не соображу как.
Спасибо сказали:
Аватара пользователя
yars
Сообщения: 1147
Статус: Slacker!
ОС: Slackware64-current

Re: challenge админам (наведение порядка в бэкапах)

Сообщение yars »

arkhnchul писал(а):
02.04.2012 15:38
и оригинальное полное имя. Выдергиваем уникальные md5...

maksimnov, что не так-то?
Slackware64-current/Xfce/Xiaomi Mi Notebook Pro 15.6 | Arch Linux/Xfce/Lenovo G580
-------------
Registered Linux User #557010
Спасибо сказали:
maksimnov
Сообщения: 3

Re: challenge админам (наведение порядка в бэкапах)

Сообщение maksimnov »

Есть готовые решения. fdupes всякие. Если лень со скриптами заморачиваться.


Есть и это не проблема, но мне не достаточно удалить дубликаты на каждом из дисков, нужно еще собрать полный комплект файлов из всех трех дисков. Диски на двух разных компьютерах в разных зданиях и + usb_hdd_box.

Соответственно нужно:

3 списка файлов
из них список уникальных файлов
из этого списки какие файлы куда и откуда копировать

Естественно нужно придумать скрипты для этого, а я сам не знаю как, вот и прошу помощи в составлении, я не программист, мне трудно сообразить как такое делается. Хотябы общий принцип объясните. Например как получить список скажем такого типа:

md5sum size name path

потом из трех списков составить один с уник. md5

потом из всего этого сделать скрипты что куда копировать.

maksimnov, что не так-то?


После удаления дубликатов нужно разобрать дерево каталогов, переведя все на один уровень, так чтоб в них не было вложеных, одноименные объединить, при совпадении имен файлов переименовать добавив к имени скажем точное время создания

Потом организуем человеческую систему бэкапа, чтобы данный вопрос более не возникал.

Обязательно займусь, это еще позавчера нужно было сделать.
Спасибо сказали:
Аватара пользователя
KiWi
Бывший модератор
Сообщения: 2521
Статус: статус, статус, статус

Re: challenge админам (наведение порядка в бэкапах)

Сообщение KiWi »

А можно мне немножко влезть с лоховским вариантом в виду rsync?
Спасибо сказали:
Аватара пользователя
yars
Сообщения: 1147
Статус: Slacker!
ОС: Slackware64-current

Re: challenge админам (наведение порядка в бэкапах)

Сообщение yars »

Я так понимаю, вам нужно что-то вроде:

Код: Выделить всё

$ find /path/to/mount/point/disk1 -type fD -ls -exec md5sum {} \; >> /tmp/filelist

?
Slackware64-current/Xfce/Xiaomi Mi Notebook Pro 15.6 | Arch Linux/Xfce/Lenovo G580
-------------
Registered Linux User #557010
Спасибо сказали:
Аватара пользователя
sgfault
Сообщения: 586
Статус: -

Re: challenge админам (наведение порядка в бэкапах)

Сообщение sgfault »

maksimnov писал(а):
02.04.2012 19:03
Соответственно нужно:

3 списка файлов
из них список уникальных файлов
из этого списки какие файлы куда и откуда копировать

Естественно нужно придумать скрипты для этого, а я сам не знаю как, вот и прошу помощи в составлении, я не программист, мне трудно сообразить как такое делается. Хотябы общий принцип объясните. Например как получить список скажем такого типа:

md5sum size name path

потом из трех списков составить один с уник. md5

потом из всего этого сделать скрипты что куда копировать.

Общий принцип: find ищет файлы, md5sum считает сумму, sort/uniq выкидывают одинаковые. Также вам стоит решить, что делать с симлинками в бекапах: следовать симлинкам (`find -L`), или нет (`find -P`). md5sum следует симлинкам:

Код: Выделить всё

$ ll bin
lrwxrwxrwx 1 sgf sgf 17 Mar  2 14:40 bin -> ../common/sgf/bin
$ md5sum bin
md5sum: bin: Is a directory

те сравнить сами симлинки с помощью хэша не удастся. Их можно было бы сравнить с помощью `readlink`, впрочем..
Если же вы следуете симлинкам, то это не решает проблему с find: несмотря на то, что все предикаты при вызове `find -L` проверяются по файлу, указанному симлинком (как и написано в info find):

Код: Выделить всё

$ ll
total 24
lrwxrwxrwx 1 sgf sgf     5 Apr  3 12:46 1.sym -> 1.tmp
-rw-r----- 1 sgf sgf 22061 Mar  1 20:40 1.tmp
$ find -L -type f
./1.tmp
./1.sym

команда, вызываемая через -exec, все равно будет вызвана и для симлинка, и для файла:

Код: Выделить всё

$ find -L -type f -exec ls -ld {} \;
-rw-r----- 1 sgf sgf 22061 Mar  1 20:40 ./1.tmp
lrwxrwxrwx 1 sgf sgf 5 Apr  3 12:46 ./1.sym -> 1.tmp


И, наконец, самая интересная часть: спец-символы в именах файлов. Тут, кроме всего, что относится к shell-у, стоит помнить, что все предикты find-а, работающие с именами: '-name', '-wholename' и '-regex', - интерпретируют имена. Это значит, что использовать их с именами, содержащими shell pattern (для первых двух) и спец-символы регулярных выражений (для последнего), нельзя. Те можно только, если вы будете как-то экранировать эти символы в именах. Альтернативой экранированию символов является только `grep -F`:

Код: Выделить всё

$ find ... | grep -F
или
$ find ... -print0 | grep -z -F

Впрочем, возможно, вам это вообще не понадобится.

Да, и еще ведь есть пустые директории, которые, наверно, тоже надо сравнивать?

И, наконец, мой вариант поиска :happy:
Составление списка:

Код: Выделить всё

#!/bin/sh

set -euf
if [ -z "$1" ]; then
    echo "Too few args"
    exit 1
elif [ ! -d "$1" ]; then
    echo "Top dir '$1' not a directory"
    exit 1
fi
cd "$1"
find -P . \( -type f -o -type l -o \( -type d -empty \) \) \
          -execdir sh -euf -c '
                for s; do
                if [ -h "$s" ]; then
                    echo -n "$s " && readlink "$s"
                elif [ -d "$s" ]; then
                    echo " $s"
                else
                    md5sum "$s" | sed -e"s/  / /"
                fi
                done' sh {} \+

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

Код: Выделить всё

$ ll -R test1/
test1/:
total 8
drwxr-x--- 4 sgf sgf 4096 Apr  3 13:41 a
lrwxrwxrwx 1 sgf sgf    5 Apr  3 13:14 1.sym -> 1.tmp
-rw-r----- 1 sgf sgf    2 Apr  3 13:17 3.tmp

test1/a:
total 12
drwxr-x--- 2 sgf sgf 4096 Apr  3 13:14 b
drwxr-x--- 2 sgf sgf 4096 Apr  3 13:15 c
lrwxrwxrwx 1 sgf sgf    8 Apr  3 13:31 3.sym -> ../3.tmp
lrwxrwxrwx 1 sgf sgf    1 Apr  3 13:41 b.sym -> b
-rw-r----- 1 sgf sgf    2 Apr  3 13:15 2.tmp

test1/a/b:
total 0

test1/a/c:
total 0
lrwxrwxrwx 1 sgf sgf 8 Apr  3 13:15 2.sym -> ../2.tmp

Код: Выделить всё

$ ll -R test2
test2:
total 8
drwxr-x--- 4 sgf sgf 4096 Apr  3 13:41 a
lrwxrwxrwx 1 sgf sgf    5 Apr  3 13:14 1.sym -> 1.tmp
-rw-r----- 1 sgf sgf    2 Apr  3 13:16 3.tmp

test2/a:
total 12
drwxr-x--- 2 sgf sgf 4096 Apr  3 13:14 b
drwxr-x--- 2 sgf sgf 4096 Apr  3 13:16 c
lrwxrwxrwx 1 sgf sgf    8 Apr  3 13:31 3.sym -> ../3.tmp
lrwxrwxrwx 1 sgf sgf    1 Apr  3 13:41 b.sym -> b
-rw-r----- 1 sgf sgf   87 Apr  3 13:46 2.tmp

test2/a/b:
total 0

test2/a/c:
total 0
lrwxrwxrwx 1 sgf sgf 13 Apr  3 13:16 2.sym -> ../../a/2.tmp

(файл, на который указывает симлинк 1.sym, не существует, симлинк 2.sym указывает на один и тот же файл, но путь написан по-разному, содержимое файлов 2.tmp различается)
Получаются такие результаты:

Код: Выделить всё

$ ~/bin/t.sh ~/tmp/test1 >| ./t1.tmp
$ cat ./t1.tmp
6d7fce9fee471194aa8b5b6e47267f03 ./3.tmp
../2.tmp ./2.sym
 ./b
b ./b.sym
../3.tmp ./3.sym
26ab0db90d72e28ad0ba1e22ee510510 ./2.tmp
1.tmp ./1.sym
$ ~/bin/t.sh ~/tmp/test2 >| ./t2.tmp
$ cat ./t2.tmp
6d7fce9fee471194aa8b5b6e47267f03 ./3.tmp
../../a/2.tmp ./2.sym
 ./b
b ./b.sym
../3.tmp ./3.sym
2fc57d6f63a9ee7e2f21a26fa522e3b6 ./2.tmp
1.tmp ./1.sym

которые сравнивать надо так

Код: Выделить всё

$ sort -s -t' ' -k2 -k1,1 ./t1.tmp ./t2.tmp | uniq -u
26ab0db90d72e28ad0ba1e22ee510510 ./2.tmp
2fc57d6f63a9ee7e2f21a26fa522e3b6 ./2.tmp
../2.tmp ./2.sym
../../a/2.tmp ./2.sym


ЗЫ. Да, кстати, а еще есть `diff -r`, который тоже может сравнивать директории. Возможно, вместо всех этих скриптов вам и его будет достаточно. Вот пример:

Код: Выделить всё

$ diff -qr test1/ test2/
diff: test1//1.sym: No such file or directory
diff: test2//1.sym: No such file or directory
Files test1//a/2.tmp and test2//a/2.tmp differ
Files test1//a/c/2.sym and test2//a/c/2.sym differ

(он следует симлинкам)

Upd. Исправлен вызов sort.
Спасибо сказали: