首页 > 数据库 >为什么在连接mysql时,设置 SetConnMaxIdleTime 没有作用

为什么在连接mysql时,设置 SetConnMaxIdleTime 没有作用

时间:2023-02-25 22:25:23浏览次数:61  
标签:max mysql db idle SetConnMaxIdleTime time go 连接

目录

在使用golang 连接 mysql时,为了节省连接资源,在连接使用过后,希望在指定长度时间不再使用后,自动关闭连接。
这时,经常会使用SetConnMaxLifetime(),设置最大连接有效时间,
使用SetConnMaxIdleTime(),设置最大空闲连接时间 max idle time。

这两个函数的作用听起来差不多,理论上,都能达到相同效果。
但是在实际使用中,却有些出人意料。

首先看下测试代码,在以下代码中,
设置 max idle time 为传入的参数值,
设置 max life time 为传入的参数值,
设置 max open conn 为1,
设置 max idle conn 为1

package main

import (
	"database/sql"
	"log"
	"fmt"
	"os"
	"strconv"
	"time"
	
	_ "github.com/go-sql-driver/mysql"
)

var dataBase = "root:xxxx@tcp(127.0.0.1:3306)/mysql?timeout=2s&readTimeout=6s&interpolateParams=true"

func getVar(name string) int {
	val := os.Getenv(name)
	if len(val) == 0 {
		panic(fmt.Sprintf("error getting: %v", name))
	}
	v, err := strconv.Atoi(val)
	if err != nil {
		panic(fmt.Sprintf("error parsing %v %v", name, err))
	}
	return v
}



func main() {
	db, err :=sql.Open("mysql", dataBase)  // connect to the db of your choice.
	if err != nil {
		panic(err)
	}
	defer db.Close()
	db.SetConnMaxIdleTime(time.Second * time.Duration(getVar("MAXIDLE")))
	db.SetConnMaxLifetime(time.Second * time.Duration(getVar("MAXLIFE")))
	db.SetMaxIdleConns(1)
	db.SetMaxOpenConns(1)
	sleep := time.Second*time.Duration(getVar("SLEEP"))
	for i := 0; i < 10; i++ {
		err = db.Ping()
		if err != nil {
            log.Fatalln("ping db fail:", err)
        }
		time.Sleep(sleep)
		print("\r", i)
	}
	fmt.Printf("\n%+v\n", db.Stats())
}

测试1

MAXIDLE=1 MAXLIFE=0 SLEEP=5 go run .

设置 max idle time 为1s,设置max life time为0s,也就是永不过期,相当于不设置life time。
每次连接之后,sleep 5s。

预期结果,循环10次,每次都会打开一个新的连接,旧的连接由于idle time到期而自动关闭。

go 1.15.15

output

9
{MaxOpenConnections:1 OpenConnections:1 InUse:0 Idle:1 WaitCount:0 WaitDuration:0s MaxIdleClosed:0 MaxIdleTimeClosed:0 MaxLifetimeClosed:0}

实际结果,只新建了一个连接,一直在使用,没有关闭连接。
也就是说设置max idle time 并没有生效。

go 1.17.12

9
{MaxOpenConnections:1 OpenConnections:0 InUse:0 Idle:0 WaitCount:0 WaitDuration:0s MaxIdleClosed:0 MaxIdleTimeClosed:10 MaxLifetimeClosed:0}

实际结果与预期相符。

测试2

MAXIDLE=1 MAXLIFE=2 SLEEP=5 go run .

设置 max idle time 为1s,设置max life time为2s,也就是idle time先到期
每次连接之后,sleep 5s。

预期结果,循环10次,每次都会打开一个新的连接,旧的连接是由于idle time到期自动关闭。

go 1.15.15

output

9
{MaxOpenConnections:1 OpenConnections:0 InUse:0 Idle:0 WaitCount:0 WaitDuration:0s MaxIdleClosed:0 MaxIdleTimeClosed:10 MaxLifetimeClosed:0}

实际结果与预期相符。

go 1.17.12

output

9
{MaxOpenConnections:1 OpenConnections:0 InUse:0 Idle:0 WaitCount:0 WaitDuration:0s MaxIdleClosed:0 MaxIdleTimeClosed:10 MaxLifetimeClosed:0}

实际结果与预期相符。

总结下,汇总以上测试结果如下表所示:

go版本 是否 max idle time 是否max life time 空闲连接回收是否生效
go 1.15.15 Y N N
go 1.15.15 Y Y Y
go 1.17.12 Y N Y
go 1.17.12 Y Y Y

在 go 1.15.15版本 或者其他相近版本中,只设置max idle time,不能自动回收空闲连接。

具体原因,可以参见 issue,或者具体查看go 源码,这应该是一个bug。

参考

database/sql: SetConnMaxIdleTime without SetConnMaxLifetime has no effect #41114

golang mysql 如何设置最大连接数和最大空闲连接数

标签:max,mysql,db,idle,SetConnMaxIdleTime,time,go,连接
From: https://www.cnblogs.com/lanyangsh/p/17155575.html

相关文章

  • mysql描述关键字
    SHOWCOLUMNS要求给出一个表名(这个例子中的FROMtab_1),它对每个字段返回一行,行中包含字段名、数据类型、是否允许NULL、键信息、默认值以及其他信息。   另外可以......
  • 908~909Maven工程环境修改,Maven的Java工程取mysql数据库数据
    Maven工程环境修改<plugins><plugin><!--https://mvnrepository.com/artifact/org.apache.tomcat.maven/tomcat7-maven-plugin-->......
  • MySQL学习笔记-数据控制语言
    SQL-数据控制语言(DCL)DCL语句用于管理数据库用户,控制数据库的访问权限一.管理用户1.查询用户#访问mysql数据库usemysql;#查询user表select*fromuser;主......
  • PyMySQL删除
    title:PyMySQL删除author:杨晓东permalink:PyMySQL删除date:2021-10-0211:27:04categories:-投篮tags:-demoPyMySQLMySQL数据库_删除"""1、删除操作......
  • MYSQL的索引、并发控制、各种事务介绍以及日志管理
    今天分享的是mysql数据库中的索引、并发控制、各种事务介绍以及日志管理,在学习过程中对这些内容的理解INDEX索引索引介绍索引:是排序的快速查找的特殊数据结构,定义作为查找......
  • 内网有线网络通过无线网络连接外网-端口映射
    场景: 笔记本电脑通过wifi连接到公司热点,可以上网。现在有个网关设备(比如串口服务器)IP地址是192.168.0.5,通过网线连接电脑,电脑为了访问网关设备,有线网络设置成了192.1......
  • 解决ssh连接远程主机出现“REMOTE HOST IDENTIFICATION HAS CHANGED”问题
    Win通过ssh连接远程主机命令提示符方式sshusername@ip此后输入你的密码通过VSCodeRemote-SSH在VSCode拓展中搜索”Remote-SSH“,安装拓展进入拓展设置设置配置......
  • 三天吃透MySQL八股文(2023最新整理)
    本文已经收录到Github仓库,该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校......
  • Jedis_连接池与Jedis_连接池工具类
    Jedis_连接池JedisPool使用:1.创建JedisPool连接池对象2.调用方法 getResource()方法获取Jedis连接/**......
  • nginx代理mysql
    [root@zhyly-pre-0034-layer-conf.d]#catmysql.confupstreammysql{server192.168.2.6:3306;}server{listen8083;proxy_passmysql;}[roo......