mysql 비디오 튜토리얼이 칼럼에서는 시간 초과 변수
권장(무료): mysql 비디오 튜토리얼
1.
mysql을 열고 '%timeout%'와 같은 변수 표시
명령을 사용하여 살펴보니, 모르면 아래와 같은 결과가 나옵니다. 타임아웃과 관련된 변수가 너무 많아서 겁이 납니다. . mysql에 대한 나의 이해가 충분하지 않은 것으로 나타났습니다. 이러한 시간 초과는 무엇을 의미합니까? 나는 오후에 몇 가지 작은 실험을 수행하고 마침내 한두 가지 실수가 있으면 언제든지 문의하십시오. 아아. show variables like '%timeout%'
命令一看,不看不知道,一看吓一跳,结果如下面所示,这么多timeout相关变量,一下就吓尿了。。原来对mysql的了解原来是如此的不够,好了,这么些timeout究竟各自是什么意思,花了一下午去学习,做了几个小实验,总算明白了一二,如有错误,请不吝赐教啊。
mysql> show variables like '%timeout%'; +-----------------------------+----------+ | Variable_name | Value | +-----------------------------+----------+ | connect_timeout | 10 | | delayed_insert_timeout | 300 | | innodb_flush_log_at_timeout | 1 | | innodb_lock_wait_timeout | 50 | | innodb_rollback_on_timeout | OFF | | interactive_timeout | 28800 | | lock_wait_timeout | 31536000 | | net_read_timeout | 30 | | net_write_timeout | 60 | | rpl_stop_slave_timeout | 31536000 | | slave_net_timeout | 3600 | | wait_timeout | 28800 | +-----------------------------+----------+
2.分析
下面从timeout里面找些比较常用的出来逐个分析下。
2.1 connect_timeout
connect_timeout指的是连接过程中握手的超时时间,在5.0.52以后默认为10秒,之前版本默认是5秒。官方文档是这样说的:
connect_timeout: The number of seconds that the mysqld server waits for a connect packet before responding with Bad handshake. The default value is 10 seconds as of MySQL 5.0.52 and 5 seconds before that
mysql的基本原理应该是有个监听线程循环接收请求,当有请求来时,创建线程(或者从线程池中取)来处理这个请求。由于mysql连接采用TCP协议,那么之前势必是需要进行TCP三次握手的。TCP三次握手成功之后,客户端会进入阻塞,等待服务端的消息。服务端这个时候会创建一个线程(或者从线程池中取一个线程)来处理请求,主要验证部分包括host和用户名密码验证。host验证我们比较熟悉,因为在用grant命令授权用户的时候是有指定host的。用户名密码认证则是服务端先生成一个随机数发送给客户端,客户端用该随机数和密码进行多次sha1加密后发送给服务端验证。如果通过,整个连接握手过程完成。(具体握手过程后续找到资料再分析)
由此可见,整个连接握手可能会有各种可能出错。所以这个connect_timeout值就是指这个超时时间了。可以简单测试下,运行下面的telnet命令会发现客户端会在10秒后超时返回。
telnet localhost 3306
在超时之前mysql中该连接状态如下:
256 | unauthenticated user | localhost:60595 | NULL | Connect | NULL | Reading from net | NULL
2.2 interactive_timeout & wait_timeout
还是先看官方文档,从文档上来看wait_timeout和interactive_timeout都是指不活跃的连接超时时间,连接线程启动的时候wait_timeout会根据是交互模式还是非交互模式被设置为这两个值中的一个。如果我们运行mysql -uroot -p
The number of seconds the server waits for activity on a noninteractive connection before closing it. On thread startup, the session wait_timeout value is initialized from the global wait_timeout value or from the global interactive_timeout value, depending on the type of client (as defined by the CLIENT_INTERACTIVE connect option to mysql_real_connect()).
2. 분석
타임아웃에서 자주 사용되는 것들을 찾아서 하나씩 분석해 보겠습니다.2.1 connect_timeout
connect_timeout은 연결 과정 중 Handshake 시간 초과를 의미하며, 5.0.52 이후 기본값은 10초이고, 이전 버전에서는 기본값이 5초였습니다. 공식 문서에는 다음과 같이 나와 있습니다.mysql> set global interactive_timeout=3; ##设置交互超时为3秒mysql의 기본 원칙은 요청이 들어오면 요청을 처리하기 위해 스레드가 생성되거나 스레드 풀에서 가져오는 수신 스레드가 있어야 한다는 것입니다. . mysql 연결은 TCP 프로토콜을 사용하므로 이전에 TCP 3방향 핸드셰이크가 수행되어야 합니다. TCP 3방향 핸드셰이크가 성공한 후 클라이언트는 차단에 들어가 서버의 메시지를 기다립니다. 이때 서버는 요청을 처리하기 위해 스레드를 생성하거나 스레드 풀에서 스레드를 가져옵니다. 주요 확인 부분에는 호스트와 사용자 이름 및 비밀번호 확인이 포함됩니다. 사용자에게 권한을 부여하기 위해 grant 명령을 사용할 때 호스트가 지정되므로 우리는 호스트 확인에 익숙합니다. 사용자 이름과 비밀번호 인증을 위해 서버는 먼저 난수를 생성하여 클라이언트에 보냅니다. 클라이언트는 난수와 비밀번호를 사용하여 여러 SHA1 암호화를 수행한 다음 확인을 위해 서버에 보냅니다. 통과하면 전체 연결 핸드셰이크 프로세스가 완료됩니다. (구체적인 Handshake 과정은 추후 찾아 분석해보겠습니다.)전체 연결 Handshake에서 다양한 오류가 발생할 수 있음을 알 수 있습니다. 따라서 connect_timeout 값은 시간 초과 시간을 나타냅니다. 다음 telnet 명령을 실행하여 간단히 테스트할 수 있으며 클라이언트가 시간 초과되고 10초 후에 반환되는 것을 확인할 수 있습니다.
mysql> show variables like '%timeout%'; ##wait_timeout已经被设置为3秒 +-----------------------------+----------+ | Variable_name | Value | +-----------------------------+----------+ | connect_timeout | 10 | | delayed_insert_timeout | 300 | | innodb_flush_log_at_timeout | 1 | | innodb_lock_wait_timeout | 50 | | innodb_rollback_on_timeout | OFF | | interactive_timeout | 3 | | lock_wait_timeout | 31536000 | | net_read_timeout | 30 | | net_write_timeout | 3 | | rpl_stop_slave_timeout | 31536000 | | slave_net_timeout | 3600 | | wait_timeout | 3 | +-----------------------------+----------+시간 초과 전 mysql의 연결 상태는 다음과 같습니다.
mysql> show variables like '%timeout%'; ERROR 2006 (HY000): MySQL server has gone away ##超时重连 No connection. Trying to reconnect... Connection id: 50 Current database: *** NONE *** +-----------------------------+----------+ | Variable_name | Value | +-----------------------------+----------+ | connect_timeout | 10 | | delayed_insert_timeout | 300 | | innodb_flush_log_at_timeout | 1 | | innodb_lock_wait_timeout | 50 | | innodb_rollback_on_timeout | OFF | | interactive_timeout | 3 | | lock_wait_timeout | 31536000 | | net_read_timeout | 30 | | net_write_timeout | 3 | | rpl_stop_slave_timeout | 31536000 | | slave_net_timeout | 3600 | | wait_timeout | 3 | +-----------------------------+----------+
2.2 Interactive_timeout & wait_timeout
먼저 공식 문서를 읽어 보겠습니다. wait_timeout과 Interactive_timeout은 모두 비활성 연결 시간 초과를 참조하며, 연결 시간은 다음과 같습니다. 스레드 시작 이때 wait_timeout은 대화형 모드인지 비대화형 모드인지에 따라 이 두 값 중 하나로 설정됩니다. mysql -uroot -p
명령을 실행하여 mysql에 로그인하면 wait_timeout이 Interactive_timeout 값으로 설정됩니다. wait_timeout 시간 내에 아무 작업도 수행하지 않으면 다시 작업할 때 시간 초과 메시지가 표시되며 이는 mysql 클라이언트가 다시 연결된다는 의미입니다.
The length of time in seconds an InnoDB transaction waits for a row lock before giving up. The default value is 50 seconds. A transaction that tries to access a row that is locked by another InnoDB transaction waits at most this many seconds for write access to the row before issuing the following error: ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction테스트는 다음과 같습니다.
mysql> CREATE TABLE `test` ( `a` int primary key) engine=innodb;mysql을 다시 입력하세요. 이때 다음을 확인할 수 있습니다.
mysql> select * from test; +---+ | a | +---+ | 1 | | 2 | | 3 |
##事务1 加行锁 mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> select * from test where a=2 for update; +---+ | a | +---+ | 2 | +---+ 1 row in set (0.01 sec)🎜🎜2.3 innodb_lock_wait_timeout & innodb_rollback_on_timeout🎜🎜🎜 먼저 공식 문서를 살펴보겠습니다. 이 값은 innodb 엔진에 대한 것입니다. innodb. 기본값은 50초입니다. 시간이 초과되면 현재 문이 롤백됩니다. innodb_rollback_on_timeout이 설정되면 전체 트랜잭션이 롤백됩니다. 그렇지 않으면 트랜잭션이 행 잠금을 기다리고 있는 문만 롤백됩니다. 🎜
##事务2,请求行锁 mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> delete from test where a=1; Query OK, 1 row affected (0.00 sec) mysql> delete from test where a=2; ##请求行锁超时 ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction mysql> select * from test; +---+ | a | +---+ | 2 | | 3 | +---+ 2 rows in set (0.00 sec) mysql> begin; ##这里我们直接开启另外的事务(或者直接commit当前事务),则原来的事务只会回滚第二条语句,最终结果就是test表中只剩下2和3.如果这里我们显示的rollback,则会回滚整个事务,保持1,2,3不变。🎜 동일한 방식으로 테스트해 보겠습니다(먼저 하나의 열만 포함하고 열 이름은 a인 innodb 엔진의 테이블 테스트를 생성합니다). 🎜
This variable specifies the timeout in seconds for attempts to acquire metadata locks. The permissible values range from 1 to 31536000 (1 year). The default is 31536000. This timeout applies to all statements that use metadata locks. These include DML and DDL operations on tables, views, stored procedures, and stored functions, as well as LOCK TABLES, FLUSH TABLES WITH READ LOCK, and HANDLER statements🎜먼저 테스트 데이터 세 조각을 삽입합니다🎜
##第一个session,获取metadata lock mysql> show create table myisam_test; -----------------------------------------------------------+ | Table | Create Table | +----------------------------------------------------------- | myisam_test | CREATE TABLE `myisam_test` ( `i` int(11) NOT NULL, `j` int(11) DEFAULT NULL, PRIMARY KEY (`i`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> select * from myisam_test; +---+------+ | i | j | +---+------+ | 2 | 1 | +---+------+ 1 row in set (0.00 sec) ##另一个session,删除表提示超时 mysql> drop table myisam_test; ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction🎜현재 innodb_rollback_on_timeout =OFF, innodb_lock_wait_timeout=1로 설정하면 두 개의 트랜잭션이 활성화됩니다 🎜
DROP TABLE t; ALTER TABLE t ...; DROP TABLE nt; ALTER TABLE nt ...; LOCK TABLE t ... WRITE;
The number of seconds to wait for more data from a connection before aborting the read. When the server is reading from the client, net_read_timeout is the timeout value controlling when to abort. When the server is writing to the client, net_write_timeout is the timeout value controlling when to abort🎜 그런 다음 innodb_rollback_on_timeout=ON이면 동일한 트랜잭션 2가 시간 초과되지만 이때 새 트랜잭션을 열기 시작하면 잠금을 요청한 전체 트랜잭션이 이전과 같이 시간 초과를 롤백하는 대신 시간 초과가 롤백됩니다. 🎜🎜🎜2.4 lock_wait_timeout🎜🎜🎜문서에서는 간단히 설명하면 lock_wait_timeout은 메타데이터 잠금 대기 시간 초과입니다. 이 시간 제한 매개변수는 모든 메타데이터 잠금 문에서 사용됩니다. 메타데이터 잠금은 mysql 메타데이터 잠금에 참여할 수 있습니다. 트랜잭션이 직렬화될 수 있도록 하기 위해 myisam 또는 innodb 엔진의 테이블이든 트랜잭션이 세션에서 열려 있는 한 작업 테이블의 메타데이터 잠금이 유지됩니다. 이때 다른 세션에서 해당 테이블의 메타데이터를 수정하려는 경우 타임아웃될 때까지 차단됩니다. 🎜
mysql -uroot -h 127.0.0.1 -P 3306 --local-infile=1🎜테스트 예시: 🎜우리는 테스트를 위해 myisam 엔진 테이블 myisam_test를 사용합니다. 레코드(1,1)가 있습니다. 이제 세션을 열고 select 문을 실행합니다. 또한 세션을 연 다음 테이블 삭제와 같은 테이블에 대한 메타데이터 작업을 수행하면 lock_wait_timeout 초 후에 시간 초과가 발생할 때까지 작업이 차단됩니다. 🎜
##第一个session,获取metadata lock mysql> show create table myisam_test; -----------------------------------------------------------+ | Table | Create Table | +----------------------------------------------------------- | myisam_test | CREATE TABLE `myisam_test` ( `i` int(11) NOT NULL, `j` int(11) DEFAULT NULL, PRIMARY KEY (`i`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> select * from myisam_test; +---+------+ | i | j | +---+------+ | 2 | 1 | +---+------+ 1 row in set (0.00 sec) ##另一个session,删除表提示超时 mysql> drop table myisam_test; ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
其中更改表结构的元数据操作指令有如下这些:
DROP TABLE t; ALTER TABLE t ...; DROP TABLE nt; ALTER TABLE nt ...; LOCK TABLE t ... WRITE;
当然,多说一句,对于myisam表的加锁以及并发插入等,这篇博客myisam表锁非常详细,有兴趣的可以看看。
2.5 net_read_timeout & net_write_timeout
文档中描述如下,就是说这两个参数在网络条件不好的情况下起作用。比如我在客户端用load data infile的方式导入很大的一个文件到数据库中,然后中途用iptables禁用掉mysql的3306端口,这个时候服务器端该连接状态是reading from net,在等待net_read_timeout后关闭该连接。同理,在程序里面查询一个很大的表时,在查询过程中同样禁用掉端口,制造网络不通的情况,这样该连接状态是writing to net,然后在net_write_timeout后关闭该连接。slave_net_timeout类似。
The number of seconds to wait for more data from a connection before aborting the read. When the server is reading from the client, net_read_timeout is the timeout value controlling when to abort. When the server is writing to the client, net_write_timeout is the timeout value controlling when to abort
测试:
我创建一个120M的数据文件data.txt。然后登陆到mysql。
mysql -uroot -h 127.0.0.1 -P 3306 --local-infile=1
导入过程设置iptables禁用3306端口。
iptables -A INPUT -p tcp --dport 3306 -j DROP iptables -A OUTPUT -p tcp --sport 3306 -j DROP
可以看到连接状态为reading from net,然后经过net_read_timeout秒后关闭。
3.总结
经过几个实验可以发现,connect_timeout在握手认证阶段(authenticate)起作用,interactive_timeout 和wait_timeout在连接空闲阶段(sleep)起作用,而net_read_timeout和net_write_timeout则是在连接繁忙阶段(query)或者网络出现问题时起作用。
위 내용은 mysql 시간 초과 변수 탐색의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!