SSD Nodes Learn Hosting plans →
Przewodniki Matt ConnorAutor: Matt Connor · Zaktualizowano 2026-10-15

SQLite na VPS w produkcji: konfiguracja i ograniczenia

Dowiedz się, kiedy SQLite jest optymalnym wyborem dla małych aplikacji na VPS. Poznaj konfigurację WAL mode, busy_timeout oraz wdrożenie replikacji danych przez Litestream.

Verified Every command ran end-to-end on a fresh Ubuntu 24.04 server, July 30, 2026.

Kiedy SQLite jest właściwą bazą danych produkcyjną na VPS

Uruchamianie SQLite w środowisku produkcyjnym na VPS jest właściwym wyborem dla większości małych aplikacji, a powód jest prosty: jeden proces na jednej maszynie zapisujący do jednego pliku nie wymaga serwera bazy danych. Nie ma demona do nadzorowania, portu do zabezpieczenia firewallem, hasła do rotacji ani drugiej maszyny, którą trzeba utrzymywać w działaniu. Zapytanie jest wywołaniem funkcji, a nie komunikacją sieciową, więc strona wykonująca czterdzieści zapytań kosztuje czterdzieści wywołań funkcji.

Ograniczenia są wąskie, ale realne. SQLite pozwala na jednego piszącego w danym momencie w całym pliku bazy danych, a pliku nie można współdzielić między dwiema maszynami. Oba limity są akceptowalne dla pojedynczego VPS z jedną aplikacją. Oba stają się krytyczne w momencie, gdy skala projektu wykracza poza ten model. Ten przewodnik omawia ustawienia czyniące SQLite bezpiecznym na serwerze, ciągłe tworzenie kopii zapasowych za pomocą Litestream oraz moment, w którym należy zrezygnować z tego rozwiązania.

Najpierw zainstaluj narzędzie wiersza poleceń. Wszystkie poniższe kroki wykonano na Ubuntu 24.04.

sudo apt update
sudo apt install -y sqlite3
sqlite3 --version

Polecenie to wyświetla wersję rozpoczynającą się od 3., po której następuje data kompilacji i skrót źródła. Ubuntu 24.04 dostarcza SQLite 3.45.1 według stanu na październik 2026. Twoja aplikacja prawdopodobnie nie korzysta z tego pliku binarnego: większość środowisk uruchomieniowych języków programowania dołącza własną kopię biblioteki SQLite, często nowszą, więc sprawdź wersję zgłaszaną przez sterownik bazy danych, zanim zaczniesz polegać na nowej funkcji.

Dlaczego tryb WAL jest pierwszym ustawieniem do zmiany

Domyślnie SQLite korzysta z dziennika wycofywania (rollback journal). Przed modyfikacją strony bazy danych, SQLite kopiuje jej oryginalną zawartość do pliku -journal, a następnie edytuje bazę w miejscu. Aby zapewnić bezpieczeństwo operacji, zakładana jest blokada wyłączna na cały plik, co powoduje, że wszyscy czytelnicy muszą czekać na zakończenie zapisu. Na komputerze osobistym jest to niezauważalne. Na serwerze WWW jedna wolna operacja zapisu wstrzymuje każde żądanie wymagające dostępu do bazy danych.

Tryb WAL (write-ahead log) odwraca tę kolejność. Proces zapisujący dołącza nowe strony do oddzielnego pliku -wal, nie modyfikując głównego pliku bazy danych. Czytelnicy korzystają z głównego pliku w wersji migawki, w której rozpoczęli odczyt, dzięki czemu nie blokują procesu zapisującego, a proces zapisujący nie blokuje czytelników. W późniejszym czasie operacja checkpoint kopiuje zgromadzone strony WAL z powrotem do głównej bazy danych. Ta pojedyncza zmiana w największym stopniu decyduje o użyteczności SQLite w zastosowaniach z aplikacjami webowymi.

Włączenie trybu WAL i weryfikacja jego stanu

