Модификация базы данных внутри резервной копии для удаления дублирующегося тега ключа, чтобы избежать сбоя при восстановлении

Это пост — очень сжатая версия моих событий за последние 24 часа. Хотя обновление ещё не прошло успешно, я надеюсь, что кто-нибудь укажет ниже, где именно возникла ошибка.

Мое обновление Discourse не прошло из-за дубликата ключа: один из тегов был продублирован. Чтобы исправить проблему с обновлением, мне потребовалась чистая установка Discourse и последующая загрузка последней резервной копии. Однако при загрузке возникла ошибка из-за того же дубликата ключа. Поэтому мне пришлось зайти внутрь резервной копии и изменить проблемный тег на что-то другое.

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

1) Поиск резервных копий: Чтобы найти резервные копии Discourse, выполните следующую команду:

sudo find / -name "*.tar.gz"

Эта команда выполнит поиск всех файлов с расширением “.tar.gz” на вашей системе. По умолчанию они должны находиться внутри контейнера в каталоге: shared/backups/default

2) Создание копии: Когда вы нашли нужную резервную копию, создайте её копию, чтобы сохранить оригинал. Используйте команду “cp”:

bash

sudo cp /path/to/original_backup.tar.gz /path/to/copy_backup.tar.gz

3) Извлечение копии: Извлеките содержимое скопированного файла резервной копии с помощью команды “tar”:

bash

tar -xzvf /path/to/copy_backup.tar.gz

Это извлечёт файлы резервной копии во временный каталог.

4) Редактирование тегов в базе данных: Перейдите в извлечённые файлы резервной копии и откройте соответствующий файл базы данных с помощью текстового редактора. У меня возникла проблема с дубликатами тегов “socialmedia”, из-за чего восстановление не удавалось. В большой базе данных множество записей с тегами, и, скорее всего, несколько экземпляров именно того тега, который вы ищете. Поэтому я использовал поиск ‘immutable socialmedia’ через Ctrl+W в Nano, что сразу перенесло меня к нужному месту.

sudo nano /path/to/extracted_database.sql

Я изменил один экземпляр тега “socialmedia” на “socialmedia2”, затем быстро проверил, что теперь он встречается только один раз. Исправить остальные теги я смогу из админ-панели после успешного восстановления.

5) Перепаковка: После редактирования файлов резервной копии создайте новый файл с исправленным содержимым. Используйте следующую команду для сжатия изменённых файлов:

tar -czvf /path/to/new_modified_backup.tar.gz /path/to/modified_files_directory

6) Перемещение в правильный каталог: Переместите новый изменённый файл резервной копии в каталог, где хранятся резервные копии. По умолчанию это обычно “/shared/backups/default”:

sudo mv /path/to/new_modified_backup.tar.gz /shared/backups/default/

7) Остановка и запуск служб: Перед восстановлением изменённой резервной копии остановите соответствующие службы, чтобы избежать возможных конфликтов в процессе восстановления. Используйте команду “./launcher stop app” для остановки приложения Discourse:

./launcher stop app

8) Восстановление резервной копии: Чтобы восстановить данные из изменённой резервной копии, используйте команду “discourse restore” с указанием пути к новому файлу:

discourse restore /shared/backups/default/new_modified_backup.tar.gz

Или вы можете сделать это через /admin на вашем сайте, так как файл теперь должен отображаться в разделе резервных копий.

9) Проверка восстановления: После завершения процесса восстановления я проверил, что изменения были успешными, просмотрев приложение Discourse и базу данных, убедившись, что дубликаты тегов “socialmedia” удалены.

10) Запуск служб: Я перезапустил ранее остановленные службы, чтобы вернуть приложение Discourse в работу. Для этого использовал команду “./launcher start app”:

./launcher start app

11) Удаление временных файлов и лишних резервных копий: После успешного восстановления я удалил все временные файлы и дополнительные резервные копии, созданные в процессе, чтобы освободить место на диске. Используйте команду “rm” для удаления файлов:

sudo rm -r /path/to/temporary_directory
sudo rm /path/to/copy_backup.tar.gz

Почему?

Почему нельзя было исправить это «онлайн», перезапустив приложение, войдя в контейнер, подключившись к PostgreSQL и сразу же исправив запись в базе данных?

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

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

