http://www.mysqlperformanceblog.com/2014/01/28/10-mysql-settings-to-tune-after-installation/
翻译加深理解。
先是几个point
- Change one setting at a time! This is the only way to estimate if a change is beneficial.
- 一次只调一个参数,确保改动是有益的。
- Most settings can be changed at runtime with
SET GLOBAL
. It is very handy and it allows you to quickly revert the change if it creates any problem. But in the end, you want the setting to be adjusted permanently in the configuration file. - 用set global 确实能让一些参数马上生效,但是到最后,还是需要写入配置文件才比较好
- A change in the configuration is not visible even after a MySQL restart? Did you use the correct configuration file? Did you put the setting in the right section? (all settings in this post belong to the
[mysqld]
section) - The server refuses to start after a change: did you use the correct unit? For instance,
innodb_buffer_pool_size
should be set in bytes whilemax_connection
is dimensionless. - max_connection 的调整,一般默认是151 ,比较小的。需要调整。
- Do not allow duplicate settings in the configuration file. If you want to keep track of the changes, use version control.
- 配置文件里不要有重复的项
- Don’t do naive math, like “my new server has 2x RAM, I’ll just make all the values 2x the previous ones”.
- 不要做简单的算术,比如机器扩容了2倍内存,就把参数乘2.
When we are hired for a MySQL performance audit, we are expected to review the MySQL configuration and to suggest improvements. Many people are surprised because in most cases, we only suggest to change a few settings even though hundreds of options are available. The goal of this post is to give you a list of some of the most critical settings.
We already made such suggestions in the past here on this blog a few years ago, but things have changed a lot in the MySQL world since then!
Basic settings
Here are 3 settings that you should always look at. If you do not, you are very likely to run into problems very quickly.
innodb_buffer_pool_size
: this is the #1 setting to look at for any installation using InnoDB. The buffer pool is where data and indexes are cached: having it as large as possible will ensure you use memory and not disks for most read operations. Typical values are 5-6GB (8GB RAM), 20-25GB (32GB RAM), 100-120GB (128GB RAM).
innodb_buffer_pool_size ,innodb 的很重要的参数,内存的使用量。一般系统的7,8成,如果是只跑mysql的话。
innodb_log_file_size
: this is the size of the redo logs. The redo logs are used to make sure writes are fast and durable and also during crash recovery. Up to MySQL 5.1, it was hard to adjust, as you wanted both large redo logs for good performance and small redo logs for fast crash recovery. Fortunately crash recovery performance has improved a lot since MySQL 5.5 so you can now have good write performance and fast crash recovery. Until MySQL 5.5 the total redo log size was limited to 4GB (the default is to have 2 log files). This has been lifted in MySQL 5.6.
innodb_log_file_size redo logs 的大小。默认5M ,肯定是太小。
Starting with innodb_log_file_size = 512M
(giving 1GB of redo logs) should give you plenty of room for writes. If you know your application is write-intensive and you are using MySQL 5.6, you can start with innodb_log_file_size = 4G
.
max_connections
: if you are often facing the ‘Too many connections’ error, max_connections
is too low. It is very frequent that because the application does not close connections to the database correctly, you need much more than the default 151 connections. The main drawback of high values for max_connections (like 1000 or more) is that the server will become unresponsive if for any reason it has to run 1000 or more active transactions. Using a connection pool at the application level or a thread pool at the MySQL level can help here.
默认151的最大连接数肯定是太小,经常因为程序没有及时关闭连接导致打到最大连接数。不过设太大也没意义,服务器最多也就能承受一定数量的并发,太大了会导致线程争用系统资源,tpmc 反而下降,这时候就可以用thread pool 了。
InnoDB settings
innodb的参数。。基本上现在都用innodb 了。不用myisam 的原因不是myisam 慢,而是他没有自恢复,就是mysql 突然挂了以后,他会导致表损坏。innodb 用了redo ,妈妈再也不用担心我crash 了以后丢数据了。丢的话最多丢1s 。跟下面的innodb_flush_log_at_trx_commit参数有关系。
InnoDB has been the default storage engine since MySQL 5.5 and it is much more frequently used than any other storage engine. That’s why it should be configured carefully.
innodb_file_per_table
: this setting will tell InnoDB if it should store data and indexes in the shared tablespace (innodb_file_per_table = OFF
) or in a separate .ibd file for each table (innodb_file_per_table= ON
). Having a file per table allows you to reclaim space when dropping, truncating or rebuilding a table. It is also needed for some advanced features such as compression. However it does not provide any performance benefit. The main scenario when you do NOT want file per table is when you have a very high number of tables (say 10k+).
每个innodb 的表一个文件。不然的话就是共享表空间。都放在ibdata1里面了 。如果你有大于1万张表,建议用共享表空间,这个参数设置为off。
With MySQL 5.6, the default value is ON so you have nothing to do in most cases. For previous versions, you should set it to ON prior to loading data as it has an effect on newly created tables only.
mysql 5.6 这个参数是on的。小于5.6,都需要手动调。
innodb_flush_log_at_trx_commit
: the default setting of 1 means that InnoDB is fully ACID compliant. It is the best value when your primary concern is data safety, for instance on a master. However it can have a significant overhead on systems with slow disks because of the extra fsyncs that are needed to flush each change to the redo logs. Setting it to 2 is a bit less reliable because committed transactions will be flushed to the redo logs only once a second, but that can be acceptable on some situations for a master and that is definitely a good value for a replica. 0 is even faster but you are more likely to lose some data in case of a crash: it is only a good value for a replica.
innodb_flush_log_at_trx_commit
这个参数默认是1,为了满足ACID 的要求,自己凭记忆翻了一遍发现还是跟文档上的有出入。
If the value of innodb_flush_log_at_trx_commit
is 0, the log buffer is written out to the log file once per second and the flush to disk operation is performed on the log file, but nothing is done at a transaction commit. When the value is 1, the log buffer is written out to the log file at each transaction commit and the flush to disk operation is performed on the log file. When the value is 2, the log buffer is written out to the file at each commit, but the flush to disk operation is not performed on it. However, the flushing on the log file takes place once per second also when the value is 2. Note that the once-per-second flushing is not 100% guaranteed to happen every second, due to process scheduling issues.
就是说为0时,每秒钟,log buffer 写到log file 里面去,事务commit 提交的时候,不做任何事情。
为1时,log buffer 写到 redo log 文件里去,并且刷新到磁盘上去。这个是同步的概念,也就限制了每秒的mysql 事务吞吐量。
为2时,log buffer 刷新到redo log file 里面去,但是不保证刷新到磁盘上去。这就是异步的一个情况,能大大增加mysql 每秒的事务处理量。之前我测试过。
一般设为2 对性能比较好,设0的话比较冒险了。可能会丢1s 的数据。
innodb_flush_method: this setting controls how data and logs are flushed to disk. Popular values are O_DIRECT when you have a hardware RAID controller with a battery-protected write-back cache and fdatasync (default value) for most other scenarios. sysbench is a good tool to help you choose between the 2 values.
innodb_flush_method 上面说是O_DIRECT 用在raid 上面,其他的用默认,现在服务器一般都有raid的。sysbench 可以测这个参数的好坏。
innodb_log_buffer_size: this is the size of the buffer for transactions that have not been committed yet. The default value (1MB) is usually fine but as soon as you have transactions with large blob/text fields, the buffer can fill up very quickly and trigger extra I/O load. Look at the Innodb_log_waits status variable and if it is not 0, increase innodb_log_buffer_size
.
innodb_log_buffer_size 就是log buffer 的大小,默认1MB,可以看Innodb_log_waits 这个状态,如果不是0的话,可以适当增加这个参数。
Other settings
其他参数
query_cache_size
: the query cache is a well known bottleneck that can be seen even when concurrency is moderate. The best option is to disable it from day 1 by setting query_cache_size = 0
(now the default on MySQL 5.6) and to use other ways to speed up read queries: good indexing, adding replicas to spread the read load or using an external cache (memcache or redis for instance). If you have already built your application with the query cache enabled and if you have never noticed any problem, the query cache may be beneficial for you. So you should be cautious if you decide to disable it.
query cache size 是著名的瓶颈及时并发中等的情况下。最好禁用他。这个cache 最好是用 优化索引, 主从复制 ,用另外的 cache ,比如memcache redis 等等。
log_bin
: enabling binary logging is mandatory if you want the server to act as a replication master. If so, don’t forget to also setserver_id
to a unique value. It is also useful for a single server when you want to be able to do point-in-time recovery: restore your latest backup and apply the binary logs. Once created, binary log files are kept forever. So if you do not want to run out of disk space, you should either purge old files with PURGE BINARY LOGS or set expire_logs_days
to specify after how many days the logs will be automatically purged.
log_bin ,如果是master的话必开,这不用说了。不是master 也要开,不然没法做恢复。然后必须加个 expire_logs_days参数,不然不会自动清log bin ,很容易爆硬盘。
Binary logging however is not free, so if you do not need for instance on a replica that is not a master, it is recommended to keep it disabled.
skip_name_resolve
: when a client connects, the server will perform hostname resolution, and when DNS is slow, establishing the connection will become slow as well. It is therefore recommended to start the server with skip-name-resolve
to disable all DNS lookups. The only limitation is that the GRANT
statements must then use IP addresses only, so be careful when adding this setting to an existing system.
禁止域名解析,因为dns 解析也是需要时间的,最好禁用,grant 赋权限的时候也只用ip 地址,不要用域名。
Conclusion
There are of course other settings that can make a difference depending on your workload or your hardware: low memory and fast disks, high concurrency, write-intensive workloads for instance are cases when you will need specific tuning. However the goal here is to allow you to quickly get a sane MySQL configuration without spending too much time on changing non-essential MySQL settings or on reading documentation to understand which settings do matter to you.
不过还有个很好的选择是用percona 的在线工具
tools.percona.com/wizard