mkdir -p ~/app
sqlite3 ~/app/app.db "PRAGMA journal_mode=WAL;"

Polecenie zwraca wal. Ten wynik nie jest jedynie informacją wizualną. PRAGMA journal_mode zwraca tryb, w którym faktycznie znajduje się baza danych, więc odpowiedź delete oznacza, że zmiana nie powiodła się i nadal używany jest dziennik wycofywania (rollback journal).

Tryb WAL jest trwały. Jest to flaga w nagłówku bazy danych, a nie ustawienie połączenia, dlatego uruchamia się go raz dla pliku bazy danych, a każde kolejne połączenie dziedziczy to ustawienie, również po restarcie systemu. Można to zweryfikować za pomocą nowego połączenia.

sqlite3 ~/app/app.db "PRAGMA journal_mode;"

Teraz należy utworzyć tabelę i sprawdzić zawartość dysku.

sqlite3 ~/app/app.db <<'SQL'
CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY, body TEXT NOT NULL);
INSERT INTO notes (body) VALUES ('first row');
SQL
ls -l ~/app/

Obecnie istnieją trzy pliki: app.db, app.db-wal oraz app.db-shm. Plik -wal przechowuje zatwierdzone strony, które nie zostały jeszcze poddane punktowi kontrolnemu (checkpoint). Plik -shm to indeks pamięci współdzielonej, który jest mapowany przez każde połączenie, aby zapewnić spójność informacji o zawartości WAL. Oba pliki należą do bazy danych i nie są plikami tymczasowymi. Skopiowanie samego app.db podczas pracy aplikacji spowoduje uzyskanie pliku, w którym brakuje wszystkich ostatnich zatwierdzeń. Usunięcie app.db przy pozostawieniu pozostałych dwóch plików spowoduje, że SQLite zastosuje te nieaktualne strony WAL do dowolnego nowego pliku, który pojawi się pod tą nazwą. W ten sposób często dochodzi do uszkodzenia nowej bazy danych podczas prób resetowania istniejącej.

Ustawienia połączeń wymagane przez każdą aplikację produkcyjną

W bazie danych przechowywane jest wyłącznie journal_mode. Wszystkie pozostałe poniższe ustawienia dotyczą pojedynczego połączenia, co oznacza, że aplikacja musi je wywoływać dla każdego otwieranego połączenia, w tym dla każdego połączenia tworzonego w tle przez pulę.

PRAGMA journal_mode = WAL;
PRAGMA busy_timeout = 5000;
PRAGMA synchronous = NORMAL;
PRAGMA foreign_keys = ON;

busy_timeout = 5000 instruuje SQLite, aby ponawiał próbę dostępu do zablokowanej bazy danych przez maksymalnie 5000 milisekund przed zwróceniem błędu database is locked. Wartość domyślna wynosi 0, co powoduje, że SQLite natychmiast zgłasza błąd w przypadku nałożenia się dwóch operacji zapisu. Ustawienie tej pojedynczej wartości eliminuje większość błędów blokad, które błędnie przypisuje się samemu SQLite.

synchronous = NORMAL to właściwe ustawienie w trybie WAL, przy czym warto zrozumieć wynikający z niego kompromis. Przy FULL, SQLite wywołuje fsync na pliku WAL przy każdym zatwierdzeniu (commit). Przy NORMAL, synchronizacja następuje dopiero podczas punktów kontrolnych (checkpoint). Dokumentacja SQLite jasno określa konsekwencje: transakcje przestają być trwałe w przypadku awarii zasilania lub twardego resetu. Baza danych nie ulegnie uszkodzeniu wskutek utraty zasilania, jednak utracone zostaną ostatnie zatwierdzenia, które nie zostały jeszcze zapisane na dysku. Na serwerze VPS jest to zazwyczaj korzystny kompromis, ponieważ eliminuje operację fsync z procesu każdej pojedynczej operacji zapisu.

