鲲鹏社区首页
中文
注册
如何通过鲲鹏BoostKit加速特性提升MySQL性能

如何通过鲲鹏BoostKit加速特性提升MySQL性能

BoostKit

发表于 2023/10/18

0

本文我们将学习鲲鹏BoostKit针对MySQL数据库提供的加速特性,了解各个特性加速原理、使用方式,以及数据库在OLAP场景和OLTP场景的整体性能提升效果。图4-1为鲲鹏BoostKit针对MySQL整体架构层面提供的加速特性全景图,从图中我们可以看到鲲鹏服务器上部署的MySQL分为MySQL Server层和存储引擎层,鲲鹏BoostKit提供的加速特性针对这两个层级均有优化。

(1)客户端访问入口提供Gazelle协议栈网络优化。

(2)针对MySQL Server层的连接器,提供线程池优化,提升高并发场景下的性能。

(3)针对MySQL Server层的执行器,提供并行查询优化,提升查询类SQL语句的执行效率。

(4)针对存储引擎层的后台线程,提供NUMA调度优化,针对后台线程进行绑核固定,减少CPU之间的切换,提升执行效率。

(5)针对存储引擎层的底层数据文件,提供NVMe原子写优化,减少数据落盘的次数。

(6)针对MySQL整体应用程序,提供GCC反馈优化,对指令进行重新排布,提升数据库代码运行效率。

图4-1 鲲鹏BoostKit针对MySQL数据库优化架构图

数据库处理通用的业务场景大致分为两类:联机事务处理OLTP和联机分析处理OLAP。

(1)OLTP主要面向交易的处理系统,以小的事务及小的查询为主,快速响应用户操作。强调数据库内存命中率,对并发操作及磁盘IO操作时延要求高。

(2)OLAP主要面向决策支持系统,对用户当前及历史数据进行分析、查询和生成报表,支持管理决策。由于分析数据量大、复杂查询,对时间要求不严格,但强调SQL执行时长及磁盘IO带宽。

下文将主要针对OLAP场景和OLTP场景下BoostKit提供的如下关键加速特性进行详细介绍,帮助开发者快速掌握加速特性的实现机制和使用方式,并验证调优效果。

(1)OLAP场景加速特性:并行查询优化、GCC反馈优化。

(2)OLTP场景加速特性:NUMA调度优化、线程池、细粒度锁优化、无锁优化、Gazelle网络优化、GCC反馈优化。

OLAP场景调优

OLAP场景是指对大规模数据进行多维度分析和查询的场景,通常需要可扩展性、数据一致性、高性能和高安全性。在这种场景下,数据库的查询响应时间和吞吐量对保证应用程序的正常运行至关重要。鲲鹏BoostKit针对数据库在OLAP在线分析处理能力方面提供了深度优化的加速特性,并通过Patch补丁包形式开源到Gitee社区,开发者需要先将Patch应用到MySQL源码中,再编译和安装MySQL。

1. MySQL并行查询优化特性概述

MySQL单SQL查询只能调度单线程,这意味着在执行查询时,只有一个CPU核心会被利用,而其他核心则处于空闲状态。这对于大型数据库和高并发查询来说是一个严重的问题,因为它会导致查询性能的瓶颈。为了充分发挥鲲鹏平台的多核优势,提高系统的并发处理能力和性能表现,鲲鹏BoostKit提出了MySQL并行查询优化特性,主要针对数据库的OLAP场景。

通过MySQL并行查询优化特性,实现了并行读取数据,使用多核多线程执行SQL语句的功能,加快了查询语句的执行速度。MySQL并行查询优化特性主要用于数据分析、BI报表及决策支持等业务场景。

MySQL并行查询优化特性以Patch补丁文件形式提供,该补丁基于MySQL 8.0.20和MySQL 8.0.25开发,并在Gitee社区开源,目前支持单表的4种扫描查询并行:

(1)JT_ALL

(2)JT_INDEX_SCAN

(3)JT_REF

(4)JT_RANGE

在满足单表条件基础上,支持简单多表并行的并行查询,不支持子查询,支持部分semi join查询。方案以白名单的方式支持。具体如下:

