精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Sqlite事務(wù)模型、性能優(yōu)化Tips、常見誤區(qū)

開發(fā) 前端
本文主要介紹sqlite的事務(wù)模型,以及基于事務(wù)模型的一些性能優(yōu)化tips,包括事務(wù)封裝、WAL+讀寫分離、分庫(kù)分表、page size優(yōu)化等。

[[277940]]

 0.前言

本文主要介紹sqlite的事務(wù)模型,以及基于事務(wù)模型的一些性能優(yōu)化tips,包括事務(wù)封裝、WAL+讀寫分離、分庫(kù)分表、page size優(yōu)化等。并基于手淘sqlite的使用現(xiàn)狀總結(jié)了部分常見問題及誤區(qū),主要集中在多線程的設(shè)置、多線程下性能優(yōu)化的誤區(qū)等。本文先提出以下幾個(gè)問題(作者在進(jìn)行統(tǒng)一存儲(chǔ)的關(guān)系存儲(chǔ)框架優(yōu)化過程中一直困惑的問題,同時(shí)也是客戶端開發(fā)者經(jīng)常搞錯(cuò)的問題)并在正文中進(jìn)行解答:

  • 1,sqlite的多進(jìn)程安全是怎么實(shí)現(xiàn)的?性能如何?
  • 2,sqlite的數(shù)據(jù)庫(kù)連接是什么?
  • 3,言sqlite必提的讀寫分離,具體指什么?能不能提升數(shù)據(jù)讀寫的性能?為什么
  • 4,sqlite提供的WAL特性解決了什么問題?
  • 5,sqlite的多線程設(shè)置是為了解決什么問題?與讀寫分離有什么關(guān)系?
  • 6,什么情況下數(shù)據(jù)庫(kù)會(huì)發(fā)生死鎖?
  • 7,有哪些性能優(yōu)化的方案?

1,sqlite主要數(shù)據(jù)結(jié)構(gòu)

在深入了解sqlite之前,最好先對(duì)sqlite的主要數(shù)據(jù)結(jié)構(gòu)有個(gè)概要的理解,sqlite是一個(gè)非常完備的關(guān)系數(shù)據(jù)庫(kù)系統(tǒng),由很多部分組成(parser,tokenize,virtual machine等等),同時(shí)sqlite的事務(wù)模型相對(duì)簡(jiǎn)化,是入門學(xué)習(xí)關(guān)系數(shù)據(jù)庫(kù)方法論的一個(gè)不錯(cuò)的選擇;下文對(duì)事務(wù)模型的分析也基于這些核心數(shù)據(jù)結(jié)構(gòu)。下面這張圖比較準(zhǔn)確的描述了sqlite的幾個(gè)核心數(shù)據(jù)結(jié)構(gòu): 

sqlite事務(wù)模型、性能優(yōu)化tips、常見誤區(qū)

1.1 Connection

connection通過sqlite3_open函數(shù)打開,代表一個(gè)獨(dú)立的事務(wù)環(huán)境(這里及下文提到的事務(wù),包括顯式聲明的事務(wù),也包括隱式的事務(wù),即每條獨(dú)立的sql語句)。

1.2 B-Tree

B-Tree負(fù)責(zé)請(qǐng)求pager從disk讀取數(shù)據(jù),然后把頁面(page)加載到頁面緩沖區(qū)(page cache)。

1.3 Pager

Pager負(fù)責(zé)讀寫數(shù)據(jù)庫(kù),管理內(nèi)存緩存和頁面(即下文提到的page caches),以及管理事務(wù),鎖和崩潰恢復(fù)。

2,sqlite事務(wù)模型及鎖

2.1 sqlite多進(jìn)程安全及Linux & windows文件鎖

  • 關(guān)于建議鎖(advisory lock)和強(qiáng)制鎖(mandatory lock)

建議鎖并不由內(nèi)核強(qiáng)制實(shí)行,如果有進(jìn)程不檢查目標(biāo)文件是否已經(jīng)由別的進(jìn)程加了鎖就往其中寫入數(shù)據(jù),內(nèi)核也不會(huì)加以阻攔。因此,建議鎖并不能阻止進(jìn)程對(duì)文件的訪問,而是需要進(jìn)程事先對(duì)鎖的狀態(tài)做一個(gè)約定,并根據(jù)鎖的當(dāng)前狀態(tài)和相互關(guān)系來確定其他進(jìn)程是否能對(duì)文件執(zhí)行指定的操作。

強(qiáng)制鎖是由內(nèi)核強(qiáng)制采用的文件鎖——由于內(nèi)核對(duì)每個(gè)read()和write()操作都會(huì)檢查相應(yīng)的鎖,會(huì)降低系統(tǒng)性能。

  • 典型的建議鎖

鎖文件;鎖文件是最簡(jiǎn)單的對(duì)文件加鎖的方法,每個(gè)需要加鎖的數(shù)據(jù)文件都有一個(gè)鎖文件(lock file)。但這種方式存在比較大的問題是無法強(qiáng)制保護(hù)需要加鎖的文件,并且當(dāng)加鎖進(jìn)程非正常退出之后,會(huì)造成其他進(jìn)程的死鎖。

