注:本篇是《高性能Mysql》第三版的读书笔记
优化服务器的设置
优化服务器的配置一般是在schema和索引优化之后进行的。大多数的默认配置已经趋近于最优设置了。
学习创建一个好的配置是从理解MySQL内核和行为开始 mysql --verbose --help |grep -A 1 'Default options' 查配置文件位置。
默认的配置如果够用就别乱改。
分为服务器级别的(全局变量),连接变量(会话作用域) 剩下的一些是对象级的。
对于一些全局变量,你给他分配太大内存,而又不用就么啥意思了。
例如:对于sort_buffer_size这个排序用的内存设置不应该设置太大,比如40M 每个连接都会使用40M,那么这个值要是被调大会导致服务器崩掉。
目前接触的MySQL的项目使用的都是innodb存储引擎。
需要配置合理的缓冲池(buffer pool)和日志文件(log file)
比较流行的做法是将缓冲池的大小设置为内存的75%
应该从服务器的内存总量开始计算,减去操作系统占用和其他进程占用。减去一下MySQL自身查询需要的缓存,减去日志文件的内存,减去MySQL中其他配置的内存占用,比如query_cache查询缓存、 一般启动日志文件并禁用查询缓存。
InnoDB缓冲池
innodb不仅仅缓存索引,还会缓存行的数据、自适应哈希索引,插入缓冲,锁、和其他内部数据结构。
如果缓冲池存放了大量数据的时候,重启预热也需要很长时间。
innodb_buffer_pool_size设置缓冲池大小。
Innodb_buffer_pool_size = 系统可用内存 - 系统正常运行内存 - (峰值时的连接数 * 每个连接需要的内存)
innodb_log_file_size 日志文件大小,存储事务持久话日志用的,这个设置16M-64M 就差不多了,默认一秒刷到磁盘的话。
线程缓存
线程缓存保存那些目前没有与连接关联但是准备为后面新的连接服务的线程。当一个新连接创建的时候,先去线程缓存中取线程。
表缓存
表缓存分为两部分:打开表的缓存,表定义缓存。表定义被所有连接共享是全局的。
innodb数据字典
innodb有自己的表缓存,可以称为表定义缓存或者数据字典,当innodb打开一张表,就增加了一个对应的对象到数据字典,每张表可能占4k或者更多内存,即使关闭也不会移除。
配置MySQL的IO行为
innodb的IO配置
innodb使用日志来减少提交事务时的开销,因为日志中记录了事务,就无须在每个事务提交时吧缓冲池的脏块刷新到磁盘中。es跟innodb存储引擎的事务日志一样,写入到日志文件,并有线程异步将日志刷新到数据文件中。只要是写到日志文件中的事务,即使断电也无所谓。
日志文件是环形方式写的,当写到尾部会从头开始写,但是不会覆盖掉还没有应用到数据文件中的日志记录。
日志文件的存在把随机IO转成了顺序IO
当innodb变更任何数据时,会写一条变更记录到内存日志缓存区。在缓冲区满的时候,事务提交的时候,或者每一秒钟,innodb会刷写缓冲区的内容到磁盘日志文件。大事务可以通过增大缓冲区大小来提高IO效率。innodb_log_buffer_size(1-8M)
innodb_flush_log_at_trx_commit 设置日志提交的频率程度。
innodb把数据保存在表空间内,本质上是一个由一个或者多个磁盘文件组成的虚拟文件系统。
innodb使用双写缓冲来避免页没写完整所导致的数据损坏。双写缓冲是表空间一个特殊的保留区域。当innodb从缓冲池刷新页面到磁盘时,首先把他们写到双写缓冲,然后再把它们写到其所属的数据区域中。
Innodb并发配置
innodb_thread_sleep_delay设置一次性可以有多少线程进入内核。 CPU数量*磁盘数*2
innodb_commit_concurrency 变量控制多少个线程可以在同一时间提交。
优化BLOB和TEXT的场景
服务器不能在内存临时表中存储blob值,只能在磁盘创建blob的临时表,效率贼低。可以通过substring函数把值转成varchar
排序blob和text字段时,它只使用前缀,然后忽略剩下部分的值。
一些基本配置参数
max_connections 最大连接数, 有一个动态的 max_used_connections状态变量随时间的变化。
thread_cache_size设置缓存线程的数量,可以通过thread_cached看有多少线程已经在缓存中了。
table_cache_size表缓存,这个要设置的足够大,避免总是需要重新打开和重新解析表的定义。
read_only 一般从库要设置成只读。
max_allowed_packet 防止服务器发送太大的包,也会控制多大的包可以被接收。
slave_net_timeout 从库与主库的连接超时时间设置。
Innodb_buffer_pool_size = 系统可用内存 - 系统正常运行内存 - (峰值时的连接数 * 每个连接需要的内存)
innodb_log_file_size 日志文件大小,存储事务持久话日志用的,这个设置16M-64M 就差不多了,默认一秒刷到磁盘的话。
操作系统和硬件优化
影响MySQL性能的硬件中CPU和I/O 资源、
CPU密集型 和 I/O密集型?
CPU密集指的是应用程序花费大量CPU去计算逻辑
I/O密集指的是应用程序 读写比较频繁。
缓存层级:CPU寄存器------CPU cache ------主存-------硬盘
随机IO是相当低性能的操作,一般对于热点数据会缓存到一起,这样不至于进行随机IO搜索,避免昂贵的磁盘寻道。
对于内存和磁盘的顺序IO都是远远快于随机IO的。