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