Восстановление системных таблеток

Примечание

Концептуальную информацию о механизме см. в разделе Резервное копирование системных таблеток.

Важно

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

Шаг 1. Переведите таблетку в Recovery-режим

Таблетку, которую требуется восстановить, необходимо перевести в Recovery-режим.

Важно

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

  1. Определите идентификатор системной таблетки, которую требуется восстановить. Идентификатор таблетки можно найти в разделе Tablets в YDB UI.

  2. Сохраните текущую конфигурацию кластера в файл config.yaml.

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

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

    Создайте изолированное окружение с PyYAML:

    python3 -m venv ./recovery && ./recovery/bin/pip install pyyaml
    

    Создайте файл скрипта:

    cat > find-tablet-hosts.py <<'EOF'
    #!/usr/bin/env python3
    import argparse
    import yaml
    
    
    def find_nodes(cfg, tid):
        bootstrap = (cfg.get("bootstrap_config") or {}).get("tablet") or []
        for tablet in bootstrap:
            if str(tablet.get("info", {}).get("tablet_id")) == tid:
                return tablet.get("node") or []
    
        for tablets_by_type in (cfg.get("system_tablets") or {}).values():
            for tablet in tablets_by_type or []:
                if str(tablet.get("info", {}).get("tablet_id")) == tid:
                    return tablet.get("node") or []
    
        return []
    
    
    parser = argparse.ArgumentParser()
    parser.add_argument("--config-path", required=True, help="Path to cluster configuration file")
    parser.add_argument("--tablet-id", required=True, help="System tablet id")
    args = parser.parse_args()
    
    with open(args.config_path) as f:
        cfg = yaml.safe_load(f) or {}
    
    cfg = cfg.get("config", cfg)
    
    hosts_by_id = {h["node_id"]: h["host"] for h in cfg.get("hosts") or []}
    
    node_ids = find_nodes(cfg, args.tablet_id)
    if not node_ids:
        node_ids = list(hosts_by_id)
    
    for node_id in sorted(set(node_ids)):
        host = hosts_by_id.get(node_id)
        if host is not None:
            print(host)
    EOF
    

    Запустите скрипт, подставив путь к своей конфигурации и идентификатор таблетки:

    Пример:

    ./recovery/bin/python find-tablet-hosts.py --config-path config.yaml --tablet-id <tablet-id> > hosts.txt
    
  4. Измените сохраненную конфигурацию, добавив boot_type: RECOVERY в секцию конфигурации запуска восстанавливаемой таблетки и сократите список узлов, где может запускаться восстанавливаемая таблетка (массив node), до одного узла.
    Пример для таблетки Hive с идентификатором 72057594037968897:

    • При использовании bootstrap_config:

          bootstrap_config:
              tablet:
              - type: FLAT_HIVE
                  node:
                  - 1
                  info:
                      tablet_id: '72057594037968897'
                      channels:
                      - channel: 0
                      history:
                      - from_generation: 0
                          group_id: 0
                      channel_erasure_name: mirror-3-dc
                      - channel: 1
                      history:
                      - from_generation: 0
                          group_id: 0
                      channel_erasure_name: mirror-3-dc
                      - channel: 2
                      history:
                      - from_generation: 0
                          group_id: 0
                      channel_erasure_name: mirror-3-dc
                  boot_type: RECOVERY
      
    • При использовании system_tablets:

      flat_hive:
      - info:
          tablet_id: 72057594037968897
        node:
        - 9
        boot_type: RECOVERY
      
  5. Обновите конфигурацию в кластере.

    • При использовании конфигурации V1 необходимо обновить статическую конфигурацию на всех хостах, полученных на шаге 3, с помощью команды:

      Скопируйте обновлённую конфигурацию во временный файл на каждом хосте:

      pscp -h hosts.txt config.yaml /tmp/config.yaml.new
      

      Сделайте резервную копию текущей конфигурации, замените её новой версией и защитите от случайных изменений:

      pssh -h hosts.txt 'sudo cp /opt/ydb/cfg/config.yaml /opt/ydb/cfg/config.yaml.bak && sudo mv /tmp/config.yaml.new /opt/ydb/cfg/config.yaml && sudo chattr +i /opt/ydb/cfg/config.yaml'
      
    • При использовании конфигурации V2, воспользуйтесь инструкцией.

  6. Перезапустите все узлы, на которых может работать восстанавливаемая таблетка. Если какой-либо узел недоступен и не может быть перезапущен, изолируйте его от кластера по сети — например, с помощью firewall.

    Пример:

    pssh -h hosts.txt 'sudo systemctl restart ydbd-storage; sleep 10'
    

    Важно

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

  7. Убедитесь, что:

    • С таблеткой нет проблем в HealthCheck.
    • Таблетка не перезапускается.
    • В App таблетки в YDB UI доступна форма восстановления.

