-
-
Notifications
You must be signed in to change notification settings - Fork 24
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
I am getting "disk I/O error" during large transactions with WAL on Windows.
Initially hit this while trying to insert a large amount of hash blobs into a DB in a single transaction, below is a reproducer.
I can't seem to trigger this on Linux, and it only seems to trigger when using WAL journal mode, so I suppose it's something in the Windows-specific WAL code.
Issue occurs on both previous and latest release version.
package main
import (
"database/sql"
"encoding/binary"
"errors"
"fmt"
"log"
"github.com/ncruces/go-sqlite3"
_ "github.com/ncruces/go-sqlite3/driver"
_ "github.com/ncruces/go-sqlite3/embed"
)
func sqliteError(err error) error {
if e := sqlite3.ExtendedErrorCode(0); errors.As(err, &e) {
return fmt.Errorf("%w (%d)", err, e)
}
return err
}
func main() {
db, err := sql.Open("sqlite3", "file:hashes.db?_pragma=journal_mode(wal)")
if err != nil {
log.Fatalf("open: %v", sqliteError(err))
}
defer db.Close()
db.SetMaxOpenConns(1)
_, err = db.Exec(`
CREATE TABLE IF NOT EXISTS hashes (
hash BLOB,
PRIMARY KEY (hash ASC)
) WITHOUT ROWID;
`)
if err != nil {
log.Fatalf("create: %v", sqliteError(err))
}
stmt, err := db.Prepare(`INSERT INTO hashes(hash) VALUES (?);`)
if err != nil {
log.Fatalf("prepare: %v", sqliteError(err))
}
var total uint64
var hash [8]byte
for batchSize := uint64(1); ; batchSize *= 2 {
log.Printf("batch = %d", batchSize)
tx, err := db.Begin()
if err != nil {
log.Fatalf("begin: %v", sqliteError(err))
}
txStmt := tx.Stmt(stmt)
for i := uint64(0); i < batchSize; i++ {
binary.BigEndian.PutUint64(hash[:], total+i)
_, err = txStmt.Exec(hash[:])
if err != nil {
log.Fatalf("exec: %v", sqliteError(err))
}
}
err = tx.Commit()
if err != nil {
log.Fatalf("commit: %v", sqliteError(err))
}
total += batchSize
}
}2025/11/05 19:48:17 batch = 1
2025/11/05 19:48:17 batch = 2
2025/11/05 19:48:17 batch = 4
2025/11/05 19:48:17 batch = 8
2025/11/05 19:48:17 batch = 16
2025/11/05 19:48:17 batch = 32
2025/11/05 19:48:17 batch = 64
2025/11/05 19:48:17 batch = 128
2025/11/05 19:48:17 batch = 256
2025/11/05 19:48:17 batch = 512
2025/11/05 19:48:17 batch = 1024
2025/11/05 19:48:17 batch = 2048
2025/11/05 19:48:17 batch = 4096
2025/11/05 19:48:17 batch = 8192
2025/11/05 19:48:17 batch = 16384
2025/11/05 19:48:17 batch = 32768
2025/11/05 19:48:18 batch = 65536
2025/11/05 19:48:18 batch = 131072
2025/11/05 19:48:19 batch = 262144
2025/11/05 19:48:20 batch = 524288
2025/11/05 19:48:23 batch = 1048576
2025/11/05 19:48:28 batch = 2097152
2025/11/05 19:48:34 exec: sqlite3: disk I/O error (5386)Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working