SQLite學習(四) - 異步I/O的實現 sqlite3async.c


一般情況下,當我們的程序有I/O 操作需要寫磁盤時,程序會等待I/O完成后才把程序控制還給用戶。由於I/O是相對比較慢的,所以這有可能會成為性能瓶頸。 SQLite的異步I/O使用一個單獨的線程完成I/O 雖然這樣沒有減少系統資源的使用,但是控制權立刻返回給用戶,更好的用戶體驗。


1. 數據庫ACID中的D
使用異步
I/O帶來的一個問題就是失去了數據庫的持久性(Durable) 特性。 由於I/O在后台進行,你不知道什么時候I/O會完成。如果在I/O完成之前系統出現錯誤,后面的用戶將看不到之前的改動。

2. SQLIte的異步IO怎么工作的?
(1) 創建一個VFS_Object
(2) sqlite3_vfs_register()注冊這個Object
(3) SQLitevfs_xwrite() 進行I/O操作時,不是直接寫到磁盤,而是寫到write-queue,等待后台進程來完成I/O
(4) SQLite執行讀取操作時,用vfx_xread(), 會同時從磁盤和write-queue讀取,這樣看上去就好像write-queue已經寫到磁盤上了
(5) asynchronous I/O VFS is registered by calls sqlite3async_initialize() and sqlite3async_shutdown().

SQLite異步I/O限制
SQLite異步I/O實現較簡單。 比如如果有大量的數據寫入write-queue, 超出了后台write線程的處理能力,write-queue將無限制的長大,這樣可能導致系統out-of-memory

3. 鎖和並發
文件鎖默認是打開的,當一個數據庫連接開始一個transaction, 會立即獲得文件鎖,transaction結束(commitRollback)也不會釋放鎖,只有當“write-queue”為空時才釋放鎖。

可以用sqlite3async_control() disable文件鎖,這樣I/O時就不需要額外的去獲得文件鎖,以得到更好的性能。

4.編譯和使用Asynchronous IO extension
異步I/O的代碼在C源文件sqlite3async.c , sqlite3async.h (目錄/ext/anysnc)中。

The asynchronous IO VFS API is described in detail in comments in sqlite3async.h. Using the API usually consists of the following steps:

1. Register the asynchronous IO VFS with SQLite by calling the sqlite3async_initialize() function.
2.  Create a background thread to perform write operations and call sqlite3async_run().
3.  Use the normal SQLite API to read and write to databases via the asynchronous IO VFS.

Refer to comments in the sqlite3async.h header file for details.

 

5.移植
現在Asynchronous IO extension支持平台有win32系統,支持pthreads interface的系統Mac OS X, Linux, and other varieties of Unix 要移植Asynchronous IO extension到其他平台,需要實現mutex and condition variable primitives.

Currently there is no externally available interface to allow this, but modifying the code within sqlite3async.c to include the new platforms concurrency primitives is relatively easy. Search within sqlite3async.c for the comment string "PORTING FUNCTIONS" for details. Then implement new versions of each of the following:

static void async_mutex_enter(int eMutex);
static void async_mutex_leave(int eMutex);
static void async_cond_


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM