innodb_buffer_pool_instances,MySQL8.0.14 - 新特性 - InnoDB Parallel Read簡述

 2023-11-19 阅读 20 评论 0

摘要:最近的MySQL8.0.14版本增加了其第一個并行查詢特性,可以支持在聚集索引上做SELECT COUNT()和check table操作。本文簡單的介紹下這個特性。 用法 增加了一個session級別參數:?innodb_parallel_read_threads 要執行并行查詢,需要滿足如下條件(ref:?row_scan_ind

最近的MySQL8.0.14版本增加了其第一個并行查詢特性,可以支持在聚集索引上做SELECT COUNT()和check table操作。本文簡單的介紹下這個特性。

用法

增加了一個session級別參數:?innodb_parallel_read_threads

要執行并行查詢,需要滿足如下條件(ref:?row_scan_index_for_mysql)

  • 無鎖查詢
  • 聚集索引
  • 不是Insert...select
  • 需要參數設置為>1

相關代碼

入口函數:

row_scan_index_for_mysqlparallel_select_count_star  // for select count(*)parallel_check_table        // for check table

innodb_buffer_pool_instances、InnoDB里實現了兩種查詢方式,一種是基于key的(key reader), 根據葉子節點上的值做分區,需要判斷可見性;另外一種是基于page的(physical read),根據page no來做分區,無需判斷可見性。目前支持的兩種查詢都是key reader的方式。

使用如下代碼創建一個reader,并調用接口函數,read()函數里的回調函數包含了如何對獲取到的行數據進行處理:

Key_reader reader(prebuilt->table, trx, index, prebuilt, n_threads);
reader.read(func), 其中func是回調函數,用于告訴線程怎么處理得到的每一行

分區并計算線程數

分區入口:

template <typename T, typename R>
typename Reader<T, R>::Ranges Reader<T, R>::partition()

流程:

  • 搜集btree的最左節點page no
  • innodb_file_per_table?從root page開始向下,嘗試構建子樹:

    • 如果該level的page個數不足線程數,繼續往下走
    • 否則,使用該level, 搜集該level的每個page的最左記錄向下直到葉子節點的最左鏈表
  • 如上搜集到的是多條代表自上而下的page no數組,需要根據這些數組創建分區range,這里有兩種創建方式:

    • Key_reader::Ranges Key_reader::create_ranges: 基于鍵值創建分區

      • 找到每個鏈表的葉子節點的第一條記錄,存儲其cursor作為當前range的起點和上一個range的終點
    • Phy_reader::Ranges Phy_reader::create_ranges:基于物理頁創建分區

      • 找到每個鏈表的葉子節點,相鄰鏈表的葉子節點組成一個range

MySQL update,線程數取分區數和配置線程數的最小值

啟動線程

啟動線程各自掃描:?start_parallel_load

為每個分區創建context(class Reader::Ctx),加入到隊列中
實現了一個Lock-free的隊列模型,多線程可以并發的從隊列中取context: 實現細節在文件include/ut0mpmcbq.h中,對應類?class mpmc_bq, 實現思路見鏈接

線程函數:

dberr_t Reader<T, R>::worker(size_t id, Queue &ctxq, Function &f)

MySQL having。每取一個分區,調用處理函數去遍歷分區:

  • Key_reader::traverse
    對于獲得的每條記錄,判斷其可見性(共享事務對象trx_t),調用回調函數處理記錄(在Key_reader::read()作為參數傳遞),對于select count(*), 就是累加記錄的計數器
  • Phy_reader::traverse
    讀取每條非標記刪除的記錄并調用回調函數處理,無需判斷可見性

對于異常情況,只返回最后一個context的錯誤碼。

該特性只是MySQL在并行查詢的第一步,甚至定義了一些接口還沒有使用,例如接口函數pread_adapter_scan_get_num_threads, 估計是給未來server層做并行查詢使用的。代碼里對應兩個適配類:

  • Parallel_reader_adapter
  • Parallel_partition_reader_adapter

另外一個可以用到的地方是創建二級索引,我們知道InnoDB創建二級索引,是先從聚集索引讀取記錄,生成多個merge file,然后再做歸并排序,但無論是生成merge file,還是排序,都可以做到并行化。官方也提到這是未來的一個優化點,相信不久的將來,我們就能看到MySQL更為強大的并行查詢功能。

Reference

innodb_thread_concurrency。WL#11720: InnoDB: Parallel read of index
MySQL 8.0.14: A Road to Parallel Query Execution is Wide Open!



本文作者:zhaiwx_yinfeng.

閱讀原文

本文為云棲社區原創內容,未經允許不得轉載。

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/5/183888.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息