5、优化服务器设置
最好是从查询语句和响应时间入手来分析问题,而不是配置项,一般节省时间和避免麻烦的还是使用默认配置,除非明确知道默认值有问题。
原则:
- 一次只改变一个设置!这是测试改变是否有益的唯一方法。
- 大多数配置能在运行时使用SET GLOBAL改变。这是非常便捷的方法它能使你在出问题后快速撤销变更。但是,要永久生效你需要在配置文件里做出改动。
- 一个变更即使重启了MySQL也没起作用?请确定你使用了正确的配置文件。请确定把配置放在了正确的区域内( [mysqld])
- 服务器在改动一个配置后启不来了:请确定你使用了正确的单位。例如,innodb_buffer_pool_size的单位是MB而max_connection是没有单位的。
- 不要在一个配置文件里出现重复的配置项。如果想追踪改动,请使用版本控制。
- 不要用天真的计算方法,例如”现在我的服务器的内存是之前的2倍,所以我得把所有数值都改成之前的2倍“。
基本配置
innodb_log_file_size:这是redolog的大小。redo日志被用于确保写操作快速而可靠并且在崩溃时恢复。从MySQL 5.5之后,崩溃恢复的性能的到了很大提升,一直到MySQL 5.5,redo日志的总尺寸被限定在4GB(默认可以有2个log文件)。这在MySQL 5.6里被提高。
一开始就把innodb_log_file_size设置成512M(这样有1GB的redo日志)会使你有充裕的写操作空间。如果你知道你的应用程序需要频繁的写入数据并且你使用的时MySQL 5.6,你可以一开始就把它设置成4G。
max_connections:如果经常看到‘Too many connections'错误,是因为max_connections的值太低了。这非常常见因为应用程序没有正确的关闭数据库连接,需要比默认的151连接数更大的值。max_connection值被设高了(例如1000或更高)之后一个主要缺陷是当服务器运行1000个或更高的活动事务时会变的没有响应。在应用程序里使用连接池或者在MySQL里使用进程池有助于解决这一问题(我们的项目目前没有用到连接池,php需要扩展才可以)。
InnoDB配置
从MySQL 5.5版本开始,InnoDB就是默认的存储引擎并且它比任何其他存储引擎的使用都要多得多。那也是为什么它需要小心配置的原因。
innodb_file_per_table:这项设置告知InnoDB是否需要将所有表的数据和索引存放在共享表空间里(innodb_file_per_table = OFF) 或者为每张表的数据单独放在一个.ibd文件(innodb_file_per_table = ON)。每张表一个文件允许在drop、truncate或者rebuild表时回收磁盘空间。这对于一些高级特性也是有必要的,比如数据压缩。但是它不会带来任何性能收益。不想让每张表一个文件的主要场景是:有非常多的表(比如10k+)。
MySQL 5.6中,这个属性默认值是ON,因此大部分情况下什么都不需要做。对于之前的版本必需在加载数据之前将这个属性设置为ON,因为它只对新创建的表有影响。
innodb_flush_log_at_trx_commit:默认值为1,表示InnoDB完全支持ACID特性。当你的主要关注点是数据安全的时候这个值是最合适的,比如在一个主节点上。但是对于磁盘(读写)速度较慢的系统,它会带来很巨大的开销,因为每次将改变flush到redo日志都需要额外的fsyncs。将它的值设置为2会导致不太可靠(reliable)因为提交的事务仅仅每秒才flush一次到redo日志,但对于一些场景是可以接受的,比如对于主节点的备份节点这个值是可以接受的。如果值为0速度就更快了,但在系统崩溃时可能丢失一些数据:只适用于备份节点。
innodb_flush_method: 这项配置决定了数据和日志写入硬盘的方式。一般来说,如果你有硬件RAID控制器,并且其独立缓存采用write-back机制,并有着电池断电保护,那么应该设置配置为O_DIRECT;否则,大多数情况下应将其设为fdatasync(默认值)。
innodb_log_buffer_size: 这项配置决定了为尚未执行的事务分配的缓存。其默认值(1MB)一般来说已经够用了,但是如果你的事务中包含有二进制大对象或者大文本字段的话,这点缓存很快就会被填满并触发额外的I/O操作。看看Innodb_log_waits状态变量,如果它不是0,增加innodb_log_buffer_size。
其他设置
query_cache_size: query cache(查询缓存)是一个众所周知的瓶颈,甚至在并发并不多的时候也是如此。 最佳选项是将其从一开始就停用,设置query_cache_size = 0(现在MySQL 5.6的默认值)并利用其他方法加速查询:优化索引、增加拷贝分散负载或者启用额外的缓存(比如memcache或redis)。如果已经为应用启用了query cache并且还没有发现任何问题,query cache可能有用。这是如果想停用它,那就得小心了。
log_bin:如果想让数据库服务器充当主节点的备份节点,那么开启二进制日志是必须的。如果这么做了之后,还别忘了设置server_id为一个唯一的值。就算只有一个服务器,如果想做基于时间点的数据恢复,这(开启二进制日志)也是很有用的:
从最近的备份中恢复(全量备份),并应用二进制日志中的修改(增量备份)。二进制日志一旦创建就将永久保存。所以如果不想让磁盘空间耗尽,可以用 PURGE BINARY LOGS 来清除旧文件,或者设置 expire_logs_days 来指定过多少天日志将被自动清除。
记录二进制日志不是没有开销的,所以如果在一个非主节点的复制节点上不需要它的话,那么建议关闭这个选项。
skip_name_resolve:当客户端连接数据库服务器时,服务器会进行主机名解析,并且当DNS很慢时,建立连接也会很慢。因此建议在启动服务器时关闭skip_name_resolve选项而不进行DNS查找。唯一的局限是之后GRANT语句中只能使用IP地址了,因此在添加这项设置到一个已有系统中必须格外小心。
服务器和配置优化
1、 存储引擎选择
MySQL中有多种存储引擎,每种存储引擎都有自己的特色。想要好的性能,第一步就是选择合适的数据库引擎
2、mysql服务器调整优化措施
- 关闭不必要的二进制日志和慢查询日志,仅在内存足够或开发调试时打开它们。
- Show variable like ‘%slow%’
- 适度使用queryCache
- 增加MySQL允许的最大连接数。可用下面的语句查看MySQL允许的最大连接数。
- Show variables like ‘%max_connexts%’
- 对于myisam表适当增加key_buffer_size。当然这需要根据key_cache的命中率进行计算
3、mysql瓶颈及应对措施
Mysql是存在瓶颈的。当MySQL单表数据量达到千万级别以上时,无论如何对MySQL进行优化,查询如何简单,MySQL的性能都会显著降低,这时候可以采用以下措施:
1、 增加MySQL配置中buffer和cache的数值,增加服务器cpu数量和内存大小、这样能很大程度上应对MySQL的性能瓶颈。
2、 使用第三方引擎或衍生版本。
3、 迁移到其他数据库。比如postgreSQL数据库相比MySQL,拥有更强大的查询优化器,不会频繁重建索引,支持物化视图等优势。
4、 对数据库进行分区分表,减少单表体积。
5、 使用NoSQL等辅助解决方案。
6、 使用中间件做数据拆分和分布式部署,如阿里的Cobar。
7、 使用数据库连接池。