foreign_keys = ON jest domyślnie wyłączone ze względu na kompatybilność wsteczną i dotyczy każdego połączenia z osobna. Schemat zawierający klauzule REFERENCES nie wymusza żadnych ograniczeń, dopóki każde połączenie nie włączy tej opcji.

Jeszcze jedno ustawienie staje się istotne na późniejszym etapie. SQLite automatycznie wykonuje punkt kontrolny, gdy plik WAL przekroczy 1000 stron, a operację tę wykonuje połączenie, które w danym momencie kończy transakcję. Jest to rozwiązanie poprawne w standardowych warunkach. Kwestia ta staje się istotna w przypadku użycia Litestream, ponieważ Litestream wymaga kontroli nad momentem wykonywania punktów kontrolnych.

Dlaczego database is locked nadal występuje po ustawieniu busy_timeout

Jest to błąd, który zmusza użytkowników do powrotu do Postgres, a ma on jedną konkretną przyczynę.

Ustawienie busy timeout rejestruje procedurę obsługi zajętości (busy handler), jednak SQLite nie gwarantuje jej wywołania.

Jeśli SQLite uzna, że wywołanie procedury obsługi zajętości mogłoby doprowadzić do zakleszczenia, zwróci aplikacji SQLITE_BUSY zamiast wywoływać tę procedurę.

Zakleszczenie, którego unika silnik, występuje podczas aktualizacji transakcji. Zwykłe BEGIN w SQLite oznacza BEGIN DEFERRED. Jeśli pierwszą instrukcją po nim jest SELECT, sesja znajduje się w transakcji odczytu. Gdy późniejsza instrukcja UPDATE w tej samej transakcji wymaga przejścia w tryb zapisu, a inne połączenie dokonało zapisu od momentu rozpoczęcia odczytu, SQLite nie może wymusić oczekiwania. Migawka danych jest już nieaktualna, a oczekiwanie doprowadziłoby jedynie do wzajemnego zakleszczenia obu połączeń. Dokumentacja wprost określa wynik takiej operacji:

Kolejne instrukcje zapisu spowodują aktualizację transakcji do transakcji zapisu, jeśli to możliwe, lub zwrócą SQLITE_BUSY.

Ustawiony limit czasu 5000 milisekund nie jest w ogóle brany pod uwagę. Błąd pojawia się natychmiast, co sprawia wrażenie, że ustawienie nie zadziałało.

Rozwiązanie składa się z jednego słowa.

BEGIN IMMEDIATE;
UPDATE notes SET body = 'edited' WHERE id = 1;
COMMIT;

BEGIN IMMEDIATE przejmuje blokadę zapisu na samym początku, przed wykonaniem jakiegokolwiek odczytu. Nie dochodzi do aktualizacji transakcji, więc nie ma ryzyka zakleszczenia, dzięki czemu procedura obsługi zajętości działa, a połączenie czeka na swoją kolej zamiast zgłaszać błąd. Transakcje tylko do odczytu należy pozostawić jako deferred. Każda transakcja zawierająca operację zapisu powinna być immediate.

Druga przyczyna błędów blokowania jest trudniejsza do wykrycia: utrzymywanie otwartej transakcji zapisu podczas wykonywania długotrwałych operacji. SQLite szereguje procesy zapisu, więc transakcja, która otwiera się, wywołuje zewnętrzny API przez sieć, a następnie wykonuje commit, zablokuje każdego innego piszącego na czas trwania tego wywołania. Należy pobrać potrzebne dane, zamknąć transakcję, wykonać powolną operację, a następnie otworzyć krótką transakcję zapisu w celu zapisania wyniku.

Ciągła kopia zapasowa z Litestream

