计算机是一种实验的科学
性能优化是实战的艺术
蒸汽机的改进不是一蹴而就的,MySQL性能的改进也是贯穿整个MySQL发展史的。MySQL之父Monty在1981年写了MySQL的第一行代码以后,在开源的帮助下MySQL成长为目前最流行的开源数据库,同样其也凝聚了非常多的开发者、DBA、工程师的心血。
本文选自《千金良方:MySQL性能优化金字塔法则》一书,将从整体上介绍性能调优的几个方面,并借用“金字塔”理论依次介绍了硬件和系统调优、MySQL 调优以及架构调优的一些原则和方法。
本文介绍的三种调优方法是按照金字塔的调优顺序排列的,如下图所示。一般来说,自底向上调优的效果是成反比的,而越往下层调优效果越好,但是难度也越大。
按照依赖关系(架构调优要求DBA对MySQL本身有一定的了解,MySQL调优依赖于系统和硬件的相关知识)和对专业知识要求的难易程度,我们按照自上而下的顺序(硬件和系统调优、MySQL调优、架构调优)描述案例,而DBA在实际应用过程中接触和优化的顺序其实是相反的。在进行优化时,首先需要关注和优化的应该是架构,如果架构不合理,那么DBA能做的事情其实是比较有限的。
对于架构调优,在系统设计时首先需要充分考虑业务的实际情况,是否可以把不适合数据库做的事情放到数据仓库、搜索引擎或者缓存中去做;然后考虑写的并发量有多大,是否需要采用分布式;最后考虑读的压力是否很大,是否需要读写分离。对于核心应用或者金融类的应用,需要额外考虑数据安全因素,数据是否不允许丢失,是否需要采用Galera或者MGR。
对于MySQL调优,需要确认业务表结构设计是否合理,SQL语句优化是否足够,该添加的索引是否都添加了,是否可以剔除多余的索引,数据库的参数优化是否足够。
最后确定系统、硬件有哪些地方需要优化,系统瓶颈在哪里,哪些系统参数需要调整优化,进程资源限制是否提到足够高;在硬件方面是否需要更换为具有更高I/O性能的存储硬件,是否需要升级内存、CPU、网络等。如果在设计之初架构就不合理,比如没有进行读写分离,那么后期的MySQL和硬件、系统优化的成本就会很高,并且还不一定能最终解决问题。如果业务性能的瓶颈是由于索引等MySQL层的优化不够导致的,那么即使配置再高性能的I/O存储硬件或者CPU也无法支撑业务的全表扫描。
对于硬件和系统的调优需要在系统上线前,甚至在数据库选型阶段和设计阶段就需要考虑起来,如果等验证测试和上线以后再去考虑提升硬件性能或者调整系统参数,要做的工作就太多了。
▌硬件优化
更高频率的 CPU 能让复杂的SQL语句在MySQL上运行的速度更快;更大的内存能让更多的热点数据缓存在内存中,使得并发效率更高;更快的存储系统能让 MySQL 及时存取数据,提升客户端的响应效率;更高的网络带宽和更低的网络延迟能让 MySQL 提供更大的吞吐率。硬件优化对数据库效率的提升非常关键。
数据库以前都运行在小型机上,资源相对较为充足,之后迁移到 x86 物理机上,大多数时候也能独占整个物理机资源,后来由于互联网的流行,虚拟化、云化带来了非常大的灵活性,但是对于数据库来说,资源缩减得非常多,而 MySQL 越来越“应用化”,一个开发人员或者系统管理员就可以将其部署起来,压力不大时使用起来也不会有问题。这样带来的问题是,其他的业务压力或者I/O压力可能就让数据库变得很缓慢,甚至一条复杂的 SQL语句或者一个SQL语句执行计划走错都会让数据库响应时间增加几十倍。要达到小型机 存储的数据库时代的稳定性和效率,对底层硬件的选型、验证、资源隔离以及优化就必不可少。CPU、内存、网络受限于企业环境,可调整和优化的空间比较小,而数据库最关键和最值得关注的就是I/O存储系统的优化,是选择普通的机械磁盘还是Flash介质存储,RAID怎么做、怎么分区,是write back还是write through,对数据库的影响非常大。
▌系统优化
由于硬件资源的限制,也为了让系统中运行的各个组件能均衡地使用硬件资源,Linux系统设计和实现了各种资源使用策略。数据库的操作系统优化从某种程度来说就是理解操作系统的资源使用策略,充分让数据库使用更多的硬件资源,发挥硬件性能。例如,为了避免内存空间使用不足而发生崩溃,Linux系统设计了swap(交换区),并且提供了一个swappiness参数,用来设置在什么情况下使用swap。当该参数设置为0时,系统在几乎没有内存的情况下才会使用swap;当其设置为100时,进程申请的内存很快就会被交换出去,在数据库场景下,应该将swappiness设置得尽可能小,以保证热点数据尽量保留在物理内存中。
▌参数调优
参数调优的目的就在于如何适配硬件和系统,在MySQL的服务器层和InnoDB层最大程度地发挥底层的性能,保证业务系统高效。
在Oracle占据大部分数据库市场的年代,多个DBA会共同维护一套Oracle数据库,这套Oracle数据库承载着多个业务系统,多个Oracle业务系统之间的参数为了适配业务或者底层硬件,在配置之间不尽相同。在MySQL在互联网上大放异彩的时代,一个DBA管理着几套甚至几十套MySQL数据库,越来越多的MySQL DBA发现,与其为每个业务系统进行特殊的参数调优,还不如确定一个能适配80%业务场景的数据库版本和数据库配置模板,并且对应地规范硬件和系统配置,保证多个MySQL系统的标准化和一致性。其实理由很简单,当规模化以后,必须要进行标准化(比如之前一个人就可以做一双皮鞋,为每个人定制,价格和成本相对比较高;如果一个工厂每天要做一万双皮鞋,就不可能为每个人定制了,而必须标准化,通过流水线提升效率),避免排查问题、升级、运维等工作不可控。比如5个不标准的MySQL系统升级到新版本需要准备5套方案,而5个标准的MySQL系统升级到新版本只需要准备1套方案,并且还可以自动化实现。
当然,并不是要非黑即白地去理解这个问题,也不是说MySQL的参数调优就不需要关注了。笔者曾经遇到过一个128GB内存的服务器,由于MySQL的buffer_pool参数只配置为128MB导致性能特别差的案例。随着硬件性能的提升、MySQL数据库版本的升级、DBA经验的提升和DBA在实际硬件上的并发测试,你可能会发现有更加适合对应硬件和操作系统的MySQL配置参数值,当验证通过后,就可以统一调整升级了。这里有一个小技巧:将[mysqld]的配置写在最后。由于写在后面的配置会直接覆盖前面的配置,如果要对MySQL服务器配置进行参数调整,那么直接在结尾添加参数就可以了,自动化程序修改起来非常方便,不容易出错。示例如下:
代码语言:javascript复制[client]
port=3306
...
[mysqldump]
default-character-set = utf8
...
[mysql]
no-auto-rehash
...
[mysqld]
default-storage-engine = INNODB
...
# 保证[mysqld]是最后一个MySQL配置组,所有需要调整的参数都添加在此位置后(利用mysqld配置项后面的覆盖前面的特性)
...
innodb_log_buffer_size = 128M
▌SQL/索引调优
SQL/索引调优要求DBA对业务和数据流非常清楚。在阿里巴巴内部,有三分之二的DBA是业务DBA,从业务需求讨论到表结构审核、SQL语句审核、上线、索引更新、版本迭代升级,甚至哪些数据应该放到非关系型数据库中,哪些数据放到数据仓库、搜索引擎或者缓存中,都需要这些DBA跟踪和复审。他们甚至可以称为数据架构师(Data Architecher)。开发人员的更替或者业务的迭代导致一些业务逻辑和代码很难跟踪,但是没关系,DBA熟悉每个表、每个字段的含义,他们跟踪业务模块关系、更新迭代的缘由、业务高峰/低谷时哪里最耗资源、是否还有优化空间等。如果这些数据模型都在的话,就很方便对业务逻辑和代码诊断和修改了。
如文章开头的图所示,金字塔的底部是架构调优,采用更适合业务场景的架构能最大程度地提升系统的扩展性和可用性。在设计中进行垂直拆分能尽量解耦应用的依赖,对读压力比较大的业务进行读写分离能保证读性能线性扩展,而对于读写并发压力比较大的业务在MySQL上也有采用读写分离的大量案例。
作为金字塔的底部,在底层硬件系统、SQL语句和参数都基本定型的情况下,单个MySQL数据库能提供的性能、扩展性等就基本定型了。但是通过架构设计和优化,却能承载几倍、几十倍甚至百倍于单个MySQL数据库能力的业务请求能力。
▌《千金良方:MySQL性能优化金字塔法则》
李春 罗小波 董红禹 著
MySQL的火热程度有目共睹,如果需要了解MySQL的安装、启动、配置等基础知识,市面上相关的书籍已是汗牛充栋。本书则尽量深入细致地介绍MySQL的基本原理,以及性能优化的实际案例。
无论你是MySQL初学者,还是专门从事MySQL工作的开发人员和运维人员,或者是资深的MySQL DBA,都值得一读!
▶ 关 于 作 者
李春
原阿里巴巴MySQL DBA团队技术Leader,全程参与阿里数据库架构从Oracle迁移到MySQL的过程,参与分布式中间件Cobar设计。现为沃趣科技联合创始人&首席架构师,负责MySQL、基础软件及部分关键组件的技术选型、风险评估等。
罗小波
沃趣科技高级数据库工程师,主要负责MySQL产品的数据库支撑与售后二线支撑。曾参与版本发布系统、轻量级监控系统、运维管理平台、数据库管理平台的设计与编写,熟悉MySQL体系结构,Innodb存储引擎,喜好专研开源技术,多次在公开场合做过线下线上数据库专题分享,发表过多篇与数据库相关的研究文章。
董红禹
沃趣科技MySQL DBA , 为过多家大型企业进行过故障解决、架构设计、性能优化,例如中信证券、浙江农信、陕西农信、邮储银行等。规划并实施了浙江农信互联网核心金融平台。
▶ 本 书 结 构
基 础 篇
第1章 MYSQL初始化安装、简单安全加固/ 3
第2章 MYSQL常用的两种升级方法/ 21
第3章 MYSQL体系结构/ 41
第4章 PERFORMANCE_SCHEMA初相识/ 56
第5章 PERFORMANCE_SCHEMA配置详解/ 66
第6章 PERFORMANCE_SCHEMA应用示例荟萃/ 93
第7章 SYS系统库初相识/ 126
第8章 SYS系统库配置表/ 132
第9章 SYS系统库应用示例荟萃/ 138
第10章 INFORMATION_SCHEMA初相识/ 151
第11章 INFORMATION_SCHEMA应用示例荟萃/ 161
第12章 MYSQL系统库之权限系统表/ 177
第13章 MYSQL系统库之访问权限控制系统/ 184
第14章 MYSQL系统库之统计信息表/ 200
第15章 MYSQL系统库之复制信息表/ 206
第16章 MYSQL系统库之日志记录表/ 218
第17章 MYSQL系统库应用示例荟萃/ 228
第18章 复制技术的演进/ 245
第19章 事务概念基础/ 263
第20章 INNODB锁/ 280
第21章 SQL优化/ 299
第22章 MYSQL读写扩展/ 308
案 例 篇
第23章 性能测试指标和相关术语/ 317
第24章 历史问题诊断和现场故障分析/ 322
第25章 性能调优金字塔/ 326
第26章 SQL语句执行慢真假难辨/ 330
第27章 如何避免三天两头换硬盘、内存、主板/ 338
第28章 每隔45天的MYSQL性能低谷/ 342
第29章 MYSQL连接无法自动释放/ 359
第30章 查询MYSQL偶尔比较慢/ 363
第31章 MYSQL最多只允许214个连接/ 367
第32章 MYSQL挂起诊断思路/ 375
第33章 硬件和系统调优/ 378
第34章 并发删除数据造成死锁/ 387
第35章 删除不存在的数据造成死锁/ 391
第36章 插入意向锁死锁/ 394
第37章 分页查询优化/ 398
第38章 子查询优化——子查询转换为连接/ 400
第39章 子查询优化——使用DELETE删除数据/ 403
工 具 篇
第40章 硬件规格常用查看命令详解/ 407
第41章 系统负载常用查看命令详解/ 433
第42章 FIO存储性能压测/ 469
第43章 HAMMERDB在线事务处理测试/ 477
第44章 SYSBENCH数据库压测工具/ 493
第45章 MYSQLADMIN和INNOTOP工具详解/ 506
第46章 利用PROMETHEUS GRAFANA 搭建炫酷的MYSQL监控平台/ 524
第47章 PERCONA TOOLKIT常用工具详解/ 538
第48章 MYSQL主流备份工具之MYSQLDUMP详解/ 598
第49章 MYSQL主流备份工具之XTRABACKUP详解/ 624
第50章 MYSQL主流备份工具之MYDUMPER详解/ 662
第51章 MYSQL主流闪回工具详解/ 675