記錄鎖;System V和BSD4.3引入了記錄鎖,相應(yīng)的系統(tǒng)調(diào)用為lockf()和flock()。而POSIX對(duì)于記錄鎖提供了另外一種機(jī)制,其系統(tǒng)調(diào)用為fcntl()。記錄鎖和鎖文件有兩個(gè)很重要的區(qū)別:1)記錄鎖可以對(duì)文件的任何一部分加鎖,這對(duì)DBMS有極大的幫助,2)記錄鎖的另一個(gè)優(yōu)點(diǎn)就是它由進(jìn)程持有,而不是文件系統(tǒng)持有,當(dāng)進(jìn)程結(jié)束時(shí),所有的鎖也隨之釋放。對(duì)于一個(gè)進(jìn)程本身而言,多個(gè)鎖絕不會(huì)沖突。(Windows中的鎖都是強(qiáng)制鎖,具體不是很熟,只知道在由于windows上文鎖的限制,sqlite多進(jìn)程下的并發(fā)性會(huì)受影響)。

2.1.1 結(jié)論

sqlite的文件鎖在linux/posix上基于記錄鎖實(shí)現(xiàn),也就是說sqlite在文件鎖上會(huì)有以下幾個(gè)特點(diǎn):

  • 多進(jìn)程使用安全,且不會(huì)因?yàn)檫M(jìn)程異常退出引發(fā)死鎖
  • 單進(jìn)程使用性能幾乎不會(huì)受損,多進(jìn)程使用的性能損耗會(huì)受一定的影響

2.2 事務(wù)模型(Without WAL)

sqlite對(duì)每個(gè)連接設(shè)計(jì)了五鐘鎖的狀態(tài)(UNLOCKED, PENDING, SHARED, RESERVED, EXCLUSIVE), sqlite的事務(wù)模型中通過鎖的狀態(tài)保證讀寫事務(wù)(包括顯式的事務(wù)和隱式的事務(wù))的一致性和讀寫安全。sqlite官方提供的事務(wù)生命周期如下圖所示,我在這里稍微加了一些個(gè)人的理解: 

sqlite事務(wù)模型、性能優(yōu)化tips、常見誤區(qū)

這里有幾點(diǎn)需要注意:

UNLOCKED、PENDING、SHARED、RESERVED狀態(tài)是非獨(dú)占的,也就是說同一個(gè)連接中多個(gè)線程并發(fā)只讀不會(huì)被阻塞。

寫操作的數(shù)據(jù)修改會(huì)先寫入page cache,內(nèi)容包括journal日志、b-tree的修改等;正是由于page cache的存在,很多耗時(shí)的“重”操作都可以不干擾其他連接和當(dāng)前連接的讀操作,真正意義上保證了sqlite可以同時(shí)處理一個(gè)寫連接和多個(gè)讀連接。

連接由RESERVED狀態(tài)進(jìn)入EXCLUSIVE狀態(tài),需要等待讀線程釋放SHARED鎖,也即寫操作會(huì)被讀操作阻塞

連接由RESERVED狀態(tài)進(jìn)入EXCLUSIVE狀態(tài)后(顯式或隱式的調(diào)用commit),數(shù)據(jù)庫(kù)進(jìn)入獨(dú)占狀態(tài),其他任何連接都無法由UNLOCK狀態(tài)進(jìn)入SHARED狀態(tài);也即寫操作會(huì)阻塞所有連接的讀操作(不包括已經(jīng)進(jìn)入SHARED狀態(tài)的操作),直到page caches寫入數(shù)據(jù)庫(kù)文件(成功或失敗)。

數(shù)據(jù)庫(kù)獨(dú)占狀態(tài)越久,其他操作的等待時(shí)間越久,即SQLITE_BUSY產(chǎn)生的一個(gè)原因。

2.2.1 結(jié)論

對(duì)于常規(guī)的事務(wù)模型(without WAL),讀寫(連接)分離,不同連接或同一個(gè)連接上的讀和寫操作仍互相阻塞,對(duì)性能提升沒有明顯幫助。

寫事務(wù)在拿到reserve鎖之前在page cache里的操作不會(huì)影響其他連接的讀寫,所以使用事務(wù)進(jìn)行批量數(shù)據(jù)的更新操作有非常大的性能優(yōu)勢(shì)。

事務(wù)模型存在死鎖的場(chǎng)景,如下圖所示: 

sqlite事務(wù)模型、性能優(yōu)化tips、常見誤區(qū)

2.3 WAL對(duì)事務(wù)模型的影響

按照官方文檔,WAL的原理如下:

對(duì)數(shù)據(jù)庫(kù)修改是是寫入到WAL文件里的,這些寫是可以并發(fā)的(WAL文件鎖)。所以并不會(huì)阻塞其語句讀原始的數(shù)據(jù)庫(kù)文件。當(dāng)WAL文件到達(dá)一定的量級(jí)時(shí)(CheckPoint),自動(dòng)把WAL文件的內(nèi)容寫入到數(shù)據(jù)庫(kù)文件中。當(dāng)一個(gè)連接嘗試讀數(shù)據(jù)庫(kù)的時(shí)候,首先記錄下來當(dāng)前WAL文件的末尾 end mark,然后,先嘗試在WAL文件里查找對(duì)應(yīng)的Page,通過WAL-Index來對(duì)查找加速(放在共享內(nèi)存里,.shm文件),如果找不到再查找數(shù)據(jù)庫(kù)文件。

