MySQL8.0.14 - 新特性 - InnoDB Parallel Read简述
最近的MySQL8.0.14版本增加了其第一個并行查詢特性,可以支持在聚集索引上做SELECT COUNT()和check table操作。本文簡單的介紹下這個特性。
用法
增加了一個session級別參數(shù):?innodb_parallel_read_threads
要執(zhí)行并行查詢,需要滿足如下條件(ref:?row_scan_index_for_mysql)
- 無鎖查詢
- 聚集索引
- 不是Insert...select
- 需要參數(shù)設置為>1
相關代碼
入口函數(shù):
row_scan_index_for_mysqlparallel_select_count_star // for select count(*)parallel_check_table // for check tableInnoDB里實現(xiàn)了兩種查詢方式,一種是基于key的(key reader), 根據(jù)葉子節(jié)點上的值做分區(qū),需要判斷可見性;另外一種是基于page的(physical read),根據(jù)page no來做分區(qū),無需判斷可見性。目前支持的兩種查詢都是key reader的方式。
使用如下代碼創(chuàng)建一個reader,并調用接口函數(shù),read()函數(shù)里的回調函數(shù)包含了如何對獲取到的行數(shù)據(jù)進行處理:
Key_reader reader(prebuilt->table, trx, index, prebuilt, n_threads); reader.read(func), 其中func是回調函數(shù),用于告訴線程怎么處理得到的每一行分區(qū)并計算線程數(shù)
分區(qū)入口:
template <typename T, typename R> typename Reader<T, R>::Ranges Reader<T, R>::partition()流程:
- 搜集btree的最左節(jié)點page no
-
從root page開始向下,嘗試構建子樹:
- 如果該level的page個數(shù)不足線程數(shù),繼續(xù)往下走
- 否則,使用該level, 搜集該level的每個page的最左記錄向下直到葉子節(jié)點的最左鏈表
-
如上搜集到的是多條代表自上而下的page no數(shù)組,需要根據(jù)這些數(shù)組創(chuàng)建分區(qū)range,這里有兩種創(chuàng)建方式:
-
Key_reader::Ranges Key_reader::create_ranges: 基于鍵值創(chuàng)建分區(qū)
- 找到每個鏈表的葉子節(jié)點的第一條記錄,存儲其cursor作為當前range的起點和上一個range的終點
-
Phy_reader::Ranges Phy_reader::create_ranges:基于物理頁創(chuàng)建分區(qū)
- 找到每個鏈表的葉子節(jié)點,相鄰鏈表的葉子節(jié)點組成一個range
-
線程數(shù)取分區(qū)數(shù)和配置線程數(shù)的最小值
啟動線程
啟動線程各自掃描:?start_parallel_load
為每個分區(qū)創(chuàng)建context(class Reader::Ctx),加入到隊列中
實現(xiàn)了一個Lock-free的隊列模型,多線程可以并發(fā)的從隊列中取context: 實現(xiàn)細節(jié)在文件include/ut0mpmcbq.h中,對應類?class mpmc_bq, 實現(xiàn)思路見鏈接
線程函數(shù):
dberr_t Reader<T, R>::worker(size_t id, Queue &ctxq, Function &f)每取一個分區(qū),調用處理函數(shù)去遍歷分區(qū):
- Key_reader::traverse
對于獲得的每條記錄,判斷其可見性(共享事務對象trx_t),調用回調函數(shù)處理記錄(在Key_reader::read()作為參數(shù)傳遞),對于select count(*), 就是累加記錄的計數(shù)器 - Phy_reader::traverse
讀取每條非標記刪除的記錄并調用回調函數(shù)處理,無需判斷可見性
對于異常情況,只返回最后一個context的錯誤碼。
該特性只是MySQL在并行查詢的第一步,甚至定義了一些接口還沒有使用,例如接口函數(shù)pread_adapter_scan_get_num_threads, 估計是給未來server層做并行查詢使用的。代碼里對應兩個適配類:
- Parallel_reader_adapter
- Parallel_partition_reader_adapter
另外一個可以用到的地方是創(chuàng)建二級索引,我們知道InnoDB創(chuàng)建二級索引,是先從聚集索引讀取記錄,生成多個merge file,然后再做歸并排序,但無論是生成merge file,還是排序,都可以做到并行化。官方也提到這是未來的一個優(yōu)化點,相信不久的將來,我們就能看到MySQL更為強大的并行查詢功能。
#阿里云開年Hi購季#幸運抽好禮!
點此抽獎:https://www.aliyun.com/acts/product-section-2019/yq-lottery?utm_content=g_1000042901
原文鏈接
本文為云棲社區(qū)原創(chuàng)內容,未經(jīng)允許不得轉載。
總結
以上是生活随笔為你收集整理的MySQL8.0.14 - 新特性 - InnoDB Parallel Read简述的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Flutter Exception降到万
- 下一篇: 云栖专辑 | 阿里开发者们的第19个感悟