Но вы же видели ошибку при обновлении?

В следующий раз облегчите себе жизнь и исправьте всё на месте.

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

Конечно, это частный случай, о котором я здесь написал; лучшим вариантом было бы заметить проблему и исправить её, пока у меня ещё был прямой доступ к базе данных приложения, но я упустил это и не нашёл другого выхода.

Не переживайте. По крайней мере, вы показали, что это возможно, узнали что-то новое и предложили другим дополнительный вариант.

Хорошая работа! :clap:

Спасибо, хотя исходный файл был 128 МБ, а новый — 29 МБ. Похоже, что повторное архивирование на сервере могло привести к усечению файла из-за его размера.

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

Выбранный вами путь был более рискованным, но, безусловно, выполнимым? Возможно, кто-то сможет поделиться советом по этому вопросу.

Вы, по-видимому, можете повторить это снова из резервной копии, так что…

Решена ли эта проблема? Текст звучит как инструкция, но похоже, что ваш сайт всё ещё не работает.

Возможно, вы делаете что-то, чего я не понимаю, но обычно достаточно выполнить ./launcher start app, чтобы запустить старый контейнер. Была ли причина, по которой вы не могли этого сделать?

Затем вы можете использовать инструменты Rails или SQL, чтобы исправить базу данных в старом контейнере, а затем снова попробовать выполнить загрузку/пересборку.

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

Раньше я проводил подобную «хирургию» над резервной копией, когда восстанавливаемый сайт был старше года. Мне кажется, дамп базы данных был достаточно малым, чтобы я мог отредактировать его в vim.

Спасибо за ответ.

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

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

Да, скорее всего так. Сейчас это немного туманно, что именно я делал, но я обновил несколько вещей независимо, основываясь на советах по устранению неполадок, которые я здесь нашёл. Одним из таких обновлений была установка последней версии PostgreSQL.

Я смог отредактировать его в vim.

Я смог отредактировать в Nano, и всё выглядело хорошо, но повторно сжатый файл был слишком маленьким, так что где-то что-то пошло не так… возможно, я не смог его отредактировать в Nano. На тот момент всё казалось рабочим.

Я надеялся, что кто-нибудь заметит ошибку и исправит меня, чтобы это стало руководством «как сделать».

Что стоит проверить в следующий раз:

  • Переделайте полную распаковку. Снова упакуйте без изменений. Проверьте, совпадает ли размер ZIP-файла с предыдущим. Если нет, возможно, вы используете другие параметры архивации?

  • Распакуйте снова, проверьте размер файла, который вы редактируете. Отредактируйте его, сохраните и убедитесь, что размер существенно не изменился.

Небольшое обновление. На прошлой неделе над этим работал кто-то другой из моей команды, но решение так и не нашлось, поэтому я попробовал ещё раз, на этот раз отредактировав базу данных на своей локальной системе.

Что я сделал:

  1. Загрузил старую резервную копию, которую хочу восстановить.
  2. Распаковал файлы с помощью 7-Zip.
  3. Открыл dump.sql в Visual Studio Code.
  4. Нашёл дублирующиеся теги непосредственно в базе данных.
  5. Нашёл, по-видимому, список тегов, выполнив поиск с использованием кавычек вокруг тега. В моём случае это ‘socialmedia’. Теги выглядят как второй и третий снизу среди найденных вхождений.

  1. Изменил одно из вхождений на:

132 ‘socialmedia2’:1A socialmedia2 en_GB 3

  1. Снова упаковал файл dump.sql с помощью 7-Zip:
  • Добавить в архив
  • Формат архива: .gzip
  1. Снова упаковал основной файл резервной копии:
  • Добавить в архив
  • Формат архива: .tar (gzip пока недоступен)
  1. Теперь у вас должен появиться заархивированный исправленный файл резервной копии .tar

  2. Упакуйте файл .tar с помощью 7-Zip, чтобы создать файл .tar.gz, соответствующий формату, используемому в Discourse:

  • Добавить в архив
  • Формат архива: .gzip
  1. Загрузите файл в раздел резервных копий и восстановите его через административную панель.

На этом этапе я столкнулся с сообщением об ошибке:

Извлечение файла дампа…
[2023-08-08 15:09:15] EXCEPTION: No such file or directory @ rb_check_realpath_internal - /var/www/discourse/tmp/restores/default/2023-08-08-150913/dump.sql.gz

Есть ли у кого-нибудь идеи, что я упустил в описанном выше процессе?

Единственное, что приходит мне в голову, — это то, что путь, который система ищет, использует сегодняшнюю дату, а не дату резервной копии (я пишу это 08-08-2023).

Это продолжение моего предыдущего поста здесь. Я публикую это снова, чтобы другим было проще найти эту информацию в будущем, если метод сработает.

Что я сделал для редактирования БД на своём ноутбуке:

  1. Скачал старую резервную копию, из которой хочу восстановить данные, через раздел администратора.
  2. Распаковал файлы с помощью 7zip.
  3. Открыл dump.sql в Visual Studio Code.
  4. Нашёл дублирующиеся теги непосредственно в БД.
  5. Нашёл, по-видимому, список тегов, выполнив поиск по тегу, заключённому в одинарные кавычки. В моём случае это было ‘socialmedia’. Теги, похоже, находятся на 2-й и 3-й позиции снизу среди найденных вхождений.

  1. Изменил одно из вхождений на:

132 ‘socialmedia2’:1A socialmedia2 en_GB 3

  1. Снова упаковал файл dump.sql с помощью 7zip:
  • Добавить в архив
  • Формат архива .gzip
  1. Снова упаковал основной файл резервной копии:
  • Добавить в архив
  • Формат архива .tar (gzip пока недоступен)
  1. Теперь вы должны увидеть упакованный исправленный файл резервной копии .tar

  2. Упакуйте файл .tar в 7zip, чтобы создать файл .tar.gz, соответствующий формату, используемому Discourse:

  • Добавить в архив
  • Формат архива .gzip
  1. Загрузите файл в раздел резервных копий и восстановите его через раздел администратора.

На этом этапе я столкнулся с ошибкой:

Извлечение файла дампа…
[2023-08-08 15:09:15] EXCEPTION: No such file or directory @ rb_check_realpath_internal - /var/www/discourse/tmp/restores/default/2023-08-08-150913/dump.sql.gz

У кого-нибудь есть идеи, что я упустил в описанном выше процессе?

Единственное, что приходит мне в голову, — это то, что путь, который он ищет, использует сегодняшнюю дату, а не дату резервной копии (я пишу это 08-08-2023).

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

Я объединил сообщения из новой темы в эту, так как, похоже, что сохранение этой проблемы сгруппированной в одном месте значительно упростит её отслеживание для будущих путешественников. :+1:

Спасибо, @Ed_S. Я оставил оригинальное имя, так как где-то читал, что это важно. Мой вопрос выше касается того, почему инструмент восстановления резервной копии искал и не нашел: /var/www/discourse/tmp/restores/default/2023-08-08-150913/dump.sql.gz, что соответствует дате, когда я выполнял восстановление.

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

Если вы просмотрите содержимое tar-архива, видите ли вы там это имя файла? В моём случае:

root@ubuntu-2gb-nbg1-1:/var/discourse/shared/standalone/backups/default# tar vtfz forumname-2023-08-03-HHMMSS-v2023mmddhhmmss.tar.gz dump.sql.gz | head
-rw-r--r-- discourse/www-data 16336925 2023-08-03 05:31 dump.sql.gz

Спасибо, Эд. Такого файла не существовало. Извините за задержку, я некоторое время был без связи.

Файла с правильным именем там нет, поэтому я просто попытался вручную создать пустой файл:

sudo mkdir -p /var/www/discourse/tmp/restores/default/2023-08-22-121010/

Но каждый раз при нажатии кнопки восстановления система ищет файл с немного другим именем (последние 6 цифр). Я предполагаю, что она ищет папку, созданную на основе временной метки, поэтому каждый раз при нажатии кнопки восстановления искомая папка меняется.

Я подозреваю, что на шаге 10, когда вы создаёте tar-архив, возникает проблема. Вы можете это увидеть? Можете ли вы использовать команду file для описания файла? Можете ли вы вывести его содержимое с помощью tar tvfz?