ИИ стёр базу данных: что делать и где искать копии

Обновлено:

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

Как это происходит

Разработчики дают ИИ-агентам (Cursor, Claude Code, Copilot, Devin, Windsurf) доступ к терминалу, файловой системе и базам данных. Иногда агент выполняет что-то необратимое.

Типичные сценарии:

  • агент запустил DROP TABLE или DROP DATABASE, «почистив» схему;
  • выполнил DELETE FROM users без WHERE;
  • запустил docker compose down -v и удалил тома с данными;
  • прогнал миграцию на продакшене вместо staging;
  • удалил файл .db или .sqlite, приняв его за временный;
  • сделал rm -rf в папке с данными при «очистке проекта».

Такие истории уже случались публично: в 2025 году широко обсуждали случай, когда ИИ-агент Replit удалил продакшен-базу проекта, несмотря на запрет вносить изменения. Агент с лишними правами действует быстрее, чем человек успевает его остановить.

Шаг 0: остановите запись

  • Остановите приложение и все сервисы, которые используют базу.
  • Остановите контейнеры: docker compose stop (не down).
  • Для PostgreSQL: sudo systemctl stop postgresql — так autovacuum не успеет окончательно вычистить удалённые строки.
  • Не устанавливайте программы и не скачивайте файлы на тот же диск.
  • Отзовите токены и ключи, которые были у ИИ-агента.

Уровень 1: очевидные места

Корзина Windows / Корзина macOS

Windows: откройте «Корзину», найдите файлы .db, .sqlite, .sql, .dump, правый клик → «Восстановить».

macOS: откройте «Корзину» в Dock, найдите файл, правый клик → «Вернуть».

Файлы, удалённые через rm в терминале или из скрипта на Python/Node.js, в корзину не попадают — переходите дальше.

Бэкапы в проекте

Проверьте папку backups/ и файлы вида .db.bak, .sql.old, backup_* в проекте и рядом:

find . \( -name "*.db" -o -name "*.sqlite" -o -name "*.dump" -o -name "*.sql" -o -name "*.bak" \) 2>/dev/null

История Git

Если файл базы когда-то попал в репозиторий:

git log --all --full-history -- "*.db"
git log --all --full-history -- "*.sqlite"

# Вернуть файл из конкретного коммита
git checkout <commit_hash> -- path/to/database.db

Даже если базы в Git нет, там есть миграции и seed-скрипты — по ним можно восстановить хотя бы схему.

Уровень 2: облачные синхронизации

Сроки хранения удалённых файлов зависят от сервиса и тарифа — ниже типичные значения, точные смотрите в справке сервиса.

iCloud Drive

  1. Откройте icloud.com → iCloud Drive.
  2. Раздел «Недавно удалённые» — файлы хранятся там около 30 дней.
  3. Найдите .db, .sqlite, .sql и восстановите.

В настройках аккаунта iCloud есть ещё раздел «Восстановление данных» (Data Recovery).

Google Drive

  1. Откройте drive.google.com → «Корзина».
  2. Найдите файл → «Восстановить».

Если файл не удалён, а испорчен, откройте «Управление версиями» в контекстном меню файла и выберите версию до инцидента.

Яндекс Диск

Откройте disk.yandex.ru → «Корзина», найдите и восстановите файл.

Dropbox

Раздел «Удалённые файлы» на dropbox.com. Срок хранения удалённых файлов и истории версий зависит от тарифа.

OneDrive

onedrive.live.com → «Корзина». Для личных аккаунтов удалённые файлы обычно хранятся 30 дней.

Уровень 3: системные бэкапы ОС

macOS Time Machine

Если к Mac подключён диск Time Machine — это самый надёжный вариант.

  1. Откройте папку, где лежал файл базы.
  2. Иконка Time Machine в строке меню → «Просмотреть резервные копии Time Machine».
  3. Шкалой справа перейдите ко времени до инцидента.
  4. Выберите файл → «Восстановить».

Time Machine хранит ежечасные копии за последние 24 часа, ежедневные — за последний месяц и еженедельные — за более ранний период, пока хватает места на диске.

Windows: История файлов

Если «История файлов» включена: откройте папку, где лежал файл, → вкладка «Главная» → «Журнал», прокрутите к нужному моменту и нажмите кнопку восстановления.

Windows: теневые копии (предыдущие версии)

  1. Правый клик на папке, где лежал файл → «Свойства» → «Предыдущие версии».
  2. Если список не пуст — выберите версию до инцидента и скопируйте файл.

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

