MySQL配置文件my.cnf中文详解,附mysql性能优化方法分享
=================================================================================================
Mysql参数优化对于新手来讲,是比较难懂的东西,其实这个参数优化,是个很复杂的东西,对于不同的网站,及其在线量,访问量,帖子数量,网络情况,以及机器硬件配置都有关系,优化不可能一次性完成,需要不断的观察以及调试,才有可能得到最佳效果。
下面先说我的服务器的硬件以及论坛情况,
CPU: 2颗四核Intel Xeon 2.00GHz
内存: 4GB DDR
硬盘: SCSI 146GB
论坛:在线会员 一般在 5000 人左右 – 最高记录是 13264.
下面,我们根据以上硬件配置结合一份已经做过一次优化的my.cnf进行分析说明:有些参数可能还得根据论坛的变化情况以及程序员的程序进行再调整。
[mysqld]
port = 3306
serverid = 1
socket = /tmp/mysql.sock
skip-locking # 避免MySQL的外部锁定,减少出错几率增强稳定性。
skip-name-resolve
禁止MySQL对外部连接进行DNS解析,使用这一选项可以消除MySQL进行DNS解析的时间。但需要注意,如果开启该选项,则所有远程主机连接授权都要使用IP地址方式,否则MySQL将无法正常处理连接请求!
back_log = 500
要求 MySQL 能有的连接数量。当主要MySQL线程在一个很短时间内得到非常多的连接请求,这就起作用,然后主线程花些时间(尽管很短)检查连接并且启动一个新线程。
back_log值指出在MySQL暂时停止回答新请求之前的短时间内多少个请求可以被存在堆栈中。只有如果期望在一个短时间内有很多连接,你需要增加它,换句话说,这值对到来的TCP/IP连接的侦听队列的大小。你的操作系统在这个队列大小上有它自己的限制。试图设定back_log高于你的操作系统的限制将是无效的。当你观察你的主机进程列表,发现大量 264084 | unauthenticated user | xxx.xxx.xxx.xxx | NULL | Connect | NULL | login | NULL 的待连接进程时,就要加大 back_log 的值了。默认数值是50,我把它改为500。
key_buffer_size = 384M
# key_buffer_size指定用于索引的缓冲区大小,增加它可得到更好处理的索引(对所有读和多重写),到你能负担得起那样多。如果你使它太大,系统将开始换页并且真的变慢了。对于内存在4GB左右的服务器该参数可设置为384M或512M。通过检查状态值Key_read_requests和 Key_reads,可以知道key_buffer_size设置是否合理。比例key_reads / key_read_requests应该尽可能的低,至少是1:100,1:1000更好(上述状态值可以使用SHOW STATUS LIKE ‘key_read%‘获得)。注意:该参数值设置的过大反而会是服务器整体效率降低!
max_allowed_packet = 32M
增加该变量的值十分安全,这是因为仅当需要时才会分配额外内存。例如,仅当你发出长查询或mysqld必须返回大的结果行时mysqld才会分配更多内存。该变量之所以取较小默认值是一种预防措施,以捕获客户端和服务器之间的错误信息包,并确保不会因偶然使用大的信息包而导致内存溢出。
table_cache = 512(5.1之后叫做table_open_cache)
table_cache指定表高速缓存的大小。每当MySQL访问一个表时,如果在表缓冲区中还有空间,该表就被打开并放入其中,这样可以更快地访问表内容。通过检查峰值时间的状态值Open_tables和Opened_tables,可以决定是否需要增加table_cache的值。如果你发现 open_tables等于table_cache,并且opened_tables在不断增长,那么你就需要增加table_cache的值了(上述状态值可以使用SHOW STATUS LIKE ‘Open%tables‘获得)。注意,不能盲目地把table_cache设置成很大的值。如果设置得太高,可能会造成文件描述符不足,从而造成性能不稳定或者连接失败。
sort_buffer_size = 4M
查询排序时所能使用的缓冲区大小。注意:该参数对应的分配内存是每连接独占!如果有100个连接,那么实际分配的总共排序缓冲区大小为100 × 4 = 400MB。所以,对于内存在4GB左右的服务器推荐设置为4-8M。
read_buffer_size = 4M
读查询操作所能使用的缓冲区大小。和sort_buffer_size一样,该参数对应的分配内存也是每连接独享!
join_buffer_size = 8M
联合查询操作所能使用的缓冲区大小,和sort_buffer_size一样,该参数对应的分配内存也是每连接独享!
myisam_sort_buffer_size = 64M
MyISAM表发生变化时重新排序所需的缓冲
query_cache_size = 64M
指定MySQL查询缓冲区的大小。可以通过在MySQL控制台执行以下命令观察:
# > SHOW VARIABLES LIKE ‘%query_cache%‘; # > SHOW STATUS LIKE ‘Qcache%‘; # 如果Qcache_lowmem_prunes的值非常大,则表明经常出现缓冲不够的情况;
如果Qcache_hits的值非常大,则表明查询缓冲使用非常频繁,如果该值较小反而会影响效率,那么可以考虑不用查询缓冲;Qcache_free_blocks,如果该值非常大,则表明缓冲区中碎片很多。
thread_cache_size = 64
可以复用的保存在中的线程的数量。如果有,新的线程从缓存中取得,当断开连接的时候如果有空间,客户的线置在缓存中。如果有很多新的线程,为了提高性能可以提高这个变量值。通过比较 Connections 和 Threads_created 状态的变量,可以看到这个变量的作用
tmp_table_size = 256M
max_connections = 1000
指定MySQL允许的最大连接进程数。如果在访问论坛时经常出现Too Many Connections的错误提示,则需要增大该参数值。
max_connect_errors = 10000000
对于同一主机,如果有超出该参数值个数的中断错误连接,则该主机将被禁止连接。如需对该主机进行解禁,执行:FLUSH HOST;。
wait_timeout = 10
指定一个请求的最大连接时间,对于4GB左右内存的服务器可以设置为5-10。
thread_concurrency = 8
该参数取值为服务器逻辑CPU数量×2,在本例中,服务器有2颗物理CPU,而每颗物理CPU又支持H.T超线程,所以实际取值为4 × 2 = 8
skip-networking
开启该选项可以彻底关闭MySQL的TCP/IP连接方式,如果WEB服务器是以远程连接的方式访问MySQL数据库服务器则不要开启该选项!否则将无法正常连接!
long_query_time = 10
log-slow-queries =
log-queries-not-using-indexes
开启慢查询日志( slow query log )
慢查询日志对于跟踪有问题的查询非常有用。它记录所有超过过long_query_time的查询,如果需要,还可以记录不使用索引的记录。下面是一个慢查询日志的例子:
开启慢查询日志,需要设置参数log_slow_queries、long_query_times、log-queries-not-using-indexes。
log_slow_queries指定日志文件,如果不提供文件名,MySQL将自己产生缺省文件名。long_query_times指定慢查询的阈值,缺省是10秒。log-queries-not-using-indexes是4.1.0以后引入的参数,它指示记录不使用索引的查询。设置 long_query_time=10
外附上使用show status命令查看mysql状态相关的值及其含义:
使用show status命令
含义如下:
aborted_clients 客户端非法中断连接次数
aborted_connects 连接mysql失败次数
com_xxx xxx命令执行次数,有很多条
connections 连接mysql的数量
Created_tmp_disk_tables 在磁盘上创建的临时表
Created_tmp_tables 在内存里创建的临时表
Created_tmp_files 临时文件数
Key_read_requests The number of requests to read a key block from the cache
Key_reads The number of physical reads of a key block from disk
Max_used_connections 同时使用的连接数
Open_tables 开放的表
Open_files 开放的文件
Opened_tables 打开的表
Questions 提交到server的查询数
Sort_merge_passes 如果这个值很大,应该增加my.cnf中的sort_buffer值
Uptime 服务器已经工作的秒数
提升性能的建议:
1.如果opened_tables太大,应该把my.cnf中的table_cache变大
2.如果Key_reads太大,则应该把my.cnf中key_buffer_size变大.可以用Key_reads/Key_read_requests计算出cache失败率
3.如果Handler_read_rnd太大,则你写的SQL语句里很多查询都是要扫描整个表,而没有发挥索引的键的作用
4.如果Threads_created太大,就要增加my.cnf中thread_cache_size的值.可以用Threads_created/Connections计算cache命中率
5.如果Created_tmp_disk_tables太大,就要增加my.cnf中tmp_table_size的值,用基于内存的临时表代替基于磁盘的
==========================================================================================================
存储引擎是什么?MySQL中的数据用各种不同的技术存储在文件(或者内 正确的编译方法固然重要,但它只是提高MySQL服务器性能工作的一部分。MySQL服务器的许多参数会影响服务器的性能表现,而且我们可以把这些参数保存到配置文件,使得每次MySQL服务器启动时这些参数都自动发挥作用。这个配置文件就是my.cnf。
MySQL服务器提供了my.cnf文件的几个示例,它们可以在/usr/local/mysql/share/mysql/目录下找到,名字分别为 my-small.cnf、my-medium.cnf、my-large.cnf以及my-huge.cnf。文件名字中关于规模的说明描述了该配置文件适用的系统类型。例如,如果运行MySQL服务器的系统内存不多,而且MySQL只是偶尔使用,那么使用my-small.cnf配置文件最为理想,这个配置文件告诉mysqld daemon使用最少的系统资源。反之,如果MySQL服务器用于支持一个大规模的在线商场,系统拥有2G的内存,那么使用mysql-huge.cnf 最为合适。
要使用上述示例配置文件,我们应该先复制一个最适合要求的配置文件,并把它命名为my.cnf。这个复制得到的配置文件可以按照如下三种方式使用:
全局:把这个my.cnf文件复制到服务器的/etc目录,此时文件中所定义的参数将全局有效,即对该服务器上运行的所有MySQL数据库服务器都有效。
局部:把这个my.cnf文件复制到[MYSQL-INSTALL-DIR]/var/将使该文件只对指定的服务器有效,其中[MYSQL-INSTALL-DIR]表示安装MySQL的目录。
用户:最后,我们还可以把该文件的作用范围局限到指定的用户,这只需把my.cnf文件复制到用户的根目录即可。
那么,如何设置my.cnf文件中的参数呢?或者进一步说,哪些参数是我们可以设置的呢?所有这些参数都对MySQL服务器有着全局性的影响,但同时每一个参数都和MySQL的特定部分关系较为密切。例如,max_connections参数属于mysqld一类。那么,如何才能得知这一点呢?这只需执行如下命令:
% >/usr/local/mysql/libexec/mysqld –help
该命令将显示出和mysqld有关的各种选项和参数。要寻找这些参数非常方便,因为这些参数都在“Possible variables for option –set-variable (-O) are”这行内容的后面。找到这些参数之后,我们就可以在my.cnf文件中按照如下方式设置所有这些参数:
set-variable = max_connections=100
这行代码的效果是:同时连接MySQL服务器的最大连接数量限制为100。不要忘了在my.cnf文件[mysqld]小节加上一个set-variable指令,具体请参见配置文件中的示例。
MySQL的max_connections参数用来设置最大连接(用户)数。每个连接MySQL的用户均算作一个连接,max_connections的默认值为100。本文将讲解此参数的详细作用与性能影响。
[max_connections]
=================================================================================================
MySQL无论如何都会保留一个用于管理员(SUPER)登陆的连接,用于管理员连接数据库进行维护操作,即使当前连接数已经达到了max_connections。因此MySQL的实际最大可连接数为max_connections+1;
这个参数实际起作用的最大值(实际最大可连接数)为16384,即该参数最大值不能超过16384,即使超过也以16384为准;
增加max_connections参数的值,不会占用太多系统资源。系统资源(CPU、内存)的占用主要取决于查询的密度、效率等;
该参数设置过小的最明显特征是出现”Too many connections”错误;
我们先来看下如何查看当前mysql的max_connections的值:
如下sql
复制代码代码如下:
show variables like "max_connections";
显示的结果如下格式
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 100 |
+-----------------+-------+
可以通过下面的sql语句将max_connections的值设置为200,当然前提是当前登录的用户有足够的权限:
set global max_connections = 200;
这个设置会马上生效,但是当mysql重启时这个设置会失效,更好的办法是修改mysql的ini配置文件my.ini
找到mysqld块,修改或者添加下面的设置:
max_connections=200
这样修改之后,即便重启mysql也会默认载入这个配置了
不过为了安全期间,建议大家直接到my.ini里修改,么有可以加上。
调整max_connections参数的值
调整此参数的方法有几种,既可以在编译的时候设置,也可以在MySQL配置文件 my.cnf 中设置,也可以直接使用命令调整并立即生效。
1、在编译的时候设置默认最大连接数
打开MySQL的源码,进入sql目录,修改mysqld.cc文件:
复制代码代码如下:
{"max_connections", OPT_MAX_CONNECTIONS,
"The number of simultaneous clients allowed.", (gptr*) &max_connections,
(gptr*) &max_connections, 0, GET_ULONG, REQUIRED_ARG, 100, 1, 16384, 0, 1,
0},
红色的”100″即为该参数的默认值,修改为想要的数值,存盘退出。然后执行
复制代码代码如下:
./configure;make;make install
重新编译安装MySQL;注意,由于编译安装且修改了MySQL源码,此操作最好在安装MySQL之前进行;
2、在配置文件my.cnf中设置max_connections的值
打开MySQL配置文件my.cnf
复制代码代码如下:
[[email protected] ~]# vi /etc/my.cnf
找到max_connections一行,修改为(如果没有,则自己添加),
复制代码代码如下:
max_connections = 1000
上面的1000即该参数的值。
3、实时(临时)修改此参数的值
首先登陆mysql,执行如下命令:
复制代码代码如下:
[[email protected] ~]# mysql -uroot -p
然后输入MySQL Root的密码。
查看当前的Max_connections参数值:
复制代码代码如下:
mysql> SELECT @@MAX_CONNECTIONS AS ‘Max Connections‘;
设置该参数的值:
复制代码代码如下:
mysql> set GLOBAL max_connections=1000;
(注意上面命令的大小写)
修改完成后实时生效,无需重启MySQL。
总体来说,该参数在服务器资源够用的情况下应该尽量设置大,以满足多个客户端同时连接的需求。否则将会出现类似”Too many connections”的错误。
【THREAD_CACHE】
=================================================================================================
MySQL里面为了提高客户端请求创建连接过程的性能,提供了一个连接池也就是 Thread_Cache池,将空闲的连接线程放在连接池中,而不是立即销毁.这样的好处就是,当又有一个新的请求的时候,mysql不会立即去创建连接 线程,而是先去Thread_Cache中去查找空闲的连接线程,如果存在则直接使用,不存在才创建新的连接线程.
有关Thread_Cache在MySQL有几个重要的参数,简单介绍如下:
thread_cache_size
Thread_Cache 中存放的最大连接线程数.在短连接的应用中Thread_Cache的功效非常明显,因为在应用中数据库的连接和创建是非常频繁的,如果不使用 Thread_Cache那么消耗的资源是非常可观的!在长连接中虽然带来的改善没有短连接的那么明显,但是好处是显而易见的.但并不是越大越好大了反而 浪费资源这个的确定一般认为和物理内存有一定关系,如下:
复制代码代码如下:
1G —> 8
2G —> 16
3G —> 32
>3G —> 64
如果短连接多的话可以适当加大.
thread_stack
每个连接被创建的时候,mysql分配给它的内存.这个值一般认为默认就可以应用于大部分场景了,除非必要非则不要动它.
thread_handing
运用Thread_Cache处理连接的方式,5.1.19添加的新特性.有两个值可选[no-threads|one-thread-per-connection] 看字面意思大家也该猜出八九分了,呵呵,no-threads 服务器使用一个线程,one-thread-per-connection 服务器为每个客户端请求使用一个线程.原手册中提到,no-threads是在Linux下调试用的.
复制代码代码如下:
mysql> show variables like ‘thread%‘;
+——————-+—————————+
| Variable_name | Value |
+——————-+—————————+
| thread_cache_size | 32 |
| thread_handling | one-thread-per-connection |
| thread_stack | 196608 |
+——————-+—————————+
3 rows in set (0.01 sec)
mysql> show status like ‘%connections%‘;
+———————-+——–+
| Variable_name | Value |
+———————-+——–+
| Connections | 199156 |
| Max_used_connections | 31 |
+———————-+——–+
2 rows in set (0.00 sec)
mysql> show status like ‘%thread%‘;
+————————+——–+
| Variable_name | Value |
+————————+——–+
| Delayed_insert_threads | 0 |
| Slow_launch_threads | 0 |
| Threads_cached | 3 |
| Threads_connected | 6 |
| Threads_created | 8689 |
| Threads_running | 5 |
+————————+——–+
6 rows in set (0.00 sec)
通过以上3个命令,可以看到服务器的 thread_cache池中最多可以存放32个连接线程,为每个客户端球使用一个线程.为每个连接的线程分配192k的内存空间.
服 务器总共有199156次连接,最大并发连接数为31,当前在thread_cashe池中的连接数为3个,连接数为6个,处于活跃状态的有5个,共创建 了8689次连接.显然这里以短连接为主.可以算出thread_cache命中率,公式为:
复制代码代码如下:
Thread_Cache_Hit=(Connections-Thread_created)/Connections*100%
当前服务器的Thread_cache命中率约为95.6%这个结果我还是比较满意的.但是可以看出 thread_cache_size有点多余改成16或8更合理一些.
【TABLE_OPEN_CACHE】
==========================================================================================================
由于MySQL是多线程的机制,为了提高性能,每个线程都是独自打开自己需要的表的文件描 述符,而不是通过共享已经打开的.针对不同存储引擎处理的方法当然也不一样.
在myisam表引擎中,数据文件的描述符 (descriptor)是不共享的,但是索引文件的描述符却是所有线程共享的.Innodb中和使用表空间类型有关,假如是共享表空间那么实际就一个数 据文件,当然占用的数据文件描述符就会比独立表空间少.
个人感觉有点像php里面的fopen打开一个连接,操作完数据之后,并不立即 关闭,而是缓存起来,等待下一个连接这个文件的请求就不必去重新打开文件了,不知样理解对不对,哈.
手册上有段关于打开表时的描述:
复制代码代码如下:
A MyISAM table is opened for each concurrent access. This means the table needs to be opened twice if two threads access the same table or if a thread accesses the table twice in the same query (for example, by joining the table to itself). Each concurrent open requires an entry in the table cache. The first open of any MyISAM table takes two file descriptors: one for the data file and one for the index file. Each additional use of the table takes only one file descriptor for the data file. The index file descriptor is shared among all threads.
如果你正用 HANDLER tbl_name OPEN语句打开一个表,将为该线程专门分配一个表。该表不被其它线程共享,只有线程调用HANDLER tbl_name CLOSE或线程终止后才被关闭。表关闭后,被拉回表缓存中(如果缓存不满)。
mysql手册上给的建议大小 是:table_cache=max_connections*n
n表示查询语句中最大表数, 还需要为临时表和文件保留一些额外的文件描述符。
这个数据遭到很多质疑,table_cache够用就好,检查 Opened_tables值,如果这个值很大,或增长很快那么你就得考虑加大table_cache了.
在下面的条件下,未使用的表 将被关闭并从表缓存中移出:
当缓存满了并且一个线程试图打开一个不在缓存中的表时。
当缓存包含超过table_cache个条目,并且缓存中的表不再被任何线程使用。
当表刷新操作发生。当执行FLUSH TABLES语句或执行mysqladmin flush-tables或mysqladmin refresh命令时会发生。
当表缓存满时,服务器使用下列过程找到一个缓存入口来使用:
当前未使用的表被释放,以最近最少使用顺序。
如果缓存满了并且没有表可以释放,但是一个新表需要打开,缓存必须临时被扩大。
如果缓存处于一个临时扩大状态并且一个表从在用变为不在用状态,它被关闭并从缓存中释放。
几个关于table_cache的 状态值:
1. table_cache:所有线程打开的表的数目。增大该值可以增加mysqld需要的文件描述符的数量。默认值是64.
2. open_tables:当前打开的表的数量.
3. opened_tables :Number of table cache misses,如果opened_tables较大,table_cache 值可能太小.
4. Open_table_definitions : The number of cached .frm files. This variable was added in MySQL 5.1.3.
5. Opened_table_definitions : The number of .frm files that have been cached. This variable was added in MySQL 5.1.24.