flask做的購物網(wǎng)站互聯(lián)網(wǎng)推廣廣告
目錄
1. DML語句讀流程概要
2. DML語句寫流程概要
3. DDL 流程概要
4. SQL的Parse和Compile
5. 讀取的執(zhí)行
6. 寫入的執(zhí)行
7. DDL的執(zhí)行
8. 小結
1. DML語句讀流程概要
TiDB Server接收sql并處理,TiKV負責持久化數(shù)據(jù),PD提供TSO和Region的數(shù)據(jù)字典信息
- Protocol Layer:接收sql
- PD Client到PD節(jié)點獲取STO
- Parse:詞法解析、語法解析,將sql解析為AST語法樹
- Compile:區(qū)分點查和非點查,生成執(zhí)行計劃
- Execute:拿著執(zhí)行計劃問PD在哪個TiKV Region讀取想要的數(shù)據(jù)
- 讀取數(shù)據(jù)后交由Execute,返回給用戶
2. DML語句寫流程概要
- Protocol Layer:接收sql
- PD Client到PD節(jié)點獲取STO
- Parse:詞法解析、語法解析,將sql解析為AST語法樹
- Compile:區(qū)分點查和非點查,生成執(zhí)行計劃
- Execute:拿著執(zhí)行計劃問PD在哪個TiKV Region讀取想要的數(shù)據(jù)
- 讀出來的數(shù)據(jù)放在memBuffer中進行修改,當用戶發(fā)起commit的時候,進入兩階段提交
- 第一階段:prewrite,將內(nèi)存中修改的信息和鎖信息寫入TiKV
- 第二階段:commit,寫提交信息,將鎖清理掉,獲取結束TSO
- 二階段提交完成后,返回給用戶提交成功數(shù)據(jù)不會丟了
3. DDL 流程概要
修改表定義、加索引等等都是DDL
- 用戶發(fā)出DDL語句
- TIDB Server中的start job接收DDL語句
- 將DDL放入TiKV中的job queue中(添加索引是放在 add index queue中)
- TIDB Server誰是owner角色誰就執(zhí)行DDL,owner中的worker去job queue(先進先出)中取DDL去執(zhí)行
- 執(zhí)行完后把該job放入history queue中
4. SQL的Parse和Compile
- Protocol Layer:接收sql
- PD Client:去PD異步獲取TSO
- Parse:詞法分析LEX,語法分析YACC,將sql轉化成AST語法樹
- compile:
- preprocess:檢測sql合法性,名稱是否正確,一些綁定信息等,判斷是否是點查
- 如果是點查(PointGet)的話直接就執(zhí)行,節(jié)約了優(yōu)化的工作
- 如果是非點查的話,進入優(yōu)化流程:
- ①邏輯優(yōu)化:關系代數(shù)、等價交換等一些規(guī)則將sql語句進行一些邏輯的變換,比如把外連接轉化為內(nèi)連接等等
- ②物理優(yōu)化:基于邏輯優(yōu)化的結果結合相關的統(tǒng)計信息(行數(shù)、列的選擇度、直方圖等等)選擇最優(yōu)的算子,如何去TiKV中好的效率最高的取得數(shù)據(jù)
- 編譯完成后生成物理執(zhí)行計劃,拿著物理執(zhí)行計劃去TiKV中取數(shù)據(jù)
5. 讀取的執(zhí)行
當Executor收到執(zhí)行計劃后,Executor做兩件事:
- ①從information schema(緩存中,是最新的)中獲得元數(shù)據(jù)(表名、列名等)
- ②要修改的數(shù)據(jù)對應Key在所在的Region以及Region所在的TiKV,第一次會從PD中獲取Region的位置,然后緩存在TiKV Client中的region Cache中,如果region Cache的信息過期了(back off),訪問的時候會再次從PD中讀取最新的信息到region Cache中
經(jīng)過了以上過程,獲得了表的元數(shù)據(jù)以及Key所在的Region和TiKV
Executor讀取數(shù)據(jù):
- 如果是點查,KV模塊就通過TiKV Client直接讀取數(shù)據(jù)
- 如果是非點查(復雜sql語句)DistSQl模塊會將復雜的sql轉換成多條對單表的查詢語句,然后通過TiKV Client去TiKV取數(shù)據(jù)
TiKV接收到請求后首先會構建一個快照snapshot
點查和非點查都會進入UnifyRead Pool線程池,按照優(yōu)先級執(zhí)行查詢,到RocksDB kv去讀取數(shù)據(jù)
一部分過濾和聚合在TiKV中做,叫coptask,還有一部分在TiDB中(比如三張表連接,三張表散落在3個TiKV中,先把數(shù)據(jù)讀到TiDB內(nèi)存中再做表連接)叫root task
6. 寫入的執(zhí)行
????????前面的讀取流程是一樣的,從讀出數(shù)據(jù)開始,把需要修改的數(shù)據(jù)讀到memBuffer中,用戶commit后進入兩階段提交
? ? ? ? 第一階段:prewrite,Transaction從memBuffer中一行一行讀取數(shù)據(jù)修改數(shù)據(jù),通過KV和TiKV Client寫到TiKV中并加鎖
- 寫請求發(fā)送給Scheduler模塊(協(xié)調(diào)事務并發(fā)寫入的沖突,并將收到的修改操作向下寫入),同時寫入同一個Key的時候,誰持有Latch誰就可以寫數(shù)據(jù),其他的需等待Latch
- 然后到RaftStore,將寫請求轉換為raft log,此時會在本地RocksDB raft持久化raft log,并把raft log發(fā)送給其他節(jié)點,然后Apply模塊把讀取rocksdb raft log應用到rocksdb kv中持久化存儲,然后反饋寫入成功。
? ? ? ? 第二階段:commit,獲取結束TSO,寫提交信息,清理鎖
7. DDL的執(zhí)行
- Protocol Layer接收DDL,經(jīng)過Parse和Compile,到達start job
- start job會檢查自己所在的TiDB Server是不是owner
- 如果是owner則直接給workers執(zhí)行,如果不是就會把DDL做成一個job放到TiKV的job queue中持久化(添加索引放在add index queue中)
- Schema load:將最新的表的元信息載入到TiDB Server
- owner中的worker會定期去查看job queue,當job queue中有job的時候workers就根據(jù)元信息執(zhí)行DDL(Job queue 和 add index queue 中的語句可以并行執(zhí)行)
- 執(zhí)行完畢后把job放在history queue中
owner節(jié)點是輪詢的,由PD節(jié)點控制
8. 小結
- DML 語句讀寫流程
- DDL語句的執(zhí)行流程
來自TiDB官方資料?