這里結(jié)合源碼,有下面幾個(gè)理解:

  • 數(shù)據(jù)的寫操作寫入WAL的過程不再需要SHARED鎖、EXCLUSIVE鎖,而是需要WAL文件鎖。
  • 數(shù)據(jù)的寫操作不會(huì)被讀操作阻塞(寫操作不再需要SHARED鎖)。
  • 數(shù)據(jù)的讀操作不會(huì)被寫操作阻塞(寫操作不再需要獨(dú)占數(shù)據(jù)庫(kù))。
  • WAL文件寫入數(shù)據(jù)庫(kù)文件的過程,依然會(huì)被讀操作阻塞,也會(huì)阻塞讀操作。
  • WAL文件的大小設(shè)置很關(guān)鍵,過大的WAL文件,會(huì)讓查找操作從B-Tree查找退化成線性查找(WAL中page連續(xù)存儲(chǔ));但大的WAL文件對(duì)寫操作較友好。

2.3.1 結(jié)論

  • 只有開了WAL,再使用讀寫(連接)分離才能有較大的性能提升。
  • WAL本質(zhì)上是將部分隨機(jī)寫操作(數(shù)據(jù)庫(kù)文件和journal日志)變成了串行寫WAL文件,并進(jìn)行了鎖分離。
  • WAL文件的大小設(shè)置很關(guān)鍵,過大的WAL文件,會(huì)讓查找操作從B-Tree查找退化成線性查找(WAL中page連續(xù)存儲(chǔ));但大的WAL文件對(duì)寫操作較友好。

2.4 多線程設(shè)置

  • 多線程是sqlite使用過程中比較容易誤解的一個(gè)概念,帶來的問題要么是產(chǎn)生各種線程安全問題,要么是無法充分發(fā)掘sqlite的性能,這里結(jié)合代碼我們簡(jiǎn)單分析一下并給出幾個(gè)重要結(jié)論。
  • 線程安全設(shè)置主要在設(shè)置bCoreMutex和bFullMutex,啟用bFullMutex之后數(shù)據(jù)庫(kù)連接和prepared statement都已加鎖(社區(qū)各種文檔都到此為止);但還是感覺不夠清晰:這兩個(gè)鎖會(huì)對(duì)我們使用sqlite有怎樣的影響?best practice又是什么?
  1. // 多線程的設(shè)置的實(shí)現(xiàn):設(shè)置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打開,則每個(gè)數(shù)據(jù)庫(kù)連接會(huì)初始化一個(gè)互斥量成員(db->mutex),也就是社區(qū)各種文檔上所說的“bFullMutex是對(duì)連接的線程保護(hù)”。
  1. if( isThreadsafe ){    // bFullMutex = 1 
  2.     db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);    // 每個(gè)數(shù)據(jù)庫(kù)連接會(huì)初始化一個(gè)成員鎖 
  3.     if( db->mutex==0 ){ 
  4.       sqlite3_free(db); 
  5.       db = 0; 
  6.       goto opendb_out; 
  7.     } 
  8.   } 

