专栏首页腾讯云数据库专家服务MySQL 8.0 新特性:Resource Group 与写入性能优化实战
原创

MySQL 8.0 新特性:Resource Group 与写入性能优化实战

前言

离 8.0 正式发布已经有一段时间了,随着小版本的不断迭代,MySQL 8.0 也加入了很多有意思/有价值的特性,例如原子 DDL,WriteSet复制,二级密码等,在专栏中也有非常多的介绍。本文介绍的特性是 Resource Group,即资源组,主要用来调度 MySQL 的资源用,其实是一个兼顾了实用性和技巧性的功能,且刚好能解决 MySQL 8.0 对写入性能的一个“负优化”。

资源组

简介

MySQL 本身是一个单进程多线程的架构,除了处理用户连接的线程外,还有很多的后台线程,例如 flush_thread,purge_thread,read_thread,write_thread 等。在旧版本中,这些线程都是同样的优先级,共享所有的 CPU 资源,也无法像 cgroup 一样把一些线程绑定到固定的核心上,独占一部分 CPU 资源。

而面对实际业务的时候,根据业务的特点来调度资源,应对不同的业务高峰期是常用的手段之一,比如业务高峰期来临之前,让业务相关的线程独占一部分 CPU 资源,提高业务处理能力。

在 MySQL 8.0 中就可以使用资源组来满足这一类需求。使用方式也比较简单:创建一个资源组,然后把线程绑定到对应的资源组即可。

如何使用

创建资源组的语法如下:

CREATE RESOURCE GROUP group_name
    TYPE = {SYSTEM|USER}
    [VCPU [=] vcpu_spec [, vcpu_spec] ...]
    [THREAD_PRIORITY [=] N]
    [ENABLE|DISABLE]

vcpu_spec: {N | M - N}
  • TYPE:设置资源组的类型,MySQL 的后台线程只能绑定到 SYSTEM 的资源组,用户线程只能绑定到 USER。
  • VCPU:用逗号分隔的序号列表,或者是用类似于 1-10 的范围形式。
  • THREAD_PRIORITY:设置优先级,数字越小,优先级越高。

绑定资源组的语法如下:

 SET RESOURCE GROUP group_name FOR thread_id1,thread_id2 ......

绑定是即时生效的,命令执行完之后立刻就能看到效果。

写入性能优化

简介

这个问题实际上是跑 8.0 基准测试的时候发现的:同配置的情况下,8.0 的写入性能相比 5.7 是下降的,而且下降的幅度并不能当做随机误差来看待。因此研究了一下 8.0 的变化,发现有一项优化:把 log_writer 和 log_flusher 拆分成了单独的线程。使用双 1 的事务提交策略时,每次提交事务都会需要写 log,是不是这两个线程单独拆出来之后,因为抢不到 CPU 资源影响到了写入性能?

测试一下

这次测试的环境:

  • 腾讯云的高 IO 型 CVM,本地 NVME 磁盘作为存储,16 核心,64GB 内存,debian 9.13。
  • MySQL 8.0.22,sysbench-1.0.20。
  • 事务提交策略为双 1,数据量为 5 张表,每张表 1000 万行数据,可以全部加载到 buffer_pool。

为了使用资源组,需要先在系统层配置一下环境:

apt-get install libcap2-bin
setcap cap_sys_nice+ep /usr/sbin/mysqld
getcap /usr/sbin/mysqld
显示:/usr/sbin/mysqld = cap_sys_nice+ep 即可

重启 MySQL 之后,预热好数据,开启 write_only 的测试,然后再设置资源组:

CREATE RESOURCE GROUP bg_thread1 TYPE = system VCPU = 0  THREAD_PRIORITY = -20;
CREATE RESOURCE GROUP bg_thread2 TYPE = system VCPU = 1  THREAD_PRIORITY = -20;
CREATE RESOURCE GROUP other_thread TYPE = system VCPU = 2-15  THREAD_PRIORITY = 0;

