Введение
После случайного удаления с помощью SQL заявка исчезает, но конфигурация приложения остаётся правильной. Вы сохраните закладку D1 Time Travel, воспроизведёте потерю на одной синтетической записи и восстановите ту же базу данных, сохранив заявку, которую удаление не затронуло.
Это самостоятельная тренировка восстановления с одной временной удалённой базой данных и предоставленным Worker только для чтения. Перед восстановлением вы проверите состояние пропавшей записи, а после восстановления — доступ приложения к данным.
Используйте собственную учебную учётную запись и новую виртуальную машину. Сначала настройка подготовит Node.js 22.22.0, затем выполнит npm install для локального Wrangler 4.131.1 и всех зависимостей для проверки в каталоге /home/labex/project/ticket-database. Версии прямых зависимостей зафиксированы; установка создаёт собственный lock-файл. Во время настройки вход в облако и операции с проверяемой базой данных не выполняются. На личном компьютере установите ту же версию Wrangler командой npm install --save-dev wrangler@4.131.1 в каталоге проекта.
В этом упражнении используются небольшие синтетические записи в пределах бесплатных лимитов D1. Использование ресурсов вашей учётной записи также учитывается в этих лимитах. Покупать домен не нужно. Не удаляйте эту виртуальную машину, пока не проверите удаление ресурсов и выход из учётной записи.
Авторизуйте эту виртуальную машину и выберите учётную запись
На этом шаге вы подключите новый терминал к собственной учебной учётной записи. Одного входа в Dashboard недостаточно для авторизации виртуальной машины. Разрешение D1 позволяет создавать базы данных, изменять SQL-данные и удалять базы; разрешение Workers позволяет выполнять развёртывание, а разрешение KV используется Wrangler для инвентаризации при очистке. Перед авторизацией внимательно проверьте страницу согласия, включая раздел Background Access.
Откройте подготовленный проект и проверьте зафиксированную версию CLI:
cd /home/labex/project/ticket-database
npx wrangler --version
Ожидаемый результат — 4.131.1. Запустите авторизацию устройства. Параметр --device выведет код для браузера, а --browser=false позволит вам самостоятельно выбрать способ открытия браузера:
npx wrangler login --device --browser=false --scopes account:read user:read d1:write workers_scripts:write workers_kv:write
Откройте показанный URL в браузере, введите текущий код, подтвердите свою учебную учётную запись и разрешения, затем авторизуйтесь. Дождитесь сообщения терминала об успешной авторизации. Никогда не вставляйте пароли или токены в файлы проекта.
npx wrangler whoami --json
Проверьте значение loggedIn: true, затем прочитайте name и id учётной записи, даже если в списке указана только одна учётная запись. Скопируйте нужный идентификатор в конфигурацию ниже. Следующая переменная оболочки использует 6 случайных байт (12 шестнадцатеричных символов), чтобы избежать совпадений с другими учащимися. Here-документ записывает JSON между строками JSON; переменная $RUN раскрывается внутри него.
Обратная косая черта перед $schema сохраняет этот ключ JSON буквально; $RUN по-прежнему подставляет уникальное имя текущего запуска.
RUN=labex-c04-d07-$(openssl rand -hex 6)
cat > wrangler.jsonc <<JSON
{
"\$schema": "./node_modules/wrangler/config-schema.json",
"name": "$RUN",
"account_id": "YOUR_ACCOUNT_ID",
"main": "src/index.js",
"compatibility_date": "2026-09-15",
"workers_dev": true,
"preview_urls": false
}
JSON
Замените YOUR_ACCOUNT_ID перед выполнением блока. Не закрывайте этот терминал, чтобы переменная RUN оставалась доступной. Поле name идентифицирует этот запуск, а account_id выбирает учётную запись для облачных операций. Файл содержит обычный JSON, который также является допустимым JSONC. При его создании Worker не развёртывается.
Создайте известную точку восстановления
На этом шаге вы создадите временную базу данных и предоставленный ticket API только для чтения. Time Travel восстанавливает прежнее состояние базы данных на месте. Он не создаёт заменяющую базу данных и может перезаписать изменения, внесённые после выбранной точки. Используйте его здесь только для этого недавно созданного учебного ресурса.
Создайте временную облачную базу данных. Параметр --binding DB задаёт короткое имя для кода приложения, --update-config записывает её настоящее имя и UUID в wrangler.jsonc, а --use-remote=false оставляет разработку локальной:
npx wrangler d1 create "$RUN-db" --binding DB --update-config --use-remote=false
Прочитайте созданные имя и идентификатор, затем проверьте сохранённую привязку:
cat wrangler.jsonc
Запись DB должна содержать имя базы данных этого запуска. Привязка — это настроенное соединение между кодом и ресурсом. Её UUID идентифицирует облачную базу данных, а параметр --local использует отдельную базу SQLite на этой виртуальной машине. В командах SQL всегда явно указывайте либо --local, либо --remote.
npx wrangler d1 execute DB --remote --file schema.sql
npx wrangler deploy
Скопируйте URL развёрнутого приложения и прочитайте обе синтетические заявки:
URL='YOUR_DEPLOYED_HTTPS_URL'
curl -i "$URL/tickets/1"
curl -i "$URL/tickets/2"
Ожидайте код 200 для заявки 1 (Cannot sign in, открыта) и заявки 2 (Invoice copy, закрыта). Если развёртывание ещё распространяется, повторяйте эти запросы в течение минуты, пока код состояния и JSON не начнут соответствовать друг другу.
Проверьте сведения о базе данных, затем сохраните её текущую закладку как артефакт восстановления. Закладка — это непрозрачная позиция в истории базы данных. Перенаправление с помощью > записывает JSON-ответ в указанный файл:
npx wrangler d1 info DB
npx wrangler d1 time-travel info DB --json > recovery.json
cat recovery.json
Убедитесь, что база данных использует рабочую серверную часть, а recovery.json содержит непустое значение bookmark. Не изменяйте этот файл до конца упражнения. Time Travel всегда включён для рабочей среды D1; для Free срок хранения составляет 7 дней, а для Paid — 30 дней. Для восстановления в рамках этого сеанса достаточно нескольких минут истории. Строка справки CLI с упоминанием 30 дней не изменяет срок хранения вашего тарифа.
Воспроизведите ограниченное случайное удаление
На этом шаге вы удалите из этой учебной базы данных только синтетическую заявку 1 и подтвердите проявление проблемы в приложении. Сначала проверьте wrangler.jsonc и сопоставьте DB с именем и UUID, которые вы только что создали. Не выполняйте эти команды для существующей базы данных приложения.
cat wrangler.jsonc
npx wrangler d1 execute DB --remote --command "DELETE FROM tickets WHERE id = 1;"
Прочитайте ответ API и запись, которую удаление не затронуло:
curl -i "$URL/tickets/1"
curl -i "$URL/tickets/2"
npx wrangler d1 execute DB --remote --command "SELECT id, subject, status, source FROM tickets ORDER BY id;"
Для заявки 1 должен вернуться код 404 с {"error":"not_found"}. Заявка 2 по-прежнему должна возвращать исходный ответ с кодом 200; SQL-запрос должен содержать только заявку 2. Сбой сети или страница 404 платформы не подтверждают, что удаление произошло.
Завершите проверку этого шага до восстановления. Она проверяет реальное состояние отсутствующей строки; восстановление без наблюдения сбоя пропустило бы свидетельство инцидента.
Восстановите историю и проверьте доступ приложения
На этом шаге вы восстановите ту же базу данных до сохранённой закладки. Прочитайте recovery.json, скопируйте точную строку bookmark в BOOKMARK, затем ещё раз проверьте идентификатор настроенной базы данных:
cat recovery.json
BOOKMARK='YOUR_SAVED_BOOKMARK'
cat wrangler.jsonc
npx wrangler d1 time-travel restore DB --bookmark "$BOOKMARK"
Команда предупредит, что перезапишет данные и отменит выполняющиеся запросы. Подтвердите действие только для этой временной базы данных. Ожидайте сообщение об успешном восстановлении и закладку для отмены операции. Не создавайте базу данных заново, не импортируйте схему повторно и не вставляйте пропавшую строку: такие действия обошли бы применяемый метод восстановления.
Запросите восстановленную базу данных и существующую привязку приложения:
npx wrangler d1 execute DB --remote --command "SELECT id, subject, status, source FROM tickets ORDER BY id;"
curl -i "$URL/tickets/1"
curl -i "$URL/tickets/2"
Обе исходные строки и оба ответа API должны вернуться. Worker по-прежнему указывает на тот же UUID, поэтому заменяющая привязка не нужна. Если во время восстановления чтение временно недоступно, повторите запрос; не заменяйте восстановление незаметным созданием нового набора данных.
В Dashboard откройте именно эту базу D1, убедитесь, что её идентификатор не изменился, и просмотрите восстановленные заявки в режиме только для чтения. Эта проверка связывает восстановленные данные с ресурсом; функциональным подтверждением служат результаты SQL-запросов и API. В Audit Logs учётной записи задайте фильтр Resource ID по UUID этой базы и выберите период, включающий восстановление. Нажмите на время события, чтобы открыть сведения, раскройте Resource и проверьте type: database.time_travel.restore. Сопоставьте идентификатор ресурса и успешную операцию с выводом команды восстановления. Аудит может появиться с задержкой; не считайте восстановление неудачным из-за временно пустого списка. Проверки данных подтверждают восстановленное состояние, а фактический вывод команды восстановления и событие аудита документируют операцию восстановления.