如果CoreMutex打開,則會(huì)設(shè)置全局的鎖控制函數(shù)。

  1. /* If the xMutexAlloc method has not been setthen the user did not 
  2.     ** install a mutex implementation via sqlite3_config() prior to  
  3.     ** sqlite3_initialize() being called. This block copies pointers to 
  4.     ** the default implementation into the sqlite3GlobalConfig structure. 
  5.     */ 
  6.     sqlite3_mutex_methods const *pFrom; 
  7.     sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex; 
  8.  
  9.     if( sqlite3GlobalConfig.bCoreMutex ){ 
  10.       pFrom = sqlite3DefaultMutex(); 
  11.     }else
  12.       pFrom = sqlite3NoopMutex(); 
  13.     } 
  14.     pTo->xMutexInit = pFrom->xMutexInit; 
  15.     pTo->xMutexEnd = pFrom->xMutexEnd; 
  16.     pTo->xMutexFree = pFrom->xMutexFree; 
  17.     pTo->xMutexEnter = pFrom->xMutexEnter; 
  18.     pTo->xMutexTry = pFrom->xMutexTry; 
  19.     pTo->xMutexLeave = pFrom->xMutexLeave; 
  20.     pTo->xMutexHeld = pFrom->xMutexHeld; 
  21.     pTo->xMutexNotheld = pFrom->xMutexNotheld; 
  22.     sqlite3MemoryBarrier(); 
  23.     pTo->xMutexAlloc = pFrom->xMutexAlloc; 
  • 而CoreMutext未打開的話,sqlite3NoopMutex()的實(shí)現(xiàn)如下(CoreMutext未打開的話,對(duì)應(yīng)使用的鎖函數(shù)均為空實(shí)現(xiàn)):
  1. sqlite3_mutex_methods const *sqlite3NoopMutex(void){ 
  2.   static const sqlite3_mutex_methods sMutex = { 
  3.     noopMutexInit, 
  4.     noopMutexEnd, 
  5.     noopMutexAlloc, 
  6.     noopMutexFree, 
  7.     noopMutexEnter, 
  8.     noopMutexTry, 
  9.     noopMutexLeave, 
  10.     0, 
  11.     0, 
  12.   }; 
  13.  
  14.   return &sMutex; 
  15.  
  16. // CoreMutext未打開的話,對(duì)應(yīng)使用的鎖函數(shù)均為空實(shí)現(xiàn) 
  17. static int noopMutexInit(void){ return SQLITE_OK; } 
  18. static int noopMutexEnd(void){ return SQLITE_OK; } 
  19. static sqlite3_mutex *noopMutexAlloc(int id){  
  20.   UNUSED_PARAMETER(id); 
  21.   return (sqlite3_mutex*)8;  
  22. static void noopMutexFree(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } 
  23. static void noopMutexEnter(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } 
  24. static int noopMutexTry(sqlite3_mutex *p){ 
  25.   UNUSED_PARAMETER(p); 
  26.   return SQLITE_OK; 
  27. static void noopMutexLeave(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } 
  • FullMutex保護(hù)了什么?

粗略看了一下,通過db->mutex(sqlite3_mutex_enter(db->mutex);)保護(hù)的邏輯塊和函數(shù)主要如下列表:

  1. sqlite3_db_status、sqlite3_finalize、sqlite3_reset、sqlite3_step、sqlite3_exec、 
  2. sqlite3_preppare_v2、column_name、blob操作、sqlite3Close、sqlite3_errmsg... 

基本覆蓋了所有的讀、寫、DDL、DML,也包括prepared statement操作;也就是說,在未打開FullMutex的情況下,在一個(gè)連接上的所有DB操作必須嚴(yán)格串行執(zhí)行,包括只讀操作。

  • CoreMutex保護(hù)了什么?

sqlite3中的mutex操作函數(shù),除了用于操作db->mutex這個(gè)成員之外,還主要用于以下邏輯塊(主要是影響數(shù)據(jù)庫(kù)所有連接的邏輯):

shm操作(index for wal)、內(nèi)存池操作、內(nèi)存緩存操作等。

2.4.1 結(jié)論

  • 多線程設(shè)置是決定DDL、DML、WAL(包括SHM)操作是否線程安全的設(shè)置。
  • 多線程設(shè)置與讀寫(連接)分離沒有任何關(guān)系,并不是實(shí)現(xiàn)讀寫(連接)分離的必要條件(很多人對(duì)這一點(diǎn)有誤解)。

3,性能優(yōu)化tips

3.1 合理使用事務(wù)

由#2.2的分析可知,寫操作會(huì)在RESERVED狀態(tài)下將數(shù)據(jù)更改、b-tree的更改、日志等寫入page cache,并最終flush到數(shù)據(jù)庫(kù)文件中;使用事務(wù)的話,只需要一次對(duì)DB文件的flush操作,同時(shí)也不會(huì)對(duì)其他連接的讀寫操作阻塞;對(duì)比以下兩種數(shù)據(jù)寫入方式(這里以統(tǒng)一存儲(chǔ)提供的API為例),實(shí)測(cè)耗時(shí)有十幾倍的差距(當(dāng)然對(duì)于頻繁的讀操作,使用事務(wù)可以減事務(wù)狀態(tài)的切換,也會(huì)有一點(diǎn)點(diǎn)性能提升):

  1. // batch insert in transaction with 1000000 records 
  2. // 
  3. AliDBExecResult* execResult = NULL
  4. _database->InTransaction([&]() -> bool {    // in transaction 
  5.   auto statement = _database->PrepareStatement("INSERT INTO table VALUES(?, ?)"); 
  6.   for (auto record : records) {    // bind 1000000 records 
  7.     // bind record 
  8.     ... 
  9.     ... 
  10.     statement->AddBatch(); 
  11.   } 
  12.   auto result = statement->ExecuteUpdate(); 
  13.   return result->is_success_; 
  14. }); 
  15.  
  16.  
  17. // batch insert with 1000000 records, no transaction 
  18. // 
  19. auto statement = _database->PrepareStatement("INSERT INTO table VALUES(?, ?)"); 
  20. for (auto record : records) {    // bind 1000000 records 
  21.   // bind record 
  22.   ... 
  23.   ... 
  24.   statement->ExecuteUpdate(); 

3.2 啟用WAL + 讀寫(連接)分離

啟用WAL之后,數(shù)據(jù)庫(kù)大部分寫操作變成了串行寫(對(duì)WAL文件的串行操作),對(duì)寫入性能提升有非常大的幫助;同時(shí)讀寫操作可以互相完全不阻塞(如#2.3所述)。上述兩點(diǎn)比較好的解釋了啟用WAL帶來的提升;同時(shí)推薦一個(gè)寫連接 + 多個(gè)讀連接的模型,如下圖所示: 

sqlite事務(wù)模型、性能優(yōu)化tips、常見誤區(qū)

3.2.1 讀寫連接分離的細(xì)節(jié)

  • 讀操作使用不同的連接并發(fā)執(zhí)行,可以完全避免由于顯式事務(wù)、寫操作之間的鎖競(jìng)爭(zhēng)帶來的死鎖。
  • 所有的寫操作、顯式事務(wù)操作都使用同一個(gè)連接,且所有的寫操作、顯式事務(wù)操作都串行執(zhí)行。

可以完全避免由于顯式事務(wù)、寫操作之間的鎖競(jìng)爭(zhēng)帶來的死鎖,如#2.2.1提到的死鎖的例子。

并發(fā)寫并不能有效的提高寫入效率,參考如下偽代碼,哪段執(zhí)行更快?

  1. // two transactions:  
  2. void Transaction_1() { 
  3.         connection_->Exec("BEGIN"); 
  4.       connection_->Exec("insert into table(value) values('xxxx')"); 
  5.       connection_->Exec("COMMIT"); 
  6.  
  7. void Transaction_2() { 
  8.         connection_->Exec("BEGIN"); 
  9.       connection_->Exec("insert into table(value) values('xxxx')"); 
  10.       connection_->Exec("COMMIT"); 
  11.  
  12. // code fragment 1: concurrent transaction 
  13. thread1.RunBlock([]() -> void { 
  14.       for (int i=0; i< 100000; i++) { 
  15.             Transaction_1(); 
  16.     } 
  17. }); 
  18.  
  19. thread2.RunBlock([]() -> void { 
  20.       for (int i=0; i< 100000; i++) { 
  21.             Transaction_2(); 
  22.     } 
  23. }); 
  24.  
  25. thread1.Join(); thread2.join(); 
  26.  
  27. // code fragment 2: serial transaction 
  28. for (int i=0; i< 100000; i++) { 
  29.   Transaction_1(); 
  30. for (int i=0; i< 100000; i++) { 
  31.   Transaction_2(); 

3.3 針對(duì)具體業(yè)務(wù)場(chǎng)景,設(shè)置合適的WAL SIZE

如#2.3提到,過大的WAL文件,會(huì)讓查找操作從B-Tree查找退化成線性查找(WAL中page連續(xù)存儲(chǔ));但大的WAL文件對(duì)寫操作較友好。對(duì)于大記錄的寫入操作,較大的wal size會(huì)有效提高寫入效率,同時(shí)不會(huì)影響查詢效率。

3.4 針對(duì)業(yè)務(wù)場(chǎng)景分庫(kù)分表

分庫(kù)分表可以有效提高數(shù)據(jù)操作的并發(fā)度;但同時(shí)過多的表會(huì)影響數(shù)據(jù)庫(kù)文件的加載速度?,F(xiàn)在數(shù)據(jù)庫(kù)方向的很多研究包括Auto sharding, paxos consensus, 存儲(chǔ)和計(jì)算的分離等;Auto

application-awared optimization,Auto hardware-awared optimization,machine

learning based optimization也是不錯(cuò)的方向。

3.5 其他

包括WAL checkpoint策略、WAL size優(yōu)化、page size優(yōu)化等,均需要根據(jù)具體的業(yè)務(wù)場(chǎng)景設(shè)置。

4,常見問題 & 誤區(qū)

4.1 線程安全設(shè)置及誤區(qū)

sqlites configuration options: https://sqlite.org/c3ref/c_config_getmalloc.html

按照sqlite文檔,sqlite線程安全模式有以下三種:

SQLITE_CONFIG_SINGLETHREAD(單線程模式)

This option sets the threading mode to Single-thread. In other words, it disables all mutexing and puts SQLite into a mode where it can only be used by a single thread.

SQLITE_CONFIG_MULTITHREAD(多線程模式)

This option sets the threading mode to Multi-thread. In other words, it disables mutexing on database connection and prepared statement objects. The application is responsible for serializing access to database connections and prepared statements. But other mutexes are enabled so that SQLite will be safe to use in a multi-threaded environment as long as no two threads attempt to use the same database connection at the same time.

SQLITE_CONFIG_SERIALIZED(串行模式)

This option sets the threading mode to Serialized. In other words, this option enables all mutexes including the recursive mutexes on database connection and prepared statement objects. In this mode (which is the default when SQLite is compiled with SQLITE_THREADSAFE=1) the SQLite library will itself serialize access to database connections and prepared statements so that the application is free to use the same database connection or the same prepared statement in different threads at the same time.

4.1.1 誤區(qū)一:多線程模式是線程安全的

產(chǎn)生這個(gè)誤區(qū)主的主要原因是官方文檔里的最后一句話:

SQLite will be safe to use in a multi-threaded environment as long as no two threads attempt to use the same database connection at the same time.

但大家往往忽略了前面的一句話:

it disables mutexing on database connection and prepared statement objects

即對(duì)于單個(gè)連接的讀、寫操作,包括創(chuàng)建出來的prepared statement操作,都沒有線程安全的保護(hù)。也即在多線程模式下,對(duì)單個(gè)連接的操作,仍需要在業(yè)務(wù)層進(jìn)行鎖保護(hù)。

4.1.2 誤區(qū)二:多線程模式下,并發(fā)讀操作是安全的

關(guān)于這一點(diǎn),#2.4給出了具體的解釋;多線程模式下(SQLITE_CONFIG_MULTITHREAD)對(duì)prepared statement、connection的操作都不是線程安全的

4.1.3 誤區(qū)三:串行模式下,所有數(shù)據(jù)庫(kù)操作都是串行執(zhí)行

這個(gè)問題比較籠統(tǒng);即使在串行模式下,所有的數(shù)據(jù)庫(kù)操作仍需遵循事務(wù)模型;而事務(wù)模型已經(jīng)將數(shù)據(jù)庫(kù)操作的鎖進(jìn)行了非常細(xì)粒度的分離,串行模式的鎖也是在上層保證了事務(wù)模型的完整性。

4.1.4 誤區(qū)四:多線程模式性能最好,串行模式性能差

多線程模式下,仍需要業(yè)務(wù)上層進(jìn)行鎖保護(hù),串行模式則是在sqlite內(nèi)部進(jìn)行了鎖保護(hù);認(rèn)為多線程模式性能好的兄弟哪來的自信認(rèn)為業(yè)務(wù)層的鎖實(shí)現(xiàn)比sqlite內(nèi)部鎖實(shí)現(xiàn)性能更高?

 

責(zé)任編輯:武曉燕 來源: 云棲社區(qū)
相關(guān)推薦

2010-08-12 11:12:27

Flex誤區(qū)

2020-12-26 15:19:00

DevOps誤區(qū)開發(fā)

2025-09-08 11:20:00

2024-03-01 12:19:00

接口性能優(yōu)化

2015-03-20 10:00:53

2009-11-10 14:18:46

2018-08-17 08:26:25

2017-06-07 15:37:51

MySQLSQL性能優(yōu)化

2019-03-21 14:18:38

iOS開發(fā)優(yōu)化原因

2011-03-21 11:14:21

Oracle性能調(diào)整

2019-09-04 08:13:53

MySQLInnodb事務(wù)系統(tǒng)

2014-10-08 10:37:41

SQLite

2021-06-27 17:35:54

DevSecOps網(wǎng)絡(luò)安全數(shù)據(jù)泄露

2023-08-03 14:45:00

數(shù)字孿生

2020-07-10 17:40:01

人工智能網(wǎng)絡(luò)技術(shù)

2021-11-15 10:50:52

Java線程池代碼

2009-02-27 13:33:47

性能優(yōu)化網(wǎng)絡(luò)性能分析工具

2012-05-16 09:29:25

JavaRailsJVM

2023-10-24 06:59:17

2025-02-20 09:27:46

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

免费观看成人网| 国产中文字幕91| 亚洲中文字幕一区| 影视一区二区三区| 亚洲欧美偷拍卡通变态| 国产精品污www一区二区三区| 久久青青草视频| 日韩国产综合| 亚洲成色999久久网站| 老头吃奶性行交视频| 欧美野外wwwxxx| 久久免费电影网| 91在线免费视频| 全部毛片永久免费看| 色综合天天爱| 日韩福利视频在线观看| 亚洲色图偷拍视频| 亚洲www.| 亚洲国产精品一区二区尤物区| 日韩电影大全在线观看| 亚洲爱情岛论坛永久| 日韩高清国产一区在线| 午夜精品免费视频| 亚洲精品卡一卡二| 加勒比久久综合| 欧美精品一区二| 嫩草视频免费在线观看| 成人免费网站视频| 亚洲一区二区五区| 欧美日韩视频免费在线观看| 免费一级毛片在线观看| 国产91高潮流白浆在线麻豆 | 欧美日韩在线精品| av一区二区三| 麻豆91在线播放免费| 欧美在线视频免费播放| 国产精品成人免费一区二区视频| 欧美www视频在线观看| 国产视频欧美视频| japanese在线观看| 婷婷视频一区二区三区| 6080国产精品一区二区| 亚洲三级视频网站| 日韩欧美看国产| 狠狠爱在线视频一区| 日韩精品在线观看av| gogo在线高清视频| 亚洲人精品一区| 亚洲亚洲精品三区日韩精品在线视频 | 在线观看免费网站黄| 久久亚洲春色中文字幕久久久| 国产激情美女久久久久久吹潮| 999久久久久| 狠狠狠色丁香婷婷综合激情| 国产专区精品视频| 亚洲一区二区视频在线播放| 美女久久久精品| 国产精品三级久久久久久电影| 成人公开免费视频| 日韩国产高清影视| 国产精品揄拍500视频| 国内av在线播放| 日本不卡视频在线| 国产精品片aa在线观看| 欧美mv和日韩mv国产网站| 91欧美一区二区三区| 99精品国产九九国产精品| 欧美久久一区二区| 婷婷激情综合五月天| 欧美电影院免费观看| 日韩免费一区二区| 国产白袜脚足j棉袜在线观看| 国产精品一区二区三区美女| 亚洲第一福利在线观看| 久久久老熟女一区二区三区91| 国产91精品入| 亚洲欧美精品一区| 亚洲天堂最新地址| 亚洲精品2区| 欧美激情欧美激情| 五月天激情国产综合婷婷婷| 日本va欧美va瓶| 成人在线播放av| www.好吊色| 91色九色蝌蚪| 天天综合狠狠精品| av中文字幕在线观看| 亚洲无线码一区二区三区| 丰满少妇被猛烈进入高清播放| 向日葵视频成人app网址| 在线精品视频免费观看| japan高清日本乱xxxxx| 日本在线中文字幕一区| 在线日韩精品视频| 特级片在线观看| 久久国产直播| 91免费国产网站| 手机看片一区二区| 中文字幕免费不卡| 人妻互换免费中文字幕| 日韩免费电影| 欧美成人性战久久| 在哪里可以看毛片| 欧美日本不卡| 国产精品久久久久7777婷婷| 国产jzjzjz丝袜老师水多| 97久久久精品综合88久久| 亚洲欧美久久久久一区二区三区| 免费污视频在线观看| 日韩欧美中文在线| 男女视频在线观看网站| 国产精品视频一区二区三区四蜜臂| 日韩网站免费观看| 精品欧美一区二区三区免费观看| 精品一区二区三区在线播放视频| 国内精品视频免费| 国产在线一区二区视频| 色八戒一区二区三区| 欧美图片自拍偷拍| 91欧美在线| 欧美一区二区影院| 亚洲AV无码一区二区三区性 | 91福利精品第一导航| 男人午夜视频在线观看| 国产一区不卡| 97视频在线观看免费高清完整版在线观看| 一级全黄裸体免费视频| 久久久久久**毛片大全| 国产精品一线二线三线| 伊人久久大香| 在线成人中文字幕| 欧美精品韩国精品| 成人国产精品免费观看动漫| 国产丝袜一区二区三区免费视频 | 国产视频一区二区三| 久久一留热品黄| 97中文字幕在线| 中文字幕日本一区| 在线观看亚洲区| 99re这里只有精品在线| 99国产精品久久| 日韩小视频在线播放| 亚洲精品在线国产| 久久久精品一区二区三区| 无码久久精品国产亚洲av影片| 91麻豆国产精品久久| 国产精品成人久久电影| 国产精选在线| 亚洲精品一区在线观看| 黄色一级视频在线观看| 国产黄色精品网站| 欧美a级黄色大片| 国产精品久一| 久久中文字幕在线| 国产人妖一区二区| 亚洲欧美日本在线| 日本中文字幕在线不卡| 欧美成人高清| 成人毛片网站| 17videosex性欧美| 亚洲精品国产精品国自产在线| 你懂的国产视频| 久久先锋影音av鲁色资源| 日韩黄色片视频| 国产一区2区| 国产在线视频不卡| 男女在线视频| 日韩av中文字幕在线播放| 伊人手机在线视频| 国产视频一区二区在线观看| 国产区二区三区| 天天做天天爱天天综合网2021| 成人免费网站在线看| h片在线免费观看| 精品福利一二区| 国产亚洲欧美在线精品| 国产三区在线成人av| 老司机久久精品| 欧美特黄一区| 蜜桃视频在线观看成人| 欧美精品资源| 久久精品一本久久99精品| 午夜精品久久久久久久91蜜桃| 天天av天天翘天天综合网| 中文字幕在线观看免费高清| 精品在线视频一区| 国产一区二区三区乱码| 国产亚洲欧美日韩在线观看一区二区 | 国产农村妇女精品一区二区| 日韩成人av网站| 欧美影院视频| 热久久美女精品天天吊色| 日韩专区在线| 亚洲福利视频在线| 在线免费看毛片| 亚洲va国产天堂va久久en| av中文字幕免费观看| 国产一区欧美日韩| 高清在线观看免费| 天天综合一区| 欧美午夜精品久久久久免费视| 亚洲精品大片| 欧美有码在线观看| 2024短剧网剧在线观看| 亚洲午夜精品视频| 精品欧美一区二区精品少妇| 色偷偷成人一区二区三区91| 成人观看免费视频| 欧美国产激情二区三区 | 视频欧美精品| 2019中文字幕全在线观看| 国产激情在线观看| 亚洲欧美日韩精品久久亚洲区| av官网在线观看| 欧美在线视频日韩| 天天干天天干天天| 亚洲成人av一区二区| 99热在线观看精品| 国产日韩精品一区二区三区| 日本性生活一级片| 国产一区美女在线| 国产aⅴ爽av久久久久| 亚洲一区中文| 亚洲 欧美 综合 另类 中字| 久久久久久久久久久久久久久久久久| 欧美成人在线免费观看| jizz久久精品永久免费| 91在线视频导航| av成人在线观看| 欧美做受高潮电影o| 国产精品国精产品一二| 精品国产欧美成人夜夜嗨| 波多野结衣在线影院| 亚洲美女视频网| 日本黄色不卡视频| 精品国产三级a在线观看| 99热这里只有精| 欧美疯狂性受xxxxx喷水图片| 少妇一级淫片日本| 91精品办公室少妇高潮对白| 你懂的国产在线| 丁香五六月婷婷久久激情| 欧美成人aaaaⅴ片在线看| 亚洲一区二区在线免费看| 欧美人妻一区二区| 亚洲影院在线观看| 久久久久成人片免费观看蜜芽| 亚洲精品免费在线播放| 日本高清一二三区| 亚洲柠檬福利资源导航| 欧美日韩色视频| 亚洲视频免费在线观看| 91香蕉视频污在线观看| 国产精品毛片久久久久久| 亚洲综合欧美综合| 国产精品萝li| 国产天堂av在线| 亚洲精品精品亚洲| 欧美人与禽zozzo禽性配| 一区二区三区在线免费观看| a级黄色片免费看| 亚洲一区二区3| 五月婷婷色丁香| 欧美亚洲愉拍一区二区| 中文字幕一区二区三区四区视频 | 欧美黑人巨大xxx极品| av免费在线观| 久久久免费观看| 综合日韩av| 国产精品r级在线| 国产极品久久久久久久久波多结野| 国产精品美女久久| 国产精品一区二区美女视频免费看| 91精品天堂| 天堂一区二区三区四区| 日韩国产高清一区| 亚洲色图插插| 91精品国产91久久久久麻豆 主演| 日韩五码在线| 三级a在线观看| 国产九九视频一区二区三区| 2一3sex性hd| 国产调教视频一区| 极品久久久久久| 精品久久久一区二区| 中文字幕在线2018| 日韩欧美国产电影| 你懂的免费在线观看视频网站| 中文字幕亚洲在线| 韩国成人免费视频| 国产成人精品综合久久久| 国产高清视频一区二区| 国内不卡一区二区三区| 日韩理论在线| 欧美激情 国产精品| 日产欧产美韩系列久久99| 美女被爆操网站| 国产女同性恋一区二区| 国产av无码专区亚洲av毛网站| 精品福利在线观看| 国产精品色综合| 精品无人区乱码1区2区3区在线| 日本亚洲精品| 欧美怡春院一区二区三区| 国产aa精品| 欧美中日韩免费视频| 综合精品一区| 国产精品igao| 97aⅴ精品视频一二三区| 最新av电影网站| 日韩人体视频一二区| 99久久精品免费看国产交换| 亚洲网站在线看| 交100部在线观看| 91精品在线观| 成人羞羞网站入口免费| 九一免费在线观看| 日本大胆欧美人术艺术动态| 黄色性视频网站| 综合久久久久综合| 成人免费视频国产免费| 亚洲成人999| 国产福利在线播放麻豆| 国产日韩中文字幕| 国产精品一区2区3区| 欧美爱爱视频免费看| 国产福利精品一区| 国产精品国产精品88| 欧美在线看片a免费观看| 偷拍25位美女撒尿视频在线观看| 欧美精品在线免费播放| 日韩在线电影| 亚洲欧洲国产日韩精品| 视频在线在亚洲| aa一级黄色片| 午夜精品123| 理论片中文字幕| 欧美激情精品久久久久久大尺度| 国产精品美女久久久久人| 影音欧美亚洲| 激情五月播播久久久精品| 毛片aaaaaa| 欧美日韩三级一区| a黄色在线观看| 国产精品人人做人人爽| 国产精品入口久久| 91蝌蚪视频在线观看| 久久久噜噜噜久久中文字幕色伊伊 | 亚洲国产精品久久久久久久| 欧美精品免费在线观看| 精品国产亚洲日本| 久久精品在线免费视频| 国产成人在线视频网址| 国产在线观看免费视频今夜| 欧美大片日本大片免费观看| 伊人影院在线视频| 成人在线观看网址| 亚洲视频精品| 亚洲观看黄色网| 在线精品国精品国产尤物884a| 粉嫩av一区| 国产欧美久久久久久| 香蕉国产精品| 涩视频在线观看| 精品久久久香蕉免费精品视频| 日韩在线免费播放| 国产精品第一第二| 91久久电影| 人妻 日韩 欧美 综合 制服| 欧美日韩一区二区免费在线观看 | 91丨九色porny丨蝌蚪| 国产91精品一区| 国产亚洲激情在线| 亚洲老司机网| 丁香六月激情婷婷| 91麻豆swag| 亚洲天堂视频在线| 欧美成人激情视频免费观看| 精品综合久久88少妇激情| 黑森林福利视频导航| 国产精品天美传媒| 精品人妻一区二区三区四区不卡 | 视频二区不卡| 亚洲欧洲精品在线| 懂色av一区二区三区免费观看| 国产精品999在线观看| 色悠悠久久久久| jizz18欧美18| 91精品无人成人www| 亚洲综合自拍偷拍| 日本视频在线观看一区二区三区| 国产精品你懂得| 黄色亚洲在线| 国产无遮挡在线观看| 精品日韩一区二区三区| 欧美成人黑人| 337p亚洲精品色噜噜狠狠p| 久久综合九色综合欧美就去吻| 国产三级自拍视频| 国产91精品黑色丝袜高跟鞋|