通过系统表找到 log_writer 和 log_flusher 的 thread_id,以及测试线程的 ID:

mysql> select THREAD_ID,NAME from performance_schema.threads;
+-----------+---------------------------------------------+
| THREAD_ID | NAME                                        |
+-----------+---------------------------------------------+
|         1 | thread/sql/main                             |
|       783 | thread/sql/one_connection                   |
|         3 | thread/innodb/io_ibuf_thread                |
|         4 | thread/innodb/io_log_thread                 |
 |        45 | thread/innodb/log_checkpointer_thread       |
|        46 | thread/innodb/log_flush_notifier_thread     |
|        47 | thread/innodb/log_flusher_thread            |
|        48 | thread/innodb/log_write_notifier_thread     |
|        49 | thread/innodb/log_writer_thread             |
|        50 | thread/innodb/srv_lock_timeout_thread       |
|        51 | thread/innodb/srv_error_monitor_thread      |
|        52 | thread/innodb/srv_monitor_thread            |
......

thread/sql/one_connection 就是用户连接,log_flusher_thread 和 log_writer_thread 就是要找的系统内部线程。

由于测试的用户连接过多,可以写个简单的脚本生成用户线程的绑定语句:

#!/bin/bash

ID_LIST=`mysql -Ne "select concat(THREAD_ID,',') from performance_schema.threads where name = 'thread/sql/one_connection';"`

echo "SET RESOURCE GROUP other_thread FOR" ${ID_LIST%,*}";"

绑定系统内部线程的语句如下:

SET RESOURCE GROUP bg_thread1 FOR 47;
SET RESOURCE GROUP bg_thread2 FOR 49;

执行完毕之后,sysbench 输出的结果如下:

[ 380s ] thds: 48 tps: 7329.74 qps: 29318.27 (r/w/o: 0.00/29318.27/0.00) lat (ms,95%): 10.46 err/s: 0.00 reconn/s: 0.00
[ 390s ] thds: 48 tps: 7385.89 qps: 29543.85 (r/w/o: 0.00/29543.85/0.00) lat (ms,95%): 10.46 err/s: 0.00 reconn/s: 0.00
[ 400s ] thds: 48 tps: 7245.54 qps: 28982.46 (r/w/o: 0.00/28982.46/0.00) lat (ms,95%): 10.65 err/s: 0.00 reconn/s: 0.00
[ 410s ] thds: 48 tps: 7326.35 qps: 29305.91 (r/w/o: 0.00/29305.91/0.00) lat (ms,95%): 10.65 err/s: 0.00 reconn/s: 0.00
[ 420s ] thds: 48 tps: 7315.21 qps: 29260.75 (r/w/o: 0.00/29260.75/0.00) lat (ms,95%): 10.46 err/s: 0.00 reconn/s: 0.00
[ 430s ] thds: 48 tps: 7305.01 qps: 29221.02 (r/w/o: 0.00/29221.02/0.00) lat (ms,95%): 10.65 err/s: 0.00 reconn/s: 0.00
[ 440s ] thds: 48 tps: 7352.34 qps: 29408.77 (r/w/o: 0.00/29408.77/0.00) lat (ms,95%): 10.27 err/s: 0.00 reconn/s: 0.00
[ 450s ] thds: 48 tps: 7356.35 qps: 29424.11 (r/w/o: 0.00/29424.11/0.00) lat (ms,95%): 10.46 err/s: 0.00 reconn/s: 0.00
[ 460s ] thds: 48 tps: 7269.48 qps: 29079.13 (r/w/o: 0.00/29079.13/0.00) lat (ms,95%): 10.65 err/s: 0.00 reconn/s: 0.00
[ 470s ] thds: 48 tps: 7295.22 qps: 29179.68 (r/w/o: 0.00/29179.58/0.10) lat (ms,95%): 10.65 err/s: 0.00 reconn/s: 0.00
[ 480s ] thds: 48 tps: 7258.87 qps: 29037.09 (r/w/o: 0.00/29036.89/0.20) lat (ms,95%): 10.65 err/s: 0.00 reconn/s: 0.00
[ 490s ] thds: 48 tps: 7312.73 qps: 29248.64 (r/w/o: 0.00/29248.64/0.00) lat (ms,95%): 10.65 err/s: 0.00 reconn/s: 0.00
[ 500s ] thds: 48 tps: 7351.52 qps: 29408.80 (r/w/o: 0.00/29408.80/0.00) lat (ms,95%): 10.65 err/s: 0.00 reconn/s: 0.00
[ 510s ] thds: 48 tps: 8298.04 qps: 33191.17 (r/w/o: 0.00/33190.97/0.20) lat (ms,95%): 8.43 err/s: 0.00 reconn/s: 0.00
[ 520s ] thds: 48 tps: 8386.27 qps: 33543.08 (r/w/o: 0.00/33543.08/0.00) lat (ms,95%): 8.58 err/s: 0.00 reconn/s: 0.00
[ 530s ] thds: 48 tps: 8379.00 qps: 33516.81 (r/w/o: 0.00/33516.71/0.10) lat (ms,95%): 8.43 err/s: 0.00 reconn/s: 0.00
[ 540s ] thds: 48 tps: 8340.53 qps: 33363.82 (r/w/o: 0.00/33363.82/0.00) lat (ms,95%): 8.74 err/s: 0.00 reconn/s: 0.00
[ 550s ] thds: 48 tps: 8401.08 qps: 33603.44 (r/w/o: 0.00/33603.44/0.00) lat (ms,95%): 8.58 err/s: 0.00 reconn/s: 0.00
[ 560s ] thds: 48 tps: 8290.48 qps: 33163.43 (r/w/o: 0.00/33163.13/0.30) lat (ms,95%): 8.74 err/s: 0.00 reconn/s: 0.00
[ 570s ] thds: 48 tps: 8263.53 qps: 33051.53 (r/w/o: 0.00/33051.43/0.10) lat (ms,95%): 8.58 err/s: 0.00 reconn/s: 0.00

