MYSQL max_user_connections back_log max_connections引數和Max_used_connections

gaopengtttt發表於2017-05-14
原創請註明出處

1、max_user_connections
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 函式呼叫棧為

點選(此處)摺疊或開啟

  1. #0 0x0000003ca5ee9880 in listen () from /lib64/libc.so.6
  2. #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)
  3.     at /root/mysql5.7.14/percona-server-5.7.14-7/include/mysql/psi/mysql_socket.h:1084
  4. #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
  5. #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
  6. #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
  7. #5 0x0000000000ec089d in network_init () at /root/mysql5.7.14/percona-server-5.7.14-7/sql/mysqld.cc:1864
  8. #6 0x0000000000ec6594 in mysqld_main (argc=52, argv=0x2e97438) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/mysqld.cc:5103
  9. #7 0x0000000000ebd344 in main (argc=9, argv=0x7fffffffe3f8) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/main.cc:25
我們一般程式設計的時候會這樣寫:


點選(此處)摺疊或開啟

  1. if((listen(listenfd,1)) == -1)//這裡設定back_log為1
  2.         {
  3.                 perror("listen");
  4.                 return -1;
  5.         }

  6.         printf("Accepting connections...\n");
  7.     


  8.         while(1)
  9.         {
  10.                 //cliaddr_len = sizeof(cliaddr);
  11.                 //4、接受來自客戶端的連線生成資料互動socket fd

  12.                 if((confd = accept(listenfd,(SCOK_ADD)&cliaddr,&cliaddr_len)) == -1 )
  13.                 {
  14.                         return 1;
  15.                 }
  16.                 else
  17.                 {
  18.                         printf("Client ip:%s Port:%d\n",inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)), ntohs(cliaddr.sin_port));
  19.                         if( (ret = pthread_create(&tid,NULL,do_work,(void*)&confd) )!=0)
  20.                         {
  21.                                 printf("%s\n",strerror(ret));
  22.                                 return 1;
  23.                         }
  24.                         if((ret = pthread_detach(tid)) != 0 )
  25.                         {
  26.                                 printf("%s\n",strerror(ret));
  27.                                 return 1;
  28.                         }
  29.                         printf("thread %lu is create and detach\n",tid);
  30.                 }
  31.                 //write(confd,"a",1);
  32.                 //close(confd);
  33.         }
  34.         close(listenfd);
  35.         return 0;
  36. }



這裡大概讓知道listen() 和 accpet()到底如何使用的,不然光說好像不太好理解。

但是具體代表什麼我們還是要參考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.

作者微信:

               

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2139047/,如需轉載,請註明出處,否則將追究法律責任。

相關文章