Kopia wykonywana raz na dobę powoduje utratę nawet całego dnia zapisu, a uruchomienie cp na działającej bazie SQLite może wygenerować kopię, której nie da się otworzyć. Dwie metody są bezpieczne. sqlite3 app.db ".backup /path/to/backup.db" korzysta z interfejsu kopii zapasowej online SQLite i działa na bazie będącej w użyciu. Litestream idzie krok dalej: monitoruje plik WAL i w sposób ciągły przesyła zmiany do pamięci obiektowej, co skraca maksymalny czas utraty danych z jednego dnia do około jednej sekundy.

Litestream to pojedynczy plik binarny Go, który działa obok aplikacji. Nie znajduje się on pomiędzy aplikacją a bazą danych. Aplikacja zapisuje dane do SQLite dokładnie tak jak wcześniej, a Litestream odczytuje plik WAL i przesyła zmiany.

cd /tmp
curl -fsSL -O https://github.com/benbjohnson/litestream/releases/download/v0.5.14/litestream-0.5.14-linux-x86_64.deb
sudo dpkg -i litestream-0.5.14-linux-x86_64.deb
litestream version

Wersja v0.5.14 jest nadal wydaniem dokumentowanym na oficjalnej stronie instalacji dla systemu Linux według stanu na październik 2026. Później pojawiły się nowsze wydania: v0.5.15 w dniu 21 lipca 2026 oraz v0.5.17, najnowszy tag, w dniu 31 sierpnia 2026. Należy zmienić wersję w obu liniach, aby odpowiadała aktualnemu tagowi na stronie wydań, a w przypadku korzystania z VPS o architekturze arm64, należy pobrać odpowiedni pakiet arm64.

Plik konfiguracyjny znajduje się w /etc/litestream.yml. Należy zacząć od lokalnej repliki plikowej, ponieważ pozwala to zweryfikować cały proces bez konieczności posiadania danych uwierzytelniających do chmury.

dbs:
  - path: /home/appuser/app/app.db
    replica:
      type: file
      path: /var/backups/litestream/app

Należy zwrócić uwagę, że pole to replica, w liczbie pojedynczej. Litestream 0.5 zastąpił tablicę replicas z serii 0.3 pojedynczym blokiem repliki, a konfiguracja zawierająca dwa wpisy kończy się niepowodzeniem przy starcie. Wiele poradników zewnętrznych nadal pokazuje starą tablicę, dlatego należy skopiować powyższy schemat, zamiast pierwszego przykładu znalezionego w wyszukiwarce. Seria 0.5 zmieniła również nazwę podkomendy litestream wal na litestream ltx, ponieważ zmienił się format kopii zapasowej na dysku.

Przed włączeniem jakichkolwiek funkcji należy sprawdzić, czy konfiguracja jest poprawnie parsowana.

sudo litestream databases -config /etc/litestream.yml

Następnie należy ręcznie zweryfikować pełny cykl. Poniższa forma pomija plik konfiguracyjny i replikuje jedną bazę danych do jednej ścieżki.

mkdir -p /tmp/replica
litestream replicate ~/app/app.db file:///tmp/replica/app

Proces ten działa na pierwszym planie i nie kończy pracy. W drugiej powłoce należy zapisać wiersz i przywrócić replikę do nowego pliku.

sqlite3 ~/app/app.db "INSERT INTO notes (body) VALUES ('written after replication started');"
litestream restore -o /tmp/restored.db file:///tmp/replica/app
sqlite3 /tmp/restored.db "SELECT count(*) FROM notes;"

Liczba zawiera nowy wiersz. Jeśli nie, zmiana nie została jeszcze zsynchronizowana: Litestream przesyła dane w interwale sync-interval, który domyślnie wynosi 1 sekundę, więc należy odczekać i spróbować przywrócić ponownie. Ta jedna sekunda to również punkt odzyskiwania. Awaria powoduje utratę co najwyżej zapisów z ostatniego interwału synchronizacji i żadna konfiguracja nie pozwala zredukować tego czasu do zera.

W przypadku rzeczywistego przechowywania danych należy zamienić blok repliki na adres URL S3. Działa to zarówno z Amazon S3, jak i z pamięcią obiektową zgodną z S3 od innych dostawców.

