如何备份sqlite数据库?


93

正确的做法是什么?我是否只复制.sq3文件?

如果网站上有用户并且在复制文件时正在写入文件怎么办?



1
您使用什么语言和驱动程序来访问数据库?
CL。

1
我正在使用PHP和PDO扩展
thelolcat 2014年

当前有一个功能要求公开php中的sqlite备份API:bugs.php.net/bug.php?id=70950
Brian Minton

Answers:


152

sqlite3命令行工具具有.backupdot命令

您可以使用以下方法连接到数据库:

sqlite3 my_database.sq3

并使用以下命令运行backup dot命令:

.backup backup_file.sq3

除了与数据库的交互式连接,您还可以执行备份并随后使用以下方法关闭连接

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

无论哪种方式,结果都是backup_file.sq3数据库的副本my_database.sq3

它与常规文件复制不同,因为它可以照顾当前在数据库上工作的所有用户。在数据库上设置了适当的锁,因此备份专门进行。


68
您可以在一行中完成所有操作……sqlite3 m_database.sq3 ".backup m_database.sq3.bak"
Mark Setchell 2014年

@Googie:我们可以使用它进行复制吗?或
mOna

4
@mOna:这只是进行备份的一种机制。复制意味着即时传播更改(一种分布式数据库),这对您不起作用。
Googie's

感谢您的答复:)
mOna

1
@RonJohn它实际上是文件的副本,但是它也可以确保对数据库的写访问受到适当锁的限制,因此它是原子操作,没有中间修改。
Googie

5

.backup是最好的方法。

sqlite3 my_database .backup my_database.back

您也可以尝试.dump命令,它使您能够将整个数据库或表转储到文本文件中。如果指定了TABLE,则仅转储与LIKE模式TABLE相匹配的表。

sqlite3 my_database .dump > my_database.back

使用转储和存储来制作档案副本的好方法,稍后再重建数据库。

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

还要检查此问题SQLite3 .backup和.dump命令是否锁定数据库?


4
在SQLite 3.8.2上,.backup无法按上述方式工作(“ .backup上缺少FILENAME参数”)
Francesc Rosas

4
这是最好的答案。如果您在许多人使用的工作数据库上使用.backup,则它可能无法正常工作,因为有时数据库已锁定。因此,如果您在CRON中使用此功能,它将无法正常工作,并且不会告诉您有错误...更好地使用.dump(始终有效)或SQLite提供的API。
忆阻器

@Memristor但是.dump不会为其他人锁定数据库吗?FWIW,我希望备份失败(通过邮件发送给管理员)而不是中断的服务。
Torsten Bronger

1
请在您的答案中修复.backup语法。它不需要'>'运算符
Nashev '18

-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();
}

您是否暗示在数据库文件的文件系统级别进行程序复制?
Andreas Tasoulas,2015年

4
1.您甚至都不说此代码是什么语言。OP说他正在使用PHP,但这似乎是Java代码。2.您逐字节复制文件。这样做的好处是什么?Java(和PHP)具有复制文件的方法。阅读docs.oracle.com/javase/tutorial/essential/io/copy.html3。这不能解决复制数据库时数据库可能写入的问题。
Christopher K.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.