Gesaan dan konteks
Perkhidmatan penyelarasan desktop membuka satu fail SQLite daripada berbilang proses dalam mod WAL. Pasukan mendapati bahawa versi terdahulu mungkin mengandungi pepijat WAL-reset dan bimbang tentang keselamatan salah baca, penulisan serentak semasa peningkatan taraf, atau menyelaraskan salinan yang rosak ke hiliran (downstream). Reka inventori versi, penilaian risiko, peningkatan taraf, pengesahan integriti, pemulihan sandaran dan pengunduran (rollback), termasuk kawalan akses multiproses.
Perkara yang diuji oleh penemu duga
- Memisahkan julat versi yang terjejas daripada keadaan yang boleh mencetuskan pepijat tersebut.
- Membina matriks peningkatan taraf daripada versi rasmi yang dibetulkan dan versi backport.
- Menyusun langkah sandaran yang konsisten, pengesahan, pengasingan dan pemulihan.
- Menerangkan had
PRAGMA integrity_checkdan bukannya menganggapnya sebagai ketepatan logik perniagaan. - Mengendalikan penulisan multiproses, checkpoint, penyalinan fail dan kesan sampingan penyelarasan.
Soalan untuk penjelasan
- Apakah versi SQLite, pilihan binaan, sistem operasi dan mod jurnal tepat yang digunakan?
- Adakah dua atau lebih proses atau bebenang sedang menulis ke atau melakukan checkpoint pada fail yang sama?
- Apakah sandaran yang disahkan, replika dan cap masa semakan-berjaya-terakhir yang wujud?
- Bolehkah proses peningkatan membekukan penulisan seketika dan memaksa proses lama ditamatkan?
- Adakah sasaran pemulihan merupakan kehilangan transaksi terkini, pembinaan semula pelayan atau pemulihan tepat seperti asal?
Jawapan 30 saat
Saya akan menginventorikan versi dan mod masa jalanan (runtime) terlebih dahulu; julat versi yang terjejas tidak membuktikan berlakunya kerosakan data. SQLite mendokumentasikan pepijat WAL-reset dalam beberapa senario WAL dari 3.7.0 hingga 3.51.2, dibetulkan dalam 3.51.3 dan kemudiannya, dengan beberapa keluaran backport. Sebelum menaik taraf, bekukan penulisan, salin pangkalan data serta bukti WAL/SHM, dan rekod garis dasar pengesahan. Naik taraf salinan yang diasingkan, kemudian jalankan pemeriksaan integriti struktur, persampelan peringkat perniagaan dan pemeriksaan konsistensi penyelarasan. Tukar fail pengeluaran hanya selepas melepasi pintu kawalan, sambil mengekalkan salinan pengunduran (rollback). Untuk jangka panjang, hadkan penulisan multiproses, pantau checkpoint, konflik kunci dan kegagalan pengesahan, serta jadikan latihan pemulihan sebahagian daripada pintu kawalan pelepasan.
Pecahan terperinci langkah demi langkah
1. Membina matriks impak
Bahan rasmi SQLite meletakkan kemungkinan julat pepijat pada 3.7.0 hingga 3.51.2, dengan pembetulan dalam 3.51.3 dan kemudiannya serta backport dalam 3.44.6 dan 3.50.7. Risiko ini juga memerlukan mod WAL, berbilang sambungan ke satu fail, serta penulisan atau checkpoint yang berselang-seli dalam tetingkap masa yang sempit. Rekod versi SQLite setiap klien, keadaan WAL, kiraan sambungan, model proses dan lokasi fail, kemudian kelaskan sebagai "versi terjejas serta keadaan pencetus wujud".
version/mode -> WAL enabled -> multi-connection/process -> concurrent write/checkpoint
| | | |
+-- upgrade gate ------------------+----------> isolate, verify, rehearse recovery2. Membekukan dan memelihara bukti
Hentikan penulisan baharu dan biarkan aplikasi menutup sambungan dengan teratur. Jika proses lama mungkin masih aktif, jangan ganti atau salin pangkalan data. Pelihara pangkalan data asal, fail WAL/SHM dalam direktori yang sama, data versi, sandaran terkini dan log pengesahan. Salin hanya daripada keadaan yang stabil; WAL yang sentiasa berubah bukanlah snapshot statik.
3. Menaik taraf dan mengesahkan dalam pengasingan
Buka salinan dengan versi yang telah dibetulkan. Jalankan pemeriksaan integriti peringkat SQLite terlebih dahulu, kemudian pemeriksaan aplikasi untuk kiraan baris, indeks utama, kunci asing, kursor penyelarasan dan transaksi terkini. integrity_check boleh menemui masalah struktur tetapi tidak dapat membuktikan semantik domain, kesamarataan replika jauh, atau kesempurnaan kerja yang belum dilakukan (uncommitted). Ikat hasil pemeriksaan dengan cincangan (hash) salinan dan versi alatan.
4. Menukar, mengundur (rollback) dan memulihkan
Selepas melepasi pintu kawalan, tukar laluan fail atau direktori berversi secara atomik dan kekalkan salinan lama sebagai baca sahaja. Jika permulaan mendedahkan kegagalan pengesahan, konflik penyelarasan atau jurang perniagaan, hentikan penulisan baharu, tukar kembali atau bina semula daripada sandaran yang dipercayai, dan kemudian selaraskan semula secara berperingkat (incrementally). Jangan jalankan VACUUM, pembaikan pukal atau menulis ganti salinan pada fail yang disyaki rosak sebelum memelihara bukti.
5. Mengawal selia penulisan multiproses dan checkpoint
Utamakan satu proses penulis untuk satu fail dan siri-selarikan (serialize) transaksi penulisan melalui barisan gilir (queue); proses lain menggunakan sambungan bacaan yang terkawal. Tentukan pihak yang mencetuskan checkpoint, had masa tamat (timeout) dan amaran kegagalan supaya berbilang komponen tidak melakukan checkpoint secara serentak. Jika akses multiproses tidak dapat dielakkan, rekod kitaran hayat sambungan, masa menunggu kunci, hasil checkpoint dan versi proses, serta lakukan ujian tegasan ke atas penulisan dan checkpoint yang berselang-seli.
6. Memantau dan menguji latihan pemulihan
Selepas pelepasan, pantau liputan versi SQLite, pertumbuhan WAL, kependaman checkpoint, konflik kunci, kegagalan integriti, percubaan semula penyelarasan dan masa pemulihan. Latih tubi "bekukan—sandarkan—sahkan—tukar—undur" pada salinan yang telah dibersihkan dan sahkan bahawa klien lama tidak boleh membuka semula pangkalan data versi lama. Nyatakan objektif pemulihan sebagai RPO dan RTO perniagaan dan bukannya sekadar mengatakan "sandaran wujud".
Jawapan model
Saya akan bermula dengan matriks impak: sama ada SQLite berada dalam lingkungan 3.7.0–3.51.2, sama ada WAL didayakan, sama ada berbilang sambungan berkongsi fail tersebut, dan sama ada penulisan dan checkpoint boleh bertindih. Berada dalam julat tersebut bermakna perlu menaik taraf dan mengesahkan; ia tidak membuktikan berlakunya kerosakan data. Bekukan penulisan, sahkan bahawa proses lama telah ditamatkan, pelihara pangkalan data, WAL/SHM, sandaran, versi dan cincangan (hashes), serta naik taraf salinan terasing kepada 3.51.3 atau versi backport yang boleh diterima.
Pengesahan mempunyai tiga lapisan: PRAGMA integrity_check untuk struktur, persampelan aplikasi untuk data dan indeks utama, serta pemeriksaan penyelarasan untuk kursor tempatan berbanding kursor jauh. Lakukan pertukaran secara atomik selepas melepasi pintu kawalan dan simpan salinan lama sebagai baca sahaja. Jika pemeriksaan atau invarian perniagaan gagal, hentikan penulisan, pulihkan salinan yang dipercayai, dan bina semula penyelarasan berperingkat. Untuk jangka panjang, pusatkan penulisan dalam satu proses, kekang checkpoint aktif, pantau konflik kunci dan kegagalan pengesahan, serta lakukan latihan pemulihan.
Kesilapan lazim
- Mengisytiharkan pangkalan data rosak semata-mata kerana versi lama sedang digunakan.
- Menaik taraf binari tanpa membekukan penulisan atau tanpa memelihara WAL/SHM dan salinan pengunduran.
- Menganggap satu kejayaan
integrity_checksebagai bukti ketepatan logik perniagaan yang lengkap. - Menjalankan VACUUM atau menulis ganti fail yang disyaki rosak sebelum memelihara bukti.
- Membiarkan banyak proses melakukan checkpoint secara bebas tanpa metrik konflik dan had masa tamat.
- Mengatakan "kami membuat sandaran secara tetap" tanpa konsistensi sandaran, RPO, RTO atau latihan pemulihan.
Soalan susulan dan respons
Jika versi terjejas tetapi tiada anomali yang kelihatan, bolehkah kita melangkau peningkatan taraf?
Tidak. Gunakan keadaan pencetus untuk menilai pendedahan jangka pendek dan jadualkan versi yang telah dibetulkan; ketiadaan kegagalan yang diperhatikan tidak menyangkal kewujudan keadaan perlumbaan (race condition) yang sempit.
Mengapakah perlu melakukan pemeriksaan perniagaan selepas PRAGMA integrity_check lulus?
Ia terutamanya memeriksa struktur pangkalan data dan kekangan terpilih. Ia tidak mengesahkan kursor penyelarasan, invarian domain, kesamarataan jauh, atau kesempurnaan transaksi terkini, jadi persampelan aplikasi dan perbandingan replika tetap diperlukan.
Apakah langkah sementara jika akses multiproses tidak boleh direka bentuk semula dengan serta-merta?
Satukan versi SQLite dan tetapan permulaan, larang checkpoint aktif yang tidak terkawal, siri-selarikan penulisan, dan tingkatkan telemetri konflik kunci. Pendekkan kelompok pelepasan kenari (canary batches) dan simpan salinan baca sahaja yang boleh ditukar kembali dengan cepat sehingga reka bentuk penulis tunggal (single-writer) tersedia.