1
0
Fork 0

Merge branch 'master' of github.com:rqlite/rqlite into more-checkpoint-test-coverage

master
Philip O'Toole 8 months ago
commit d02599d9e0

@ -1,3 +1,7 @@
## 8.18.5 (unreleased)
### Implementation changes and bug fixes
- [PR #1644](https://github.com/rqlite/rqlite/pull/1644): Expose BUSY TIMEOUT on /status.
## 8.18.4 (January 30th 2024) ## 8.18.4 (January 30th 2024)
### Implementation changes and bug fixes ### Implementation changes and bug fixes
- [PR #1644](https://github.com/rqlite/rqlite/pull/1644): Remove an unnecessary memcpy during Snapshotting. - [PR #1644](https://github.com/rqlite/rqlite/pull/1644): Remove an unnecessary memcpy during Snapshotting.

@ -321,20 +321,35 @@ func (db *DB) WALSize() (int64, error) {
return 0, err return 0, err
} }
// SetBusyTimeout sets the busy timeout for the database. // SetBusyTimeout sets the busy timeout for the database. If a timeout is
func (db *DB) SetBusyTimeout(ms int) error { // is less than zero it is not set.
_, err := db.rwDB.Exec(fmt.Sprintf("PRAGMA busy_timeout=%d", ms)) func (db *DB) SetBusyTimeout(rwMs, roMs int) (err error) {
return err if rwMs >= 0 {
_, err := db.rwDB.Exec(fmt.Sprintf("PRAGMA busy_timeout=%d", rwMs))
if err != nil {
return err
}
}
if roMs >= 0 {
_, err = db.roDB.Exec(fmt.Sprintf("PRAGMA busy_timeout=%d", roMs))
if err != nil {
return err
}
}
return nil
} }
// BusyTimeout returns the current busy timeout value. // BusyTimeout returns the current busy timeout value.
func (db *DB) BusyTimeout() (int, error) { func (db *DB) BusyTimeout() (rwMs, roMs int, err error) {
var rwN int err = db.rwDB.QueryRow("PRAGMA busy_timeout").Scan(&rwMs)
err := db.rwDB.QueryRow("PRAGMA busy_timeout").Scan(&rwN)
if err != nil { if err != nil {
return 0, err return 0, 0, err
} }
return rwN, err err = db.rwDB.QueryRow("PRAGMA busy_timeout").Scan(&roMs)
if err != nil {
return 0, 0, err
}
return rwMs, roMs, nil
} }
// Checkpoint checkpoints the WAL file. If the WAL file is not enabled, this // Checkpoint checkpoints the WAL file. If the WAL file is not enabled, this
@ -359,16 +374,16 @@ func (db *DB) CheckpointWithTimeout(mode CheckpointMode, dur time.Duration) (err
}() }()
if dur > 0 { if dur > 0 {
bt, err := db.BusyTimeout() rwBt, _, err := db.BusyTimeout()
if err != nil { if err != nil {
return fmt.Errorf("failed to get busy_timeout on checkpointing connection: %s", err.Error()) return fmt.Errorf("failed to get busy_timeout on checkpointing connection: %s", err.Error())
} }
if err := db.SetBusyTimeout(int(dur.Milliseconds())); err != nil { if err := db.SetBusyTimeout(int(dur.Milliseconds()), -1); err != nil {
return fmt.Errorf("failed to set busy_timeout on checkpointing connection: %s", err.Error()) return fmt.Errorf("failed to set busy_timeout on checkpointing connection: %s", err.Error())
} }
defer func() { defer func() {
// Reset back to default // Reset back to default
if _, err := db.rwDB.Exec(fmt.Sprintf("PRAGMA busy_timeout=%d", bt)); err != nil { if err := db.SetBusyTimeout(rwBt, -1); err != nil {
db.logger.Printf("failed to reset busy_timeout on checkpointing connection: %s", err.Error()) db.logger.Printf("failed to reset busy_timeout on checkpointing connection: %s", err.Error())
} }
}() }()
@ -1115,6 +1130,7 @@ func (db *DB) pragmas() (map[string]interface{}, error) {
"journal_mode", "journal_mode",
"foreign_keys", "foreign_keys",
"wal_autocheckpoint", "wal_autocheckpoint",
"busy_timeout",
} { } {
var s string var s string
if err := v.QueryRow(fmt.Sprintf("PRAGMA %s", p)).Scan(&s); err != nil { if err := v.QueryRow(fmt.Sprintf("PRAGMA %s", p)).Scan(&s); err != nil {

@ -19,23 +19,23 @@ func testBusyTimeout(t *testing.T, db *DB) {
t.Fatalf("failed to set busy_timeout: %s", err.Error()) t.Fatalf("failed to set busy_timeout: %s", err.Error())
} }
bt, err := db.BusyTimeout() rw, _, err := db.BusyTimeout()
if err != nil { if err != nil {
t.Fatalf("failed to get busy_timeout: %s", err.Error()) t.Fatalf("failed to get busy_timeout: %s", err.Error())
} }
if exp, got := rbt, bt; exp != got { if exp, got := rbt, rw; exp != got {
t.Fatalf("expected busy_timeout %d, got %d", exp, got) t.Fatalf("expected busy_timeout %d, got %d", exp, got)
} }
rbt2 := random.Intn(10000) rw2 := random.Intn(10000)
if err := db.SetBusyTimeout(rbt2); err != nil { if err := db.SetBusyTimeout(rw2, 0); err != nil {
t.Fatalf("failed to set busy_timeout: %s", err.Error()) t.Fatalf("failed to set busy_timeout: %s", err.Error())
} }
bt, err = db.BusyTimeout() rw, _, err = db.BusyTimeout()
if err != nil { if err != nil {
t.Fatalf("failed to get busy_timeout: %s", err.Error()) t.Fatalf("failed to get busy_timeout: %s", err.Error())
} }
if exp, got := rbt2, bt; exp != got { if exp, got := rw2, rw; exp != got {
t.Fatalf("expected busy_timeout %d, got %d", exp, got) t.Fatalf("expected busy_timeout %d, got %d", exp, got)
} }
} }

@ -30,8 +30,8 @@ class TestSingleNode(unittest.TestCase):
n = self.cluster.wait_for_leader() n = self.cluster.wait_for_leader()
ro_pragmas = n.pragmas()['ro'] ro_pragmas = n.pragmas()['ro']
rw_pragmas = n.pragmas()['rw'] rw_pragmas = n.pragmas()['rw']
self.assertEqual(ro_pragmas, d_("{'foreign_keys': '0', 'journal_mode': 'wal', 'synchronous': '0', 'wal_autocheckpoint': '1000'}")) self.assertEqual(ro_pragmas, d_("{'busy_timeout': '5000', 'foreign_keys': '0', 'journal_mode': 'wal', 'synchronous': '0', 'wal_autocheckpoint': '1000'}"))
self.assertEqual(rw_pragmas, d_("{'foreign_keys': '0', 'journal_mode': 'wal', 'synchronous': '0', 'wal_autocheckpoint': '0'}")) self.assertEqual(rw_pragmas, d_("{'busy_timeout': '5000', 'foreign_keys': '0', 'journal_mode': 'wal', 'synchronous': '0', 'wal_autocheckpoint': '0'}"))
def test_simple_raw_queries(self): def test_simple_raw_queries(self):
'''Test simple queries work as expected''' '''Test simple queries work as expected'''

Loading…
Cancel
Save