l'éditeur php Banana vous apporte une solution à l'erreur de perte de table intermittente dans SQLite. Lorsque nous utilisons une base de données SQLite, nous pouvons rencontrer des erreurs de mémoire ou des pertes de tables. Cette erreur est généralement provoquée par des opérations de base de données incorrectes ou des problèmes de mémoire. Afin de résoudre ce problème, nous pouvons prendre certaines mesures, telles que l'optimisation des instructions de requête, l'augmentation des limites de mémoire, etc. Dans cet article, nous détaillerons comment dépanner et résoudre ce problème pour garantir le bon fonctionnement de la base de données.
Nous utilisons SQLite 3.39.4 dans Go via github.com/mattn/go-sqlite3 v1.14.16. La chaîne de connexion est ":memory:?cache=shared&mode=rwc&_mutex=no&_journal=WAL&_sync=NORMAL"
Nous voyons occasionnellement l'erreur « No such table: configuration » dans nos tests. Ce qui est déroutant, c'est que la requête en question a été utilisée avec succès dans le scénario de test et que la table apparaît ensuite dans les requêtes adressées à sqlite_master , à la fois dans la connexion à la base de données et dans l'objet de transaction qui génère l'erreur. Cependant, dès qu’une erreur se produit, la requête n’aboutit plus.
Je me rends compte que c'est une question plutôt vague, mais quelqu'un peut-il au moins suggérer où chercher ? Les connexions à la base de données ont toujours la même valeur de pointeur.
Mise à jour :
Lors de mon deuxième essai, j'ai presquepourrais reproduire le problème dans ce 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) } }
C'est différent du problème réel car showTables n'affiche pas les tables dans SSCCE mais c'est le cas dans le test réel. Cet exemple montre le problème de l'utilisation de :memory:
au lieu de example.db
, mais uniquement si la transaction n'est pas fermée. Est-ce un comportement connu ou attendu des bases de données en mémoire ? :memory:
而不是 example.db
的问题,但前提是事务未关闭。这是内存数据库已知的或预期的行为吗?
Go database/sql
隐式使用连接池,但 :memory:
Solution de contournementGo database/sql
utilise implicitement le regroupement de connexions, mais les bases de données :memory:
ouvrent leurs connexions en privé
https://www.php.cn/link/d346256ad566cf97801e5cecc45a2557
cache=shared
,正如您所尝试的那样。但 SQLite 要求将其指定为 URI:file::memory:?cache=shared
(file:
Étant donné que plusieurs connexions SQLite sont créées/fermées en coulisses, vous ne savez pas vraiment quelle connexion exécute chaque instruction et sur quelle base de données, donc naturellement certaines connexions peuvent voir certaines données et d'autres ne peuvent pas arriver.
Une façon de partager une connexion est d'utiliser
est important).file:memdb1?mode=memory&cache=shared
(命名为 memdb1
file:/memdb1?vfs=memdb
(命名为 /memdb1
,并使用 memdb
)VFS)
🎜 🎜 Vos autres paramètres peuvent être inutiles voire nuisibles (pour les bases de données en mémoire). 🎜Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!