(1)单表白名单:

Select {列名| Aggregate } from table where {=|>| < |>= |<= |like |between…and| in} group by {列名} having {列名}order by {列名| Aggregate } limit x

Aggregate代表:sum min max avg count

(2)多表白名单:

Select {列名| Aggregate } from table1 table2 … where {=|>| < |>= |<= |like |between…and| in} group by {列名} having {列名}order by {列名} limit x

如果查询是系统表、临时表、非innodb表、存储过程、串行化隔离级别,并行功能也不生效。

(3)semi join查询:

部分semi join可以经过MySQL的优化器后,会变为普通的简单查询。如果执行计划最里层的表是一张外表,那么这类的SQL也可以支持并行查询。

(4)聚合的四则运算:

支持聚合操作的四则运算,例如:sum()/sum(),a*sum(),a为一个常数。

2. MySQL并行查询优化特性实现原理

在并行查询中涉及到2个关键事件:表的切分和执行计划的改造。

(1)表的切分

将扫描的数据划分成多份,让多个线程并行扫描。InnoDB引擎是索引组织表,数据以B+tree的形式存储在磁盘上。分区的逻辑为,从根节点页面出发,逐层往下扫描,当判断某一层的分支数超过了配置的线程数,则停止拆分。在实现时,实际上总共会进行两次分区。第一次是按根节点页的分支数划分分区,每个分支的最左叶子节点的记录为左下界,并将这个记录记为相邻上一个分支的右上界。通过这种方式,将B+tree划分成若干子树,每个子树就是一个扫描分区。经过第一次分区后,可能出现分区数不能充分利用多核问题,比如配置了并行扫描线程为3,第一次分区后,产生了4个分区,那么前3个分区并行做完后,第4个分区至多只有一个线程扫描,最终效果就是不能充分利用多核资源。

为解决第一次分区的负载不均衡问题,将对第4个分区进行第二次分区。第二次分区后,可以获得多个更小数据量的块,这样可以使每个线程的扫描数据更加均衡。

(2)执行计划改造

MySQL的执行计划是一棵左深树,在并行执行之前,MySQL使用一个线程递归来执行这棵左深树,然后将join结果进行sort或者aggregation。并行的目标就是使用多个线程来并行执行这颗执行计划树。将第一张non-const primary表进行拆分,每个线程的执行计划与原执行计划完全相同,只是第一张表只是该表的一部分,这样一来,每个线程就执行了一部分的执行计划,这些线程称为worker线程。执行完后,将结果交给leader汇总,然后再执行sort、aggregation或者直接发给客户端。

(3)调优步骤

使用MySQL并行查询优化特性,需要先将Patch应用到MySQL源码中,再编译和安装MySQL。具体操作步骤如下:

步骤 1:参考表4-1下载MySQL源码。

表4-1 MySQL不同版本源码下载地址

版本

下载地址

MySQL 8.0.20

https://github.com/mysql/mysql-server/archive/mysql-8.0.20.tar.gz

MySQL 8.0.25

https://github.com/mysql/mysql-server/archive/mysql-8.0.25.tar.gz

须知:

从Github下载的代码没有包含boost文件夹,您可以从MySQL官网下载含有boost的源码并从中获取boost文件夹,在编译时需要用到该boost文件夹的路径。

步骤 2:参考表4-2下载MySQL并行查询优化特性Patch包。

表4-2 MySQL不同版本Patch包说明

支持版本

Patch包

说明

MySQL 8.0.20

code-pq.patch

源代码的Patch,包含了所有并行查询功能需要的代码。

mtr-pq.patch

mysql-test中mtr测试的Patch,保证所有mtr测试都通过。

MySQL 8.0.25

code-pq-for-MySQL-8.0.25.patch

源代码的Patch,包含了所有并行查询功能需要的代码。

mtr-pq-for-MySQL-8.0.25.patch

mysql-test中mtr测试的Patch,保证所有mtr测试都通过。

步骤 3:解压源码包并进入MySQL源码目录。

tar -zxvf mysql-boost-8.0.20.tar.gz
cd mysql-8.0.20

步骤 4:在源码根目录,使用git初始化命令来建立git管理信息。

git init
git add -A
git commit -m "Initial commit"

一般情况下,系统自带git,若需要安装git,请先参见《MySQL 移植指南》中配置Yum源相关内容,再执行如下命令安装git。

yum install git

若未配置git的提交用户信息,git commit前需要先配置用户邮件及用户名称信息。

git config user.email "123@example.com"
git config user.name "123"

步骤 5:合入MySQL并行查询优化特性补丁。

此处以Patch应用到MySQL 8.0.20版本为例:

git apply --whitespace=nowarn -p1 < mtr-pq.patch
git apply --whitespace=nowarn -p1 < code-pq.patch

步骤 6:根据正常的编译安装MySQL源码的操作步骤进行MySQL的编译安装。详细信息请参见《MySQL 移植指南》。

步骤 7:通过以下两种方式中的任意一种来使用并行查询优化特性。

1)方式1:设置系统参数。

通过设置全局参数force_parallel_execute来控制是否启用并行查询;通过设置全局参数parallel_default_dop来控制使用多少线程去并行查询。上述参数在使用过程中可以随时修改,无需重启数据库。

例如,若开启并行执行,并且并发度为4:

force_parallel_execute=on;
parallel_default_dop=4;

可以根据实际情况调整parallel_cost_threshold参数的值,如果设置为0,则所有查询都会使用并行;如果设置为非0,则只有查询语句的代价估值大于该值的查询才会使用并行。

2)方式2:使用hint语法。

使用hint语法可以控制单个语句是否进行并行执行。在系统默认关闭并行执行的情况下,可以使用hint对特定的SQL进行加速,hint指定的并行度不能大于parallel_max_threads,否则将不能启用SQL语句的并行查询。相反地,也可以限制某类SQL进入并行执行。

a. SELECT /*+ PQ */ … FROM … 表示使用默认的并发度4进行并行查询。

b. SELECT /*+ PQ(8) */ … FROM … 表示使用并发度为8进行并行查询。

c. SELECT /*+ NO_PQ */ … FROM … 表示这条语句不使用并行查询。

步骤 8:通过TPC-H测试可以得到使用MySQL并行查询优化特性前后的性能提升效果,详细测试步骤请参见《TPC-H 测试指导(for MySQL)》。

从测试数据来看,采用MySQL并行查询优化特性后可以提高并行度,查询性能可以提升1倍以上(性能提升与并行度有关)。

----结束

OLTP场景调优

OLTP场景是指面向交易的在线事务处理场景,通常需要高并发、高可用、高性能和高安全性。在这种场景下,数据库的性能和响应时间对于保证应用程序的正常运行至关重要。鲲鹏BoostKit针对数据库在OLTP在线交易事务处理能力方面提供了深度优化的加速特性,并通过Patch补丁包形式开源到Gitee社区,开发者需要先将Patch应用到MySQL源码中,再编译和安装MySQL。

1. MySQL NUMA调度优化特性

在MySQL OLTP场景下,高并发情况下系统会默认将MySQL的线程在OS的CPU上进行调度,如图4-2左侧区域所示,这会导致线程频繁跨越NUMA节点进行访问,这种情况会增加CPU的开销,从而限制性能的提升。因此,需要对线程调度进行优化,以减少NUMA节点之间访问的开销,从而提高系统的性能,如图4-2右侧区域所示。

采用MySQL NUMA调度优化特性后可以对MySQL前台线程和后台线程进行精细化调度,从而提高关键线程的处理效率,减少远程访问存储的次数,从而提升整个系统的性能。

(1)对前台处理线程做动态绑定,固定NUMA CPU减少跨NUMA访问,同时需要保证CPU访问的负载必须均衡。

(2)对后台处理线程做静态绑定,固定NUMA CPU减少跨NUMA访问,提升后台线程效率。

图4-2 MySQL NUMA调度优化框架