Шаг 2. Найдите файлы резервных копий

  1. На каждом хосте, полученном на шаге 3, проверьте наличие резервных копий. Путь к резервным копиям определяется параметром path в секции конфигурации system_tablet_backup_config.

    Имя каждой резервной копии содержит ключевую информацию: backup_<timestamp>_g<generation>_s<step>, где:

    • timestamp — время создания резервной копии;
    • generation — поколение таблетки, увеличивается при каждом перезапуске таблетки;
    • step — шаг таблетки в рамках поколения, увеличивается при каждом изменении состояния таблетки.
  2. Выберите наиболее актуальную резервную копию, пригодную для восстановления.

    Выберите резервную копию с максимальным поколением, а при равном поколении — с максимальным шагом.

    Убедитесь, что резервная копия полностью записана. Выбранная резервная копия должна содержать директорию snapshot, а не snapshot.tmp. Наличие snapshot.tmp означает, что запись снапшота не была завершена и копия непригодна для восстановления. В этом случае выберите предыдущую по актуальности копию.

    ls /path/to/backup/directory/hive/72057594037968897/backup_20251007T193502_g214_s1222/snapshot/
    
    manifest.json
    schema.json
    Tablet.json
    TabletFollowerGroup.json
    ...
    

    Проверьте, что файлы резервной копии содержат данные:

    ls -lh /path/to/backup/directory/hive/72057594037968897/backup_20251007T193502_g214_s1222/snapshot
    
    total 128K
    -rw-r--r-- 1 ydb disk  591 May 27 11:34 manifest.json
    -rw-r--r-- 1 ydb disk  12K May 27 11:34 schema.json
    -rw-r--r-- 1 ydb disk  47K May 27 11:34 Tablet.json
    -rw-r--r-- 1 ydb disk  41K May 27 11:34 TabletFollowerGroup.json
    ...
    

    Посчитайте чексумму от файла changelog.json и сверьте ее с чексуммой, записанной в changelog.json.sha256:

    sha256sum /path/to/backup/directory/hive/72057594037968897/backup_20251007T193502_g214_s1222/changelog.json
    
    ea4bdc2f7afaf7b6d35adbf13b5360e4e4a19046f742effdf1b4f0bb9c449185
    
    cat /path/to/backup/directory/hive/72057594037968897/backup_20251007T193502_g214_s1222/changelog.json.sha256
    
    ea4bdc2f7afaf7b6d35adbf13b5360e4e4a19046f742effdf1b4f0bb9c449185
    

    В случае, если чексуммы отличаются, то возможны две ситуации:

    • Последняя запись в changelog.json не была полностью записана. В этом случае, чексумма, хранящаяся в changelog.json.sha256 находится в одной из записей в changelog.json в поле prev_sha256. Для восстановления необходимо отредактировать файлы: удалить/дополнить не полностью записанные записи в changelog.json и обновить чексумму в changelog.json.sha256.
    • Произошло повреждение данных, восстановление невозможно.

Шаг 3. Перенесите файлы резервной копии

  1. Определите, на каком хосте запущена таблетка в Recovery-режиме. Для этого откройте YDB UI и найдите хост, на котором работает таблетка.

  2. Если файлы резервной копии находятся на другом хосте, скопируйте их на хост с таблеткой в Recovery-режиме с помощью scp, rsync или любого другого доступного инструмента:

    Скопируйте бекап из директории с бекапами в свою домашнюю директорию:

    cp -R /path/to/backup/directory/hive/72057594037968897/backup_20251007T193502_g214_s1222 ~/backup_20251007T193502_g214_s1222
    

    Скопируйте бекап на целевой хост:

    scp -r ~/backup_20251007T193502_g214_s1222 target-host:~/backup_20251007T193502_g214_s1222
    

    В случае, если операция копирования между хостами напрямую недоступна, то необходимо копировать через промежуточный хост:

    
    scp -r backup-host:~/backup_20251007T193502_g214_s1222 backup_20251007T193502_g214_s1222
    
    scp -r backup_20251007T193502_g214_s1222 target-host:~/backup_20251007T193502_g214_s1222
    

    После копирования бекапа на целевой хост, предоставьте доступ к нему процессу ydb:

    chown -R ydb ~/backup_20260527104029Z_g1911_s
    

