MySQLMySQL数据库

MySQL8.0.14 - 新特性 - InnoDB Paral

2019-02-28  本文已影响27人  阿里云云栖号

最近的MySQL8.0.14版本增加了其第一个并行查询特性,可以支持在聚集索引上做SELECT COUNT()和check table操作。本文简单的介绍下这个特性。

用法

增加了一个session级别参数: innodb_parallel_read_threads

要执行并行查询,需要满足如下条件(ref: row_scan_index_for_mysql)

相关代码

入口函数:

row_scan_index_for_mysql
    parallel_select_count_star  // for select count(*)
    parallel_check_table        // for check table

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()

流程:

线程数取分区数和配置线程数的最小值

启动线程

启动线程各自扫描: 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)

每取一个分区,调用处理函数去遍历分区:

对于异常情况,只返回最后一个context的错误码。

该特性只是MySQL在并行查询的第一步,甚至定义了一些接口还没有使用,例如接口函数pread_adapter_scan_get_num_threads, 估计是给未来server层做并行查询使用的。代码里对应两个适配类:

另外一个可以用到的地方是创建二级索引,我们知道InnoDB创建二级索引,是先从聚集索引读取记录,生成多个merge file,然后再做归并排序,但无论是生成merge file,还是排序,都可以做到并行化。官方也提到这是未来的一个优化点,相信不久的将来,我们就能看到MySQL更为强大的并行查询功能。

Reference

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



本文作者:zhaiwx_yinfeng.

阅读原文

本文为云栖社区原创内容,未经允许不得转载。

上一篇下一篇

猜你喜欢

热点阅读