Я получаю от 4 до 100 очень больших архивных файлов tar (~20 ГБ) каждый день. Раньше я объединял их, проходя по каждому из архивов, которые я вижу в файловой системе, и делая что-то вроде этого
/bin/tar -concatenate --file=allTars.tar receivedTar.tar
Проблема в том, что по мере объединения все большего количества файлов tar, он должен прочитать до конца, allTars.tar
чтобы начать объединение снова. Иногда требуется более 20 минут, чтобы начать добавлять еще один файл tar. Это слишком медленно, и я пропускаю согласованное время доставки полного allTars.tar
.
Я также попробовал передать команде tar список файлов следующим образом:
/bin/tar --concatenate --file=alltars.tar receiverTar1.tar receivedTar2.tar receivedTar3.tar...etc
Это дало очень странные результаты. allTars.tar
Размер должен был соответствовать ожидаемому (т. е. близко к receivedTar.tar
сумме размеров всех файлов), но при allTars.tar
распаковке файлы, похоже, были перезаписаны.
Есть ли способ объединить все эти tar-файлы в одну команду, чтобы не приходилось каждый раз читать до конца объединяемого архива?иправильно ли они распакованы и со всеми файлами/данными?
решение1
Это может вам не помочь, но если вы готовы использовать эту -i
опцию при извлечении из конечного архива, то вы можете просто cat
объединить tar. Файл tar заканчивается заголовком, полным нулей, и еще большим количеством нулей до конца записи. С --concatenate
tar необходимо пройти по всем заголовкам, чтобы найти точное положение конечного заголовка, чтобы начать перезапись там.
Если вы просто cat
tar, у вас просто есть дополнительные нули между заголовками. Эта -i
опция просит tar игнорировать эти нули между заголовками. Так что вы можете
cat receiverTar1.tar receivedTar2.tar ... >>alltars.tar
tar -itvf alltars.tar
Кроме того, ваш tar --concatenate
пример должен работать. Однако, если у вас есть файл с одинаковым именем в нескольких архивах tar, вы перезапишете этот файл несколько раз, когда будете извлекать все из полученного tar.
решение2
Этот вопрос довольно старый, но я бы хотел, чтобы мне было легче найти следующую информацию раньше. Так что если кто-то еще наткнется на это, наслаждайтесь:
То, что Джефф описывает выше, является известной ошибкой в gnu tar (сообщение об этом поступило в августе 2008 г.). Только первый архив (тот, что после опции -f
) удаляет маркер EOF. Если вы попытаетесь объединить более 2 архивов, последний архив(ы) будет "скрыт" за маркерами конца файла.
Это ошибка в tar. Он объединяет целые архивы, включая конечные нулевые блоки, поэтому по умолчанию чтение полученного архива останавливается после первой конкатенации.
Источник:https://lists.gnu.org/archive/html/bug-tar/2008-08/msg00002.html (и последующие сообщения)
Учитывая возраст ошибки, я задаюсь вопросом, будет ли она когда-нибудь исправлена. Я сомневаюсь, что есть критическая масса, которая затронута.
Лучшим способом обойти эту ошибку может быть использование этой -i
опции, по крайней мере для файлов .tar в вашей файловой системе.
Как отмечает Джефф, tar --concatenate
может потребоваться много времени, чтобы достичь EOF, прежде чем он объединит следующий архив. Так что если вы собираетесь застрять с «сломанным» архивом, которому нужна опция tar -i
для распаковки, я предлагаю следующее:
Вместо использования
tar --concatenate -f archive1.tar archive2.tar archive3.tar
вам, вероятно, будет лучше бежать cat archive2.tar archive3.tar >> archive1.tar
или pipe to dd
, если вы собираетесь записывать на ленточное устройство. Также обратите внимание, что этомогпривести к неожиданному поведению, если ленты не были обнулены перед (пере)записью на них новых данных. По этой причине подход, который я собираюсь использовать в своем приложении, — это вложенные tar, как предлагается в комментариях под вопросом.
Вышеуказанное предложение основано на следующем очень небольшом контрольном образце:
time tar --concatenate -vf buffer.100025.tar buffer.100026.tar
real 65m33.524s
user 0m7.324s
sys 2m50.399s
time cat buffer.100027.tar >> buffer.100028.tar
real 46m34.101s
user 0m0.853s
sys 1m46.133s
Размер всех файлов buffer.*.tar составляет 100 ГБ, система практически простаивала, за исключением каждого из вызовов. Разница во времени достаточно существенна, поэтому я лично считаю этот бенчмарк валидным, несмотря на небольшой размер выборки, но вы свободны в своем собственном суждении об этом и, вероятно, лучше всего запустить такой бенчмарк на своем собственном оборудовании.
решение3
Как вы уже сказали, целевой архивный файл должен быть прочитан до конца, прежде чем к нему будет добавлен второй исходный архив. У GNU tar есть опция, -n
которая предписывает ему предполагать, что файл доступен для поиска (помните, tar был разработан для ленточных и потоковых архивов, которые не доступны для поиска). GNU tar по умолчанию предположительно автоматически определяет, доступен ли файл, однако многие пользователи, такие как вы, могут сделать так, чтобы tar пропускал чтение полного содержимого каждой записи, добавив опцию -n
:
tar -n --concatenate --file=target_file.tar other_file.tar
Я не могу проверить (на момент написания), какие версии tar, если таковые имеются, будут работать так, как ожидается, для этой команды. Если другие пользователи имеют возможность доказать это решение, пожалуйста, прокомментируйте ниже, и я обновлю этот ответ соответствующим образом.
решение4
Поскольку конкатенация требует интенсивного ввода-вывода, я бы рекомендовал либо 3 SSD (1 ТБ) в RAID 0. Один SSD на sata 3 даст 500 МБ/с чтения и примерно столько же для записи. Дорого, да, но быстро x3.