Назад
Tailscale знайшла 16-річний баг WAL-Reset у SQLite
SiTech Team2 წთ. საკითხავი

Tailscale знайшла 16-річний баг WAL-Reset у SQLite

Після 19 випадків пошкодження баз даних за пів року Tailscale та розробники SQLite виявили рідкісну гонку даних, що ховалася в ядрі бази щонайменше 16 років.

Протягом шести місяців контрольна площина Tailscale пережила 19 окремих випадків пошкодження бази даних, і всі вони мали одну причину — помилку глибоко в SQLite. У докладному дописі компанія розповідає, як разом із розробниками ядра бази знайшла й виправила «баг WAL-Reset» — рідкісну гонку даних, яка, за оцінками, існувала в SQLite щонайменше 16 років.

Шарди з одним письменником і агресивні чекпойнти

Контрольна площина Tailscale поділена на координаційні шарди, кожен із власною базою SQLite, доступ до якої має лише один процес на Go — саме той дизайн, для якого SQLite й створювався. Від 2022 року компанія використовує SQLite як основну базу: повний знімок робиться кожні кілька хвилин і завантажується в S3.

У серпні минулого року конвеєр, що читає ці резервні копії, повідомив про помилку, а PRAGMA integrity_check підтвердила пошкодження файлу. Випадок повторився — загалом 19 разів за пів року. Щоразу контрольна площина шарда вимикалася — спочатку більш ніж на годину, — тож пристрої, які виходили в мережу, не могли підключитися, а адмінконсоль і API були недоступні.

Помилка, яку не вдалося відтворити

Пошкодження не корелювало з жодним шардом, клієнтом, функцією чи рівнем навантаження, і відтворити його не вдавалося. Tailscale уклала контракт на професійну підтримку з розробниками SQLite і розгорнула криміналістичну телеметрію в продакшені. Конвеєр журналювання транзакцій, який відтворює кожен змінювальний SQL-вираз на добрій резервній копії, дав першу справжню підказку: у двох випадках дані, зафіксовані однією транзакцією, були невидимі для наступних.

Баг WAL-Reset

Команда SQLite створила tmstmpvfs — обгортку навколо шару віртуальної файлової системи для трасування чекпойнтів. Логи показали рідкісну гонку між чекпойнтом і транзакцією запису: чекпойнт вважає, що сторінки скопійовано з WAL у головний файл бази, хоча насправді ні — дані безповоротно втрачаються, а індекси вказують на неіснуючі сторінки. Виправлення вийшло в SQLite 3.51.3: додано перевірку, яка виявляє, коли WAL перезапустив інший потік.

Першу спробу — 3.52.0 — довелося відкликати: вона спричинила хибні сигнали про пошкодження в 13 базах Tailscale через застарілі expression-індекси. Tailscale знизила точність часових міток до цілих секунд, а SQLite згодом додала функцію самовідновлення індексів. Після двох місяців очікування діагностичне попередження нарешті спрацювало і довело, що гонка трапляється і в продакшені. Відтоді — чотири місяці без інцидентів.

SSiTech

SiTech — веброзробка з підтримкою AI

Створюємо швидкі та сучасні сайти й інтегруємо AI у бізнес-процеси. Маєте проєкт чи запитання? Із задоволенням допоможемо.