概述

1. 配置相关:硬件、数据大小、query类型、系统需求(响应时间、事务、一致性等等
2. 需要个性化配置:默认配置只是使server运行,考虑通用性、其他运行程序、不占用太多资源
3. 调整一个参数不可能获得较大性能提升,需要为一堆参数设置合理值,慢慢提升
4. 内存使用、IO、disc存储;基于负载的调试;需要特殊定制的query
 
配置基础
1. 两种设置方法:my.cnf 命令行()
确定一直使用的参数放在cnf里,否则下次执行可能丢失
2. 查看mysql使用哪个配置
$ which mysqld
/usr/sbin/mysqld
$ /usr/sbin/mysqld --verbose --help | grep -A 1 'Default options'
Default options are read from the following files in the given order:
/etc/mysql/my.cnf ~/.my.cnf /usr/etc/my.cnf
3. 配置有不同的使用范围:server、connnection(session)、object;connection有对应的global的,会覆盖,仅影响该conn
query_cache_size:global
sort_buffer_size:global defaul;per-session也可以单独设置
join_buffer_size:global defaul;per-session也可以单独设置;一个含有多个join的query可以有多个join buffer
4. 动态参数在server运行时可以修改 但是重启失效,下面是使用不同方法修改session和global的sort_buffer_size
SET           sort_buffer_size  = <value>;
SET GLOBAL    sort_buffer_size  = <value>;
SET         @@sort_buffer_size := <value>;
SET @@session.sort_buffer_size := <value>;
SET  @@global.sort_buffer_size := <value>;
小心使用,做很多工作:比如将buffer中的dirty data flush
一下几个变量动态修改很关键:
key_buffer_size:
table_cache_size:修改的时候没影响,当其他线程open table时,检查现在cache中的table数量与这个变量比较
thread_cache_size:缓存线程
query_cache_size:删除所有cached的query,重新设定cache大小 初始化
read_buffer_size
read_rnd_buffer_size
sort_buffer_size
5. 不是越大越好
做一个banchmark suit
每次改动一两个参数
有可能影响操作系统:sort_buffer_size与cpu cache;read_buffer_size与server的read-ahead和系统的IO
也有可能相互关联:innodb_log_file_size的最佳设置取决于innodb_buffer_pool_size
 
General Tuning
1. 起点:my-huge.cnf, my-large.cnf, and my-small.cnf
仅适用于只使用MyISAM
2. Menory Usage
这个是必须定制的
两种:一种不可控制(run server/parse query) 一种可以控制
如下方法定制
确定内存使用的上线
确定每个连接使用的内存,比如sort buffer、临时表
确定OS需要多少内存能保证运行正常,包括运行其他程序
假定上述合理的话,将其他的内存用于mysql的caches,比如InnoDB的buffer pool
mysql能用多少内存
上限难以界定,出发点事全部物理内存
32位linux内核限定 任何单个进程使用内存在2.5-2.7G
64位也有类似限定,很多buffer限定在4G之内
每个连接的内存需求:估算峰值期间内存需要
为OS预留内存:最佳情况是不要swap memory to disc,一般不大于1G/2G
最重要的cache
OS cache for MyISAM data;
MyISAM key Cache;
InnoDB buffer pool;
query Cache
其他的cache通常不会使用太多内存
使用单一的engine便于调试
3. MyISAM key cache
也叫key buffer,默认只有一个,但是可以建立多个
仅cache index,不cache data(让OS cache data)
最重要的是key_buffer_size,需要分配25-50%的cache内存
默认缓存所有的index在一个buffer内,但是可以建多个,这样就可以有大于4G的index在内存
监视性能和key buffer的使用:SHOW STATUS and SHOW VARIABLES
Cache hit ratio
100 - ( (Key_reads * 100) / Key_read_requests )
Percentage of buffer in use
100 - ( (Key_blocks_unused * key_cache_block_size) * 100 / key_buffer_size )
经验上,每秒的cache misses也很重要,假定硬盘每秒可以100随机读,5个miss没影响,但是80miss会使IO成为瓶颈
Key_reads / Uptime
计算10秒的增量:$ mysqladmin extended-status -r -i 10 | grep Key_reads
当决定key buffer大小时,可以查看index在硬盘的大小,buffer不需要比这个大
$ du -sch `find /path/to/mysql/data/directory/ -name "*.MYI"`
myisam_block_size:5.1以后,设定key block size
read-around write: cache读1K,OS读4K用完discard,cache修改,os还要再读在写回
4. InnoDB buffer pool
缓存index和data,insert buffer、lock等
延迟写操作,合并后统一写
严重依赖buffer pool,在一个专用server上,需要将80%的内存分配给他
可以使用show和innotop等工具监视内存使用和性能
InnoDB是没有LOAD INDEX INTO CACHE这样的功能的
在很少境况下,大buffer(如50G)有问题:ckpt/insertMerge slow、
innodb_max_dirty_pages_pct:限制在buffer中的dirty数据,默认90%,达到就flush
Innodb_buffer_pool_pages_dirty:现有的dirty page
5. Thread cache
hold线程,目前没和任何conn绑定,但ready to serve conn
thread_cache_size:cache中的thread数量,除非有大量conn一般不需要修改
查看Threads_created,确保thread cache足够大:没秒少于10个可以认为合理,但通常都可以达到1以下
比较好的方法是查看Threads_connected,然后将thread_cache_size设置为波动大小:
100-200,设置为100;500-700,设置为200
设置很大没什么用,设置很小也不会节约内存,每个thread大概占256k,与query相比很小
将这个值设的足够大,让create操作不频繁就行
6. table cache
包含.frm和其他信息,具体与engine有关(Myisam data/index file描述符;mergeTable file描述符s  描述符:可以不用open file)
设计偏重Myisam,是唯一个server与engine没有彻底分离的部分
innodb对他的file描述符不怎么使用,会使用解析的.frm
5.1开始分为两部分table和talbe definition:table_open_cache and table_definition_cache
Opened table每个线程每个表有一份,但definition是global的
如果Opened_tables很大或在增长,说明参数设小了(table_cache, 5.1:table_open_cache)
过大的缺点是:如果含有很多Myisam 关server会很慢
如果发现 Mysql不能打开更多的file错误:修改open_files_limit in your my.cnf
7. Innodb 数据字典
innodb每个表都有一个cache,叫table definition cache或数据字典,每个表大概4K,当他们closed时从数据字典移开
主要性能问题是:打开和计算统计信息,需要IO
innoDB在启动时建统计信息,并不持久保存,每张表都会顺序做这个工作,会导致启动花费很长时间
innodb_open_files:InnoDB能打开的.ibd文件个数,最好足够使所有的.ibd文件都打开