SQLite學習筆記(十一)&&Sqlite虛擬機器原理

來源:互聯網
上載者:User

標籤:

前言
      我們知道任何一種關係型資料庫管理系統都支援SQL(Structured Query Language),相對於檔案管理系統,使用者不用關心資料在資料庫內部如何存取,也不需要知道底層的儲存結構,熟悉SQL,就能熟練使用資料庫。SQL的引入,使得資料庫系統需要將SQL轉換為內部的資料結構,然後與底層的儲存結構打通,達到使用者存取資料的目的。所謂的SQL對應的資料結構,我們通常稱之為執行計畫,每個SQL執行前,都需要產生執行計畫,然後執行。SQL如何變化到等價的執行計畫?我們熟悉的資料庫,Oracle,Sqlserver,Mysql等通過對SQL進行詞法分析,文法分析,語義分析,產生執行計畫等步驟,最終產生執行計畫,這個計劃一般是一個複雜的資料結構。SQLite也通過以上幾步產生執行計畫,但特別的是,SQLite的執行計畫是一串指令流,這個指令流是由代碼產生器產生,代碼產生器將文法樹翻譯成一種SQLite專用的內部指令,通過虛擬機器來解析執行。指令流相當於SQL與虛擬機器的中介,由於指令流是扁平的,SQLite提供方法(PRAGMA vdbe_trace=ON)讓使用者可以看到執行SQL的每一條指令,清楚地知道資料在SQLite內部是如何流轉的。本文主要講SQLite的虛擬機器(Virtual Database Engine,簡稱VDBE)的原理以及相關的內部指令。

虛擬機器
     所謂虛擬機器是指對真實電腦資源環境的一個抽象,它為語言程式提供了一套完整的電腦介面。比如我們熟悉的JAVA語言,我們在跑JAVA程式時,其實是運行在JVM(JAVA Virtual Machine)環境中,所有的JAVA程式首先被編譯為.class類檔案,這種類檔案在虛擬機器上執行,也就是說class檔案並不與作業系統指令對應,而是經過虛擬機器間接與作業系統互動。SQLite的虛擬機器也是如此,編譯SQL產生的指令流只有SQLite虛擬機器(Virtual Database Engine,簡稱VDBE)能識別,由虛擬機器與底層的儲存(表,索引)互動,這種方式使得SQLite內部模組分工非常清晰,耦合度很低。如所示,我們可以看到VDBE的位置,它處於編譯器與Btree模組的中間,是SQLite的核心,負責SQL到資料存取的互動。後面我提到的虛擬機器都是指SQLite虛擬機器(Virtual Machine,VM),VM模組將底層儲存看作是記錄維度檔案系統,通過執行指令流,來讀寫表上的記錄。

                                      
VDBE資料結構和API

struct Vdbe{sqlite3 *db;   /* The database connection that owns this statement */Op *aOp;     /* Space to hold the virtual machine‘s program */int nOp;     /* Number of instructions in the program */Mem **apArg;    /* Arguments to currently executing user function */Parse *pParse;  /* Parsing context used to create this Vdbe */int pc;         /* The program counter */Mem *aMem;      /* The memory locations */int nMem;       /* Number of memory locations currently allocated */Mem *aColName;  /* Column names to return */u16 nResColumn; /* Number of columns in one row of the result set */char *zSql;     /* Text of the SQL statement that generated this */}

      我從源碼中選取了比較重要的對象,主要包括資料庫物件(db),指令流對象(aOp,nOp),綁定輸入的參數值(apArg),解析SQL的對象(pParse),指令流計數器(pc),儲存臨時變數的寄存器(aMem,nMem),返回結果集集的列名和列資訊(aColName,nResColumn)以及執行的產生虛擬機器指令的SQL(zSql)等。這些基本就是虛擬機器對象的全部,有指令,有寄存器,有指令計數器,與組合語言非常相似,只不過VDBE裡面的指令是sqlite內部識別的指令,而組合語言指令是與機器指令對應的。如果想瞭解VDBE所有的對象,可以參考vdbeInt.h中關於該結構的定義,另外關於sqlite3結構和Parse結構可以參考sqliteInt.h檔案。
     瞭解了Vdbe資料結構,我們再來看看我們平時常用的API是如何與VDBE交換資料的。通常我們要執行一個語句,會執行如下幾個步驟。
1.調用sqlite3_prepare_*來編譯產生指令流,返回一個sqlite3_stmt對象,其實這個對象就是vdbe對象。
2.調用sqlite3_bind_*來將參數傳遞給vdbe,
3.調用sqlite3_step進行執行,這時候會啟動虛擬機器執行一條條指令,直到遇到中斷或者停止指令為止
4.調用sqlite3_column_*來擷取上一步準備好的結果集
5.調用sqlite3_finalize,銷毀vdbe對象,結束這次執行。
此外我們還可能用到sqlite3_reset介面,這個介面將指令流回退到第一條指令,使用者可以調用sqlite3_step重新執行。有關API的詳細說明,可以參考檔案vdbeapi.c。 

虛擬機器指令
      虛擬機器核心就是扁平化指令,SQLite定義了一系列指令語言,每個指令做一小部分動作,虛擬機器通過執行一些列指令達到查詢,修改資料庫的目的。每一條指令包含一個操作符和5個運算元,形式如下:<opcode,P1,P2,P3,P4,P5>。P1,P2,P3是一個32位有符號整數,P1一般是遊標編號,P2一般是指令需要跳轉的指令位置,P4是一個32位/64位整數,64位的浮點數,或者是指向字串的指標,或者是二進位等,P5是一個無編號的字元。不是每條指令都使用了全部5個運算元,有的指令只需要2到3個運算元。後面一篇文章我會結合執行個體詳細講解指令的作用,以及對應運算元的含義。

虛擬機器執行流程
      虛擬機器的核心流程在sqlite3VdbeExec函數中,我們調用sqlite3_step時就會調用到該函數。由於這個函數比較大,大概有6000行代碼,裡麵包含了每條指令的執行過程,為了方便說明,我會簡化函數內容來說明這個函數的邏輯,抽象的代碼如下。從代碼流程來看,邏輯非常簡單,通過迴圈遍曆指令數組中的每條指令逐一執行,直到遇到中斷或終止指令為止。如果需要逐條瞭解每條指令的含義,還需要仔細閱讀代碼。

sqlite3VdbeExec(Vdbe *p){  Op *aOp = p->aOp; /* Copy of p->aOp */  Op *pOp = aOp; /* Current operation */  for(pOp=&aOp[p->pc]; rc==SQLITE_OK; pOp++){    switch(pOp->opcode){    case OP_Goto: //jump to P2指向的指令    {      pOp = &aOp[pOp->p2 - 1];      break;    }    case OP_Integer: // value P1 is written into register P2.    {      pOut = out2Prerelease(p, pOp);      pOut->u.i = pOp->p1;      break;    }    case OP_Real:    {      ......      break;    }    case OP_Halt:    {      ......      break;    }    ...    }// end of switch  } // end of for
}

小結
     本文介紹了SQLite虛擬機器以及對應的指令流。通過介紹vdbe的儲存結構,我們瞭解到vdbe對象所包含的內容;通過介紹API,我們瞭解到API與虛擬機器的關係;通過介紹函數sqlite3VdbeExec的實現,我們知道虛擬機器執行流程非常清晰,通過執行一系列指令流,就可以實現查詢,更新資料。

SQLite學習筆記(十一)&&Sqlite虛擬機器原理

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.