dbs:
  - path: /home/appuser/app/app.db
    replica:
      url: s3://your-bucket-name/app
      region: us-east-1

snapshot:
  interval: 24h
  retention: 24h

Dane uwierzytelniające należy przechowywać poza tym plikiem. Litestream odczytuje LITESTREAM_ACCESS_KEY_ID oraz LITESTREAM_SECRET_ACCESS_KEY ze zmiennych środowiskowych, więc należy umieścić je w pliku typu drop-in dla systemd, którego właścicielem jest root, z uprawnieniami 600.

Powyższe wartości migawek są wartościami domyślnymi, a domyślny czas retencji często zaskakuje użytkowników. Retencja określa, jak długo Litestream przechowuje migawki oraz należące do nich pliki, a tym samym wyznacza, jak daleko wstecz można przywrócić dane. Dwadzieścia cztery godziny oznaczają, że nieudana migracja zauważona w środę rano jest nie do odzyskania ze stanu z poniedziałku. W Litestream 0.5 retencja jest ustawieniem globalnym w głównym bloku snapshot, a nie ustawieniem dla każdej repliki z osobna. Aby ustawić tydzień, należy zmienić ten blok na retention: 168h i opłacić dodatkowe miejsce w pamięci. Linia retention: wewnątrz bloku repliki to składnia serii 0.3. Litestream 0.5 ignoruje ją bez zgłaszania błędu i pozostaje przy domyślnych 24 godzinach.

Weryfikacja przywracania danych przed wystąpieniem awarii

litestream restore -o /tmp/check.db /home/appuser/app/app.db
sqlite3 /tmp/check.db "PRAGMA integrity_check;"
sqlite3 /tmp/check.db "SELECT count(*) FROM notes;"

Dla podanej ścieżki bazy danych, litestream restore wyszukuje pasującą replikę w /etc/litestream.yml i pobiera ją. PRAGMA integrity_check wyświetla ok w przypadku poprawnego pliku; każdy inny wynik oznacza, że przywrócona kopia nie nadaje się do użytku. Należy uruchamiać to zadanie zgodnie z harmonogramem przy użyciu usługi i timera systemd oraz monitorować wyjście polecenia. Dopóki przywracanie kopii zapasowej nie zostanie wykonane przynajmniej raz, nie można mieć pewności, że proces działa poprawnie.

Uruchamianie Litestream w systemd

Pakiet Debian instaluje jednostkę litestream, która odczytuje /etc/litestream.yml.

sudo systemctl enable litestream
sudo systemctl start litestream
sudo journalctl -u litestream -f

Poprawne wyjście wymienia każdą bazę danych z konfiguracji, a następnie pozostaje w stanie oczekiwania, poza okresowymi komunikatami o synchronizacji. Błąd no such file or directory w odniesieniu do ścieżki bazy danych oznacza, że ścieżka w konfiguracji jest błędna lub proces nie ma uprawnień do jej odczytu. Jednostka domyślnie działa jako root, co stanowi wyższy poziom uprawnień niż jest wymagany dla tego zadania. Litestream musi mieć możliwość odczytu i zapisu zarówno bazy danych, jak i katalogu, w którym się ona znajduje, ponieważ operuje na plikach -wal oraz -shm obok bazy danych. Należy zatem przypisać procesowi konto użytkownika, na którym działa już aplikacja, w tych przykładach oznaczone jako appuser.

# /etc/systemd/system/litestream.service.d/override.conf
[Service]
User=appuser
Group=appuser

Zastosuj zmiany za pomocą sudo systemctl daemon-reload oraz sudo systemctl restart litestream. Konfiguracja dedykowanego konta serwisowego z minimalnymi uprawnieniami zajmuje kilka minut i stanowi różnicę między agentem kopii zapasowych a drugim procesem z uprawnieniami root na serwerze.

