文档章节

Go连接MySql数据库too many connections

牛牛张
 牛牛张
发布于 2015/06/05 22:15
字数 868
阅读 136
收藏 12

Go中连接数据库的连接池:当你需要和数据库通信时,就会从连接池里面取出一个连接,和数据库交互。使用完的闲置的连接会回到连接池,等待下一次的调用。如果连接池里面没有闲置的连接,会自动创建一个新的连接出来。其中有一段:

An sql.Row returns the connection when Scan() is called, sql.Rows returns either when Close() is called or all rows have been iterated over with Next(), and sql.Tx will return when Commit or Rollback() are called. If you forget to completely iterate an sql.Rows and you forget to Close it, that connection will never go back to the pool.

       从上面可以看到,sql.Row如果不遍历完或者直接调用Close()方法,执行这次查询的连接就会一直存在!当连接池里的可用连接用光后,就开始创建新的连接。这就是为什么调用SetMaxOpenConns没有用的原因,因为这个函数只是设置连接池里的连接数而已!如果因为不及时释放连接而让连接池干掉了,还是会不断的创建新的连接,直到用光MySql所有的连接,报错。明白以后,在所有调用DB.Query的函数里加上了:

defer row.Close()

        这样查询连接就能在函数结束或者异常的情况下被关闭,就不会持续创建新的连接了。满以为这样就可以解决问题了,但是服务器运行了以后,过段时间仍然会出现相同的错误。在phpMyadmin里的监控页面,可以看到程序运行以后MySql的连接数猛增。问题又变得无解了,只能重新一行行检查代码。

        Go中的函数可以有多个返回值,使用下划线可以忽略不需要的返回值:

_, err := m.DB.Query("sql")

        程序中update和del之类的sql语句不需要返回值,就直接忽略了。猜想这样也是没法释放连接的,因为即使你不接受返回值,不代表这个变量就不存在了。也就是说返回的sql.Row还是存在的,只是你没有接收而已。没接收,就更谈不上释放连接了,所以最后产生了大量的连接继续报错。回头看看那篇文章,看到这么一段:

Ping and Exec will release the connection right before returning, but the others will pass ownership of the connection to the result, whether that's an sql.Row, sql.Rows, or sql.Tx.

        也就是说Ping和Exec方法在调用完之后,会自动释放连接。把代码中所有不需要返回值的语句改成由Exce方法执行,go run 一下,ok,连接数终于正常了!

        问题是解决了,总起来以后要注意一下的东西:

  • 程序连接数据库会有连接泄漏的情况,需要及时释放连接

  • Go sql包中的Query和QueryRow两个方法的连接不会自动释放连接,只有在遍历完结果或者调用close方法才会关闭连接

  • Go sql中的Ping和Exec方法在调用结束以后就会自动释放连接

  • 忽略了函数的某个返回值不代表这个值就不存在了,如果该返回值需要close才会释放资源,直接忽略了就会导致资源的泄漏。

  • 有close方法的变量,在使用后要及时调用该方法,释放资源

本文转载自:http://studygolang.com/articles/3049

共有 人打赏支持
牛牛张
粉丝 8
博文 45
码字总数 10212
作品 0
海淀
高级程序员
mysql的最大连接数设置

在使用MySQL数据库的时候,经常会遇到这么一个问题,就是“Can not connect to MySQL server. Too many connections”-mysql 1040错误,这是因为访问MySQL且还未释放的连接数目已经达到MySQL...

longfirst
2016/06/27
79
0
查看mysql数据库连接数、并发数相关信息

查看mysql数据库连接数、并发数相关信息: 1.show status like 'Threads%'; +-------------------+-------+ | Variable_name | Value | +-------------------+-------+ | Threads_cached | ......

1024菜bird
04/16
0
0
调整 MySQL 并发相关的参数

MySQL server 是多线程结构,包括后台线程和客户服务线程。多线程可以有效利用服务器资源,提高数据库的并发性能。在 MySQL 中,控制并发连接和线程的主要参数包括 maxconnections、backlog...

waterandair
2017/10/09
0
0
Mysql管理及优化设置命令整理 | fcblog.cn

1、查看数据列表: show databases; 2、创建数据库: create database xxxx; 其中xxxx为要创建的数据库名 3、删除数据库: drop database xxxx; 其中xxxx为要删除的数据库名 4、查看数据库真...

废柴阿刚
2017/12/15
0
0
Linux下修改mysql默认最大连接数,查看当前设置的最大连接数

1,,查看当前设置的最大连接数: mysqladmin -uroot -p数据库连接密码 variables |grep maxconnections 2,,mysql启动和停止的命令: service mysqld start 3,,修改默认的最大连接数的方...

岸芷汀兰
2015/10/22
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

OSChina 周三乱弹 —— 公司女同事约我

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @莱布妮子:分享水木年华的单曲《蝴蝶花(2002年大提琴版)》 《蝴蝶花(2002年大提琴版)》- 水木年华 手机党少年们想听歌,请使劲儿戳(这里) ...

小小编辑
11分钟前
28
7
Linux环境搭建 | VMware下共享文件夹的实现

在进行程序开发的过程中,我们经常要在主机与虚拟机之间传递文件,比如说,源代码位于虚拟机,而在主机下阅读或修改源代码,这里就需要使用到 「共享文件」 这个机制了。本文介绍了两种共享文...

良许Linux
今天
5
0
JUC锁框架——AQS源码分析

JUC锁介绍 Java的并发框架JUC(java.util.concurrent)中锁是最重要的一个工具。因为锁,才能实现正确的并发访问。而AbstractQueuedSynchronizer(AQS)是一个用来构建锁和同步器的框架,使用A...

长头发-dawn
今天
3
0
docker中安装了RabbitMQ后无法访问其Web管理页面

在官网找了"$ docker run -d --hostname my-rabbit --name some-rabbit -p 8080:15672 rabbitmq:3-management"这条安装命令,在docker上安装了RabbitMQ,,结果输入http://localhost:8080并不......

钟然千落
今天
4
1
spring-cloud | 分布式session共享

写在前面的话 各位小伙伴,你们有福了,这一节不仅教大家怎么实现分布式session的问题,还用kotlin开发,喜欢kotlin的小伙伴是不是很开心! 以前在写Android的时候,就对客户端请求有一定的认...

冯文议
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部