В этом примере показаны оба исходных обращения после восстановления в той же базе. Сгенерированное имя обозначает этот пример запуска; ваши имя и UUID будут другими. Снимок показывает восстановленные строки. Проверки SQL/API подтверждают восстановленный доступ, а фактический вывод команды Time Travel и соответствующее событие аудита подтверждают операцию восстановления.

В заголовке указано общее действие create. В раскрытом разделе Resource значение type: database.time_travel.restore обозначает восстановление. Проверьте успешный результат, точный UUID базы и время; эти значения относятся к данному примеру запуска.
Удалите временные ресурсы
На этом шаге вы удалите только ресурсы этой лабораторной работы, пока виртуальная машина всё ещё авторизована. Сначала завершите все функциональные проверки. Не удаляйте конфигурацию, пока не закончите проверку удаления.
npx wrangler delete
Подтвердите удаление только Worker, имя которого указано в конфигурации этого запуска.
npx wrangler d1 delete DB
Проверьте приглашение и подтвердите удаление только базы данных этого запуска. Затем выведите список баз данных:
npx wrangler d1 list --json
Имя и UUID записанной вами базы данных должны отсутствовать в успешном ответе. Другие ресурсы могут сохраниться. Ошибка аутентификации или сети не даёт однозначного результата: восстановите доступ и повторите проверку, прежде чем продолжать. Выполните проверку этого шага, пока вы всё ещё вошли в систему.
Завершите авторизацию этой виртуальной машины
На этом шаге завершите авторизацию только после успешной независимой проверки удаления. Выход удаляет сохранённую на этой виртуальной машине авторизацию Wrangler; простого закрытия виртуальной машины недостаточно для очистки облачных ресурсов.
npx wrangler logout
npx wrangler whoami --json
Ожидайте loggedIn: false. Этот запрос без аутентификации может завершиться с ненулевым кодом; это ожидаемо только в том случае, если структурированный ответ явно сообщает, что вы вышли из системы. Завершите проверку, затем закройте учебную среду.
Резюме
Вы потренировались восстанавливать случайно удалённую заявку. Вы проверили наблюдаемые результаты в базе данных, явно контролировали выбранную учётную запись и локальное состояние, а затем удалили временные ресурсы перед выходом из системы.