Шаг 4. Выполните восстановление

  1. Откройте App восстанавливаемой таблетки в YDB UI.

  2. В форме восстановления укажите полный путь до директории с файлами резервной копии, например:

    /path/to/backup/directory/hive/72057594037968897/backup_20251007T193502_g214_s1222
    
  3. При необходимости установите флаги:

    • Dry Run — выполняет пробное восстановление без внесения изменений в хранилище. Позволяет убедиться в корректности резервной копии. После завершения пробного восстановления необходимо перезапустить таблетку.
    • Skip Checksum Validation — пропускает проверку контрольных сумм файлов резервной копии.

    Важно

    Всегда выполняйте Dry Run перед восстановлением, чтобы убедиться в корректности резервной копии.

    Важно

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

  4. Нажмите кнопку Start Restore. Перед началом восстановления система запросит подтверждение, так как операция перезаписывает существующие данные таблетки. Подтвердите действие для запуска. После начала восстановления форма становится недоступной — повторный запуск невозможен до перезапуска таблетки.

    Примечание

    Восстановление также можно запустить с помощью curl, отправив POST-запрос на страницу App таблетки с параметром restoreBackup:

    curl -X POST "http://<host>:<mon_port>/tablets/app?TabletID=72057594037968897&restoreBackup=/tablet/hive/72057594037968897/backup_20251007T193502_g214_s1222"
    

    Где <host> — адрес узла кластера, <mon_port> — порт мониторинга этого узла.

  5. Отслеживайте прогресс восстановления. Страница не обновляется автоматически — для получения актуального статуса обновляйте страницу вручную. Продолжительность восстановления зависит от объёма резервной копии.

    Примечание

    Восстановление выполняется на стороне сервера и не зависит от браузера. Вы можете закрыть страницу или браузер — это не прервёт процесс восстановления. При повторном открытии страницы отобразится актуальный статус.

    Под формой отображается текущий статус операции. Возможные статусы:

    • Restoring from '<путь>' — восстановление выполняется, данные из резервной копии считываются и записываются в хранилище. Дополнительно отображается прогресс-бар с процентом выполнения операции.
    • Restore from '<путь>' completed successfully — восстановление завершено успешно. Можно переходить к следующему шагу.
    • Restore from '<путь>' completed, but changelog is not fully restored — основные данные таблетки восстановлены, но хвост журнала изменений в резервной копии повреждён, и часть последних изменений потеряна. Изучите, какие данные были потеряны, и при необходимости восстановите их вручную, либо переходите к следующему шагу.
    • Restore from '<путь>' failed: <описание ошибки> — восстановление завершилось с ошибкой. Изучите описание ошибки и при необходимости повторите попытку.

    Для принудительного прерывания восстановления перезапустите таблетку.

  6. Дождитесь успешного завершения восстановления. Если форма восстановления снова стала доступна (кнопка Start Restore активна, статус сброшен), это означает, что таблетка была перезапущена и восстановление прервано. В этом случае начните восстановление заново с пункта 2.

Шаг 5. Верните таблетку к нормальному режиму работы

После успешного восстановления:

  1. Верните конфигурацию в исходное состояние, удалив boot_type: RECOVERY из секции конфигурации запуска восстанавливаемой таблетки и восстановив изначальный список узлов, где может запускаться восстанавливаемая таблетка.

    • При использовании конфигурации V1 необходимо обновить статическую конфигурацию на всех хостах, полученных на шаге 3, с помощью команды:

      Снимите защиту от случайных изменений и замените новую конфигурацию исходной версией:

      pssh -h hosts.txt 'sudo chattr -i /opt/ydb/cfg/config.yaml && sudo mv /opt/ydb/cfg/config.yaml.bak /opt/ydb/cfg/config.yaml'
      
    • При использовании конфигурации V2, воспользуйтесь инструкцией.

  2. Перезапустите все узлы, на которых может работать восстанавливаемая таблетка. Если какие-либо узлы были изолированы от кластера по сети на предыдущих шагах, снимите сетевую изоляцию.

    Пример:

    pssh -h hosts.txt 'sudo systemctl restart ydbd-storage; sleep 10'
    
  3. Убедитесь, что:

    • С таблеткой нет проблем в HealthCheck.
    • Таблетка не перезапускается.
    • В App таблетки в YDB UI отсутствует форма восстановления.
  4. Поочерёдно перезапустите все узлы кластера для синхронизации состояния внутренних кешей в памяти с состоянием таблетки. После перезапуска каждого узла дождитесь его возвращения в рабочее состояние и убедитесь в отсутствии проблем в HealthCheck; только после этого переходите к следующему узлу.

Следующая