MySQL的配置文件my.cnf中默认存在一行skip-external-locking的参数,即“跳过外部锁定”。根据MySQL开发网站的官方解释,External-locking用于多进程条件下为MyISAM数据表进行锁定。
如果你有多台服务器使用同一个数据库目录(不建议),那么每台服务器都必须开启external locking;
调整MySQL运行参数,修改/etc/my.cnf文件调整mysql运行参数重启MySQL后生效,在MySQL4版本以后,一部分内部变量可以在MySQL运行时设置,不过重启MySQL就失效了。
当外部锁定(external-locking)起作用时,每个进程若要访问数据表,则必须等待之前的进程完成操作并解除锁定。由于服务器访问数据表时经常需要等待解锁,因此在单服务器环境下external locking会让MySQL性能下降。所以在很多Linux发行版的源中,MySQL配置文件中默认使用了skip-external-locking来避免external locking。
当使用了skip-external-locking后,为了使用MyISAMChk检查数据库或者修复、优化表,你必须保证在此过程中MySQL服务器没有使用需要操作的表。如果没有停止服务器,也至少需要先运行
1 | mysqladmin flush-tables |
命令,否则数据表可能出现异常。
如果是多服务器环境,希望打开external locking特征,则注释掉这一行即可
1 | # skip-external-locking |
如果是单服务器环境,则将其禁用即可,使用如下语句
在老版本的MySQL中,此参数的写法为:
如果在新版本MySQL配置中依然使用此写法,则可能出现:
[Warning] ‘–skip-locking’ is deprecated and will be removed in a future release. Please use ‘–skip-external-locking’ instead.
【优化建议】利用mysql skip-name-resolve 拔高外部访问速度
mysql skip-name-resolve 提高外部访问速度
设置建议:
对于单台运行的WEB服务器,建议加上:
skip
-
locking
skip
-
name
-
resolve
skip
-
networking
在 PHP链接数据库时使用”LOCALHOST”.这样MySQL 客户端库将覆盖之并尝试连接到本地套接字.(
我们可以从 PHP.INI 中
代码:
; Default socket name
for
local MySQL connects. If empty, uses the built
-
in
; MySQL defaults.
mysql.default_socket
=
/
tmp
/
mysql.sock
看出 默认情况下 UNIX 将访问
/
tmp
/
mysql.sock)
*
以下是部分选项解释:
my.cnf 默认是不存在的.你可以在
/
usr
/
local
/
share
/
mysql
/
下看到:
1
. my
-
huge.cnf
2
. my
-
innodb
-
heavy
-
4G.cnf
3
. my
-
large.cnf
4
. my
-
medium.cnf
5
. my
-
small.cnf
等文 件.将其中合适你机器配置的文件拷贝到
/
etc
/
my.cnf或mysql data目录
/
my.cnf(
/
var
/
db
/
mysql)下或
~/
.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
=
384
指定MySQL可能的连接数量。当 MySQL主线程在很短的时间内接收到非常多的连接请求,该参数生效,主线程花费很短的时间检查连接并且启动一个新线程。
back_log参数 的值指出在MySQL暂时停止响应新请求之前的短时间内多少个请求可以被存在堆栈中。 如果系统在一个短时间内有很多连接,则需要增大该参数的值,该参数值指定到来的TCP
/
IP连接的侦听队列的大小。不同的操作系统在这个队列大小上有它自 己的限制。
试图设定back_log高于你的操作系统的限制将是无效的。默认值为50。对于Linux系统推荐设置为小于512的整数。
key_buffer_size
=
256M
# key_buffer_size指定用于索引的缓冲区大小,增加它可得到更好的索引处理性能。
对于内存在 4GB左右的服务器该参数可设置为256M或384M。
注意:该参数值设置的过大反而会是服务器整体效率降低!
max_allowed_packet
=
4M
thread_stack
=
256K
table_cache
=
128K
sort_buffer_size
=
6M
查询排序时所能使用的缓冲区大小。注意:该参数对应的分配内存是每连接独占!如果有100个连接,那么实际分配的总共排序缓冲区大 小为100 ×
6
= 600MB。所以,对于内存在4GB左右的服务器推荐设置为6
-
8M。
read_buffer_size
=
4M
读查询操作所能使用的缓冲区大小。和sort_buffer_size一样,该参数对应的分配内存也是每连接独享!
join_buffer_size
=
8M
联合查询操作所能使用的缓冲区大小,和sort_buffer_size一样,该参数对应的分配内存也是每连接独享!
myisam_sort_buffer_size
=
64M
table_cache
=
512
thread_cache_size
=
64
query_cache_size
=
64M
指定MySQL查询缓冲区的大小。可以通过在MySQL控制台执行以下命令观察:
代码:
#
>
SHOW VARIABLES LIKE ‘
%
query_cache
%
’;
#
>
SHOW STATUS LIKE ‘Qcache
%
’;
如果 Qcache_lowmem_prunes的值非常大,则表明经常出现缓冲不够的情况;
如果Qcache_hits的值非常大,则表明查询缓冲使 用非常频繁,如果该值较小反而会影响效率,那么可以考虑不用查询缓冲;Qcache_free_blocks,如果该值非常大,则表明缓冲区中碎片很多。
tmp_table_size
=
256M
max_connections
=
768
指定 MySQL允许的最大连接进程数。如果在访问论坛时经常出现Too Many Connections的错误提 示,则需要增大该参数值。
max_connect_errors
=
10000000
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数据库服务器则不要开启该选项!否则将无法正 常连接!
【问题分析】mysql中的 skip-name-resolve 问题
今天安装了个,重启时发现Error.log有下面提示:
100616 21:05:15 [Warning] 'user' entry 'root@hexuweb101' ignored in --skip-name-resolve mode. |
2 | 100616 21:05:15 [Warning] 'user' entry '@hexuweb101' ignored in --skip-name-resolve mode |
产生的原因是 my.cnf 中我设置了 skip-name-resolve,skip-name-resolve是禁用dns解析,所以在mysql的授权表中就不能使用主机名了,只能使用IP 。
与是我删除了user table 中的host是域名项就可以了。
如果你有一个很慢的DNS和许多主机,你可以通过用--skip-name-resolve禁用DNS查找或增加HOST_CACHE_SIZE定义(默认值:128)并重新编译mysqld来提高性能。
你可以用--skip-host-cache选项启动服务器来禁用主机名缓存。要想清除主机名缓存,执行FLUSH HOSTS语句或执行mysqladmin flush-hosts命令。
如果你想要完全禁止TCP/IP连接,用--skip-networking选项启动mysqld。
新加的一台服务器,连接内网中的一台mysql服务器的时候,经常出现超时。
登陆到mysql,查看进程的信息
show processlist;
发现大量的进程的状态为 login
原来默认的时候mysql启动时是不使用 skip-name-resolve选项的,这样的话,从其它主机的连接会比较慢,因为mysql会对这个ip做dns反向查询,导致大量的连接处于 login状态…..
解决这个问题有两个办法
一是加入 skip-name-resolve参数重启mysql
二是在 /etc/hosts中加入一句 192.168.0.2 server2 其中 192.168.0.2是新加的服务器的内网ip,server2是新服务器的主机名
在mysql客户端登陆mysql服务器的登录速度太慢的解决方案一篇文章中,我介绍了如何通过在my.ini文件(linux下是my.cnf文 件)中 添加”SKIP-NAME-RESOLVE”的参数设置,使得客户端在登录服务器的时候不通过主机解析这一关,直接登陆的方法,以此来提高登录速度。
这里要介绍一下这种方法的负面作用,以及不合理的时机使用这种方法会引发的不可发现的错误。
首先,回顾一下在my.ini文件中添加”SKIP-NAME-RESOLVE”参数来提高访问速度的原理:
在没有设置该参数的时候,客户端在登陆请求发出后,服务器要解析请求者是谁,经过解析,发现登录者是从另外的电脑登录的,也就是说不是服务器本机, 那么, 服务器会到mysql.user表中去查找是否有这个用户,假设服务器IP是192.168.0.1,而客户机的IP是192.168.0.2;那么查询 的顺序是先找‘root’@'192.168.0.2′这 个user是否存在,若存在,则匹配这个用户登陆,并加载权限列表。若没有该用户,则查找‘root’@'%’这个用户是否存在,若存在,则加载权限列表。否则,登 录失败。
在设置了SKIP-NAME-RESOLVE参数后,客户端的登录请求的解析式同上面一样的,但是在服务器本机的解析过程却发生了改变:服务器会把在本机 登录的用户自动解析为‘root’@'127.0.0.1′; 而不是‘root’@'localhost’;这样 一来就坏了,因为我们在服务器上登录是为了进行一些维护操作,但是显然,‘root’@'127.0.0.1′这个用户是被默认为‘root’@'%’这个用户的,这个用户还没有足够得权限去执行一些超 级管理员‘root’@'localhost’才能 执行的大作。因为未分配权限。
所以结论是:加入你在服务器本机上登录mysql服务器的话,要么先取消SKIP-NAME-RESOLVE的参数设置,重新启动服务器再登陆,设置完成 后,再设置上该参数;要么就给‘root’@'127.0.0.1′分 配超级管理员权限,但这么做显然是不明智的,因为任何人在任何机器上都可以用这个用户执行管理员操作,前提是知道了密码。
我有一次在mysql服务器上执行数据库创建脚本,并同时创建表、触发器、存储过程等。结果,总是失败,经过了一上午的折腾,最后发现时这个参数造成我以‘root’@'127.0.0.1′这个用户登陆了服 务器,这个用户没有创建触发器的权限。后来,取消了SKIP-NAME-RESOLVE参数后,执行成功,再把该参数设置回去。重启。OK。
所以,在设置这个参数的时候一定要注意时机:先用超级管理员将所有的用户创建好,再将权限分配好之后,才设置这个参数生效。
【参数说明】
[mysqld]
max_allowed_packet=16M
增加该变量的值十分安全,这是因为仅当需要时才会分配额外内存。例如,仅当你发出长查询或mysqld必须返回大的结果行时mysqld才会分配更多内存。该变量之所以取较小默认值是一种预防措施,以捕获客户端和服务器之间的错误信息包,并确保不会因偶然使用大的信息包而导致内存溢出。
如果你正是用大的BLOB值,而且未为mysqld授予为处理查询而访问足够内存的权限,也会遇到与大信息包有关的奇怪问题。如果怀疑出现了该情况,请尝试在mysqld_safe脚本开始增加ulimit -d 256000,并重启mysqld。
##########################################
##### MySQL怎样打开和关闭数据库表 #####
##########################################
table_cache, max_connections和max_tmp_tables影响服务器保持打开的文件的最大数量。如果你增加这些值的一个或两个,你可以遇到你的操作系统每个进程打开文件描述符的数量上强加的限制。然而,你可以能在许多系统上增加该限制。请教你的OS文档找出如何做这些,因为改变限制的方法各系统有很大的不同。
table_cache与max_connections有关。例如,对于200个打开的连接,你应该让一张表的缓冲至少有200 * n,这里n是一个联结(join)中表的最大数量。
打开表的缓存可以增加到一个table_cache的最大值(缺省为64;这可以用mysqld的-O table_cache=#选项来改变)。一个表绝对不被关闭,除非当缓存满了并且另外一个线程试图打开一个表时或如果你使用mysqladmin refresh或mysqladmin flush-tables。
当表缓存满时,服务器使用下列过程找到一个缓存入口来使用:
不是当前使用的表被释放,以最近最少使用(LRU)顺序。
如果缓存满了并且没有表可以释放,但是一个新表需要打开,缓存必须临时被扩大。
如果缓存处于一个临时扩大状态并且一个表从在用变为不在用状态,它被关闭并从缓存中释放。
对每个并发存取打开一个表。这意味着,如果你让2个线程存取同一个表或在同一个查询中存取表两次(用AS),表需要被打开两次。任何表的第一次打开占2个文件描述符;表的每一次额外使用仅占一个文件描述符。对于第一次打开的额外描述符用于索引文件;这个描述符在所有线程之间共享
skip-networking
不在tcp/ip端口上进行监听,所有的连接都是通过本地的socket文件连接,这样可以提高安全性,确定是不能通过网络连接数据库。
skip-locking
避免mysql的外部锁定,增强稳定性
skip-name-resolve
避免mysql对外部的连接进行DNS解析,若使用此设置,那么远程主机连接时只能使用ip,而不能使用域名
max_connections = 3000
指定mysql服务所允许的最大连接进程数,
max_connect_errors = 1000
每个主机连接允许异常中断的次数,当超过该次数mysql服务器将禁止该主机的连接请求,直到mysql服务重启,或者flushhosts命令清空host的相关信息
table_cache = 614k
表的高速缓冲区的大小,当mysql访问一个表时,如果mysql表缓冲区还有空间,那么这个表就会被打开通放入高速缓冲区,好处是可以更快速的访问表中的内容。
如果open_tables和opened_tables的值接近该值,那么久该增加该值的大小
max_allowed_packet = 4M
设定在网络传输中一次可以传输消息的最大值,系统默认为1M,最大可以是1G
sort_buffer_size = 16M
排序缓冲区用来处理类似orderby以及groupby队列所引起的排序,系统默认大小为2M,该参数对应分配内存是每个连接独占的,若有100个连接,实际分配的排序缓冲区大小为6*100;推荐设置为6M-8M
join_buffer_size 8M
联合查询操作所使用的缓冲区大小。
thread_cache_size = 64
设置threadcache池中可以缓存连接线程的最大数量,默认为0,该值表示可以重新利用保存在缓存中线程的数量,当断开连接时若缓存中还有空间,那么客户端的线程将被放到缓存中,如果线程重新被请求,那么请求将从缓存中读取,若果缓存中是空的或者是新的请求,那么线程将被重新创建。设置规律为:1G内存设置为8,2G内存设置为16,4G以上设置为64
query_cache_size = 64M
指定mysql查询缓冲区的大小,用来缓冲select的结果,并在下一次同样查询的时候不再执行查询而直接返回结果,根据Qcache_lowmem_prunes的大小,来查看当前的负载是否足够高
query_cache_limit = 4M
只有小于该值的结果才被缓冲,放置一个极大的结果将其他所有的查询结果都覆盖
tmp_table_size 256M
内存临时表的大小,如果超过该值,会将临时表写入磁盘
default_storage_engine = MYISAM
创建表时默认使用的存储引擎
log-bin=mysql-bin
打开二进制日志功能
key_buffer_size = 384M
指定索引缓冲区的大小,内存为4G时刻设置为256M或384M
read_buffer_size = 8M
用来做MYISAM表全表扫描的缓冲大小
。。。。。。。。。
[参考资料]
1、MySQL的my.cnf文件里的配置项解释_数据库技术http://www.linuxidc.com/Linux/2009-05/19804.htm
2、my.cnf和my.ini配置详解-CSDN.NET http://blog.csdn.net/johnstrive/article/details/46770447
3、MySQL配置文件my.cnf参数优化和中文详解_Mysql_脚本之家 http://www.jb51.net/article/48082.htm