Error 1040 Too many connections

在使用MySQL的過程中,應用程序有時會碰到錯誤:

Error 1040 Too many connections

這個錯誤表示,已經達到MySQL的最大連接數。

什麼是MySQL的最大連接數?

1.最大連接數的定義

max_connections是指MySQL 同時處理的連接的最大數量。
默認的最大連接數是151,
如果希望更大的連接數,可以將max_connections調整爲更大值。
但更大的連接數,也意味着,更大的內存佔用。

實際上的最大連接數是max_connections+1.
有一個連接是預留的,只有SUPER權限的用戶纔可以使用。
SUPER權限的用戶可以使用這個連接,登錄MySQL診斷問題。

更確切一些,是指MySQL同時處理的連接數量。這些連接,包括正在建立的連接,已建立的連接, 以及正在斷開的連接。
已通過簡單demo驗證。基本思路是,在出現"Too many connections"錯誤的時候,看下有多少連接已建立。數據測試顯示,報錯時,並未達到max_connections。
以下是測試代碼, 首先使用普通用戶連接,嘗試不斷建立連接,當出現"Too many connections"錯誤的時候,使用超級權限用戶查詢當前的連接數,打印已經建立的連接數。

package main
import (
        "database/sql"
        "log"
        "sync"

        _ "github.com/go-sql-driver/mysql"

)

var superDB *sql.DB
var superDataBase = "root:Aa123456@tcp(127.0.0.1:3306)/?loc=Local&parseTime=true&timeout=1s&readTimeout=6s"

var DB *sql.DB
var dataBase = "orchestrator:orch_backend_password@tcp(127.0.0.1:3306)/?loc=Local&parseTime=true&timeout=1s&readTimeout=6s"

func Init(dataBase string) *sql.DB {
        db, err := sql.Open("mysql", dataBase)
        if err != nil {
                log.Fatalln("open db fail:", err)
        }

        // max idle
        db.SetMaxIdleConns(1000)

        err = db.Ping()
        if err != nil {
                log.Fatalln("ping db fail:", err)
        }

        return db
}

func main() {
        superDB = Init(superDataBase)
        DB = Init(dataBase)

        for i:=0; i < 1000; i++ {
                go one_worker()
        }

        select {
        }
}

func one_worker() {
        for {
                var connectionId int
                err := DB.QueryRow("select CONNECTION_ID()").Scan(&connectionId)
                if err != nil {
                        log.Println("query connection id failed:", err)
                        if err.Error() == "Error 1040: Too many connections"{
                                var varName string
                                var threadsConnected int
                                err := superDB.QueryRow("show status like 'Threads_connected'").Scan(&varName, &threadsConnected)
                                if err != nil {
                                        log.Println("show threads connected failed:", err)
                                }
                                log.Println("threads connected:", threadsConnected)
                                panic("too many....")
                        }
                }
        }
}

日誌輸出:

... ...
[mysql] 2020/04/05 21:48:02 packets.go:36: read tcp 127.0.0.1:52921->127.0.0.1:3306: read: connection reset by peer
[mysql] 2020/04/05 21:48:02 packets.go:36: read tcp 127.0.0.1:52893->127.0.0.1:3306: read: connection reset by peer
[mysql] 2020/04/05 21:48:02 packets.go:36: read tcp 127.0.0.1:52954->127.0.0.1:3306: read: connection reset by peer
2020/04/05 21:48:02 query connection id failed: Error 1040: Too many connections
[mysql] 2020/04/05 21:48:02 packets.go:36: read tcp 127.0.0.1:52885->127.0.0.1:3306: read: connection reset by peer
[mysql] 2020/04/05 21:48:02 packets.go:36: read tcp 127.0.0.1:52876->127.0.0.1:3306: read: connection reset by peer
2020/04/05 21:48:02 query connection id failed: Error 1040: Too many connections
[mysql] 2020/04/05 21:48:02 packets.go:36: read tcp 127.0.0.1:52927->127.0.0.1:3306: read: connection reset by peer
2020/04/05 21:48:02 query connection id failed: Error 1040: Too many connections
[mysql] 2020/04/05 21:48:02 packets.go:36: read tcp 127.0.0.1:52905->127.0.0.1:3306: read: connection reset by peer
2020/04/05 21:48:02 query connection id failed: Error 1040: Too many connections
[mysql] 2020/04/05 21:48:02 packets.go:36: read tcp 127.0.0.1:52940->127.0.0.1:3306: read: connection reset by peer
2020/04/05 21:48:02 threads connected: 145
panic: too many....

goroutine 1111 [running]:
main.one_worker()
	/Users/lanyang/workspace/mysql_example/mysql_max_connections.go:69 +0x369
created by main.main
	/Users/lanyang/workspace/mysql_example/mysql_max_connections.go:47 +0xa4
exit status 2

從上面的輸出可以看到,出現錯誤"Too many connections"時, 當前已經建立的連接爲145, 是小於152(151+1)的。

2.最大連接數的查看和修改

最大連接數的查看

mysql> show variables like "max_connections";
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 151   |
+-----------------+-------+
1 row in set (0.08 sec)

最大連接數的修改
使用超級用戶登錄,進行修改:

SET GLOBAL max_connections = 300;

這個修改只是臨時的,下次MySQL重啓後,又恢復默認值。

配置文件中修改,永久生效:

vi /etc/my.cnf

[mysqld]
max_connections = 300

修改配置後,重啓MySQL Server後生效。

3.參考

Too many connections

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章