
Tailscale обяви на 12 август 2026 г., че поредицата от сривове и повредени бази данни, които тормозеха услугата от август 2025 г. насам, се дължи на един-единствен бъг в SQLite — грешка, стояла незабелязана в кода от юли 2010 г. Разработчиците на SQLite я кръстиха WAL-Reset bug и я поправиха във версия 3.51.3, а The Register първи разказа историята извън блога на компанията.
Как започна всичко
Tailscale (мрежата от типа mesh VPN върху WireGuard) държи контролния си панел не в една голяма база, а в множество изолирани shard-ове, всеки със собствена SQLite база. Идеята е проблем в един shard да не събаря останалите.
През август 2025 г. конвейерът, който чете резервните копия в S3, докладва грешка в една от базите. После в друга. И в трета. За шест месеца Tailscale брои 19 отделни случая на повреда без очевиден общ спусък. Имало е и шестседмично затишие между октомври и декември, след което инцидентите се връщат — по думите на екипа, като нежелан коледен подарък.
Най-обезпокоителното откритие: запис, потвърден от базата, просто изчезва. „Запис се е изпарил във въздуха, без да върне грешка. Това би трябвало да е невъзможно!“, пишат от Tailscale в подробния си технически разказ.
Какво всъщност се чупи
SQLite в режим WAL (Write-Ahead Log) не пише директно в основния файл на базата. Новите транзакции отиват в отделен WAL файл, а периодична операция, наречена checkpoint, ги прехвърля в основната база и нулира лога.
Точно там е дупката. Ако запис се случи в много тесен времеви прозорец по време на checkpoint, полето в WAL-index заглавката се записва погрешно. „Процесът по checkpoint се обърква — мисли си, че част от страниците вече са копирани от WAL в основния файл, а те не са“, обяснява Алекс Чан от Tailscale. Следващият checkpoint прескача тези данни и базата остава трайно повредена.
Условията са тежки за възпроизвеждане: нужни са две или повече връзки към един и същ файл в различни нишки или процеси, които пишат или правят checkpoint в един и същи момент. Затова бъгът е оцелял 16 години — засегнати са всички издания от 3.7.0 (21 юли 2010 г.) до 3.51.2 (9 януари 2026 г.). Самите разработчици на SQLite сравняват честотата му с тази на дефекти в SSD или удари от космически лъчи и признават, че не са успели да го възпроизведат без специално модифициран тестов код.
Защо тогава Tailscale удря точно в него? Защото поемат ръчен контрол над checkpoint процеса и го изпълняват изключително агресивно. Изводът, който екипът си вади сам, е кратък: „Да ползваш скучна технология по нестандартен начин е риск.“
Шест месеца лов и специален инструмент
Разследването отнема месеци и съвместна работа с поддръжниците на SQLite. За да го проследят, те написват специална обвивка около виртуалната файлова система — шима tmstmpvfs, който записва подробна трасировка на всичко, което се случва с файла. Работата е финансирана от Tailscale, а кодът е в дървото на SQLite:
ext/misc/tmstmpvfs.c
Първата поправка идва в trunk версията 3.52.0. Тя обаче носи и странична промяна в закръгляването при преобразуване на текст към числа с плаваща запетая, което подлудява expression индексите на Tailscale — 13 бази докладват „повреда“, която се оказва фалшива тревога. Canary внедряването не я хваща, защото тестовите shard-ове нямат подходящите времеви печати. SQLite оттегля 3.52.0 и на 13 март 2026 г. пуска 3.51.3 само с поправката за WAL-Reset. Има и backport-и за 3.44.6 и 3.50.7. Tailscale от своя страна намалява точността на времевите си печати до цели секунди.
Снимка: Tailscale
Финалното потвърждение идва през май 2026 г. Екипът е оставил аларма, която се задейства, когато новата проверка засече опасната ситуация и я предотврати. Съобщението „SQLite опита повреда на shard2 в party mode, но системата я спря“ доказва, че условията наистина са се случвали в продукция. От тогава насам няма нито един нов инцидент.
Кого още засяга
Малко след публикацията инженер от Antithesis показа, че бъгът се възпроизвежда за 15 минути с напълно обикновен товар от паралелни записи и checkpoint-и срещу 3.51.2, докато 3.51.3 минава чисто. Екипът на Ubuntu пък провери с TLA+ дали разпределеният dqlite е засегнат.
Ако вашето приложение ползва SQLite в WAL режим с няколко процеса или нишки върху един файл, обновете до 3.51.3 или по-нова (или до backport-ите 3.44.6 / 3.50.7). Стандартната употреба с автоматичен checkpoint е практически незастрашена.
Изводът
Историята е добро напомняне, че повредата в базата не винаги е ваша вина — но и че отклонението от стандартната употреба на дори най-изпитания софтуер си има цена. За разлика от месечните маратони с уязвимости, тук няма нападател и няма експлойт: просто две нишки, които веднъж на милиарди пъти се разминават с микросекунда. И както при прекъснатите подводни кабели, последствията се усещат далеч отвъд мястото на самата повреда.
Харесва ви? Отбележете ни и ще ни виждате по-нагоре в Google.
Предпочитан източник в Google