SSD Nodes Learn Hosting plans →
Przewodniki Matt ConnorAutor: Matt Connor · Zaktualizowano 2026-08-07

SQLite w produkcji na VPS: konfiguracja i ograniczenia

Dowiedz się, kiedy SQLite jest odpowiednią bazą danych dla aplikacji na VPS. Poznaj konfigurację WAL mode, busy_timeout oraz wykorzystanie Litestream do replikacji danych.

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 do utrzymania 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ą konkretne i rzeczywiste. SQLite pozwala na jednego piszącego w danym momencie w obrębie całego 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 wyrośniesz z tego modelu. Ten przewodnik omawia ustawienia czyniące SQLite bezpiecznym na serwerze, ciągłą kopię zapasową za pomocą Litestream oraz moment, w którym należy zrezygnować z tego rozwiązania.

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

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

Polecenie to wyświetla wersję zaczynają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 lipiec 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

Nocne kopiowanie powoduje utratę nawet całego dnia zapisów, a uruchomienie cp na aktywnej 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 w trakcie użycia. Litestream idzie dalej: monitoruje plik WAL i w sposób ciągły przesyła zmiany do pamięci obiektowej, co ogranicza potencjalną utratę 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 tak samo jak wcześniej, a Litestream odczytuje plik WAL i przesyła zmienione dane.

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 to wydanie dokumentowane na oficjalnej stronie instalacji dla systemu Linux na lipiec 2026, a v0.5.15 ukazała się 21 lipca 2026. Należy zmienić wersję w obu liniach, aby odpowiadała aktualnemu tagowi na stronie wydań, a w przypadku VPS z architekturą 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 używania 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ę błędem 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 uruchomieniem czegokolwiek 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 dodać 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 wierszy uwzględnia nowy wpis. Jeśli tak nie jest, zmiana nie została jeszcze zsynchronizowana: Litestream wysyła dane w interwale sync-interval, który domyślnie wynosi 1 sekundę, więc należy odczekać i spróbować przywracania 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 na osiągnięcie 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ą kompatybilną 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 środowiska, dlatego 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 snapshotów to ustawienia domyślne, a domyślny okres retencji często zaskakuje użytkowników. Retencja określa, jak długo Litestream przechowuje snapshoty oraz powiązane z nimi pliki, co wyznacza również maksymalny czas wstecz, do którego można przywrócić dane. Dwadzieścia cztery godziny oznaczają, że błędna migracja zauważona w środę rano jest nieodwracalna, jeśli stan z poniedziałku został już usunięty. Należy ustawić retention: 168h na tydzień i opłacić dodatkowe miejsce w pamięci.

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

Poprawny wynik działania wymienia każdą bazę danych z konfiguracji, a następnie pozostaje w stanie oczekiwania, wyświetlając jedynie okresowe komunikaty o synchronizacji. Błąd no such file or directory dotyczący ścieżki do bazy danych oznacza, że ścieżka w konfiguracji jest nieprawidłowa lub proces nie ma uprawnień do jej odczytu. Jednostka domyślnie działa jako root, co stanowi wyższy poziom uprawnień niż 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 w lokalizacji bazy danych. Należy zatem przypisać proces do konta, z którego korzysta już aplikacja.

# /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 szczegół dotyczący kolejności ma znaczenie w przypadku odtwarzania maszyny od zera. Baza danych powinna zostać przywrócona przed uruchomieniem aplikacji. litestream restore obsługuje -if-db-not-exists, który zwraca kod wyjścia 0, jeśli plik już istnieje, więc bezpiecznie jest uruchamiać go przy każdym starcie systemu. Umieść go w linii ExecStartPre w jednostce aplikacji, dzięki czemu nowy serwer VPS pobierze bazę danych, a istniejący nie podejmie żadnych działań. litestream replicate posiada odpowiadającą mu flagę -restore-if-db-not-exists, jeśli preferowane jest utrzymanie konfiguracji 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 formułuje tę zasadę bez wyjątków:

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

Zatem 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ęć masową, jest widoczne dla systemu Linux jako zwykły dysk ze zwykłym systemem plików, co jest rozwiązaniem poprawnym. 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 jej zaplanowanie.

Obciążenia z dużą liczbą operacji zapisu. Możliwość wykonywania tylko jednego zapisu w czasie jest cechą formatu pliku, a nie parametrem, który można dostroić. Krótkie operacje zapisu są tanie, ponieważ każde zatwierdzenie (commit) jest dopisaniem do pliku WAL, więc przepustowość zależy bardziej od opóźnień zapisu małych porcji danych na dysku niż od wydajności CPU. Zobacz NVMe w porównaniu z dyskami SATA SSD na VPS, aby sprawdzić, jak wygląda ta różnica. Długotrwałe transakcje stanowią rzeczywisty problem, ponieważ ustawiają wszystkich innych zapisujących w kolejce.

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 oznacza, że Litestream musi przesłać go w całości ponownie. Dokumentacja Litestream odradza wykonywanie tej operacji w trakcie aktywnej replikacji. Należy zatrzymać replikator, wykonać vacuum, uruchomić go ponownie i przygotować się na nowy, pełny snapshot.

Dwa replikatory dla jednej bazy danych. Nigdy nie należy uruchamiać 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.

#sqlite#wal#litestream#backups#production