原创请注明出处
1、 max_user_conne ctions
max_user_connections这个参数是单个用户允许连接的最大会话数量,在建立用户的时候也有类似的限制,这里仅仅说的是这个参数
下面是官方文档说明:
The maximum number of simultaneous connections permitted to any given MySQL user account. A
value of 0 (the default) means “no limit.”
This variable has a global value that can be set at server startup or runtime. It also has a read-only
session value that indicates the effective simultaneous-connection limit that applies to the account
associated with the current session. The session value is initialized as follows:
? If the user account has a nonzero MAX_USER_CONNECTIONS resource limit, the session
max_user_connections value is set to that limit.
? Otherwise, the session max_user_connections value is set to the global value.
报错如下:
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1203 (42000): User root already has more than 'max_user_connections' active connections
2、max_connections
max_connections:这个参数是MYSQL服务端允许的最大连接会话数量,没什么好说的
下面是官方文档说明:
The maximum permitted number of simultaneous client connections. By default, this is 151. See
Section B.5.2.7, “Too many connections”, for more information.
Increasing this value increases the number of file descriptors that mysqld requires. If the required
number of descriptors are not available, the server reduces the value of max_connections. See
Section 9.4.3.1, “How MySQL Opens and Closes Tables”, for comments on file descriptor limits.
测试也非常简单报错如下:
[root@testmy ~]# /mysqldata/mysql5.7/bin/mysql --socket=/mysqldata/mysql5.7/mysqld3307.sock -utestmy -pGelc123123
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1040 (HY000): Too many connections
3、 Max_used_connections 、Max_used_connections_time
这里还大概说一下
mysql> show global status like '%max%';
+-----------------------------------+---------------------+
| Variable_name | Value |
+-----------------------------------+---------------------+
| Max_used_connections | 7 |
| Max_used_connections_time | 2017-05-10 17:10:56 |
这两个状态说的是MYSQL SERVER自上次启动起来最大连接数量和发生的时间,和上面讲参数没任何关系。
? Max_used_connections
The maximum number of connections that have been in use simultaneously since the server started.
? Max_used_connections_time
The time at which Max_used_connections reached its current value. This variable was added in
MySQL 5.7.5
4、 back_log
back_log:这个参数的解释相对于比较复杂和难以理解,难以理解是因为大多DBA对LINUX下C编程不熟悉,
这个参数说的就是sokcet编程中的listen调用的时候使用形参back_log
函数原型
int listen(int sockfd, int backlog);
man page中描述:
DESCRIPTION
listen() marks the socket referred to by sockfd as a passive socket, that is, as a socket that will be used to accept incoming connection requests using accept(2).
The sockfd argument is a file descriptor that refers to a socket of type SOCK_STREAM or SOCK_SEQPACKET.
The backlog argument defines the maximum length to which the queue of pending connections for sockfd may grow. If a connection request arrives when the queue is full, the client may receive an error with
an indication of ECONNREFUSED or, if the underlying protocol supports retransmission, the request may be ignored so that a later reattempt at connection succeeds.
RETURN VALUE
On success, zero is returned. On error, -1 is returned, and errno is set appropriately.
sockfd没什么好说的create的时候返回的scoket文件描述符,这里的backlog实际上是一个未决连接的一个队列,如果超过可能值会返回ECONNREFUSED的一个错误,但是如果底层协议支持retransmission,
,这个错误将被忽略然后再次尝试知道成功。它取决于LINUX系统设置/proc/sys/net/core/somaxconn和函数backlog的小值当然LINUX系统默认这个值是128.
下面是MYSQL官方文档描述:
The number of outstanding connection requests MySQL can have. This comes into play when the
main MySQL thread gets very many connection requests in a very short time. It then takes some
time (although very little) for the main thread to check the connection and start a new thread. The
back_log value indicates how many requests can be stacked during this short time before MySQL
momentarily stops answering new requests. You need to increase this only if you expect a large number
of connections in a short period of time.
In other words, this value is the size of the listen queue for incoming TCP/IP connections. Your operating
system has its own limit on the size of this queue. The manual page for the Unix listen() system
call should have more details. Check your OS documentation for the maximum value for this variable.
back_log cannot be set higher than your operating system limit
实际上它说在有大量连接时候,可能出现这样的问题,这里使用了一个short time来描述,也明确告诉你这个
参数和 Unix listen() system调用有关。
MYSQL listen 函数调用栈为
我们一般编程的时候会这样写:
但是具体代表什么我们还是要参考LINUX 系统编程手册和实际编程的模型我们先来看这样一张图
我刻意讲一部分中文内容截取出来更加方便大家理解。
当服务端忙于处理其他客户端的时候listen()和accept()之间的这种非原子化的流程消耗的时间将会放大,一般来说这里是很短的一段的时间,也就是
MYSQL官方手册说的short time,在这里的客户端connect()过来,还没到服务端accept()函数调用这个时候将会进入未决连接请求队列,有了这个基础
我们来梳理一下这个流程
MYSQL connect()-->>服务端listen()-->>进入未决连接队列-->>服务端accpet()-->>建立连接传输交互
那么这个参数实际控制的是一种阻塞,如果我设置back_log为2,那么同时进入未决连接队列的连接就是2,这个时候如果这两个连接都还没有accpet()
完成那么,又来的新连接只有等待进入这个队列,就是一种阻塞。
这种问题实在不好测试,我使用程序讲back_log设置1模拟了一下大量连接,确实可能出现堵塞问题,但是没找到如何查看back_log当前未决连接个数的输出,
所以说服力也就有限,所以先放到这里,如果以后找到方法模拟一下。
下面资料转自网络
http://blog.chinaunix.net/uid-24782829-id-3456109.html
listen函数仅由TCP服务器调用,它做两件事情:
1、当socket函数创建一个套接口时,它被假设为一个主动套装口,也就是说,它是一个将调用connet发起连接的客户套接口。listen函数把一个未连接的套接口转换成一个被动套接口,指示内核应接受指向该套接口的连接请求。根据TCP状态转换图,调用listen导致套接口从CLOSED状态转换到LISTEN状态。
2、本函数的第二个参数规定了内核应该为相应套接口排队的最大连接个数。
为了更好的理解backlog参数,我们必须认识到内核为任何一个给定的监听套接口维护两个队列:
1、未完成连接队列(incomplete connection queue),每个这样的SYN分节对应其中一项:已由某个客户发出并到达服务器,而服务器正在等待完成相应的TCP三路握手过程。这些套接口处于SYN_RCVD状态。
2、已完成连接队列(completed connection queue),每个已完成TCP三路握手过程的客户对应其中一项。这些套接口处于ESTABLISHED状态。
当来自客户的SYN到达时,TCP在未完成连接队列中创建一个新项,然后响应以三路握手的第二个分节:服务器的SYN响应,其中稍带对客户SYN的ACK(即SYN+ACK)。这一项一直保留在未完成连接队列中,直到三路握手的第三个分节(客户对服务器SYN的ACK)到达或者该项超时为止(曾经源自Berkeley的实现为这些未完成连接的项设置的超时值为75秒)。如果三路握手正常完成,该项就从未完成连接队列移到已完成连接队列的队尾。当进程调用accept时,已完成连接队列中的队头项将返回给进程,或者如果该队列为空,那么进程将被投入睡眠,直到TCP在该队列中放入一项才唤醒它。
未完成队列(incomplete connection queue)的长度现在由/proc/sys/net/ipv4/tcp_max_syn_backlog设置,在现在大多数最新linux内核都是默认512,这个设置有效的前提是系统的syncookies功能被禁用,如果系统的syncookies功能被启用,那么这个设置是无效的。Syncookies是在内核编译的时候设置的,查看syncookies是否启动:
cat /proc/sys/net/ipv4/tcp_syncookies
如果是“1”说明已启用,为“0”说明未启用。
那么为syncookies是做什么的呢,为什么它会和未完成队列有关系。简单的说它是为防范SYN Flood攻击的设计。具体请参考“syncookies介绍”(http://baike.baidu.com/view/9033755.htm)。
继续看backlog,如果我们给listen的backlog参数设值超过了/proc/sys/net/core/somaxconn,那么backlog参数的值为自动被改写为/proc/sys/net/core/somaxconn的值,它的默认大小为128.
作者微信:
1、 max_user_conne ctions
max_user_connections这个参数是单个用户允许连接的最大会话数量,在建立用户的时候也有类似的限制,这里仅仅说的是这个参数
下面是官方文档说明:
The maximum number of simultaneous connections permitted to any given MySQL user account. A
value of 0 (the default) means “no limit.”
This variable has a global value that can be set at server startup or runtime. It also has a read-only
session value that indicates the effective simultaneous-connection limit that applies to the account
associated with the current session. The session value is initialized as follows:
? If the user account has a nonzero MAX_USER_CONNECTIONS resource limit, the session
max_user_connections value is set to that limit.
? Otherwise, the session max_user_connections value is set to the global value.
报错如下:
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1203 (42000): User root already has more than 'max_user_connections' active connections
2、max_connections
max_connections:这个参数是MYSQL服务端允许的最大连接会话数量,没什么好说的
下面是官方文档说明:
The maximum permitted number of simultaneous client connections. By default, this is 151. See
Section B.5.2.7, “Too many connections”, for more information.
Increasing this value increases the number of file descriptors that mysqld requires. If the required
number of descriptors are not available, the server reduces the value of max_connections. See
Section 9.4.3.1, “How MySQL Opens and Closes Tables”, for comments on file descriptor limits.
测试也非常简单报错如下:
[root@testmy ~]# /mysqldata/mysql5.7/bin/mysql --socket=/mysqldata/mysql5.7/mysqld3307.sock -utestmy -pGelc123123
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1040 (HY000): Too many connections
3、 Max_used_connections 、Max_used_connections_time
这里还大概说一下
mysql> show global status like '%max%';
+-----------------------------------+---------------------+
| Variable_name | Value |
+-----------------------------------+---------------------+
| Max_used_connections | 7 |
| Max_used_connections_time | 2017-05-10 17:10:56 |
这两个状态说的是MYSQL SERVER自上次启动起来最大连接数量和发生的时间,和上面讲参数没任何关系。
? Max_used_connections
The maximum number of connections that have been in use simultaneously since the server started.
? Max_used_connections_time
The time at which Max_used_connections reached its current value. This variable was added in
MySQL 5.7.5
4、 back_log
back_log:这个参数的解释相对于比较复杂和难以理解,难以理解是因为大多DBA对LINUX下C编程不熟悉,
这个参数说的就是sokcet编程中的listen调用的时候使用形参back_log
函数原型
int listen(int sockfd, int backlog);
man page中描述:
DESCRIPTION
listen() marks the socket referred to by sockfd as a passive socket, that is, as a socket that will be used to accept incoming connection requests using accept(2).
The sockfd argument is a file descriptor that refers to a socket of type SOCK_STREAM or SOCK_SEQPACKET.
The backlog argument defines the maximum length to which the queue of pending connections for sockfd may grow. If a connection request arrives when the queue is full, the client may receive an error with
an indication of ECONNREFUSED or, if the underlying protocol supports retransmission, the request may be ignored so that a later reattempt at connection succeeds.
RETURN VALUE
On success, zero is returned. On error, -1 is returned, and errno is set appropriately.
sockfd没什么好说的create的时候返回的scoket文件描述符,这里的backlog实际上是一个未决连接的一个队列,如果超过可能值会返回ECONNREFUSED的一个错误,但是如果底层协议支持retransmission,
,这个错误将被忽略然后再次尝试知道成功。它取决于LINUX系统设置/proc/sys/net/core/somaxconn和函数backlog的小值当然LINUX系统默认这个值是128.
下面是MYSQL官方文档描述:
The number of outstanding connection requests MySQL can have. This comes into play when the
main MySQL thread gets very many connection requests in a very short time. It then takes some
time (although very little) for the main thread to check the connection and start a new thread. The
back_log value indicates how many requests can be stacked during this short time before MySQL
momentarily stops answering new requests. You need to increase this only if you expect a large number
of connections in a short period of time.
In other words, this value is the size of the listen queue for incoming TCP/IP connections. Your operating
system has its own limit on the size of this queue. The manual page for the Unix listen() system
call should have more details. Check your OS documentation for the maximum value for this variable.
back_log cannot be set higher than your operating system limit
实际上它说在有大量连接时候,可能出现这样的问题,这里使用了一个short time来描述,也明确告诉你这个
参数和 Unix listen() system调用有关。
MYSQL listen 函数调用栈为
点击(此处)折叠或打开
- #0 0x0000003ca5ee9880 in listen () from /lib64/libc.so.6
- #1 0x00000000016e3482 in inline_mysql_socket_listen (src_file=0x21c5f30 "/root/mysql5.7.14/percona-server-5.7.14-7/sql/conn_handler/socket_connection.cc", src_line=522, mysql_socket=..., backlog=2)
- at /root/mysql5.7.14/percona-server-5.7.14-7/include/mysql/psi/mysql_socket.h:1084
- #2 0x00000000016e5b1b in TCP_socket::get_listener_socket (this=0x7fffffffdb40) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/conn_handler/socket_connection.cc:522
- #3 0x00000000016e41d8 in Mysqld_socket_listener::setup_listener (this=0x339d550) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/conn_handler/socket_connection.cc:808
- #4 0x0000000000ecefed in Connection_acceptor<Mysqld_socket_listener>::init_connection_acceptor (this=0x2fd4a90) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/conn_handler/connection_acceptor.h:55
- #5 0x0000000000ec089d in network_init () at /root/mysql5.7.14/percona-server-5.7.14-7/sql/mysqld.cc:1864
- #6 0x0000000000ec6594 in mysqld_main (argc=52, argv=0x2e97438) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/mysqld.cc:5103
- #7 0x0000000000ebd344 in main (argc=9, argv=0x7fffffffe3f8) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/main.cc:25
点击(此处)折叠或打开
- if((listen(listenfd,1)) == -1)//这里设置back_log为1
- {
- perror("listen");
- return -1;
- }
-
- printf("Accepting connections...\n");
-
-
-
- while(1)
- {
- //cliaddr_len = sizeof(cliaddr);
- //4、接受来自客户端的连接生成数据交互socket fd
-
- if((confd = accept(listenfd,(SCOK_ADD)&cliaddr,&cliaddr_len)) == -1 )
- {
- return 1;
- }
- else
- {
- printf("Client ip:%s Port:%d\n",inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)), ntohs(cliaddr.sin_port));
- if( (ret = pthread_create(&tid,NULL,do_work,(void*)&confd) )!=0)
- {
- printf("%s\n",strerror(ret));
- return 1;
- }
- if((ret = pthread_detach(tid)) != 0 )
- {
- printf("%s\n",strerror(ret));
- return 1;
- }
- printf("thread %lu is create and detach\n",tid);
- }
- //write(confd,"a",1);
- //close(confd);
- }
- close(listenfd);
- return 0;
- }
这里大概让知道listen() 和 accpet()到底如何使用的,不然光说好像不太好理解。
我刻意讲一部分中文内容截取出来更加方便大家理解。
当服务端忙于处理其他客户端的时候listen()和accept()之间的这种非原子化的流程消耗的时间将会放大,一般来说这里是很短的一段的时间,也就是
MYSQL官方手册说的short time,在这里的客户端connect()过来,还没到服务端accept()函数调用这个时候将会进入未决连接请求队列,有了这个基础
我们来梳理一下这个流程
MYSQL connect()-->>服务端listen()-->>进入未决连接队列-->>服务端accpet()-->>建立连接传输交互
那么这个参数实际控制的是一种阻塞,如果我设置back_log为2,那么同时进入未决连接队列的连接就是2,这个时候如果这两个连接都还没有accpet()
完成那么,又来的新连接只有等待进入这个队列,就是一种阻塞。
这种问题实在不好测试,我使用程序讲back_log设置1模拟了一下大量连接,确实可能出现堵塞问题,但是没找到如何查看back_log当前未决连接个数的输出,
所以说服力也就有限,所以先放到这里,如果以后找到方法模拟一下。
下面资料转自网络
http://blog.chinaunix.net/uid-24782829-id-3456109.html
listen函数仅由TCP服务器调用,它做两件事情:
1、当socket函数创建一个套接口时,它被假设为一个主动套装口,也就是说,它是一个将调用connet发起连接的客户套接口。listen函数把一个未连接的套接口转换成一个被动套接口,指示内核应接受指向该套接口的连接请求。根据TCP状态转换图,调用listen导致套接口从CLOSED状态转换到LISTEN状态。
2、本函数的第二个参数规定了内核应该为相应套接口排队的最大连接个数。
为了更好的理解backlog参数,我们必须认识到内核为任何一个给定的监听套接口维护两个队列:
1、未完成连接队列(incomplete connection queue),每个这样的SYN分节对应其中一项:已由某个客户发出并到达服务器,而服务器正在等待完成相应的TCP三路握手过程。这些套接口处于SYN_RCVD状态。
2、已完成连接队列(completed connection queue),每个已完成TCP三路握手过程的客户对应其中一项。这些套接口处于ESTABLISHED状态。
当来自客户的SYN到达时,TCP在未完成连接队列中创建一个新项,然后响应以三路握手的第二个分节:服务器的SYN响应,其中稍带对客户SYN的ACK(即SYN+ACK)。这一项一直保留在未完成连接队列中,直到三路握手的第三个分节(客户对服务器SYN的ACK)到达或者该项超时为止(曾经源自Berkeley的实现为这些未完成连接的项设置的超时值为75秒)。如果三路握手正常完成,该项就从未完成连接队列移到已完成连接队列的队尾。当进程调用accept时,已完成连接队列中的队头项将返回给进程,或者如果该队列为空,那么进程将被投入睡眠,直到TCP在该队列中放入一项才唤醒它。
未完成队列(incomplete connection queue)的长度现在由/proc/sys/net/ipv4/tcp_max_syn_backlog设置,在现在大多数最新linux内核都是默认512,这个设置有效的前提是系统的syncookies功能被禁用,如果系统的syncookies功能被启用,那么这个设置是无效的。Syncookies是在内核编译的时候设置的,查看syncookies是否启动:
cat /proc/sys/net/ipv4/tcp_syncookies
如果是“1”说明已启用,为“0”说明未启用。
那么为syncookies是做什么的呢,为什么它会和未完成队列有关系。简单的说它是为防范SYN Flood攻击的设计。具体请参考“syncookies介绍”(http://baike.baidu.com/view/9033755.htm)。
继续看backlog,如果我们给listen的backlog参数设值超过了/proc/sys/net/core/somaxconn,那么backlog参数的值为自动被改写为/proc/sys/net/core/somaxconn的值,它的默认大小为128.
作者微信: