加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

Sqlite事务模型、性能优化Tips、常见误区

发布时间:2019-09-26 21:35:31 所属栏目:建站 来源:hamsongliu
导读:0.前言 本文主要介绍sqlite的事务模型,以及基于事务模型的一些性能优化tips,包括事务封装、WAL+读写分离、分库分表、page size优化等。并基于手淘sqlite的使用现状总结了部分常见问题及误区,主要集中在多线程的设置、多线程下性能优化的误区等。本文先

这里结合源码,有下面几个理解:

  • 数据的写操作写入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又是什么?
  1. // 多线程的设置的实现:设置bCoreMutex和bFullMutex 
  2.  
  3. #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0  /* IMP: R-54466-46756 */ 
  4.     case SQLITE_CONFIG_SINGLETHREAD: { 
  5.       /* EVIDENCE-OF: R-02748-19096 This option sets the threading mode to 
  6.       ** Single-thread. */ 
  7.       sqlite3GlobalConfig.bCoreMutex = 0;  /* Disable mutex on core */ 
  8.       sqlite3GlobalConfig.bFullMutex = 0;  /* Disable mutex on connections */ 
  9.       break; 
  10.     } 
  11. #endif 
  12. #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-20520-54086 */ 
  13.     case SQLITE_CONFIG_MULTITHREAD: { 
  14.       /* EVIDENCE-OF: R-14374-42468 This option sets the threading mode to 
  15.       ** Multi-thread. */ 
  16.       sqlite3GlobalConfig.bCoreMutex = 1;  /* Enable mutex on core */ 
  17.       sqlite3GlobalConfig.bFullMutex = 0;  /* Disable mutex on connections */ 
  18.       break; 
  19.     } 
  20. #endif 
  21. #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-59593-21810 */ 
  22.     case SQLITE_CONFIG_SERIALIZED: { 
  23.       /* EVIDENCE-OF: R-41220-51800 This option sets the threading mode to 
  24.       ** Serialized. */ 
  25.       sqlite3GlobalConfig.bCoreMutex = 1;  /* Enable mutex on core */ 
  26.       sqlite3GlobalConfig.bFullMutex = 1;  /* Enable mutex on connections */ 
  27.       break; 
  28.     } 
  29. #endif 
  • 如果FullMutex打开,则每个数据库连接会初始化一个互斥量成员(db->mutex),也就是社区各种文档上所说的“bFullMutex是对连接的线程保护”
  1. if( isThreadsafe ){    // bFullMutex = 1 
  2.     db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);    // 每个数据库连接会初始化一个成员锁 
  3.     if( db->mutex==0 ){ 
  4.       sqlite3_free(db); 
  5.       db = 0; 
  6.       goto opendb_out; 
  7.     } 
  8.   } 

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读