本文根据优才网课程整理,面向web开发者,内容以实用为主,专业DBA能够绕行。php
若是你在大公司,可能有专门的DBA来作这些事情,若是你在一个小公司当架构师或者技术总监,或者你本身创业,那DBA的活你也得干了。我们来说一下基本的mysql安装和优化。mysql
一: MYSQL安装和基本配置linux
在linux上安装,能够用包管理工具来安装,比较简单:
RedHat 系列:yum -y install mysql mysql-server
Debian系列:sudo apt-get install mysql mysql-serverweb
安装以后不知道mysql装到哪了怎么办,用whereis mysql 命令来找一下。 先找到mysql的默认配置文件。通常来讲,安装后有这么几个备选的配置:算法
my-huge.cnf my-innodb-heavy-4G.cnf my-large.cnf my-medium.cnf my-small.cnf
就2014年的机器配置来讲,我们直接用my-huge.cnf。把my-huge.cnf 复制到/etc/下,更名my.cnf。配置文件就有了, 而后启动mysql: /etc/init.d/mysqld start 。sql
安装以后默认的账号是root, 密码为空。我们要作的第一件事是改root密码。
进入mysql:mysql -uroot -p
选择数据库: use mysql
改密码: UPDATE user SET Password = PASSWORD('xxxx') WHERE user = 'root';
刷新权限: FLUSH PRIVILEGES;数据库
如今数据库装好了, 账号和权限也设置了,是否是就可使用了呢,还要检查几个配置。打开配置文件 vim /etc/my.cnfvim
skip-networking 要关闭。
bind-address = 127.0.0.1 这一行要关闭或者修改为容许的IP
skip-name-resolve 禁止dns解析,只能用IP连,这个能够打开。缓存
若是你的mysql通过一段时间运行,挺过了访问高峰,我们再来检查一下配置是否合适。下面说的配置,都必须是在运行一段时间后检查才有意义。若是刚启动没多久,mysql的运行状态没有表明性,不能做为参考。检查配置参数也没意义。服务器
二:链接数(connection)配置
max_connections 能够设置最大并发链接数。当MySql的并发链接达到这个设定值时,新的链接将会被拒绝(“Can not connect to MySQL server. Too many connections”-mysql 1040错误,)。当发现MySql有能力处理更多的并发的时候, 建议调大这个值,相应给服务器带来更高的负载(CPU/IO/内存)。
查看设置的最大链接是多少:
mysql> show variables like 'max_connections'; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | max_connections | 151 | 容许的最大链接数 +-----------------+-------+ 看当前链接数:show status like 'threads_connected'; 最大链接数: show status like "max_used_connections";
若是max_used_connections已经接近 max_connections了,就说明max_connections过小。不合适了。
还有一些跟链接数相关的配置:
back_log=50
MySQL能暂存的链接数量。当主要MySQL线程在一个很短期内获得很是多的链接请求,这就起做用。若是MySQL的链接数据达到max_connections时,新来的请求将会被存在堆栈中,以等待某一链接释放资源,该堆栈的数量即back_log,若是等待链接的数量超过back_log,将不被授予链接资源。
back_log值指出在MySQL暂时中止回答新请求以前的短期内有多少个请求能够被存在堆栈中。只有若是指望在一个短期内有不少链接,你须要增长它,换句话说,这值对到来的TCP/IP链接的侦听队列的大小。
不一样的操做系统在这个队列大小上有它本身的限制。试图设定back_log高于你的操做系统的限制将是无效的。默认值为50。对于Linux系统推荐设置为小于512的整数。
若是连接数超过max_connections+back_log ,才会出错。
max_connect_errors=10
当客户端链接服务端超时(超过connect_timeout), 服务端就会给这个客户端记录一次error,当出错的次数达到max_connect_errors的时候,这个客户端就会被锁定。除非执行FLUSH HOSTS命令。
connect_timeout=5
链接超时的秒数
三:查询缓存(query_cache)配置
查询缓存就是内存中的一块存储区域,其存储了用户的SQL文本以及相关的查询结果。一般状况下,用户下次查询时,若是所使用的SQL文本是相同的,而且自从上次查询后,相关的纪录没有被更新过,此时数据库就直接采用缓存中的内容。从内存中读取要比从硬盘上速度要快好几百倍。
MYSQL的查询缓存用于缓存select查询结果,并在下次接收到一样的查询请求时,再也不执行实际查询处理而直接 返回结果,有这样的查询缓存能提升查询的速度,使查询性能获得优化.
要使用缓存,有几个条件。
一是所采用的SQL语句是相同的。每次查询的语句不同,确定不能用到缓存。好比语句里带当前秒数 where ctime > xxx
二是表数据没有改过。没有改过结构,没有update,insert
三:客户端与服务器的默认字符集得同样
因此能够看出,要利用好缓存,有大量的相同的查询,而不多改变表里的数据,不然没有必要使用此功能.
查看查询缓存的设置:
SHOW VARIABLES LIKE '%query_cache%'; +------------------------------+----------+ | Variable_name | Value | +------------------------------+----------+ | have_query_cache | YES | | query_cache_limit | 1048576 | 若是单个查询结果大于这个值,则不Cache | query_cache_min_res_unit | 4096 | 每次给QC结果分配内存的大小 | query_cache_size | 33554432 | | query_cache_type | ON | | query_cache_wlock_invalidate | OFF | +------------------------------+----------+ query_cache_type=1
若是设置为1,将会缓存全部的结果,除非你的select语句使用SQL_NO_CACHE禁用了查询缓存。
若是设置为2,则只缓存在select语句中经过SQL_CACHE指定须要缓存的查询。
query_cache_size 默认是32M,过小了,可调到128M或者256M。 能够经过Qcache_lowmem_prunes变量的值来检查是否当前的值知足你目前系统的负载。
query_cache_size的工做原理:一个SELECT查询在DB中工做后,DB会把该语句缓存下来,当一样的一个SQL再次来到DB里调用时,DB在该表没发生变化的状况下把结果从缓存中返回给Client。这里有一个关建点,就是DB在利用Query_cache工做时,要求该语句涉及的表在这段时间内没有发生变动。那若是该表在发生变动时,Query_cache里的数据又怎么处理呢?首先要把Query_cache和该表相关的语句所有置为失效,而后在写入更新。那么若是Query_cache很是大,该表的查询结构又比较多,查询语句失效也慢,一个更新或是Insert就会很慢,这样看到的就是Update或是Insert怎么这么慢了。因此在数据库写入量或是更新量也比较大的系统,该参数不适合分配过大。并且在高并发,写入量大的系统,建系把该功能禁掉。
Qcache_lowmem_prunes能够检查是否设置的过小。
query_cache_limit 默认是1M,根据你的经常使用查询的数据结果大小来定。若是返回的数据小,能够设置小一点。
设置值大对大数据查询有好处,但若是你的查询都是小数据查询,就容易形成内存碎片和浪费
查看缓存使用效果如何:
show status like '%Qcache%'; +-------------------------+----------+ | Variable_name | Value | +-------------------------+----------+ | Qcache_free_blocks | 160 | 目前还处于空闲状态的 Query Cache中内存 Block 数目,数目大说明可能有碎片。FLUSH QUERY CACHE会对缓存中的碎片进行整理,从而获得一个空闲块。 | Qcache_free_memory | 23147296 | 缓存中的空闲内存总量。 | Qcache_hits | 52349 | 缓存命中次数。 | Qcache_inserts | 8827 | 缓存失效次数。 | Qcache_lowmem_prunes | 0 | 缓存出现内存不足而且必需要进行清理以便为更多查询提供空间的次数。这个数字最好长时间来看;若是这个数字在不断增加,就表示可能碎片很是严重,或者内存不多。 | Qcache_not_cached | 2446 | 没有被cache和不适合进行缓存的查询的数量,一般是因为这些查询不是SELECT语句以及因为query_cache_type设置的不会被Cache的查询。show,use,desc | Qcache_queries_in_cache | 5234 | 当前被cache的SQL数量。 | Qcache_total_blocks | 10796 | 缓存中块的数量。 +-------------------------+----------+ show global status like 'Com_select'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | Com_select | 12592 | com_select 变量记录的是无缓存的查询次数+错误查询+权限检查查询。 +---------------+-------+
Mysql的查询缓存命中率没有官方算法,只有前人的经验总结
命中率 ≈ qcache_hits / (qcache_hits + com_select)
缓存碎片率 = Qcache_free_blocks / Qcache_total_blocks * 100% ,若是碎片率过高,20% ,能够FLUSH QUERY CACHE整理缓存碎片,或者试试减少query_cache_min_res_unit,若是你的查询都是小数据量的话。
查询缓存利用率 = (query_cache_size – Qcache_free_memory) / query_cache_size * 100%
#查询缓存利用率在25%如下的话说明query_cache_size设置的过大,可适当减少;查询缓存利用率在80%以上并且Qcache_lowmem_prunes > 50的话说明query_cache_size可能有点小,要不就是碎片太多。
如何提升命中率:
1:字符集相同,2:SQL语句尽可能固定(SQL语句避免随机数,秒数等) 3 加大缓存空间 4:适当分表,动静分离,
四:临时表缓存(tmp_table_size)配置
mysql进行复杂查询或者 作高级GROUP BY操做的时候,系统为了优化查询,生成一些临时表。经过设置tmp_table_size选项来设置临时表占用空间的大小。
咱们使用explain分析SQL,若是在Extra列看到Using temporary就意味着使用了临时表。
MySQL临时表分为“内存临时表”和“磁盘临时表”,其中内存临时表使用MySQL的MEMORY存储引擎,磁盘临时表使用MySQL的MyISAM存储引擎;
通常状况下,MySQL会先建立内存临时表,但内存临时表超过配置指定的值后,MySQL会将内存临时表导出到磁盘临时表
临时表将在你链接MySQL期间存在。当你断开时,MySQL将自动删除表并释放所用的空间。
mysql> SHOW VARIABLES LIKE '%tmp_table_size%'; +----------------+----------+ | Variable_name | Value | +----------------+----------+ | tmp_table_size | 33554432 | +----------------+----------+ 1 row in set (0.00 sec) mysql> show global status like 'created_tmp%'; +-------------------------+----------+ | Variable_name | Value | +-------------------------+----------+ | Created_tmp_disk_tables | 690421 | 服务器执行语句时在硬盘上自动建立的临时表的数量 | Created_tmp_files | 755473 | mysqld已经建立的临时文件的数量 | Created_tmp_tables | 14372959 | 服务器执行语句时自动建立的内存中的临时表的数量。若是Created_tmp_disk_tables较大,你可能要增长tmp_table_size值使临时 表基于内存而不基于硬盘 +-------------------------+----------+
每次建立临时表,Created_tmp_tables增长,若是临时表大小超过tmp_table_size,则是在磁盘上建立临时表,Created_tmp_disk_tables也增长,Created_tmp_files表示MySQL服务建立的临时文件文件数,比较理想的配置是:
Created_tmp_disk_tables / Created_tmp_tables * 100% <= 25%
好比上面的服务器Created_tmp_disk_tables / Created_tmp_tables * 100% =1.20%,应该至关好了
默认大小是 32M,可调到64-256最佳,线程独占,太大可能内存不够I/O堵塞
跟临时表相关的另外一配置是max_heap_table_size ,
用户能够建立的独立的内存表所容许的最大容量.这个变量不适用与用户建立的内存表(memory table).
SHOW VARIABLES LIKE '%max_heap_table_size%'; 我们但愿临时表是放到内存的。因此这个值设置的临时表缓存的空间同样就行。
(实际起限制做用的是tmp_table_size和max_heap_table_size的最小值。)若是临时表大于这两个的任何一个,都会存硬盘缓存:自动地把它转化为基于磁盘的MyISAM表,存储在指定的tmpdir目录下
五:索引缓冲区(key_buffer_size)配置
key_buffer_size是对MyISAM表性能影响最大的一个参数.key_buffer_size指定索引缓冲区的大小,它决定索引处理的速度,尤为是索引读的速度。经过检查状态值Key_read_requests和Key_reads,能够知道key_buffer_size设置是否合理。比例key_reads /key_read_requests应该尽量的低,至少是1:100,1:1000更好
key_buffer_size只对MyISAM表起做用。即便你不使用MyISAM表,可是内部的临时磁盘表是MyISAM表,也要使用该值。可使用检查状态值created_tmp_disk_tables得知详情。
mysql> show variables like 'key_buffer_size'; +-----------------+----------+ | Variable_name | Value | +-----------------+----------+ | key_buffer_size | 67108864 | 索引缓冲区的大小 +-----------------+----------+ show variables like 'key_cache_block_size'; mysql> show global status like 'key%'; +------------------------+------------+ | Variable_name | Value | +------------------------+------------+ | Key_blocks_not_flushed | 0 |索引缓存内已经更改,但尚未清空到硬盘上的索引的数据块数量。 | Key_blocks_unused | 0 | 索引缓存内未使用的块数量。你可使用该值来肯定使用了多少键缓存 | Key_blocks_used | 53585 | 索引缓存内使用的块数量。该值为高水平线标记,说明已经同时最多使用了多少块。 | Key_read_requests | 4952122733 | 一共有XXX个索引读取请求, | Key_reads | 11879 | 索引读取请求在内存中没有找到,直接从硬盘读取索引 | Key_write_requests | 10508455 | 将索引的数据块写入缓存的请求数。 | Key_writes | 6042774 | 将索引向硬盘写入数据块的物理写操做的次数。 +------------------------+------------+
比例key_reads /key_read_requests应该尽量的低,至少是1:100,1:1000更好
若是Key_reads太大,则应该把my.cnf中key_buffer_size变大.能够用Key_reads/Key_read_requests计算出cache失败率
Key_writes/Key_write_requests:比例接近1较好
别人的经验是内存在4GB左右的服务器该参数可设置为384M或512M。能够本身算一下本身数据库的索引文件大小。注意:该参数值设置的过大反而会是服务器总体效率下降!
Cache命中比率:
1 - Key_reads / Key_read_requests
Key buffer的使用率
100 – ( (Key_blocks_unused * key_cache_block_size) * 100 / key_buffer_size )