SQLite體系架構

zcbin發表於2018-03-04

SQLite採用模組設計,其架構圖如下所示:

SQLite架構

介面(Interface)

介面由SQLite C API組成,外部通過JDBC等連線SQLite,最後也是呼叫這些C API進行操作。

編譯器(Compiler)

在編譯器中,分詞器(Tokenizer)和分析器(Parser)對SQL進行語法檢查,然後把它轉化為底層能更方便處理的分層的資料結構---語法樹,然後把語法樹傳給程式碼生成器(code generator)進行處理。而程式碼生成器根據它生成一種針對SQLite的彙編程式碼,最後由虛擬機器(Virtual Machine)執行。

  • 詞法分析器(Tokenizer)

當執行一個包含SQL語句的字串時,介面程式要把這個字串傳遞給tokenizer。Tokenizer的任務是把原有字串分割成一個個識別符號(token),並把這些識別符號傳遞給解析器。Tokenizer是用手工編寫的,在C檔案tokenize.c中。

  • 語法分析器(Parser)

語法分析器的工作是在指定的上下文中賦予識別符號具體的含義。SQLite的語法分析器使用Lemon LALR(1)分析程式生成器來產生,Lemon做的工作與YACC/BISON相同,但它使用不同的輸入句法,這種句法更不易出錯。Lemon還產生可重入的並且執行緒安全的語法分析器。Lemon定義了非終結析構器的概念,當遇到語法錯誤時它不會洩露記憶體。驅動Lemon的原始檔可在parse.y中找到。

  • 程式碼生成器(Code Generator)

語法分析器在把識別符號組裝成完整的SQL語句後,就呼叫程式碼生成器產生虛擬機器程式碼

虛擬機器(Virtual Machine)

架構中最核心的部分是虛擬機器,或者叫做虛擬資料庫引擎(Virtual Database Engine,VDBE)。它和Java虛擬機器相似,解釋執行位元組程式碼。VDBE的位元組程式碼由128個操作碼(opcodes)構成,它們主要集中在資料庫操作。它的每一條指令都用來完成特定的資料庫操作(比如開啟一個表的遊標)或者為這些操作棧空間的準備(比如壓入引數)。總之,所有的這些指令都是為了滿足SQL命令的要求。

後端(Back-End)

後端由B-樹(B-tree),頁快取(page cache,pager)和作業系統介面(即系統呼叫)構成。B-tree和page cache共同對資料進行管理。B-tree的主要功能就是索引,它維護著各個頁面之間的複雜的關係,便於快速找到所需資料。而pager的主要作用就是通過OS介面在B-tree和Disk之間傳遞頁面。

  • B-樹(B-Tree)

一個SQLite資料庫使用B-樹的形式儲存在磁碟上,B-樹的實現位於原始檔btree.c中。資料庫中的每個表和索引使用一棵單獨的B-樹,所有的B-樹存放在同一個磁碟檔案中。檔案格式的細節被記錄在btree.c開頭的備註裡。B-樹子系統的介面在標頭檔案btree.h中定義。

  • 頁面快取記憶體(Page Cache)

B-樹模組以固定大小的資料塊形式從磁碟上請求資訊,預設的塊大小是1024個位元組,但是可以在512和65536個位元組之間變化。頁面快取記憶體負責讀、寫和快取這些資料塊。頁面快取記憶體還提供回滾和原子提交的抽象,並且管理資料檔案的鎖定。B-樹驅動模組從頁面快取記憶體中請求特定的頁,當它想修改頁面、想提交或回滾當前修改時,它也會通知頁面快取記憶體。頁面快取記憶體處理所有麻煩的細節,以確保請求能夠快速、安全而有效地被處理。 頁面快取記憶體的程式碼實現被包含在單一的C原始檔pager.c中。頁面快取記憶體子系統的介面在標頭檔案pager.h中定義。

OS介面

為了在POSIX和Win32作業系統之間提供移植性,SQLite使用一個抽象層來提供作業系統介面。OS抽象層的介面在os.h中定義,每種支援的作業系統有各自的實現:Unix使用os_unix.c,Windows使用os_win.c,等等。每個特定作業系統的實現通常都有自己的標頭檔案,如os_unix.h, os_win.h等。

參考資料

相關文章