Бэкап вместо защиты: как ошибка разрушала данные
Компания Tailscale завершила полугодовое расследование причины неожиданных сбоев в своей инфраструктуре и выявила редкий дефект SQLite, который оставался незамеченным с 2010 года. Неисправность привела к повреждению нескольких страниц базы данных, что нарушило функционирование всей VPN-сети.
Проблема впервые проявилась в августе 2025 года во время операций резервного копирования. При диагностике инженеры исключили множество типичных причин: нарушения блокировок, проблемы управления памятью и ошибки многопоточности. Поиск решения потребовал привлечения разработчиков самого SQLite и создания специального диагностического инструмента.
Сервис Tailscale использует SQLite для хранения информации о подключениях в приватных одноранговых сетях на базе протокола WireGuard. Система автоматически создавала полные резервные копии каждые несколько минут и загружала их в облачное хранилище.
Основная причина проблемы заключалась в механизме контрольных точек. SQLite применяет двухуровневую запись: сначала изменения записываются в отдельный журнал упреждающей записи (WAL), а затем переносятся в основной файл при создании контрольной точки. Tailscale управляла этим процессом вручную для быстрого создания согласованных копий, что создавало нестандартную нагрузку на систему.
Ошибка, названная WAL-Reset, возникала при совпадении операций создания контрольной точки и новой транзакции записи. В этот критический момент SQLite ошибочно полагала, что некоторые страницы уже перенесены из журнала в основной файл, хотя они оставались в журнале. Впоследствии эти страницы терялись без возможности восстановления, однако база сохраняла ссылки на них, приводя к повреждению всей структуры.
Данный баг активируется только при одновременном наличии нескольких условий: активном режиме WAL, множественных открытых подключениях к одному файлу и точном временном совпадении операций. При стандартных настройках вероятность критически низкая, однако интенсивное ручное управление контрольными точками в системе Tailscale значительно увеличивала риск.
Согласно анализу разработчиков SQLite, дефект присутствовал в коде начиная с версии 3.7.0 (июль 2010 года). Патч уже выпущен, и пользователям рекомендуется обновиться. Хотя вероятность встретить эту ошибку невысока, её последствия серьёзны: необратимая потеря данных и разрушение целостности базы.