Istotny jest jeden szczegół dotyczący kolejności, jeśli kiedykolwiek zajdzie potrzeba odtworzenia maszyny od zera. Baza danych powinna zostać przywrócona przed uruchomieniem aplikacji. litestream restore akceptuje -if-db-not-exists, co powoduje wyjście z kodem 0, jeśli plik już istnieje, więc bezpiecznie jest uruchamiać to polecenie przy każdym starcie systemu. Należy umieścić je w linii ExecStartPre w jednostce aplikacji, dzięki czemu nowy serwer VPS pobierze bazę danych, podczas gdy istniejący nie podejmie żadnych działań. litestream replicate posiada odpowiadającą mu flagę -restore-if-db-not-exists, jeśli wolisz utrzymać tę konfigurację w jednym miejscu.

Gdzie SQLite zawodzi na VPS

Sieciowe systemy plików. Jest to ograniczenie, którego nie da się obejść konfiguracją. Tryb WAL wymaga, aby każdy proces korzystający z bazy danych współdzielił niewielki obszar pamięci, co zapewnia plik -shm. Dokumentacja SQLite określa tę zasadę bez wyjątków:

Wszystkie procesy korzystające z bazy danych muszą znajdować się na tym samym komputerze hosta; WAL nie działa przez sieciowy system plików.

Dlatego baza danych na zamontowanym udziale NFS (network file system) lub SMB może ulec uszkodzeniu i żaden pragma temu nie zapobiegnie. Istnieje tu rozróżnienie, które często jest pomijane. Sieciowe urządzenie blokowe (network block device), które większość dostawców VPS dołącza jako dodatkową pamięć, jest dla systemu Linux zwykłym dyskiem ze zwykłym systemem plików i to rozwiązanie jest poprawne. Zamontowany udział sieciowy (file share) nim nie jest.

Drugi serwer aplikacji. Żadne ustawienie nie sprawi, że to zadziała. Gdy zaistnieje potrzeba obsługi tych samych danych przez dwie maszyny, wymagana jest baza danych komunikująca się przez sieć. Należy podjąć decyzję o takiej migracji, póki jest czas na planowanie.

Obciążenia z dużą liczbą operacji zapisu. Możliwość zapisu tylko przez jednego klienta naraz jest cechą formatu pliku, a nie parametrem, który można dostroić. Krótkie operacje zapisu są mało kosztowne, ponieważ każdy commit jest dopisywany do WAL, więc przepustowość zależy bardziej od opóźnień zapisu małych porcji danych na dysku niż od wydajności CPU. Zobacz NVMe kontra SATA SSD na VPS, aby sprawdzić, jak wygląda ta różnica. Długotrwałe transakcje stanowią rzeczywisty problem, ponieważ ustawiają każdego innego piszącego w kolejce za sobą.

Zapytania analityczne. SQLite to magazyn wierszowy stworzony do transakcji. Pulpit nawigacyjny skanujący sto milionów wierszy to inne zadanie dla innego narzędzia, a DuckDB w porównaniu z SQLite w pracy serwerowej opisuje, gdzie przebiega ta granica.

VACUUM podczas replikacji. Pełne VACUUM nadpisuje cały plik bazy danych, co unieważnia śledzenie na poziomie stron, na którym polega Litestream. Dokumentacja Litestream odradza wykonywanie tej operacji w miejscu, gdy replikacja jest aktywna. Zaleca się VACUUM INTO, które zapisuje skompensowaną kopię do oddzielnego pliku i pozostawia oryginał bez zmian. Jeśli konieczne jest wykonanie vacuum w miejscu, udokumentowana procedura jest dłuższa niż restart: zatrzymaj replikator, wykonaj vacuum, usuń ukryty katalog śledzenia Litestream znajdujący się obok bazy danych oraz istniejące dane zdalnej repliki, a następnie uruchom go ponownie, aby rozpoczął pracę od świeżej pełnej migawki. Ten ostatni krok powoduje utratę dotychczasowej historii przywracania.

