面试题答案
一键面试备份策略
- 使用 WAL 模式:
- SQLite 有三种日志模式:DELETE、TRUNCATE 和 WAL(Write - Ahead Logging)。WAL 模式在写入数据时,不会直接修改数据库文件,而是将修改写入到 WAL 文件中。这样在备份时,可以在不锁定数据库的情况下进行。
- 开启 WAL 模式:
PRAGMA journal_mode = WAL;
- 定期检查点:
- 在 WAL 模式下,随着时间推移,WAL 文件会不断增长。通过定期执行检查点操作,可以将 WAL 文件中的修改合并到主数据库文件中,并截断 WAL 文件。
- 执行检查点操作:
PRAGMA wal_checkpoint(FULL);
- 文件级备份:
- 对于 SQLite 数据库,它本质上就是一个文件。在 WAL 模式下,主数据库文件相对稳定,备份时可以直接复制主数据库文件和 WAL 文件(如果存在)。
- 示例(假设使用 Python):
import shutil shutil.copy2('original_database.db', 'backup_database.db') if os.path.exists('original_database.db - wal'): shutil.copy2('original_database.db - wal', 'backup_database.db - wal')
- 优化空间占用:
- VACUUM 操作:在备份前执行
VACUUM
操作,它会重新组织数据库文件,将删除的页重新利用,从而减小数据库文件的大小。
VACUUM;
- PRAGMA auto_vacuum:设置
PRAGMA auto_vacuum = 2
(FULL 模式),这样 SQLite 会在删除数据时自动回收空间,减少文件增长。
- VACUUM 操作:在备份前执行
恢复策略
- 基于文件的恢复:
- 如果是通过文件级备份得到的备份文件,恢复时直接将备份的数据库文件和 WAL 文件(如果存在)复制回原位置即可。
- 示例(假设使用 Python):
shutil.copy2('backup_database.db', 'original_database.db') if os.path.exists('backup_database.db - wal'): shutil.copy2('backup_database.db - wal', 'original_database.db - wal')
- 数据导入恢复:
- 可以通过
sqlite3
命令行工具的.dump
命令将数据库导出为 SQL 脚本,恢复时执行该 SQL 脚本。 - 导出:
sqlite3 original_database.db '.dump' > backup.sql
- 恢复:
sqlite3 new_database.db < backup.sql
- 可以通过
异常处理机制
- I/O 错误:
- 备份过程中:如果在复制文件(文件级备份)或执行 SQL 导出(
.dump
)时发生 I/O 错误,记录错误信息,停止当前备份操作。可以尝试重新执行备份操作,例如在文件复制失败时,尝试多次复制。 - 恢复过程中:若在复制文件或执行 SQL 脚本恢复时发生 I/O 错误,同样记录错误信息,停止恢复操作。可以尝试重新执行恢复步骤,如重新复制文件或重新执行 SQL 脚本。对于文件复制错误,可以检查目标磁盘空间是否充足、文件权限是否正确等。
- 备份过程中:如果在复制文件(文件级备份)或执行 SQL 导出(
- 数据库损坏:
- 备份前检测:在备份前,可以使用
PRAGMA integrity_check
命令检查数据库的完整性。如果发现损坏,尝试使用PRAGMA quick_check
进一步快速检查,若确定损坏,可以尝试使用sqlite3
工具的RECOVER
模式(虽然不保证完全恢复)。 - 恢复后检测:恢复完成后,再次执行
PRAGMA integrity_check
检查恢复后的数据库完整性。如果发现损坏,可能需要从更早的备份中恢复,并检查在备份和恢复过程中是否有其他操作导致了损坏(如硬件故障、软件错误等)。
- 备份前检测:在备份前,可以使用