Go Gin框架结合MySQL数据库时,"invalid memory address or nil pointer dereference"错误排查指南
在Go语言Gin框架与MySQL数据库的开发中,"invalid memory address or nil pointer dereference"错误时有发生,尤其在程序运行一段时间后。本文分析此类错误,并提供排查方法。
错误示例:
2021/10/22 09:50:49 [Recovery] 2021/10/22 - 09:50:49 panic recovered: runtime error: invalid memory address or nil pointer dereference ... /root/onlineUsers/hello.go:63 (0x840f36) main.func1: _, err = stmt.Exec(req.IdCode, c.Request.RemoteAddr) ...
错误提示hello.go文件63行出现空指针引用,代码为_, err = stmt.Exec(req.IdCode, c.Request.RemoteAddr),表明stmt变量可能为空指针。
虽然建议使用stmt.ExecContext进行更好的上下文管理,但这并非导致空指针引用的根本原因。空指针引用是由于访问空指针指向的内存地址造成的。
更可能的原因是stmt在调用stmt.Exec前已被关闭或释放,常见场景:
- 数据库连接池连接回收: 如果未正确管理数据库连接,连接池可能在stmt仍在使用时回收连接,导致stmt失效。
- 预编译语句提前关闭: 如果stmt是通过Prepare预编译获得的,使用完毕后必须调用stmt.Close()关闭。 在stmt.Close()后继续使用stmt将导致空指针引用错误。 这与“prepare 拿到的stmt,关闭了还在用?”的问题描述一致。
解决方法:
仔细检查hello.go文件63行之前的代码,确认stmt变量的生命周期和使用方法,确保在调用stmt.Exec前,stmt是一个有效的、未关闭的数据库语句对象。 重点关注stmt的创建、使用和关闭过程,确保所有执行路径都正确处理。 检查代码是否存在资源泄露或错误的资源管理。 建议使用defer stmt.Close()确保stmt在函数结束时正确关闭。 此外,检查数据库连接池配置,确保连接池大小合理,并避免连接被过早回收。