MySQL NUMA调度优化特性以Patch补丁文件形式提供,该补丁基于MySQL 8.0.20和MySQL 8.0.25版本开发,并在Gitee社区开源,使用该特性前,需要先将Patch应用到MySQL源码中,再编译和安装MySQL。具体操作步骤如下:

步骤 1:参考表4-3下载MySQL源码,并上传至服务器“/home”目录。

表4-3 MySQL不同版本源码下载地址

版本

源码下载地址

MySQL 8.0.20

https://downloads.mysql.com/archives/get/p/23/file/mysql-boost-8.0.20.tar.gz

MySQL 8.0.25

https://downloads.mysql.com/archives/get/p/23/file/mysql-boost-8.0.25.tar.gz

步骤 2:参考表4-4下载MySQL NUMA调度优化特性Patch,并上传至MySQL源码的根目录。

表4-4 MySQL不同版本NUMA调度特性Patch下载地址

版本

NUMA调度特性Patch下载地址

MySQL 8.0.20                                    

https://gitee.com/kunpengcompute/mysql-server/releases/download/21.0.RC1.B031/0001-SCHED-AFFINITY.patch

MySQL 8.0.25

https://gitee.com/kunpengcompute/mysql-server/releases/download/KunpengBoostKit22.0.RC4.SchedAffinity/KunpengBoostKit22.0.RC4-CODE-SCHED-AFFINITY-FOR-MySQL-8.0.25.patch

步骤 3:(可选)如果没有配置Yum源,请配置Yum源,详细信息请参见配置Yum源

步骤 4:该特性实现依赖libnuma,以CentOS为例,编译MySQL前,需安装如下依赖。

yum install -y numactl numactl-devel numactl-libs

如果编译时未找到libnuma相关依赖,MySQL仍会正常编译,但本特性将无法生效。

步骤 5:以基于MySQL 8.0.20版本应用该特性为例,上传源码至“/home”目录下后,解压源码包并进入源码根目录。

cd /home
tar -zxvf mysql-boost-8.0.20.tar.gz
cd mysql-8.0.20

步骤 6:在源码根目录,使用git初始化命令来建立git管理信息。

git init
git add -A
git commit -m "Initial commit"

1)一般情况下,系统自带git,若需要安装git,请先参见《MySQL 移植指南》中配置Yum源相关内容,再执行如下命令安装git。

yum install git

2)若未配置git的提交用户信息,git commit前需要先配置用户邮件及用户名称信息。

git config user.email "123@example.com"
git config user.name "123"

步骤 7:(可选)如果没有安装dos2unix,请执行如下命令安装dos2unix。

yum install dos2unix

步骤 8:合入NUMA调度优化特性Patch补丁。

dos2unix 0001-SCHED-AFFINITY.patch
git apply --check 0001-SCHED-AFFINITY.patch
git apply --whitespace=nowarn 0001-SCHED-AFFINITY.patch

步骤 9:根据正常的编译安装MySQL源码的操作步骤进行MySQL的编译安装。详细信息请参见《MySQL 移植指南》。

步骤 10:在重新编译MySQL之后,还需额外在配置文件、启动参数或运行时配置系统变量才能生效。具体参数配置优化建议如表4-5所示。详细的参数说明请参见NUMA调度优化特性使用说明

数据库的配置文件默认路径为“/etc/my.cnf”。也可以通过以下命令行指定defaults-file选项,其中“/tmp/myconfig.txt”表示指定配置文件的路径。

/tmp/myconfig.txtmysqld --defaults-file=/tmp/myconfig.txt

表4-5 MySQL NUMA调度特性参数配置建议

参数

配置建议

sched_affinity_numa_aware

是否开启前台进程绑核,sched_affinity_foreground_thread不为空值,则sched_affinity_foreground_thread设置的CPU core(s)会根据numa node进行分组,而一个会话所在的线程只会在其中特定组中的core(s)间迁移,建议配置为ON。

sched_affinity_foreground_thread

指定MySQL前台线程(用户线程)运行的CPU core,建议前台线程和后台线程绑在不同的core上。

sched_affinity_log_writer

设置MySQL log_writer线程允许运行的CPU core(s),建议后台线程绑在同一个numa node的core上。

