这里结合源码,有下面几个理解:
- 数据的写操作写入WAL的过程不再需要SHARED锁、EXCLUSIVE锁,而是需要WAL文件锁
- 数据的写操作不会被读操作阻塞(写操作不再需要SHARED锁)
- 数据的读操作不会被写操作阻塞(写操作不再需要独占数据库)
- WAL文件写入数据库文件的过程,依然会被读操作阻塞,也会阻塞读操作
- WAL文件的大小设置很关键,过大的WAL文件,会让查找操作从B-Tree查找退化成线性查找(WAL中page连续存储);但大的WAL文件对写操作较友好。
2.3.1 结论
- 只有开了WAL,再使用读写(连接)分离才能有较大的性能提升
- WAL本质上是将部分随机写操作(数据库文件和journal日志)变成了串行写WAL文件,并进行了锁分离
- WAL文件的大小设置很关键,过大的WAL文件,会让查找操作从B-Tree查找退化成线性查找(WAL中page连续存储);但大的WAL文件对写操作较友好
2.4 多线程设置
- 多线程是sqlite使用过程中比较容易误解的一个概念,带来的问题要么是产生各种线程安全问题,要么是无法充分发掘sqlite的性能,这里结合代码我们简单分析一下并给出几个重要结论。
- 线程安全设置主要在设置bCoreMutex和bFullMutex,启用bFullMutex之后数据库连接和prepared statement都已加锁(社区各种文档都到此为止);但还是感觉不够清晰:这两个锁会对我们使用sqlite有怎样的影响?best practice又是什么?
- // 多线程的设置的实现:设置bCoreMutex和bFullMutex
-
- #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-54466-46756 */
- case SQLITE_CONFIG_SINGLETHREAD: {
- /* EVIDENCE-OF: R-02748-19096 This option sets the threading mode to
- ** Single-thread. */
- sqlite3GlobalConfig.bCoreMutex = 0; /* Disable mutex on core */
- sqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */
- break;
- }
- #endif
- #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-20520-54086 */
- case SQLITE_CONFIG_MULTITHREAD: {
- /* EVIDENCE-OF: R-14374-42468 This option sets the threading mode to
- ** Multi-thread. */
- sqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */
- sqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */
- break;
- }
- #endif
- #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-59593-21810 */
- case SQLITE_CONFIG_SERIALIZED: {
- /* EVIDENCE-OF: R-41220-51800 This option sets the threading mode to
- ** Serialized. */
- sqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */
- sqlite3GlobalConfig.bFullMutex = 1; /* Enable mutex on connections */
- break;
- }
- #endif
- 如果FullMutex打开,则每个数据库连接会初始化一个互斥量成员(db->mutex),也就是社区各种文档上所说的“bFullMutex是对连接的线程保护”
- if( isThreadsafe ){ // bFullMutex = 1
- db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); // 每个数据库连接会初始化一个成员锁
- if( db->mutex==0 ){
- sqlite3_free(db);
- db = 0;
- goto opendb_out;
- }
- }
(编辑:ASP站长网)
|