Сравните массивные каталоги с отчетом о проделанной работе


13

Я только что перевел 2 000 000 файлов (3 ТБ) с одного RAID на другой.

Я хочу убедиться, что мои данные не повреждены.

rsync -c занимает очень много времени.

diff не показывает мне, что он делает.

Есть ли альтернатива, которая (а) быстрее, и (б) покажет мне прогресс во время сравнения?

(Я на Mac, и brew search diffдает мне apgdiff colordiff diffstat diffutils fmdiff libxdiff open-vcdiff podiff rfcdiff vbindiff bsdiff diffpdf diffuse dwdiff kdiff3 ndiff perceptualdiff rdiff-backup tkdiff wdiff ... один из них сделает работу?)



Я также не понимаю, почему rsyncскопировал данные со скоростью около 150 МБ / с, но diffсравнивает их со скоростью всего 60 МБ / с ...?
Дан

1
Копирование rsyncпроисходит быстрее, т.к. rsyncпо умолчанию не использует контрольные суммы для сравнения файлов, оно смотрит информацию о размере и дате. Когда вы используете rsync -cвсе файлы, их контрольные суммы должны быть рассчитаны, что является обременительной задачей, поэтому не по умолчанию.
SLM

Да, но diff не копирует ... он просто читает оба файла; в то время как rsync для копирования должен прочитать каждый байт, а затем записать его. Это был rsync с нуля, поэтому он копировал каждый файл.
Дан

Ответы:


6

редактировать для исправления и ясности опций - я забыл '--brief'

diff -rs --brief "$dir1" "$dir2" 

-r, --recursive              recursively compare any subdirectories found
-s, --report-identical-files report when two files are the same
-q, --brief                  report only when files differ
--speed-large-files      assume large files and many scattered small changes

и добавьте другие варианты по вкусу, в зависимости от того, что вы сравниваете:

-i, --ignore-case            ignore case differences in file contents
-b, --ignore-space-change    ignore changes in the amount of white space
-B, --ignore-blank-lines     ignore changes whose lines are all blank
--strip-trailing-cr      strip trailing carriage return on input
--ignore-file-name-case  ignore case when comparing file names

diff -rs будет читать каждый байт оригинала и копии, а также сообщать файлы, которые совпадают.

Формат вывода diff определяется POSIX, поэтому он довольно переносим. Вы можете добавить что-то вроде:

| тройник различий.1 | grep -v -ee 'Файлы. * и. * идентичны'

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

РЕДАКТИРОВАТЬ - слишком долго, чтобы быть комментарием, в ответ на:

файлы размером более 10 ГБ не проверяются

Вы можете попробовать эту опцию diff: --speed-large-files

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

Я думал, что есть опция -h или bdiff, которая лучше работает с большими файлами, но я не могу найти ее в Fedora. Я считаю, что параметр --speed-large-files является преемником опции «-h» «нерешительное сравнение».

Другой подход состоит в том, чтобы повторить команду rsync, которую вы использовали, с '-vin' (verbose, itemize, no_run). Это сообщит о любых различиях, которые обнаружит rsync - и их не должно быть.

Чтобы переместить некоторые файлы, вы смотрите на скрипт, например:

if [ cmp -s "$dir1/$path" "$dir2/$path" ] ; then 
target="$dir2/verified/$path"
mkdir -p $(basename "$target")
mv  "$dir2/$path" "$target"
fi

но я не рекомендую делать это. Основной вопрос «как я могу быть уверен, что rsync правильно скопировал файловую иерархию?» и если вы можете продемонстрировать себе, что rsync работает хорошо, с помощью diff или другого инструмента, то вы можете просто положиться на rsync, а не обходить его.

rsync -vin будет сравнивать, основываясь на любых других параметрах, которые вы ему предоставите. Я думал, что по умолчанию это контрольная сумма, но вы правы, для этого требуется -c или --checksum.

Утилита diff действительно предназначена для файлов строк текста, но она должна сообщать «идентичные» under -s для двоичных файлов.

--Brief должна подавлять любой вывод содержимого файла - мои извинения за то, что упустил его ранее - он был полу-похоронен в ужасном сценарии.


Есть ли способ получить его для mvкаждого найденного файла в «проверенной» папке в корне диска, сохранив полный путь? Например, если /disk1/a/b/c/file1идентично /disk2/a/b/c/file1, то переместите его в /disk1/verified/a/b/c/file1. Тогда я мог получить только плохо скопированные файлы. (До сих пор МНОГО файлов более 10 ГБ не проверяются, что очень страшно.)
Дан

Вы можете попробовать эту опцию: --speed-large-files
D McKeon

Что это делает именно?
Дан

Если я запускаю rsync -vin- это делает байтовое сравнение или сравнение контрольной суммы? Я думал, что rsync сравнивает только размер / дату, если вы не добавите -c. И из того, что я прочитал, speed large filesкажется, что разница только с недвоичными файлами ... или я ошибаюсь?
Дан

diffдает мне результаты в виде "Files __ and ___ differ"... и я запускаю его, sed -e "s/Files /cp -afv /" -e "s/ and / /" -e "s/ differ$//"чтобы попытаться сгенерировать скрипт для повторного копирования плохих файлов. Но вывод diff не заключен в кавычки, поэтому он не работает. Могу ли я получить его, чтобы дать мне процитированные пути?
Дан

4

Вот diffс отчетом о прогрессе на основе количества файлов:

diff -rqs dir1 dir2 | pv -l -s filecount > logfile

Вам понадобится pv (программа просмотра каналов): http://www.ivarch.com/programs/pv.shtml

Объяснение:

  • diff -r рекурсивно сравнивать каталог и подкаталоги.
  • diff -qпечатать только имена файлов отличаются. не печатать фактические различия.
  • diff -sвыведите также имена файлов, которые не отличаются. это важно для информации о прогрессе.
  • pv -l сообщить о прогрессе на основе количества строк.
  • pv -s count рассчитать время для завершения на основе подсчета.
  • Перенаправление на logfileэто для приятного вывода. В противном случае выход из diffбудет смешиваться со строкой состояния из pv.

чтобы получить количество файлов, используйте следующую команду:

find dir1 -type f | wc -l

Фильтруйте файл журнала для файлов, которые отличаются:

grep -v "^Files .* identical$" logfile

Этот вариант будет печатать файлы, которые отличаются в реальном времени, а также регистрировать все в logfile:

diff -rqs dir1 dir2 | pv -l -s filecount | 
    tee logfile | grep -v "^Files .* identical$"

В качестве альтернативы вы можете регистрировать только файлы, которые отличаются:

diff -rqs dir1 dir2 | pv -l -s filecount | 
    grep -v "^Files .* identical$" > logfile

Примечание: приведенные выше команды будут сообщать о прогрессе на основе количества файлов. Это работает лучше всего, если есть много маленьких файлов. Если у вас есть несколько огромных файлов, то вам не очень понравится с этим.

К сожалению, я не знаю простого способа сообщить о прогрессе на основе сравнения байтов.


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

Больше подробностей:


0

Я бы посмотрел на использование своего рода хэш-приложения для проверки целостности данных. Я знаю, что многие утилиты для поиска дубликатов файлов используют хеш-коды для выявления дубликатов / недубликатов. Мне кажется, что это расследование может быть полезным.


0

Для этого вы можете использовать rdiff-backup . Установите его на обоих серверах, и он сделает умные сравнения контрольных сумм и синхронизирует то, чего еще нет.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.