当前位置: 首页 > 科技观察

MySQL8.0.31并行索引构建特性一览

时间:2023-03-13 23:51:48 科技观察

MySQL8.0.31于2022年10月11日发布,比我预想的早了一周,先赞一下。看了releasenotes,新增内容不多。感觉MySQL8.0正式版已经进入维稳的下半场了。英语不好的同学可以点这里查看徐一涛老师对8.0.31的快速解读。另外,根据徐老师最新的推文,我还了解到MySQL对8.0版本延长了标准支持(PremierSupport)期,从原来的2023.4延长到2025.4,但是延长支持(ExtendedSupport)期没有变,它仍然是2026.4。在这次发布的8.0.31的新特性中,我注意到一个不起眼的说法:InnoDB:InnoDB现在支持并行索引构建,提高了索引构建性能。特别是,将排序的索引条目加载到B树中现在是多线程的。以前,此操作由单个线程执行。只有这么简单的一句话,没有更多的延伸解释。总之,支持并行索引构建,提高索引构建性能。要并行构建索引测试,让我们直接进行测试。使用sysbench建一个400万行记录的测试表。当只有一个主键索引时,表空间的物理文件大小为1044381696Bytes。添加测试索引后,表空间的物理文件大小增加到1434451968Bytes,增加了37.35%。mysql>CREATETABLE`t1`(`id`intNOTNULLAUTO_INCREMENT,`k`intNOTNULLDEFAULT'0',`c`char(120)NOTNULLDEFAULT'',`pad`char(60)NOTNULLDEFAULT'',PRIMARYKEY(`id`))ENGINE=InnoDBDEFAULTCHARSET=latin1;mysql>selectcount(*)fromt1;+----------+|计数(*)|+--------+|4000000|+----------+1rowinset(0.35sec)下面分别针对GreatSQL8.0.25-16和MySQL8.0.31做重建索引的测试,运行每个数据库10次,计算其每次耗时,去掉最大和最小偏差值,取剩余8次计算平均值。首先使用默认设置,最终结果如下:GreatSQL8.0.25-16MySQL8.0.31平均耗时(秒)42.52931.202可以看出使用MySQL8.0.31重建索引的效率有增加了约36%。它仍然令人印象深刻。如果在线环境中有大表,提升效果可能更可观。进一步提升索引构建效率从MySQL8.0.27开始,新增选项innodb_ddl_buffer_size作为OnlineDDL时的缓冲区(替代innodb_sort_buffer_size),提升辅助索引构建效率。这是在线DDL期间可以使用的总缓冲区。如果有多个DDL并发线程,每个线程的最大可用缓冲区是innodb_ddl_buffer_size/innodb_ddl_threads。它的默认值为1MB,这显然太低了。本例我尝试修改为64M、128MB、256MB、512MB、1GB,然后对比测试效果。自8.0.27以来还添加了选项innodb_ddl_threads。用于定义OnlineDDL的并发线程数。默认值为4,可根据实际情况调整。模式平均耗时(秒)增长比例GreatSQL8.0.25-16默认值42.529MySQL8.0.31默认值31.20236.30%64M23.44881.38%64M+8thds21.202100.59%128M22.85686.07%128M+8thds21%21907.45256256M+8THDS21.26699.99%512M22.88585.84%512M+8THDS23.22783.10%1G25.23968.51%1G+8THDS24.48673.69%可以看出,当适当增加innodb_ddl_buffer_size和innodb_ddl_threads的值时,重建索引的耗时明显减少。在最好的情况下,索引重建的效率可以提高一倍;然而,它的效率并不随着值的增加而线性增加。看来线上生产环境需要根据实测情况进行调整。循环自动测试的shell脚本也顺便分享一下:#!/bin/bashdb=MySQL#Setdifferentddlbuffersizefordbpin641282565121024doexec3>&14>&21>>parallel-index-build-${dbp}m.log2>&1#循环10次foriin$(seq110)doecho"$dbcycle$i"mysql-N-s-q-f-S./$db/mysql.sock-e"setglobalinnodb_ddl_buffer_size=$dbp*1024*1024"test>/dev/null2>&1mysql-f-S./$db/mysql.sock-e"select@@global.innodb_ddl_buffer_size"测试mysql-N-s-q-f-S./$db/mysql.sock-e“改变表t1删除索引i1,删除索引i2;”test>/dev/null2>&1sleep5timemysql-N-s-q-f-S./$db/mysql.sock-e"altertablet1添加索引i1(k),添加索引i2(pad);"测试echo""echo""sleep5done#Adjustddlthreads=8exec3>&14>&21>>parallel-index-build-${dbp}m-8th.log2>&1foriin$(seq110)做echo"$dbcycle$i"mysql-N-s-q-f-S./$db/mysql.sock-e"setglobalinnodb_ddl_threads=8"test>/dev/null2>&1mysql-f-S./$db/我的ql.sock-e"select@@global.innodb_ddl_threads"testmysql-N-s-q-f-S./$db/mysql.sock-e"altertablet1dropindexi1,dropindexi2;"test>/dev/null2>&1sleep5timemysql-N-s-q-f-S./$db/mysql.sock-e"altertablet1添加索引i1(k),添加索引i2(pad);"测试echo""echo""sleep5done#restoreddlthreads=4mysql-N-s-q-f-S./$db/mysql.sock-e"setglobalinnodb_ddl_threads=4"test>/dev/null2>&1mysql-f-S./$db/mysql.sock-e"select@@global.innodb_ddl_threads"testdone并行建索引的限制最后我们看一下并行建索引的新特性:virtual不支持列(virtualcolumns)不支持全文索引(full-textindex)。不支持空间索引。期待MySQL8.0未来版本中更多实用的新特性。延展阅读MySQL8.0.31的变化,https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-31.htmlConfiguringParallelThreadsforOnlineDDLOperations,https://dev.mysql.com/doc/refman/8.0/en/online-ddl-parallel-thread-configuration.html在线DDL内存管理,https://dev.mysql.com/doc/refman/8.0/en/online-ddl-内存管理.html

最新推荐
猜你喜欢