sched_affinity_log_flusher

设置MySQL log_flusher线程允许运行的CPU core(s) ,建议后台线程绑在同一个numa node的core上。

sched_affinity_log_write_notifier

设置MySQL log_write_notifier线程允许运行的CPU core(s) ,建议后台线程绑在同一个numa node的core上。

sched_affinity_log_flush_notifier

设置MySQL log_flush_notifier线程允许运行的CPU core(s) ,建议后台线程绑在同一个numa node的core上。

sched_affinity_log_checkpointer

设置MySQL log_checkpointer线程允许运行的CPU core(s) ,建议后台线程绑在同一个numa node的core上。

sched_affinity_purge_coordinator

设置MySQL purge_coordinator线程允许运行的CPU core(s) ,建议后台线程绑在同一个numa node的core上。

步骤 11:配置新的参数后,请重启MySQL数据库。

步骤 12:(可选)查看MySQL状态变量Sched_affinity_status、Sched_affinity_group_number和Sched_affinity_group_capacity。

开启MySQL NUMA调度优化特性后,执行如下SQL语句即可查看MySQL状态变量的信息。

show status like "%状态变量名%";

步骤 13:通过TPC-C测试可以得到使用MySQL NUMA调度优化特性前后的性能提升效果,详细测试步骤请参见《BenchMarkSQL 测试指导》。

MySQL NUMA调度优化特性可以使TPC-C综合性能提升10%,优化前后对比效果如图4-3所示。

图4-3 MySQL NUMA调度优化特性优化前后性能对比

----结束

2. MySQL线程池特性

在默认的MySQL连接器下,每个接入的连接都会分配一个线程,当连接数非常大时,线程的上下文切换及线程之间热锁的竞争将会占用大量CPU资源,导致服务性能下降。为了解决这个问题,鲲鹏BoostKit引入了线程池连接器模块,该模块基于Percona线程池,并加入了新的优化和Bug修复。

使用线程池连接器模块后,如图4-4所示,连接的建立与调度由线程池连接器接管,通过引入可动态伸缩的、多分组的线程池,使服务器即使在有大量客户端连接的情况下,也能保持最佳性能。线程池方案通过每个分组上的listener线程进行网络任务的侦听,将触发的任务放入高优先级队列或低优先级队列,由空闲的worker线程按优先级从队列中的取出任务从而进行处理。每个CPU同时处理任务个数是有限的,一般2~5个最优,从而保持稳定的业务处理能力。

图4-4 MySQL线程池特性实现原理

MySQL线程池特性以Patch补丁文件形式提供,该补丁基于MySQL 5.7.27、8.0.20、8.0.25版本开发,并在Gitee社区开源,使用该特性前,需要先将Patch应用到MySQL源码中,再编译和安装MySQL。MySQL 8.0.25版本支持可插拔动态加载线程池插件。

此处以MySQL 8.0.25版本应用该特性为例,介绍以root用户使能特性的具体操作步骤。

步骤 1:下载MySQL 8.0.25源码,上传源码至服务器“/home”目录下后,解压源码包并进入MySQL源码的根目录。
cd /home
tar -zxvf mysql-boost-8.0.25.tar.gz
cd mysql-8.0.25

步骤 2:下载MySQL线程池特性Patch,并上传至MySQL源码的根目录。

步骤 3:在源码根目录,使用git初始化命令来建立git管理信息。
git init
git add -A
git commit -m "Initial commit"

1)一般情况下,系统自带git,若需要安装git,请先参见《MySQL 移植指南》中配置Yum源相关内容,再执行如下命令安装git。

yum install git

2)若未配置git的提交用户信息,git commit前需要先配置用户邮件及用户名称信息。

git config user.email "123@example.com"
git config user.name "123"

步骤 4:合入线程池特性Patch补丁。

git apply --check KunpengBoostKit22.0.RC4-CODE-THREADPOOL-FOR-MySQL-8.0.25.patch
git apply --whitespace=nowarn KunpengBoostKit22.0.RC4-CODE-THREADPOOL-FOR-MySQL-8.0.25.patch

