golang 原生database\sql 的重连机制实现

 更新时间:2026年02月12日 11:38:34   作者:落舞者  
本文主要介绍了golang 原生database\sql 的重连机制实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

1. 连接池的自动管理

Go 的 database/sql确实有部分自动重连能力,但有限制:

✅ 支持的情况

  1. 连接失效自动重试

    • 如果驱动返回 ErrBadConndatabase/sql 会自动重试操作
    • 连接池会自动检测并移除失效的连接
    • 下次使用时,会从连接池获取新连接(如果连接池中有可用连接)
  2. 连接池自动补充

    • 当连接池中的连接失效时,会在需要时自动创建新连接
    • 只要 sql.DB 对象没有被关闭,连接池会持续工作

❌ 不支持的情况

  1. 整个连接池被关闭

    • 如果调用了 db.Close(),整个连接池被关闭
    • 不会自动重新打开,需要重新创建 sql.DB 对象
  2. 长时间停机后的恢复

    • 如果 MySQL 停机时间很长,连接池中的所有连接都可能失效
    • 虽然连接池会尝试创建新连接,但没有主动的健康检查
    • 只有在实际使用时才会发现连接失效并重试

2. 实际场景分析

场景1: MySQL 短暂停机(几秒到几分钟)

// 程序已连接
db, _ := sql.Open("mysql", "dsn...")

// MySQL 停机
// ... MySQL 重启 ...

// 下次使用时
rows, err := db.Query("SELECT * FROM users")
// ✅ 可能成功:如果连接池中有可用连接,会自动重试
// ⚠️ 可能失败:如果所有连接都失效,需要等待重试或手动处理

行为

  • database/sql 会检测到连接失效(返回 ErrBadConn
  • 自动重试操作,尝试从连接池获取新连接
  • 如果连接池中有可用连接,会成功
  • 如果所有连接都失效,会创建新连接

场景2: MySQL 长时间停机(几分钟到几小时)

// 程序已连接
db, _ := sql.Open("mysql", "dsn...")

// MySQL 长时间停机
// ... 所有连接都失效 ...

// MySQL 重启后
rows, err := db.Query("SELECT * FROM users")
// ⚠️ 第一次调用可能失败,需要重试
// ✅ 后续调用会成功(连接池已恢复)

行为

  • 连接池中的所有连接都已失效
  • 第一次调用时,会尝试使用失效的连接,失败
  • database/sql 检测到 ErrBadConn,自动重试
  • 重试时会创建新连接,成功

场景3: 调用 db.Close() 后

// 程序已连接
db, _ := sql.Open("mysql", "dsn...")

// 关闭连接池
db.Close()

// 尝试使用
rows, err := db.Query("SELECT * FROM users")
// ❌ 失败:sql: database is closed
// ❌ 不会自动重连,需要重新创建 sql.DB 对象

行为

  • sql.DB 对象被标记为已关闭
  • 所有操作都会返回 sql: database is closed 错误
  • 不会自动重新打开

实际使用建议

1. 对于 MySQL 短暂停机

原生机制通常足够

db, _ := sql.Open("mysql", "dsn...")
// 不需要特殊处理,database/sql 会自动处理连接失效

2. 对于 MySQL 长时间停机

建议添加重试逻辑

db, _ := sql.Open("mysql", "dsn...")

// 添加重试逻辑
var rows *sql.Rows
var err error
for i := 0; i < 3; i++ {
    rows, err = db.Query("SELECT * FROM users")
    if err == nil {
        break
    }
    time.Sleep(time.Second)
}

3. 对于需要 Close() 的场景

原生机制不支持

db.Close()
// ❌ 无法恢复,需要重新创建

总结

database/sql 原生机制

  • ✅ 处理连接失效和自动重试
  • ✅ 连接池自动管理
  • ❌ 不支持 Close() 后恢复
  • ❌ 没有主动健康检查

到此这篇关于golang 原生database\sql 的重连机制实现的文章就介绍到这了,更多相关golang 重连机制内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 对Golang中的FORM相关字段理解

    对Golang中的FORM相关字段理解

    这篇文章主要介绍了对Golang中的FORM相关字段理解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-05-05
  • go函数的参数设置默认值的方法

    go函数的参数设置默认值的方法

    Go语言不直接支持函数参数默认值,但可以通过指针、结构体、变长参数和选项模式等方法模拟,下面给大家分享几种方式模拟函数参数的默认值功能,感兴趣的朋友一起看看吧
    2025-01-01
  • go格式“占位符”输入输出 类似python的input

    go格式“占位符”输入输出 类似python的input

    这篇文章主要介绍了go格式“占位符”, 输入输出,类似python的input,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-04-04
  • Golang哈希算法实现配置文件的监控功能详解

    Golang哈希算法实现配置文件的监控功能详解

    这篇文章主要介绍了Golang哈希算法实现配置文件的监控功能,哈希和加密类似,唯一区别是哈希是单项的,即哈希后的数据无法解密,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2023-03-03
  • 使用Go语言实现谷歌翻译功能

    使用Go语言实现谷歌翻译功能

    这篇文章主要为大家详细介绍了如何使用Go语言实现谷歌翻译功能,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考下
    2024-02-02
  • 使用golang开发一个curl命令行工具

    使用golang开发一个curl命令行工具

    这篇文章主要为大家详细介绍了如何使用golang开发一个简单的curl命令行工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-11-11
  • Go 内联优化让程序员爱不释手

    Go 内联优化让程序员爱不释手

    这篇文章主要介绍了Go 内联优化让程序员爱不释手,内联是在编译过程中自动进行的一类基本优化之一,文章围绕主题展开更多详细介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-06-06
  • GO语言利用K近邻算法实现小说鉴黄

    GO语言利用K近邻算法实现小说鉴黄

    本文给大家分享的是一段GO语言利用K近邻算法实现小说鉴黄的方法,本方法的鉴别的关键是关键是向量点的选择和阈值的判定,推荐给大家,有需要的小伙伴可以参考下。
    2015-03-03
  • GO语言实现的端口扫描器分享

    GO语言实现的端口扫描器分享

    这篇文章主要介绍了GO语言实现的端口扫描器分享,本文直接给出实现代码,代码中包含大量注释,需要的朋友可以参考下
    2014-10-10
  • Golang中urlencode与urldecode编码解码详解

    Golang中urlencode与urldecode编码解码详解

    这篇文章主要给大家介绍了关于Golang中urlencode与urldecode编码解码的相关资料,在Go语言中转码操作非常方便,可以使用内置的encoding包来快速完成转码操作,Go语言中的encoding包提供了许多常用的编码解码方式,需要的朋友可以参考下
    2023-09-09

最新评论