Jak wykonać kopię zapasową bazy danych sqlite?

98

Jak to zrobić we właściwy sposób? Czy po prostu skopiuję plik .sq3?

Co się stanie, jeśli w witrynie są użytkownicy, a plik jest zapisywany podczas kopiowania?

thelolcat
źródło
6
SQLite ma do tego API
pułkownik trzydzieści dwa
1
Jakiego języka i sterownika używasz do uzyskiwania dostępu do bazy danych?
CL.
1
Używam PHP i rozszerzenia PDO
thelolcat
Obecnie istnieje prośba o udostępnienie interfejsu API kopii zapasowych sqlite na php: bugs.php.net/bug.php?id=70950
Brian Minton

Odpowiedzi:

156

Narzędzie wiersza poleceń sqlite3 zawiera .backuppolecenie dot .

Możesz połączyć się ze swoją bazą danych za pomocą:

sqlite3 my_database.sq3

i uruchom polecenie backup kropka z:

.backup backup_file.sq3

Zamiast interaktywnego połączenia z bazą danych możesz również wykonać kopię zapasową, a następnie zamknąć połączenie za pomocą

sqlite3 my_database.sq3 ".backup 'backup_file.sq3'"

Tak czy inaczej wynikiem jest kopia nazwana backup_file.sq3bazy danych my_database.sq3.

Różni się od zwykłego kopiowania plików, ponieważ dba o wszystkich użytkowników aktualnie pracujących nad bazą danych. W bazie danych są ustawione odpowiednie blokady, więc kopia zapasowa jest wykonywana wyłącznie.

Googie
źródło
69
Możesz to wszystko zrobić w jednej linii ...sqlite3 m_database.sq3 ".backup m_database.sq3.bak"
Mark Setchell
@Googie: Czy możemy go użyć do replikacji? lub
mOna
4
@mOna: To tylko mechanizm tworzenia kopii zapasowych. Replikacja oznacza propagowanie zmian w locie (rodzaj rozproszonej bazy danych), czego to nie zrobi.
Googie
Dzięki za odpowiedź :)
mOna
1
@RonJohn W rzeczywistości tworzy kopię pliku, ale zapewnia również, że dostęp do zapisu w bazie danych jest ograniczony odpowiednimi blokadami, więc jest to operacja atomowa, bez pośrednich modyfikacji.
Googie
6

.backup to najlepszy sposób.

sqlite3 my_database .backup my_database.back

możesz także wypróbować polecenie .dump, które daje możliwość zrzutu całej bazy danych lub tabel do pliku tekstowego. Jeśli określono TABLE, zrzuca tylko tabele pasujące do LIKE wzorca TABLE.

sqlite3 my_database .dump > my_database.back

Dobry sposób na wykonanie kopii archiwalnej przy użyciu funkcji dump and store. Rekonstruuj bazę danych w późniejszym czasie.

sqlite3 my_database .dump | gzip -c > my_database.dump.gz
zcat my_database.dump.gz | sqlite3 my_database

Sprawdź również to pytanie Czy polecenia SQLite3 .backup i .dump blokują bazę danych?

Lava Sangeetham
źródło
4
W SQLite 3.8.2 .backupnie działa tak, jak pokazano powyżej („brak argumentu NAZWA_PLIKU w .backup”)
Francesc Rosas
4
To najlepsza odpowiedź. Jeśli używasz .backup na działającej bazie danych używanej przez wiele osób, może nie działać, ponieważ w pewnym momencie baza danych jest zablokowana. Więc jeśli używasz tego w CRON, nie zadziała i nie powie Ci, że wystąpił błąd ... lepiej użyj .dump (zawsze działa) lub API podanego przez SQLite.
Memristor,
@Memristor Ale czy .dump nie blokuje DB dla innych? FWIW, wolałbym, aby nieudana kopia zapasowa (z pocztą do administratora) zamiast zakłóconej usługi.
Torsten Bronger,
1
Popraw składnię .backup w swojej odpowiedzi. Nie potrzebuje operatora '>'
Nashev
-23
try {
    final String inFileName = "/data/data/your app package/databases/db";
    File dbFile = new File(inFileName);
    FileInputStream fis = new FileInputStream(dbFile);
    String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/CALC/Backup";
    File dir = new File(path);
    if (!dir.exists()) dir.mkdirs();
    String outFileName = path + "/filename"; // output file name
    // Open the empty db as the output stream
    OutputStream output = new FileOutputStream(outFileName);

    // Transfer bytes from the inputfile to the outputfile
    byte[] buffer = new byte[1024];
    int length;
    while ((length = fis.read(buffer)) > 0) {
        output.write(buffer, 0, length);
    }
    Toast.makeText(getActivity(), "Backup Successfully", 2).show();
    // Close the streams
    output.flush();
    output.close();
    fis.close();
} 
catch (Exception e) {
    e.printStackTrace();
}
Baran
źródło
Czy sugerujesz programowe kopiowanie plików baz danych na poziomie systemu plików?
Andreas Tasoulas
4
1. Nie mówisz nawet, w jakim języku jest ten kod. OP powiedział, że używa PHP, ale wydaje się, że to kod java. 2. Kopiujesz plik bajt po bajcie. Jaka powinna być korzyść z takiego postępowania? Java (i php) mają metody kopiowania plików. Przeczytaj docs.oracle.com/javase/tutorial/essential/io/copy.html 3. Nie rozwiązuje to problemu, w którym baza danych może zostać zapisana podczas kopiowania.
Christopher K.