Dwa replikatory na jednej bazie danych. Nigdy nie uruchamiaj dwóch procesów Litestream dla tej samej bazy danych lub tego samego miejsca docelowego replikacji. Dokumentacja wyraźnie wskazuje, że zapobieganie takiej sytuacji jest obowiązkiem użytkownika, a skutkiem jest replika, której nie można przywrócić.

Czego Litestream nie obejmuje

Litestream chroni wyłącznie plik bazy danych. Przesłane pliki, konfiguracja aplikacji, certyfikaty TLS (transport layer security) oraz pliki jednostek pozostają w gestii administratora. Należy połączyć to rozwiązanie z szyfrowanymi kopiami zapasowymi poza serwerem przy użyciu restic wykonywanymi według harmonogramu, aby zapewnić pełną ochronę. W przypadku nowej maszyny, pierwsze dziesięć minut na nowym VPS obejmuje konfigurację konta użytkownika oraz firewalla, co w niniejszym przewodniku uznano za wykonane.

FAQ

Czy SQLite jest wystarczająco dobre dla aplikacji produkcyjnej?

Dla jednej aplikacji na jednym serwerze – tak, pod warunkiem włączenia trybu WAL, ustawienia limitu czasu zajętości (busy timeout) oraz ciągłego wykonywania kopii zapasowych. Istotne ograniczenia mają charakter strukturalny: jeden zapisujący w danym momencie oraz jedna maszyna hosta. Aplikacja mieszcząca się w tych limitach zyskuje bazę danych bez narzutu sieciowego i bez konieczności monitorowania osobnego procesu. Aplikacja, która nie spełnia tych założeń, wymaga bazy danych typu klient-serwer i żadna optymalizacja tego nie zmieni.

Dlaczego nadal otrzymuję database is locked po ustawieniu busy_timeout?

Ponieważ SQLite pomija procedurę obsługi zajętości, gdy oczekiwanie mogłoby doprowadzić do zakleszczenia. Transakcja rozpoczynająca się od zwykłego BEGIN jest odroczona: początkowe SELECT umieszcza ją w transakcji odczytu, a późniejszy zapis musi dokonać aktualizacji (upgrade). Jeśli w międzyczasie inne połączenie wykonało zapis, SQLite natychmiast zwraca SQLITE_BUSY zamiast wywoływać procedurę obsługi zajętości, ponieważ migawka odczytu jest już nieaktualna. Każdą transakcję, która będzie zapisywać dane, należy rozpoczynać od BEGIN IMMEDIATE, aby blokada zapisu została założona od razu i aby limit czasu miał zastosowanie.

Czy mogę przechowywać bazę danych SQLite na zasobie sieciowym?

Nie na sieciowym systemie plików, takim jak NFS czy SMB. Tryb WAL wymaga, aby wszystkie procesy współdzieliły pamięć poprzez plik -shm, a dokumentacja SQLite stanowi, że każdy proces korzystający z bazy danych musi znajdować się na tym samym komputerze-hoście. Sieciowe urządzenie blokowe (network block device) dostarczone przez operatora to inna sytuacja: Linux widzi zwykły dysk ze zwykłym systemem plików, na którym SQLite działa poprawnie.

Czy potrzebuję Litestream, jeśli wykonuję już nocne kopie zapasowe?

To zależy od tego, jak dużą utratę danych jesteś w stanie zaakceptować. Nocne zadanie oznacza utratę do dwudziestu czterech godzin zapisów. Litestream synchronizuje dane mniej więcej raz na sekundę, więc awaria kosztuje utratę około ostatniej sekundy pracy. Jest to również bezpieczniejsze niż kopiowanie pliku bazy danych za pomocą cp, co może przechwycić bazę danych w trakcie zapisu. Litestream obejmuje tylko bazę danych, więc należy równolegle utrzymywać ogólną kopię zapasową plików.

Czy ten artykuł był przydatny?

#sqlite#wal#litestream#backups#production