步骤 5:根据正常的编译安装MySQL源码的操作步骤进行MySQL的编译安装。详细信息请参见《MySQL 移植指南》。

步骤 6:在重新编译MySQL之后,可直接使用编译的后的软件目录。

在MySQL 8.0.25版本中,也可将plugin_output_directory目录下的thread_pool.so拷贝到目标MySQL的plugin_dir变量所指定的目录下,进行安装使用。MySQL 5.7.27、8.0.20版本则不支持本步骤的以下操作。

1)方式一:执行以下SQL语句,安装线程池插件。

须知:

当前方式安装线程池插件后,将立即生效。
INSTALL PLUGIN thread_pool SONAME "thread_pool.so";
INSTALL PLUGIN THREAD_POOL_GROUPS SONAME "thread_pool.so";
INSTALL PLUGIN THREAD_POOL_QUEUES SONAME "thread_pool.so";
INSTALL PLUGIN THREAD_POOL_STATS SONAME "thread_pool.so";
INSTALL PLUGIN THREAD_POOL_WAITS SONAME "thread_pool.so";

2)方式二:在MySQL配置文件中添加线程池插件配置信息。

须知:

当前方式安装线程池插件后,需要重启数据库才能生效。
plugin-load-add=thread_pool.so

安装完成后,可以通过如下SQL语句查看线程池插件是否安装成功。

show plugins;

回显信息中状态为“ACTIVE”时,表示插件已安装成功。

步骤 7:参考以下参数调优建议对MySQL线程池进行调整和优化。

数据库的配置文件默认路径为“/etc/my.cnf”。也可以通过以下命令行指定defaults-file选项,“/tmp/myconfig.txt”表示指定配置文件的路径。
/tmp/myconfig.txtmysqld --defaults-file=/tmp/myconfig.txt

参数名称

参数含义

配置建议

thread_pool_size

该参数用于设置线程池中线程组的数量。

采用默认值时表示线程组数与CPU核数一致,也可根据实际场景(例如连接数超过CPU逻辑核数,性能瓶颈不在锁争用,且CPU压不满的场景)将线程组数设置为1~3倍CPU数或者最优并发数,以获取更佳性能。

thread_pool_oversubscribe

该参数表示每个线程组的超额线程数。thread_pool_oversubscribe取默认值时,表示每个CPU核心的超额线程数,默认值为3,是一个能够充分利用CPU资源的经验值,如果设置为小于3的值,可能导致更多的睡眠和唤醒。

当线程组中活跃工作线程数超过该参数时,认为活跃工作线程过多,需要限制活跃工作线程数,建议配置最优性能时的并发数/thread_pool_size的配置值。

thread_pool_toobusy

该参数表示线程组是否过于忙碌的线程数阈值。

当线程组中活跃的工作线程数+锁或IO等待中的工作线程数>该阈值加1时,认为线程组过于忙碌,不再处理低优先级的任务,等待当前执行的任务和高优先级队列中的任务被处理,直到线程组回到非忙碌的状态,建议与thread_pool_oversubscribe配置相同的值。

thread_pool_dedicated_listener

该参数用于指定listener线程是否固定只负责epoll_wait等待网络事件。

建议设置为ON,在获取网络事件后,listener线程将所有网络事件任务放入优先队列或普通队列,然后继续进入epoll_wait等待网络事件,以获取更高效率的网络事件。

步骤 8:通过TPC-C测试可以得到使用MySQL线程池特性前后的性能提升效果,详细测试步骤请参见《BenchMarkSQL 测试指导》。

线程池连接器对于大量连接的OLTP短查询的场景将有最大帮助。在OLTP TPC-C场景下,启用线程池之前,MySQL运行10000个并发任务的性能只有原来的10%左右。启用线程池功能后,性能可维持在85%,对比效果如图4-5所示。

图4-5 开启MySQL线程池前后的性能对比

----结束

3. MySQL细粒度锁优化特性

