Ce face PRAGMA journal_mode (WAL)
Ca să nu strice baza dacă programul se oprește în mijlocul unei scrieri, SQLite folosește un jurnal. Implicit (DELETE), înainte de a modifica fișierul copiază paginile vechi într-un fișier baza.db-journal, pe care îl șterge la final.
În modul WAL (write-ahead log), modificările sunt adăugate întâi într-un fișier baza.db-wal, iar fișierul principal rămâne neschimbat până la un checkpoint. Avantajul: cititorii nu blochează scriitorul și scriitorul nu blochează cititorii, iar scrierile mici sunt de obicei mai rapide. Rămâne valabil: un singur scriitor odată.
Modul WAL se salvează în fișierul bazei, deci îl setezi o singură dată. Lângă bază apar fișierele -wal și -shm, care fac parte din bază cât timp e deschisă. WAL nu funcționează pe sisteme de fișiere în rețea (NFS, partajări SMB). O bază în memorie are mereu modul memory.
Parametri
| Parametru | Descriere |
|---|---|
DELETE |
Implicit: jurnal separat, șters după fiecare tranzacție. |
WAL |
Jurnal cu scriere în avans: citiri și o scriere în paralel. Persistent. |
TRUNCATE / PERSIST |
Ca DELETE, dar golesc sau marchează jurnalul în loc să îl șteargă. |
MEMORY / OFF |
Jurnal în memorie sau deloc: o oprire bruscă poate strica baza. |
Exemple
Exemplul 1: Trecerea unei baze în modul WAL
O bază nou creată pornește în modul delete. Setarea întoarce noul mod, wal. După o scriere, lângă magazin.db apar fișierele -shm și -wal (comanda .shell rulează ls din sqlite3).
.open magazin.db
PRAGMA journal_mode;
PRAGMA journal_mode = WAL;
CREATE TABLE vanzari (oras TEXT, suma INTEGER);
INSERT INTO vanzari VALUES ('Iași', 1200), ('Cluj', 900);
.shell ls magazin.db*
Rezultat
╭──────────────╮
│ journal_mode │
╞══════════════╡
│ delete │
╰──────────────╯
╭──────────────╮
│ journal_mode │
╞══════════════╡
│ wal │
╰──────────────╯
magazin.db
magazin.db-shm
magazin.db-wal
Exemplul 2: Checkpoint manual
wal_checkpoint(TRUNCATE) mută paginile din -wal în fișierul principal și golește jurnalul. Rezultatul: busy (0 = nu a fost blocat), paginile din jurnal și paginile mutate; după TRUNCATE jurnalul este gol, deci ultimele două sunt 0. Implicit, SQLite face checkpoint singur când jurnalul trece de 1000 de pagini.
.open magazin.db
PRAGMA journal_mode = WAL;
CREATE TABLE vanzari (oras TEXT, suma INTEGER);
INSERT INTO vanzari VALUES ('Iași', 1200);
PRAGMA wal_checkpoint(TRUNCATE);
PRAGMA wal_autocheckpoint;
Rezultat
╭──────────────╮
│ journal_mode │
╞══════════════╡
│ wal │
╰──────────────╯
╭──────┬─────┬──────────────╮
│ busy │ log │ checkpointed │
╞══════╪═════╪══════════════╡
│ 0 │ 0 │ 0 │
╰──────┴─────┴──────────────╯
╭────────────────────╮
│ wal_autocheckpoint │
╞════════════════════╡
│ 1000 │
╰────────────────────╯
Exemplul 3: O bază în memorie
Pentru :memory:, jurnalul este mereu în memorie, iar cererea de WAL este ignorată.
PRAGMA journal_mode;
PRAGMA journal_mode = WAL;
Rezultat
╭──────────────╮
│ journal_mode │
╞══════════════╡
│ memory │
╰──────────────╯
╭──────────────╮
│ journal_mode │
╞══════════════╡
│ memory │
╰──────────────╯
Greșeli frecvente
- Copiezi doar fișierul
.dbal unei baze în WAL cât timp e deschisă. Ultimele modificări pot fi încă în-wal; foloseșteVACUUM INTOsau.backup. - Ștergi fișierele
-walși-shmcrezând că sunt temporare. Fișierul-walpoate conține tranzacții confirmate care nu au ajuns încă în bază. - Pui baza în WAL pe un disc din rețea. Modul WAL are nevoie de memorie partajată pe aceeași mașină; pe NFS sau SMB rămâi la
DELETE.
Comenzi înrudite
BEGIN, COMMIT, ROLLBACK: Grupează mai multe modificări într-o tranzacție: fie se salvează toate cu COMMIT, fie niciuna cu ROLLBACK.VACUUM: Reconstruiește fișierul bazei de date: eliberează spațiul rămas după ștergeri și, cu INTO, face o copie compactă..open: Închide baza curentă și deschide (sau creează) alt fișier de bază de date, fără să ieși din sqlite3.PRAGMA integrity_check: Verifică dacă fișierul bazei de date este întreg: paginile, indexurile și constrângerile. Răspunde „ok” dacă totul e în regulă.