可以看到从 510s 之后,写入的 QPS 发生了比较明显的变化,提升了约 4000,大概 13%。

而对比一下改之前和改之后的 CPU 使用情况:

修改前的 top
修改后的 top

可以看到,绑定了 CPU 之后,0 和 1 号线程的负载情况发生了明显的变化,说明改动已经即时生效,两个内部线程独占了两个 CPU 核心。

总结一下

当然,这个写入的问题在之后的版本中应该会有官方修复方案,但是从这个简单的写入性能优化中,也可以看到资源组的实际效果还是比较明显的,当存在一些特殊需求,需要倾斜一部分资源的时候,合理的使用资源组这个功能可以最大限度的保障业务的稳定与高效。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • MySQL8.0新特性集锦

    在8.0版本之前,默认字符集为latin1,utf8指向的是utf8mb3,8.0版本默认字符集为utf8mb4,utf8默认指向的也是utf8mb4。

    MySQL技术
  • MySQL 8.0与MariaDB 10.4,谁更易于填坑补锅?

    贺春旸,凡普金科DBA团队负责人,《MySQL管理之道:性能调优、高可用与监控》第一、二版作者,曾任职于中国移动飞信、安卓机锋网。致力于MariaDB、Mong...

    jeanron100
  • MySQL resource group详解

    提示:公众号展示代码会自动折行,建议横屏阅读 「第一部分 资源组简介」 MySQL-8.0中新增了resource group资源组的功能。MySQL资源...

    腾讯数据库技术
  • 嗦一嗦 MySQL 8.0的新特性(一)

    导读 MySQL8.0 GA版本发布了,展现了众多新特性,本系列译文将整理为3篇,为大家介绍升级的部分新特性。 本文为第1篇,重点为大家介绍SQL、JSON上...

    wubx
  • MySQL 8.0新特性:降序索引

    上两篇文章分别介绍了MySQL8.0的相关的新特性《MySQL 8.0新特性:隐藏索引》和《MySQL 8.0新特性:隐藏字段》,本文继续介绍MySQL8.0的...

    SEian.G
  • MySQL 8.0 版本功能变更介绍

    作者介绍:朱强,腾讯云数据库高级工程师,主要负责腾讯云数据库MySQL的开发和运营,曾就职于华为和网宿,在存储、文件系统开发有丰富经验。

    腾讯云数据库 TencentDB
  • MySQL 8 第一个正式版发布:更好的性能

    MySQL 8.0 系列的首个正式版 8.0.11 已发布,官方表示 MySQL 8 要比 MySQL 5.7 快 2 倍,还带来了大量的改进和更快的性能!

    Debian中国
  • 手把手搭建生产可用的Nacos集群

    本节详细探讨如何搭建一个生产可用的Nacos集群。讨论的内容主要包括:使用MySQL作为存储持久化数据,以及如何搭建Nacos集群。

    用户1516716
  • 超越官方版本的MySQL8.0来了

    7月8日,拥有60+全新特性,性能全面超越官方版本的腾讯云MySQL 8.0正式发布。在全新引擎的驱动下,腾讯云MySQL8.0数据库通过优化锁系统,事务系统...

    腾讯云数据库 TencentDB
  • MySQL性能基准测试对比:5.7 VS 8.0

    版权声明:本文由腾讯云数据库产品团队整理,页面原始内容来自于severalnines英文官网,若转载请注明出处。翻译目的在于传递更多全球最新数据库领域相关信息,...

    腾讯云数据库 TencentDB
  • MySQL企业版线上专场 | 三合一精华版

    2020年4月7~9日,MySQL团队与3306π社区联合举办大型线上活动,为广大MySQL的爱好者和使用者带来一场MySQL技术盛宴。活动期间,叶金荣老师每晚...

    MySQLSE
  • MySQL 8.0.11 (2018-04-19, General Availability)

    仅支持通过使用 in-place 方式从 MySQL 5.7 升级到 MySQL 8.0 升级; 不支持从 MySQL 8.0 降级到 MySQL 5....

    MySQL轻松学
  • 前沿观察 | MySQL性能基准测试对比:5.7 VS 8.0

    ? 点小蓝字加关注! 版权声明:本文由腾讯云数据库产品团队整理,页面原始内容来自于severalnines英文官网,若转载请注明出处。翻译目的在于传递更多全球...

    腾讯云数据库 TencentDB
  • MySQL8.03 RC 已发布

    The MySQL 8.0.3 Release Candidate is available

    wubx
  • 演讲实录:MySQL 8.0 中的复制技术

    在近期的第七届数据技术嘉年华上,甲骨文MySQL研发工程师宋利兵做了“MySQL-8.0中的复制技术”为主题的演讲,介绍了MySQL-8.0中异步复制和Grou...

    数据和云
  • MySQL8.03 RC 已发布

    MySQL开发团队非常高兴地宣布,第一个8.0 RC版本8.0.3现已可在dev.mysql.com下载(相对于8.0.2,8.0.1和8.0.0,8.0.3添...

    wubx
  • Python第十二章-多进程和多线程02-多线程

    MySQL被Sun收购后,搞了个过渡的6.0版本,没多久就下线了(有一次居然听说有人在线上用6.0版本,我惊得下巴都掉了)。被Oracle收购后,终于迎来了像样...

    不会飞的小鸟
  • 新来的领导下令升级 MySQL 8.0,完美掉坑…

    那既然隐式排序为什么还要保留Order by?隐式排序的目的又是什么呢?让我们一起来看看。

    Java技术栈
  • MySQL 8.0复制新特性

    截止2017年8月,MySQL 8.0 仍然是 beta 版本,复制功能有一些很棒的改进。最初,这些改进是为组复制(GR)开发的,但由于 GR 在底层使用常规复...

    wubx

扫码关注云+社区

领取腾讯云代金券