在MySQL OLTP场景下,大量并发的DML语句(Insert, Update, Delete)会访问lock_sys->mutex全局锁保护的关键数据结构,导致锁竞争激烈,性能下降。为了解决这个问题,鲲鹏BoostKit提供了采用细粒度hash桶锁来替换全局锁的优化特性,能够减少锁冲突,提高并发度。

MySQL细粒度锁优化特性根据页的page_no计算出一个原始哈希值,能够具体定位到哈希表的某个hash_cell_t桶上。 lock_sys->mutex全局锁替换成细粒度hash桶锁。具体实现原理如下:

(1)MySQL中的每个表和行都可以看作是一种资源,事务可以请求访问资源。但是并发的事务对资源的访问可能造成冲突,因此MySQL设计了Lock-sys用于管理对表和行的访问。

(2)Lock sys中有一个关键的数据结构,这个关键的数据结构对应的是事务操作各个页的行为,Lock sys持有一把全局大锁保护这个数据结构,大量SQL语句导致的大量并发操作会争抢这一把全局大锁,锁竞争非常严重导致性能下降。

(3)针对这一问题,BoostKit做了如图4-6所示的优化,将大锁保护的数据结构拆分成若干个哈希桶组成的数据结构,把Lock sys大锁拆分成若干把细粒度锁,每个细粒度锁保护一个哈希桶,当某个事务操作某个页时,通过页的page_no定位到哈希桶,这样抢同一个细粒度锁的并发就大大降低了。

(4)举个例子,如果有6个事务,事务1操作页1,事务2操作页2……事务6操作页6,每个操作耗时t,优化前6个并发争抢一把锁,一个一个来,耗时6t,优化后,如果设置3个桶,1和4,2和5,3和6操作的页分别对应同一个哈希桶,1、2、3并发进行,然后4、5、6并发进行,耗时2t。所以鲲鹏BoostKit提供的MySQL细粒度锁优化通过减少了锁冲突,提升了并发性能。

图4-6 MySQL细粒度锁优化特性实现原理

MySQL细粒度锁优化特性以Patch补丁文件形式提供,该补丁基于MySQL 8.0.20版本开发,并在Gitee社区开源,使用该特性前,需要先将Patch应用到MySQL源码中,再编译和安装MySQL。具体操作步骤如下:

步骤 1:下载MySQL 8.0.20源码,上传源码至服务器“/home”目录下后,解压源码包并进入MySQL源码的根目录。

cd /home
tar -zxvf mysql-boost-8.0.20.tar.gz
cd mysql-8.0.20

步骤 2:下载MySQL细粒度锁优化特性Patch,并上传至MySQL源码的根目录。

步骤 3 解压源码包并进入MySQL源码目录。

tar -zxvf mysql-boost-8.0.20.tar.gz
cd mysql-8.0.20

步骤 4:在源码根目录,使用git初始化命令来建立git管理信息。

git init
git add -A
git commit -m "Initial commit"

1)一般情况下,系统自带git,若需要安装git,请先参见《MySQL 移植指南》中配置Yum源相关内容,再执行如下命令安装git。

yum install git

2)若未配置git的提交用户信息,git commit前需要先配置用户邮件及用户名称信息。

git config user.email "123@example.com"
git config user.name "123"

步骤 5:(可选)如果没有配置Yum源,请配置Yum源,详细信息请参见配置Yum源

步骤 6:(可选)如果没有安装dos2unix,请执行如下命令安装dos2unix。

yum install dos2unix

步骤 7:合入MySQL细粒度锁优化特性Patch补丁。

dos2unix 0001-SHARDED-LOCK-SYS.patch
git apply --check 0001-SHARDED-LOCK-SYS.patch
git apply --whitespace=nowarn 0001-SHARDED-LOCK-SYS.patch

步骤 8:根据正常的编译安装MySQL源码的操作步骤进行MySQL的编译安装。详细信息请参见《MySQL 移植指南》。

步骤 9:通过TPC-C测试可以得到使用MySQL细粒度锁优化特性前后的性能提升效果,详细测试步骤请参见《BenchMarkSQL 测试指导》。

MySQL细粒度锁优化特性可以使TPC-C综合性能提升10%。

图4-7 MySQL细粒度锁优化特性优化前后性能对比

