sqlite 技术补课

原创
2021/10/15 09:54
阅读数 32

--------sqlite c++常用接口
创建连接
sqlite3_open(const char *filename, sqlite3 **ppDb)

sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void *data, char **errmsg)

sqlite3_close(sqlite3*)


--------数据库事务=一系列数据操作的集合
事务定义了一组SQL命令的边界,这组命令或者作为一个整体被全部执行,或者都不执行,这被称为数据库完整性的原子性原则。
默认情况下,SQLite中每条SQL语句自成事务(自动提交模式)。所有成功完成的命令偶都自动提交,所有遇见错误的命令都回滚。

原子性(Atomicity): 确保工作单位内的所有操作都成功完成,否则,事务会在出现故障时终止,之前的操作也会回滚到以前的状态。
一致性(Consistency):确保数据库在成功提交的事务上正确地改变状态。
隔离性(solation): 使事务操作相互独立和透明。
持久性(Durability): 确保已提交事务的结果或效果在系统发生故障的情况下仍然存在。

--------事务机制:
BEGIN TRANSACTION:开始事务处理。
COMMIT:保存更改,或者可以使用 END TRANSACTION 命令。
ROLLBACK:回滚所做的更改。

sqlite3_exec(db, "begin;", 0, 0, &zErrMsg); //开启事务
sqlite3_exec(db, "commit;", 0, 0, 0); 提交事务
sqlite3_exec(db, "rollback;", 0, 0, 0); 回滚事务

--------SQLite事务类型
SQLite有三种不同的事务类型:
DEFERRED(推迟)
MMEDIATE(立即)
EXCLUSIVE(排它)

--------SQLite提供5种冲突解决方案:REPLACE、IGNORE、FAIL、ABORT和ROLLBACK。
replace 由新的一行来替换有冲突的行
ignore 跳过有冲突的行
fail 到有冲突的行终止命令,但是不恢复之前已经修改的记录。
abort(默认) 终止命令,恢复命令做的修改
rollback(最严格),终止命令和事务,回滚整个事务

--------数据库连接模型
常见的模型:一个数据库文件,多个连接,每个连接有自己的语句。

当两个连接同时操作数据库进行读写的时候,SQLITE如何保证事务的正确性,以及如何保证读和读是可以并发的呢?答案是不同优先级的锁。

--------SQLite锁机制
SQLite有一个加锁表,用来帮助不同的写数据库都能够在最后一刻加锁,保证最大的并发性。 SQLite有五种不同的锁状态:

unlocked:最初状态,未加锁,连接还没有开始访问数据库
shared:共享锁,多个连接可以同时获得并保持shared锁,即多个连接可以同时从同一个数据库中读数据。
reserved:保留锁,一个连接如果想要写数据库,必须首先获得一个reserved锁。一个数据库同时只能有一个reserved锁,该reserved锁可以与shared锁共存,它是写数据库的第一个阶段。reserved锁既不阻止其他拥有shared锁的连接继续读数据库,也不阻止其他连接获得新的shared锁。当一个连接获得了reserved锁,就可以开始处理数据库修改操作了。尽管这些修改只能在缓冲区进行,而不是实际写到磁盘,修改保存在内存缓冲区中。
pending:未决锁,当连接想要提交修改时,需要将reserved锁提升为pending锁。获得pending锁后,其他连接就不能再获得新的共享锁了,但已经拥有shared锁的连接仍然可以继续正常读数据库。此时,拥有reserved锁的连接等待其他拥有shared锁的连接完成工作并释放其共享锁。
exclusive:排它锁,一旦所有的其他共享锁都被释放,拥有pending锁的连接就可以将锁提升至exclusive锁,此时就可以自由地对数据库进行修改。所有以前所缓存的修改都会被写到数据库文件中。

读操作锁变化
UNLOCKED -> PENDING -> SHARED -> UNLOCKED

写操作锁状态变化:
UNLOCKED -> SHARED -> RESVERED -> PENDING-> EXCLUSIVE -> UNLOCKED

sqllite rollback journal机制回顾
rollback journal机制的原理是:在修改数据库文件中的数据之前,先将修改所在分页中的数据备份在另外一个地方,然后才将修改写入到数据库文件中;如果事务失败,则将备份数据拷贝回来,撤销修改;如果事务成功,则删除备份数据,提交修改。
简单来说就是备份机制

WAL机制的原理是:修改并不直接写入到数据库文件中,而是写入到另外一个称为WAL的文件中;如果事务失败,WAL中的记录会被忽略,撤销修改;如果事务成功,它将在随后的某个时间被写回到数据库文件中,提交修改。
简单来说就是队列机制

checkpoint会将wal文件同步到数据库文件
wal文件积累到1000页 sqlite自动执行,也可手动执行,执行后wal文件会被清空。

读:找到wal文件最后一次写入点,并忽略此后的写入操作,如果数据在wal文件读wal文件否则直接读数据库文件。
写:直接写入wal文件即可,必须枷锁保证独占。因此写不能并行。

wal文件相当于数据库缓存,共享内存。
必须在同一个机器进行这就傻逼了,无法进行分布式迁移。
缺点:
.3.7.0之前的SQLite无法识别启用了WAL机制的数据库文件。版本要求
.每个数据库现在对应3个文件:<yourdb>.db,<yourdb>-wal,<yourdb>-shm。
当写入数据达到GB级的时候,数据库性能将下降。

wal接口
      PRAGMA journal_mode

      PRAGMA wal_checkpoint

      PRAGMA wal_autocheckpoint

      sqlite3_wal_checkpoint

      sqlite3_wal_autocheckpoint

      sqlite3_wal_hook


sqlite 的分布式实现方案:rqlite 后续再学习

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部