SQLite3 如果突发断电、关机,数据到底会不会丢?
SQLite是一个小型的数据库产品,但是其中的运维命令并不像想象的简单,这里核心的运维命令是PRAGMA,PRAGMA 语句是特定于 SQLite 的 SQL 扩展,用于修改 SQLite 库的操作或查询 SQLite 库的内部(非表)数据。PRAGMA 语句使用与其他 SQLite 命令。
这里有一个注意的地方,也就是PRAGMA命令本身,会进行更迭,同时在系统中使用错误的PRAGMA命令不会报错,这点是需要注意的。
PRAGMA 命令执行计划图
下面以数据库运维中的重要性和系统性能的重要性来进行关键命令的描述。
synchronous 这里有一个表,关于sqlite3的性能和数据安全性之间的比率:
| OFF | 0 | |||
| NORMAL | 1 | |||
| FULL | 2 | |||
| EXTRA | 3 |
这里在进入SQLite的时候需要考虑你的SQLite适用于哪种模型:
[root@localhost data]# sqlite3 test.dbSQLite version 3.47.1 2024-11-25 12:07:48Enter ".help" for usage hints.sqlite>sqlite>sqlite> PRAGMA synchronous = FULL;sqlite>sqlite> PRAGMA synchronous;2sqlite>
关键业务我们推荐FULL模式。
WAL日志刷新是SQLite一个关键的数据库运维项目,这里我们可以管控的是在断电后,到底需要多长时间数据库可以恢复工作的问题,这里就牵扯我们之前学习到了SQLite的工作模式,必须是wal然后我们的数据刷新上面提到的同步模式要是full 那么现在我们要决定的是数据页面的刷新率,也就是我们产生多少数据页面后,进行数据页面刷新的问题。
[root@localhost data]# sqlite3 test.dbSQLite version 3.47.1 2024-11-25 12:07:48Enter ".help"for usage hints.sqlite>sqlite>sqlite> PRAGMA synchronous = FULL;sqlite>sqlite> PRAGMA synchronous;2sqlite>sqlite>sqlite> PRAGMA wal_autocheckpoint;1000sqlite> PRAGMA wal_autocheckpoint = 200;200sqlite> PRAGMA wal_autocheckpoint;200sqlite> PRAGMA wal_checkpoint;0|10179839|10179839sqlite> PRAGMA wal_checkpoint(TRUNCATE);0|0|0sqlite> PRAGMA wal_autocheckpoint;1000sqlite> PRAGMA wal_checkpoint;0|0|0
这里我们注意几个命令:
PRAGMA autocheckpoint;这个命令查看当前数据页面多少,才产生一次checkpoint 的工作。键入命令后会显示当前的配置是多少。
如果对数据页面触发值想进行改动,可以使用 PRAGMA wal_autocheckpint = 200; 这个意思是产生了200个页面就进行数据的刷新到磁盘的工作。
同时需要注意每次启动数据库都需要带有一个配置的文件的脚本,来加载配置否则SQLite是不会加载正确的预设配置给你。
所以你的JAVA程序在启动SQLite的时候,应该将这些写入,或者写一个脚本如下:
PRAGMA journal_mode = WAL;PRAGMA synchronous = FULL;PRAGMA wal_autocheckpoint = 200;
把这些存储在一个.sql文件中,然后启动的时候,但是在操作中我发现了一个新的问题,关于一些配置可以固化,一些不可以,这里我们总结了一个表。
一、SQLite PRAGMA 持久化 vs 非持久化
这些 PRAGMA 会写入数据库文件,对所有连接永久生效。
journal_mode | ||
auto_vacuum | ||
encoding | ||
application_id | ||
page_size | ||
user_version |
这些只影响当前连接或事务,不会写入数据库文件。
synchronous | ||
wal_autocheckpoint | ||
checkpoint_fullfsync | ||
analysis_limit | ||
cache_size | ||
cache_spill | ||
busy_timeout | ||
automatic_index | ||
foreign_keys | ||
foreign_key_check | ||
integrity_check | ||
defer_foreign_keys | ||
incremental_vacuum | ||
data_version | ||
database_list | ||
index_listindex_info / index_xinfo | ||
学到这里,那就出现一个问题,一个库或者一个SQLite的数据库要进行哪些初始化设置。
对新库的初始化包含了如下的设置:
1)数据库存储文本的编码
2)数据库页面的大小
3) 设置文件身份标识
4)设置数据文件的版本
5)控制SQLite是否进行磁盘空间的回收
6)设置数据库运行的模式
下面是这六项,在LINUX 和WINDOWS 中的比对异同点。
二、SQLite 在 Linux 与 Windows 下的关键 PRAGMA 差异说明
chcp 65001 |
结论: SQLite 行为完全一致,主要差异来自 Windows 终端默认不是 UTF-8。
结论: 两平台行为一致,4K 页通常最佳。
示例:sql PRAGMA application_id = 0x1234ABCD;
PRAGMA incremental_vacuum | |||
| 最大差异:锁实现不同 |
下面是这些命令的几种集合,可以将这些进行一个标准化的设置:
1)设置数据库编码(仅空库且未建表时有效)
PRAGMA encoding = 'UTF-8';
2)设置数据库页面大小(仅空库有效)
PRAGMA page_size = 4096;
3)设置 database file 的 application id(应用识别)
PRAGMA application_id = 0x1234ABCD;
4)设置数据库 schema 版本(供程序使用)
PRAGMA user_version = 20240101;
5)设置自动回收空间模式(写入数据库文件结构)
NONE / FULL / INCREMENTAL PRAGMA auto_vacuum = FULL;
6)设置日志模式(journal_mode)
DELETE / TRUNCATE / PERSIST / MEMORY / WAL PRAGMA journal_mode = WAL;
7)设置同步级别(磁盘安全等级)
OFF / NORMAL / FULL / EXTRA PRAGMA synchronous = NORMAL;
8)WAL 模式下自动 checkpoint 间隔(不持久化,每次连接需设置)
PRAGMA wal_autocheckpoint = 200;
9) 可选:严格表(类似强类型)
CREATE TABLE t(a INTEGER, b TEXT) STRICT;
10)可选:快速收缩空间
PRAGMA incremental_vacuum;