Asjdf

一只在杭电摸鱼的小火鸡

GORM 与 SQLite 的特性、坑点与缓解方式

2024-01-13 大约708字 预计阅读2分钟

# 前言

近期在用 GORM + SQLite 做客户端信息存储的时候发现了诸如:no such tabletable is locked等诸多问题,特总结一篇 GORM 与 SQLite 的特性、坑点与缓解方式。

# no such table

# 报错原文

SQL logic error: no such table: your_table_name

# 具体情况

新建表的逻辑正常(未改动的情况下),在将使用文件存储的 SQLite 转为内存存储后发生此错误。

- db, err := gorm.Open(sqlite.Open("./tmp.db"), &gorm.Config{})
+ db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})

# 原因

每个":memory:“连接都会在内存中打开一个全新的 SQL 数据库,因此如果 SQL 引擎碰巧打开另一个连接并且您只指定了”:memory:",则该连接将看到一个全新的数据库。

# 解决方案

使用"file::memory:?cache=shared"(或"file:foobar?mode=memory&cache=shared")使得到该字符串的每个连接都将指向同一个内存数据库。

除此之外,如果连接池中的最后一个连接关闭,则数据库将会被删除,所以请务必确保最大空闲连接数>0且连接寿命是无限的

# database is locked

# 报错原文

database is locked

# 原因

在数据库写入的同时尝试进行读取

# 解决方案

  1. 减少读事务SQLITE隔离性。
    • 使用 RepeatableRead 避免创建范围锁。
    • 同一 *sql.DB 连接内不支持并发。
  2. 使用多个 *sql.DB 连接(每个*sql.DB不支持同时读写)
    • 不能与:memory:数据库一起使用。
  3. 使用“Write Ahead Log WAL”模式可以同时进行读写(默认模式在写入期间锁定数据库)
    • 不能与:memory:数据库一起使用
  4. 在同一进程内同步对 sql.DB 的访问

# 在 MacOS 上出现大量读取失败

# 错误原文

unable to open database file"

# 原因

默认情况下,MacOS 限制操作系统范围内同时打开的文件较少

# 解决方案

调整系统/Session最大打开文件数限制

闽ICP备2022001901号-1 公安网备图标闽公网安备35030302354429号

主题 atom-hugo-theme