本文由云 + 社区发表
作者:数据库
版权声明:本文由腾讯云数据库产品团队整理,页面原始内容来自于 severalnines 英文官网,若转载请注明出处。翻译目的在于传递更多全球最新数据库领域相关信息,并不意味着腾讯云数据库产品团队赞同其观点或证实其内容的真实性。如果其他媒体、网站或其他任何形式的法律实体和个人使用,必须经过著作权人合法书面授权并自负全部法律责任。不得擅自使用腾讯云数据库团队的名义进行转载,或盗用腾讯云数据库团队名义发布信息。
原文链接:https://severalnines.com/blog/mysql-performance-benchmarking-mysql-57-vs-mysql-80
在 Oracle MySQL 团队的推动下,MySQL 8.0 发生了巨大的变化和修改。
物理文件已更改。例如,.frm, .TRG,.TRN 和 .par 不再存在。添加了大量的新特性,如通用表表达式 (Common Table Expressions CTE),窗口函数(Window Functions),不可见索引( Invisible Indexes),正则表达式(regexp)-MySQL8.0 现在已经完全支持 Unicode,且具有多字节安全特性。数据字典也发生了变化。它现在与一个事务性数据字典合并,该字典存储有关数据库对象的信息。与以前的版本不同,字典数据存储在元数据文件和非事务表中。
安全性得到了改进,caching_sha2_password 认证方式取代了之前的 mysql_native_password 认证方式,成为默认的身份验证方式。它提供了更强大的灵活性,而且也加强了安全性,即它要求必须使用安全连接或通过 RSA 密钥对实现的支持密码交换的未加密链接。
有了 MySQL 8.0 提供的所有这些很出色的功能,以及进行的增强和改进,我们团队很有兴趣来了解下 MySQL 8.0 当前版本的性能情况。特别是考虑到我们针对 MySQL 8.0.x 设计的 ClusterControl 正在进行中(请继续保持关注)。这篇博文不会讨论 MySQL8.0 的特性,但打算将其性能与 MySQL 5.7 进行对比,看看它是如何改进的。
Server Setup and Environment 服务器设置和环境
对于此基准测试,我打算使用基于 AWS EC2 最小配置的系统环境:
· 实例类型:t2.xlarge 实例
· 存储:gp2(SSD 存储,最小 100 IOPS,最大 16000 IOPS)
· 虚拟 CPU:4
· 内存:16GiB
· MySQL5.7 版本:MySQLCommunity Server (GPL) 5.7.24
· MySQL8.0 版本:MySQLCommunity Server - GPL 8.0.14
在这个基准测试中,我也针对一些参数项的取值进行了配置,它们是:
· innodb_max_dirty_pages_pct= 90 ## 这是 MySQL 8.0 中的默认值。
· innodb_max_dirty_pages_pct_lwm= 10 ## 这是 MySQL 8.0 中的默认值
· innodb_flush_neighbors=0
· innodb_buffer_pool_instances=8
· innodb_buffer_pool_size=8GiB
这里对两个版本(MySQL 5.7 和 MySQL 8.0)其余参数项的配置是参照 ClusterControl 的 my.cnf 模板进行调优。
此外,我在这里不使用 MySQL8.0 的新身份验证方式,即 caching_sha2_password 认证方式。替代的是在这两个版本中都使用 mysql_native_password,外加配置 innodb_dedicated_serve=OFF(默认值),因为 innodb_dedicated_serve 是 MySQL 8.0 的新特性。
为了简化工作,我使用 ClusterControl 配置 MySQL 5.7 Community version 节点,然后把该节点从集群中的剔除,使其成为一个单独主机,并关闭集群控制主机,使 MySQL 5.7 节点处于休眠状态 (不监控流量)。从技术上讲,MySQL 5.7 和 MySQL8.0 都是休眠节点,在节点上没有活动连接通,因此它基本上是一个纯粹的基准测试。
搜索关注 “腾讯云数据库” 官方微信,立得 10 元腾讯云无门槛代金券,体验移动端一键管理数据库,更有从初阶到高阶数据库实战教程等你来约!
Commands and Scripts Used 使用的命令和脚本
对于此任务,sysbench 用于测试和负载模拟这两个环境。以下测试中使用的命令和脚本:
sb-prepare.sh #!/bin/bash host=$1#host192.168.10.110port=3306user='sysbench'password='MysqP@55w0rd'table_size=500000rate=20ps_mode='disable'sysbench/usr/share/sysbench/oltp_read_write.lua --db-driver=mysql --threads=1--max-requests=0 --time=3600 --mysql-host=$host --mysql-user=$user--mysql-password=$password --mysql-port=$port --tables=10 --report-interval=1--skip-trx=on --table-size=$table_size --rate=$rate --db-ps-mode=$ps_modeprepare
sb-run.sh
#!/usr/bin/envbash2 host=$1port=3306user="sysbench"password="MysqP@55w0rd"table_size=100000tables=10rate=20ps_mode='disable'threads=1events=0time=5trx=100path=$PWD counter=1 echo "thread,cpu" >${host}-cpu.csv for i in 16 32 64 128 256 512 1024 2048; do threads=$i mysql -h $host -e"SHOW GLOBAL STATUS" >> $host-global-status.logtmpfile=$path/${host}-tmp${threads}touch $tmpfile/bin/bashcpu-checker.sh $tmpfile $host $threads & /usr/share/sysbench/oltp_read_write.lua--db-driver=mysql --events=$events --threads=$threads --time=$time--mysql-host=$host --mysql-user=$user --mysql-password=$password--mysql-port=$port --report-interval=1 --skip-trx=on --tables=$tables--table-size=$table_size --rate=$rate --delete_inserts=$trx --order_ranges=$trx--range_selects=on --range-size=$trx --simple_ranges=$trx --db-ps-mode=$ps_mode--mysql-ignore-errors=all run | tee -a $host-sysbench.log echo"${i},"`cat ${tmpfile} | sort -nr | head -1` >> ${host}-cpu.csvunlink ${tmpfile} mysql -h $host -e"SHOW GLOBAL STATUS" >> $host-global-status.logdone python $path/innodb-ops-parser.py $host mysql -h $host -e "SHOW GLOBALVARIABLES" >> $host-global-vars.log
因此,脚本只是准备 sbtestschema 并填充表和记录。然后,它使用
/usr/share/sysbench/oltp_read_write.lua 脚本执行读/写负载测试。该脚本转储全局状态和 MySQL 变量,收集 CPU 利用率,并解析由脚本 innodb-ops-parser.py 处理的 InnoDB 行操作。脚本根据基准测试期间收集的转储日志生成 * .csv 文件,我在这里使用 Excel 电子表格从 * .csv 文件生成图表。请检查 github 中提交的代码。
现在,让我们继续处理图表结果!
InnoDB 行操作
基本上在这里,我只提取了 InnoDB 行操作,它执行查找(读取),删除,插入和更新。当线程数量增加时,MySQL 8.0 明显优于 MySQL 5.7!在这两个版本中都没有针对配置项进行任何个性化变更,只有我统一配置的参数项。所以这两个版本中的配置几乎都使用默认值。
有趣的是,MySQL 团队关于新版本中读写性能的声明,这些图表指出了性能的显著提高,特别是在高负载服务器上。想一下 MySQL 5.7 和 MySQL 8.0 在 InnoDB 行操作上的区别,确实存在有很大的不同,特别是当线程数增加的时候。MySQL 8.0 表明,无论工作负载如何,它都能高效地运行。
事务处理
如上图所示,MySQL 8.0 的结果趋势显示出其处理事务所需的时间的巨大变化。纵轴数值越低,代表性能越好,意味着处理事务的速度更快。处理的事务统计表(第二张表)还显示出这两个版本处理事务的数量没有差异。这意味着,两个版本处理的事务数量几乎相同,但它们的完成速度不同。虽然 MySQL 5.7 在较低的负载下可以大量事务,但是实际的负载,特别是在生产中,可能会更高——尤其是在最繁忙的时期。
上面的图仍然显示的是两个版本能够处理的事务数量,只是将读和写分离开来。然而,图中实际上是存在异常值,而我没有将这些值包括在内,因为它们是这一小部分异常结果会扭曲图形。
MySQL 8.0 体现出一个很大的改进,特别是对于读取。表现在写操作的效率上,特别是对于高工作负载的服务器。在 8.0 版本中,影响 MySQL 读取性能的重要新增支持是:可以按降序 (或正向索引扫描) 创建索引的能力。以前的版本只有升序或反向索引扫描,如果需要降序,MySQL 必须执行 filesort(如果需要 filesort,需要检查 max_length_for_sort_data 的值)。当最有效的扫描顺序混合某些列的升序和其他列的降序时,降序索引还使优化器可以使用多列索引。有关详细信息,请参见此处。
CPU 资源
在此基准测试中,我决定测试一些硬件资源,尤其是 CPU 利用率。
让我先解释一下如何在基准测试中获取 CPU 使用率。在对数据库进行基准测试时,sysbench 测试结果中不包括在此过程中使用的硬件资源的统计信息。因此,我所做的是通过创建文件的方式来创建标识,通过 SSH 连接到目标主机,然后用 Linux 命令 “top” 收集数据并在测试结束前进行解析,然后再次收集。然后分析出 mysqld 进程占用最大的 CPU 使用量,最后删除该标识文件。你可以查看我在 github 上的代码。
让我们再次讨论图表结果,似乎表明 MySQL 8.0 消耗了大量的 CPU,超过 MySQL 5.7。然而,MySQL 8.0 可能必须消耗额外的 CPU 在新的变量配置上。例如,这些变量可能会影响您的 MySQL 8.0:
· innodb_log_spin_cpu_abs_lwm = 80
· innodb_log_spin_cpu_pct_hwm = 50
· innodb_log_wait_for_flush_spin_hwm = 400
· innodb_parallel_read_threads = 4
在此基准测试中,具有默认值的变量将保留其默认值。由于 MySQL 8.0 重新设计了 InnoDB 写入 REDO 日志的方式(这是一个改进),前三个变量可配置处理重做日志的使用的 CPU 资源。例如,变量 innodb_log_spin_cpu_pct_hwm 具有 CPU 亲和性,这意味着如果 mysqld 仅绑定到 4 个内核,它将忽略其他 CPU 内核。对于并行读取线程,在 MySQL 8.0 中添加了一个新变量,您可以调整要使用的线程数。
然而,我没有深入研究这个问题。可以通过利用 MySQL8.0 提供的特性来提高性能。
结论
MySQL 8.0 中有许多改进。基准测试结果显示,与 MySQL 5.7 相比,MySQL 8.0 不仅在处理读负载时,而且在读写混合的高负载下的性能都取得了令人瞩目的进步。搜索关注 “腾讯云数据库” 官方微信,立得 10 元腾讯云无门槛代金券,体验移动端一键管理数据库,更有从初阶到高阶数据库实战教程等你来约!
再来看 MySQL 8.0 的新特性,看起来它不仅利用了最新的软件技术(如 Memcached 的改进,远程管理以获得更好的 DevOps 工作性能等),还有硬件。例如,用 UTF8MB4 替换 latin1 作为默认字符编码。这意味着它需要更多的磁盘空间,因为 UTF8 在非 US-ASCII 字符上需要 2 个字节。虽然此基准测试没有利用使用 caching_sha2_password 的新身份验证方法,但它是否使用加密不会影响性能。一旦经过身份验证,它就会存储在缓存中,这意味着身份验证只进行一次。因此,如果您在客户端只使用一个用户,则不会出现问题,并且比以前的版本更安全。
由于 MySQL 利用最新的硬件和软件,因此会更改其默认变量。你可以在这里阅读更多细节。
总的来说,MySQL 8.0 的性能已经远超过 MySQL 5.7 了。
此文已由腾讯云 + 社区在各渠道发布
获取更多新鲜技术干货,可以关注我们腾讯云技术社区 - 云加社区官方号及知乎机构号