----结束

4. MySQL无锁优化特性

在MySQL OLTP场景下,大量并发的DML语句(Insert, Update, Delete)会访问trx_sys全局结构体中的关键数据结构,导致出现临界区竞争和同步瓶颈。为了解决这个问题,鲲鹏BoostKit对MySQL事务管理器进行了改造,如图4-8所示,使用无锁哈希表来维护事务单元,读写场景下使用同步锁机制实现事务隔离级别和多版本控制,从而减少锁冲突,提高并发度。

由于MySQL的事务管理器使用链表、数组等数据结构维持全局的事务记录。Trx-sys是MySQL中的一个全局实例,维护事务系统的各种信息,例如rw_trx_set、rw_trx_list等事务对象的容器。这些容器本身并不是线程安全的,并且有时需要对Trx-sys里多个数据(包括这些容器和其他数据)进行同步操作,MySQL原始代码中使用Trx-sys->mutex实现这一目的。但是在高并发写的场景下,系统中存在大量读写事务相关操作,对Trx-sys->mutex的竞争开始形成吞吐量瓶颈。在Trx-sys->mutex保护的临界区中各类操作中,我们通过profiling识别出两个主要耗时操作:rw_trx_set.insert和rw_trx_set.erase。在本特性中,我们采用无锁哈希对象rw_trx_hash来替代rw_trx_set的功能,从而显著减小Trx-sys->mutex临界区耗时,缓解Trx-sys->mutex竞争,提升系统吞吐量。

图4-8 MySQL无锁优化特性实现原理

MySQL无锁优化特性以Patch补丁文件形式提供,该补丁基于MySQL 8.0.20版本开发,并在Gitee社区开源,使用该特性前,需要先将Patch应用到MySQL源码中,再编译和安装MySQL。具体操作步骤如下:

步骤 1:下载MySQL 8.0.20源码,上传源码至服务器“/home”目录下后,解压源码包并进入MySQL源码的根目录。

cd /home
tar -zxvf mysql-boost-8.0.20.tar.gz
cd mysql-8.0.20

步骤 2:下载MySQL无锁优化特性Patch,并上传至MySQL源码的根目录。

步骤 3 在源码根目录,使用git初始化命令来建立git管理信息。

git init
git add -A
git commit -m "Initial commit"

1)一般情况下,系统自带git,若需要安装git,请先参见《MySQL 移植指南》中配置Yum源相关内容,再执行如下命令安装git。

yum install git

2)若未配置git的提交用户信息,git commit前需要先配置用户邮件及用户名称信息。

git config user.email "123@example.com"
git config user.name "123"

步骤 4:(可选)如果没有配置Yum源,请配置Yum源,详细信息请参见配置Yum源

步骤 5:(可选)如果没有安装dos2unix,请执行如下命令安装dos2unix。

yum install dos2unix

步骤 6:先合入MySQL细粒度锁优化特性Patch补丁,再合入MySQL无锁优化特性Patch补丁。

本特性的前置特性为MySQL细粒度锁优化特性,所以需要先合入MySQL细粒度锁优化特性,再合入本特性。

dos2unix 0001-SHARDED-LOCK-SYS.patch
git apply --check 0001-SHARDED-LOCK-SYS.patch
git apply --whitespace=nowarn 0001-SHARDED-LOCK-SYS.patch
dos2unix 0002-LOCK-FREE-TRX-SYS.patch
git apply --check 0002-LOCK-FREE-TRX-SYS.patch
git apply --whitespace=nowarn 0002-LOCK-FREE-TRX-SYS.patch

步骤 7:根据正常的编译安装MySQL源码的操作步骤进行MySQL的编译安装。详细信息请参见《MySQL 移植指南》。

步骤 8:通过TPC-C测试可以得到使用MySQL无锁优化特性前后的性能提升效果,详细测试步骤请参见《BenchMarkSQL 测试指导》。

MySQL无锁优化特性可以使Sysbench写场景性能提升20%。

图4-9 MySQL无锁优化特性Sysbench写场景优化前后性能对比

----结束

本页内容