首頁  >  文章  >  後端開發  >  SQLite 中間歇性表格遺失錯誤:記憶體:資料庫

SQLite 中間歇性表格遺失錯誤:記憶體:資料庫

WBOY
WBOY轉載
2024-02-09 20:24:09898瀏覽

SQLite 中间歇性表丢失错误:内存:数据库

php小編香蕉為你帶來關於SQLite中間歇性表遺失錯誤的解決方法。當我們使用SQLite資料庫時,可能會遇到記憶體錯誤或表格遺失的情況。這種錯誤通常是由於不正確的資料庫操作或記憶體問題引起的。為了解決這個問題,我們可以採取一些措施,例如優化查詢語句、增加記憶體限制等。在本文中,我們將詳細介紹如何排除和解決這個問題,以確保資料庫的正常運作。

問題內容

我們透過 github.com/mattn/go-sqlite3 v1.14.16 在 Go 中使用 SQLite 3.39.4。連接字串為 ":memory:?cache=shared&mode=rwc&_mutex=no&_journal=WAL&_sync=NORMAL"

我們偶爾會在測試中看到錯誤「沒有這樣的表:配置」。令人困惑的是,有問題的查詢已經在測試案例中成功使用,並且該表隨後顯示在 sqlite_master 的查詢中,無論是在資料庫連接還是引發錯誤的事務物件中。但是,一旦發生錯誤,查詢就不會再成功。

我意識到這是一個相當模糊的問題,但有人至少可以建議去哪裡看嗎?資料庫連接始終具有相同的指標值。

更新

第二次嘗試時,我幾乎可以在此 SSCCE 中重現問題:

package main

import (
    "database/sql"
    "fmt"
    _ "github.com/mattn/go-sqlite3"
    "os"
)

func main() {
    os.Remove("example.db")
    db, err := sql.Open("sqlite3", ":memory:")
    if err != nil {
        panic(err)
    }

    for _, s := range []string{
        "CREATE TABLE if not exists Configuration (" +
            "`id` varchar(1024) NOT NULL," +
            "`body` varchar(10240) DEFAULT NULL, " +
            "PRIMARY KEY (id) " +
            ")",
        "INSERT INTO Configuration (id, body) VALUES ('some-unique-value', 'another-unique-value')",
    } {
        _, err = db.Exec(s)
        if err != nil {
            panic(err)
        }
    }

    for i := 0; i < 10; i++ {
        tx, err := db.Begin()
        if err != nil {
            panic(err)
        }

        q, err := tx.Prepare("select Configuration.id, Configuration.body \n\t\t\tfrom Configuration\n\t\t\tWHERE Configuration.id = ? ")
        fmt.Println(i, err)
        if q != nil {
            _ = q.Close()
        }

        fmt.Println("tx:")
        showTables(tx)

        fmt.Println("db:")
        showTables(db)

        tx.Commit()
    }
}

func showTables(db interface {
    Query(query string, args ...interface{}) (*sql.Rows, error)
}) {
    r, err := db.Query("SELECT name FROM sqlite_master")
    if err != nil {
        panic(err)
    }
    for r.Next() {
        var name string
        _ = r.Scan(&name)
        fmt.Println(name)
    }
}

它與實際問題不同,因為 showTables 不會顯示 SSCCE 中的表,但在實際測試中顯示。此範例顯示使用 :memory: 而不是 example.db 的問題,但前提是交易未關閉。這是記憶體資料庫已知的或預期的行為嗎?

解決方法

Go database/sql 隱含使用連接池,但:memory: 資料庫預設是打開它們的連接的私有。 請參閱:https://www.php.cn/link/d346256ad566cf97801e5cecc45a2557

#由於在幕後創建/關閉多個SQLite 連接,因此您並不真正知道哪個連接正在運行每個語句以及針對哪個資料庫,因此很自然,某些連接可以看到某些數據,而其他連接則看不到。

共享連線的一種方法是使用 cache=shared,正如您所嘗試的那樣。但 SQLite 要求將其指定為 URI:file::memory:?cache=sharedfile: 很重要)。

開啟共享記憶體資料庫的更可靠方法是:

  • file:memdb1?mode=memory&cache=shared(命名為 memdb1
  • file:/memdb1?vfs=memdb(命名為 /memdb1,並使用 memdb VFS)

您的其他參數可能是不必要的,甚至可能有害(對於記憶體資料庫)。

以上是SQLite 中間歇性表格遺失錯誤:記憶體:資料庫的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除