vssadmin list shadows /for=C:

Смонтировать теневую копию как папку (обратный слеш в конце обязателен):

mklink /d C:\ShadowCopy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\

Уровень 4: облачные провайдеры баз данных

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

  • Supabase — раздел Backups в панели проекта; ежедневные бэкапы на платных планах, Point-in-Time Recovery — платное дополнение.
  • Railway — проверьте вкладку Backups у тома сервиса (если бэкапы были включены); если нет — сразу пишите в поддержку.
  • PlanetScale — раздел Backups в панели базы.
  • AWS RDS / Aurora — RDS → инстанс → «Restore to point in time»; восстановление возможно в пределах настроенного срока хранения автоматических бэкапов (максимум 35 дней).
  • Google Cloud SQL — Instances → инстанс → Backups; есть автоматические бэкапы и PITR, если они были включены.
  • Azure SQL Database — Portal → база → Restore, восстановление на момент времени в пределах срока хранения.
  • Render — у платных managed-баз есть восстановление на момент времени; проверьте раздел Recovery/Backups в панели.
  • Timeweb Cloud, Selectel, Yandex Cloud — раздел «Резервные копии» у кластера БД. Если нужного бэкапа нет в интерфейсе, сразу создавайте тикет в поддержку.

Как применить полученный дамп — в статье как восстановить базу из бэкапа.

Уровень 5: PostgreSQL без бэкапа

Если бэкапов нет, но после DELETE сервер не успел выполнить VACUUM, удалённые строки могут физически оставаться в файлах данных как «мёртвые» версии.

  1. Остановите сервер и сделайте полную копию каталога данных ($PGDATA) — все эксперименты только на копии.
  2. На копии отключите autovacuum для пострадавшей таблицы: ALTER TABLE users SET (autovacuum_enabled = false);
  3. Попробуйте прочитать мёртвые строки расширением pg_dirtyread или утилитой pg_filedump, которая разбирает страницы данных напрямую.

Если настроено архивирование WAL и есть базовый бэкап (pg_basebackup), всё проще: восстановите кластер на момент перед инцидентом (PITR). Без базового бэкапа WAL сам по себе не превращается обратно в данные. Посмотреть, что произошло, можно утилитой pg_waldump:

pg_waldump -p "$PGDATA/pg_wal" 000000010000000000000010 | grep -E "DELETE|TRUNCATE"

После DROP TABLE или TRUNCATE файлы таблицы удаляются, и шансы резко падают — остаётся восстановление файлов с диска или специалисты.

Уровень 6: восстановление удалённых файлов с диска

Если удалён сам файл базы (.db, .sqlite), попробуйте утилиты восстановления файлов. Устанавливайте и запускайте их НЕ с того диска, где была база: используйте другой диск или загрузочную флешку, найденные файлы сохраняйте тоже на другой диск.

TestDisk и PhotoRec (бесплатно, Windows/macOS/Linux)

# TestDisk — восстановление удалённых файлов на ряде файловых систем
sudo testdisk /dev/sda

# PhotoRec — поиск файлов по сигнатурам
sudo photorec /dev/sda

PhotoRec ищет файлы SQLite по сигнатуре: файл начинается со строки SQLite format 3 (53 51 4C 69 74 65 20 66 6F 72 6D 61 74 20 33 00).

Другие инструменты

  • Recuva (Windows) — простой бесплатный вариант, фильтруйте по расширениям .db, .sqlite, .sql.
  • Disk Drill (Windows/macOS) — платный, бесплатный режим позволяет просмотреть найденное. cleverfiles.com
  • R-Studio — профессиональный инструмент. r-studio.com

Про SSD: если включён TRIM, контроллер вскоре после удаления очищает освобождённые блоки, и программное восстановление чаще всего не помогает. На HDD шансов заметно больше.

Уровень 7: лаборатории восстановления данных

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

Как не допустить повторения

1. Минимальные права для ИИ

Не давайте ИИ-агенту учётку администратора базы. Создайте отдельного пользователя:

-- PostgreSQL: пользователь только для чтения
CREATE ROLE ai_agent LOGIN PASSWORD 'сгенерируйте_пароль';
GRANT CONNECT ON DATABASE myapp TO ai_agent;
GRANT USAGE ON SCHEMA public TO ai_agent;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO ai_agent;
-- права на таблицы, созданные позже
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO ai_agent;

