一.概述
锁类别 |
字节范围 |
说明 |
PENDING_BYTE |
0x40000000 |
一种过渡锁,读事务获取读锁,写事务获取写锁前,都需要获取该锁。 |
RESERVED_BYTE |
0x40000001 |
表示线程要开始写操作,某一时刻只能有一个RESERVED Lock,但是RESERVED锁和SHARED锁可以共存,而且可以对数据库加新的SHARED锁。 |
SHARED_LOCK |
0x40000002-0x40000200 |
共享锁,开启事务时,都需要获取该锁 |
EXCLUSIVE_LOCK |
0x40000002-0x40000200 |
排它锁 |
类型 |
操作 |
锁信息 |
说明 |
读事务 |
begin |
|
不持有锁 |
select c1 from user where id=1 |
Lock: Pending(Read) Lock:Shared(Read) Unlock:Pending |
获取Shared读锁前,需要先获取Pending共享锁, 通过这种方式与写事务互斥。 |
|
commit |
UnLock:Shared |
|
|
写事务 |
begin |
|
|
Update c1=c1+1 where id=1 |
Lock: Pending(Read) Lock:Shared Unlock:Pending Lock:Reserved(Write) |
先获取Shared读锁,然后获取Reserved的排它锁,阻止其它写事务 |
|
commit |
Lock:Pending(Write) Lock:Exclusive(Write) Unlock: Pending Unlock: Exclusive(Write) |
获取Pending的排它锁,阻止新的读事务,最后上排它锁,阻止所有读事务,读写不能并发 Pending锁方式好处是,减少写饿死的几率。 |
![](https://images0.cnblogs.com/blog2015/176539/201508/262206507972929.png)
二.Wal锁类型
锁类别 |
字节范围 |
说明 |
|||
读事务(WAL) |
begin |
|
|
||
select c1 from user where id=1 |
DB文件: Lock: Pending(Read) Lock:Shared Unlock:Pending WAL文件: Lock:WAL_READ_LOCK(Read) |
除了获取DB文件锁,还需要获取WAL锁,得到最新提交事务的位点。 若有事务再作检查点,需要重试多次。 |
|||
commit |
Unlock:WAL_READ_LOCK Unlock:Shared |
|
|||
写事务(WAL) |
begin |
|
|
||
Update c1=c1+1 where id=1 |
DB文件: Lock: Pending-Read Lock:Shared(Read) Unlock:Pending WAL文件: Lock:WAL_READ_LOCK(Read) Lock:WAL_WRITE_LOCK(Write) |
通过 EXCLUSIVE-WRITE-LOCK控制写写并发 由于不操作DB文件,因此不存在读写冲突,读写可以并发。 |
|||
commit |
WAL文件: Lock:SHARED-READ-LOCK Unlock:WAL_READ_LOCK(Read) Unlock: WAL_WRITE_LOCK(Write)
DB文件: Unlock:Shared |
获取SHARED-READ-LOCK目的是为了获取最新提交日志的位点 |
|||
检查点 操作 (WAL)
|
|
WAL文件: Lock:WAL_CKPT_LOCK(write) Lock:WAL_READ_LOCK(write) UnLock:WAL_READ_LOCK UnLock:WAL_CKPT_LOCK |
EXCLUSIVE-CKPT-LOCK WAL_READ_LOCK阻止读写事务。 |
锁类别 |
字节范围 |
说明 |
WAL_WRITE_LOCK |
120 |
写锁位置 |
WAL_CKPT_LOCK |
121 |
检查点锁位置 |
WAL_RECOVER_LOCK |
122 |
故障恢复锁位置 |
WAL_READ_LOCK |
123 |
读锁(表示不需要wal文件) |
|
124-127 |
读锁(每个位置,对应一个锁) 做检查点时,逐一对每个位置上写锁,若上锁失败表示对应位置上的读事务没有结束,根据检查点策略确定是等待(FULL),还是停止推进(PASSIVE)。 |
三.调试
gcc sqlite3.c -g -lpthread -ldl -fPIC -shared -DSQLITE_TEST -DSQLITE_DEBUG -DSQLITE_LOCK_TRACE -DSQLITE_FORCE_OS_TRACE -o libsqlite3.so