Попытка запустить проверку svnadmin приводит к несоответствию контрольной суммы

У меня есть репозиторий 7-летней давности. Чтобы выполнить некоторое обслуживание, я запустил svnadmin verify в репозиторий. Я получил ошибку несоответствие контрольной суммы в нескольких версиях.

Я попытался создать дамп без плохих ревизий и пересоздать репозиторий, но было много молодых ревизий, которые зависят от плохих ревизий. Я не могу создать резервную копию своего репозитория с помощью svnadmin dump, когда он находится в этом состоянии.

Есть ли обходной путь для этих ошибок, чтобы создать файл дампа репозитория?


person noti    schedule 22.08.2013    source источник


Ответы (2)


[Я знаю, что это связано с другим ответом на этот вопрос, но ответы SO не должны на самом деле ссылаться на сторонние ресурсы, и я хотел бы думать, что этот ответ должен пережить мой личный сайт блога, поэтому опубликуйте его здесь для потомков .]

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

Симптом:

Запуск проверки svnadmin в репозитории приводит к «несоответствию контрольной суммы при чтении представления». Вывод здесь вводит в заблуждение, потому что в строке перед сообщением об ошибке будет написано что-то вроде «* Проверенная версия 23». Это означает, что на самом деле это ревизия 24, которая плоха. Вы также обнаружите, что если вы попытаетесь сделать дамп репозитория, он успешно выгрузит ревизии с 0 по 23, но затем сбой 24. Если вы попытаетесь сделать дамп ревизий 0:23, а затем 25:HEAD, как я, вы, обнаружил, что версия 25:HEAD не работает.

Диагностика:

Одно (или несколько) изменений в файлах в редакции, которые вызывают проблемы, имеют контрольную сумму, отличную от той, которая записана в файле ревизии в то время. Поэтому, когда svnadmin verify просматривает содержимое ревизии и пересчитывает контрольную сумму, она обнаруживает, что они не совпадают, и сообщает вам об этом. Это означает одно из двух: 1) контрольная сумма, записанная в то время, была неправильной, и данные в ревизии/файле действительны, или 2) данные в ревизии/файле повреждены, а контрольная сумма в то время была правильной. .

Если файл, генерирующий неверную контрольную сумму, является текстовым файлом, вы можете просмотреть содержимое файла версии и проверить, не повреждено ли оно. Если файл бинарный, как у меня, это, вероятно, не вариант. Тем более, если файл большой (у меня было несколько сотен МБ).

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

Возможное решение:

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

Процесс:

Я предполагаю, что вы работаете напрямую с сервером в Linux. Я использую Debian, поэтому обычно доступны такие инструменты, как grep и hexedit (хотя мне пришлось установить hexedit). Те же принципы применимы и к Windows, но инструменты должны измениться.

1) Определите версию, которая повреждена. Это просто — это версия после последней успешно проверенной версии.

2) Определите файл в ревизии с неверной контрольной суммой и найдите неверную контрольную сумму в ревизии. Это сложнее — файлы ревизий (хранящиеся в /repository/db/revs) бинарные и в моем случае огромные. Но grep здесь ваш друг. svnadmin verify выдает контрольную сумму, которая записана в данный момент — она хранится в файле ревизии рядом с описанием файла. Вот команда grep, которая ищет в конкретном файле ревизии контрольную сумму, которую мы получили:

grep -e "79a1686d0dfb8618b8ccfc9eb7d74759" -A 3 -B 3 -b -a main/db/revs/24

Здесь длинная строка в кавычках — это «ожидаемая» контрольная сумма, которую мне дала проверка svnadmin, следующие параметры предполагают, что файл является двоичным (-a), и печатать 3 строки контекста до (-B 3) и после (-A 3) каждого совпадения, и, что особенно важно, смещение каждой строки с начала файла (-b). Это должно вывести 7 строк файла (к счастью, раздел, описывающий файлы и их свойства, в основном текстовый)

384989609-id: 5cu.0.r24/384989609
384989633-type: file
384989644-count: 0
384989653:text: 24 75689685 293851064 294285337 79a1686d0dfb8618b8ccfc9eb7d74759
384989724-props: 24 384989543 53 0 113136892f2137aa0116093a524ade0b
384989782-cpath: /path/to/the/bad/file.exe
384989842-copyroot: 0 /

Число в начале каждой строки — это смещение, которое мы скоро будем использовать. Строка cpath наиболее интересна — это файл, который, как вы можете ожидать, будет поврежден. Но это строка :text:, которую нам нужно изменить, чтобы все заработало. Как описано здесь (ищите раздел о формате файла ревизии), эта строка имеет вид « ». Мы не хотим менять первые 4 параметра — они, скорее всего, в порядке. Но 5-й параметр — это неверная контрольная сумма, и она понадобится нам на следующем шаге.

3) Измените неверную контрольную сумму, чтобы она соответствовала «фактической» контрольной сумме, полученной в процессе проверки svnadmin. Опять же, это распечатывается при запуске проверки. Чтобы внести изменения, я использовал hexedit, который, к счастью, не пытается загрузить весь (огромный) файл ревизии. в память. Вы просто запускаете его и нажимаете «Return», чтобы ввести смещение в файле, к которому нужно перейти. Он хочет, чтобы он был в шестнадцатеричном формате, поэтому быстрое преобразование превращает 384989653 в 16F279D5. Оттуда вы можете нажать Tab, чтобы переключиться на редактирование ASCII, быстро найти неправильную контрольную сумму и перезаписать ее новой, действительной контрольной суммой; затем нажмите Ctrl-X, чтобы сохранить файл и выйти.

4) Повторно запустите проверку svnadmin. Теперь он должен успешно проверить сломанную версию и двигаться дальше. Если это не так, проверьте, совпадают ли ревизия и контрольная сумма, по которой она не работает. Если это не так, то у вас больше поврежденных файлов/ревизий, и вам следует повторять шаги с 1 по 3, пока они все не исчезнут. Надеюсь, их не будет слишком много. И помните: то, что ваш репозиторий теперь можно проверить, не означает, что ваши данные действительны. Все, что вы сделали, это сказали инструменту svnadmin, что контрольная сумма для данных, которые у вас есть, совпадает с контрольной суммой, которую он ожидает.

Надеюсь, это будет полезно другим администраторам SVN.

person MrCranky    schedule 23.04.2014

Погуглив, я нашел следующий сообщение.
Следуя этим рекомендациям, я возможность «исправить» плохие версии и выполнить полную команду проверки svnadmin. Кроме того, это позволило мне создать полный дамп репозитория.

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

Надеется, что это поможет любому.

person noti    schedule 22.08.2013
comment
Да, я написал этот пост некоторое время назад, и вы правы, вы, скорее всего, получите поврежденные данные. Что было неясно в моем случае, так это то, была ли неправильной контрольная сумма SVN или сами данные. Если данные в порядке, но контрольная сумма была рассчитана неправильно (по какой-либо причине), то эти ревизии не являются «плохими». Но, безусловно, они подозрительны и нуждаются в тщательном осмотре. У SVN просто нет информации, необходимой для того, чтобы сказать, в порядке ли файл или нет, и, конечно же, нет того, что нужно для воссоздания файла. - person MrCranky; 10.10.2013