Для SQLite открывайте базу в режиме только для чтения: sqlite3 "file:app.db?mode=ro" или соответствующий флаг в драйвере.

2. Правила для агента

В AGENTS.md, CLAUDE.md или .cursorrules:

## Правила работы с базой данных
- Никогда не выполнять DROP TABLE, DROP DATABASE, TRUNCATE, DELETE без WHERE без явного подтверждения пользователя
- Никогда не запускать docker compose down -v
- Перед любой миграцией или деструктивной операцией — сделать бэкап и спросить подтверждение

Помните: это инструкции для модели, а не системное ограничение. Настоящую защиту дают права доступа и бэкапы.

3. Бэкап перед каждой задачей с базой

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

Хранить такие копии вне машины можно в dbsend: CLI загружает SQLite-файл (сам делая согласованную копию), файл DuckDB или plain SQL-дамп PostgreSQL/MySQL как новую версию, а запуск по расписанию вы настраиваете через cron или CI. Если агент что-то сломает, вы вернётесь к версии до инцидента:

dbsend backup ./app.db -l before-agent-task
dbsend log
dbsend restore <snapshotId> ./app.restored.db --yes

Агенту можно дать доступ к бэкапам через MCP-сервер dbsend с ключом только на чтение: он увидит версии и сравнит их, но ничего не удалит. Восстановление через MCP подтверждает человек — запросом в клиенте или одноразовым кодом из prepare_restore, — сама модель запустить его не может.

4. Разделение окружений

Не давайте агенту доступ к продакшен-базе при работе с кодом — только dev или staging.

# .env.development
DATABASE_URL=postgresql://localhost:5432/myapp_dev

# .env.production — не должен попадать в контекст ИИ
DATABASE_URL=postgresql://prod-server:5432/myapp_prod

5. Журналирование опасных операций

В PostgreSQL включите логирование изменяющих запросов:

# postgresql.conf
log_statement = 'mod'   # DDL плюс INSERT/UPDATE/DELETE/TRUNCATE

Значение 'ddl' пишет только изменения схемы (CREATE, ALTER, DROP) и создаёт меньше логов.

Чеклист на случай паники

  1. Остановить запись на диск.
  2. Корзина Windows/macOS.
  3. Папка backups/ в проекте.
  4. История Git: git log --all -- "*.db".
  5. Корзины iCloud, Google Drive, Яндекс Диска, OneDrive, Dropbox.
  6. Time Machine.
  7. «Предыдущие версии» и теневые копии Windows.
  8. Бэкапы облачного провайдера БД.
  9. Утилиты восстановления файлов — с другого диска.
  10. Тикет в поддержку провайдера с пометкой «срочно».
  11. Лаборатория восстановления данных.

Частые вопросы

ИИ выполнил DELETE без WHERE — данные можно восстановить?

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

Агент запустил docker compose down -v. Что делать?

Флаг -v удаляет именованные и анонимные тома, объявленные в compose-файле, и Docker не кладёт их в корзину. Данные в bind mount (папка на хосте вроде ./pgdata) при этом не удаляются. Если данные были в томе — помогут только внешние бэкапы или восстановление файлов с диска.

Есть ли восстановление через облако на бесплатном плане?

Корзины Google Drive, iCloud, Яндекс Диска и OneDrive доступны на бесплатных тарифах. Восстановление на момент времени у облачных БД (Supabase, RDS и других) обычно требует платного плана или заранее включённой настройки.

Как настроить бэкапы, чтобы больше не попасть в эту ситуацию?

Делайте бэкап по расписанию (cron, systemd-таймер или CI) и перед каждой рискованной операцией, храните копии вне сервера и регулярно проверяйте восстановление. Пошагово — в статье как настроить автоматические бэкапы, а хранение версий и оповещения о пропущенных бэкапах для SQLite — на странице бэкап SQLite в dbsend.

Файл был на SSD. Есть ли шанс?

Если TRIM включён (на большинстве современных систем так и есть), шансы программного восстановления низкие. Остаётся лаборатория, которая работает с микросхемами памяти напрямую, — дорого и без гарантий.

Как объяснить ИИ-агенту, что он не должен удалять данные?

Пропишите запреты в AGENTS.md или .cursorrules, но не полагайтесь только на них: это инструкции, а не ограничения. Настоящая защита — отдельный пользователь БД с минимальными правами, разделение окружений и бэкапы.