Skip to content

Commit 409c190

Browse files
authored
Remove journal on import (#213)
1 parent ba282fa commit 409c190

File tree

4 files changed

+48
-20
lines changed

4 files changed

+48
-20
lines changed

cmd/litefs-bench/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ func run(ctx context.Context) error {
6262
defer func() { _ = db.Close() }()
6363

6464
if _, err := db.Exec(`PRAGMA busy_timeout = 5000`); err != nil {
65-
return fmt.Errorf("set busy timeout")
65+
return fmt.Errorf("set busy timeout: %w", err)
6666
}
6767

6868
// Initialize cache.

cmd/litefs/import_test.go

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ func TestImportCommand_Create(t *testing.T) {
4848

4949
// Ensure an existing database can be overwritten by an import.
5050
func TestImportCommand_Overwrite(t *testing.T) {
51+
dir := t.TempDir()
52+
5153
// Generate a database on the regular file system.
5254
dsn := filepath.Join(t.TempDir(), "db")
5355
dbx := testingutil.OpenSQLDB(t, dsn)
@@ -60,7 +62,7 @@ func TestImportCommand_Overwrite(t *testing.T) {
6062
}
6163

6264
// Run an LiteFS mount.
63-
m0 := runMountCommand(t, newMountCommand(t, t.TempDir(), nil))
65+
m0 := runMountCommand(t, newMountCommand(t, dir, nil))
6466
waitForPrimary(t, m0)
6567

6668
// Generate data into the mount.
@@ -89,16 +91,37 @@ func TestImportCommand_Overwrite(t *testing.T) {
8991
t.Fatal(err)
9092
} else if got, want := y, 100; got != want {
9193
t.Fatalf("y=%d, want %d", got, want)
94+
} else if err := db.Close(); err != nil {
95+
t.Fatal(err)
9296
}
9397

9498
// Reconnect and verify correctness.
95-
if err := db.Close(); err != nil {
96-
t.Fatal(err)
97-
}
9899
db = testingutil.OpenSQLDB(t, filepath.Join(m0.Config.MountDir, "db"))
99100
if err := db.QueryRow(`SELECT y FROM u`).Scan(&y); err != nil {
100101
t.Fatal(err)
101102
} else if got, want := y, 100; got != want {
102103
t.Fatalf("y=%d, want %d", got, want)
103104
}
105+
106+
// Add new transactions.
107+
if _, err := db.Exec(`INSERT INTO u VALUES (200)`); err != nil {
108+
t.Fatal(err)
109+
}
110+
if err := db.Close(); err != nil {
111+
t.Fatal(err)
112+
}
113+
114+
// Restart mount.
115+
if err := m0.Close(); err != nil {
116+
t.Fatal(err)
117+
}
118+
m0 = runMountCommand(t, newMountCommand(t, dir, m0))
119+
120+
db = testingutil.OpenSQLDB(t, filepath.Join(m0.Config.MountDir, "db"))
121+
var sum int
122+
if err := db.QueryRow(`SELECT SUM(y) FROM u`).Scan(&sum); err != nil {
123+
t.Fatal(err)
124+
} else if got, want := sum, 300; got != want {
125+
t.Fatalf("sum=%d, want %d", got, want)
126+
}
104127
}

db.go

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,10 @@ func (db *DB) rollbackJournal(ctx context.Context) error {
288288
return err
289289
}
290290

291+
if err := os.Remove(db.JournalPath()); err != nil {
292+
return err
293+
}
294+
291295
return nil
292296
}
293297

@@ -526,8 +530,8 @@ func (db *DB) WriteDatabase(f *os.File, data []byte, offset int64) error {
526530
// Track dirty pages if we are using a rollback journal. This isn't
527531
// necessary with the write-ahead log (WAL) since pages are appended
528532
// instead of overwritten. We can determine the dirty set at commit-time.
533+
pgno := uint32(offset/int64(db.pageSize)) + 1
529534
if db.mode == DBModeRollback {
530-
pgno := uint32(offset/int64(db.pageSize)) + 1
531535
db.dirtyPageSet[pgno] = struct{}{}
532536
}
533537

@@ -1151,15 +1155,14 @@ func (db *DB) invalidateJournal(mode JournalMode) error {
11511155
f, err := os.OpenFile(db.JournalPath(), os.O_RDWR, 0666)
11521156
if err != nil && !os.IsNotExist(err) {
11531157
return fmt.Errorf("open journal: %w", err)
1154-
}
1155-
defer func() { _ = f.Close() }()
1158+
} else if err == nil {
1159+
defer func() { _ = f.Close() }()
11561160

1157-
if _, err := f.Write(make([]byte, SQLITE_JOURNAL_HEADER_SIZE)); err != nil {
1158-
return fmt.Errorf("clear journal header: %w", err)
1159-
} else if err := f.Sync(); err != nil {
1160-
return fmt.Errorf("sync journal: %w", err)
1161-
} else if err := f.Close(); err != nil {
1162-
return fmt.Errorf("close journal: %w", err)
1161+
if _, err := f.Write(make([]byte, SQLITE_JOURNAL_HEADER_SIZE)); err != nil {
1162+
return fmt.Errorf("clear journal header: %w", err)
1163+
} else if err := f.Sync(); err != nil {
1164+
return fmt.Errorf("sync journal: %w", err)
1165+
}
11631166
}
11641167

11651168
default:
@@ -1326,6 +1329,11 @@ func (db *DB) Import(ctx context.Context, r io.Reader) error {
13261329
return err
13271330
}
13281331

1332+
// Invalidate journal, if one exists.
1333+
if err := db.invalidateJournal(JournalModePersist); err != nil {
1334+
return fmt.Errorf("invalidate journal: %w", err)
1335+
}
1336+
13291337
// Truncate WAL, if it exists.
13301338
if _, err := os.Stat(db.WALPath()); err == nil {
13311339
if err := os.Truncate(db.WALPath(), 0); err != nil {
@@ -1397,8 +1405,9 @@ func (db *DB) importToLTX(ctx context.Context, r io.Reader) (Pos, error) {
13971405
pos.PostApplyChecksum ^= ltx.ChecksumPage(pgno, buf)
13981406
}
13991407

1400-
// Finish page block to compute checksum and then finish header block.
14011408
pos.PostApplyChecksum |= ltx.ChecksumFlag
1409+
1410+
// Finish page block to compute checksum and then finish header block.
14021411
enc.SetPostApplyChecksum(pos.PostApplyChecksum)
14031412
if err := enc.Close(); err != nil {
14041413
return Pos{}, fmt.Errorf("close ltx encoder: %s", err)

fuse/file_system_test.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -283,15 +283,11 @@ func TestFileSystem_ReadOnly(t *testing.T) {
283283
_, err := db.Exec(`INSERT INTO t VALUES (100)`)
284284

285285
switch mode := testingutil.JournalMode(); mode {
286-
case "delete":
286+
case "delete", "persist", "truncate":
287287
var e sqlite3.Error
288288
if !errors.As(err, &e) || e.Code != sqlite3.ErrReadonly {
289289
t.Fatalf("unexpected error: %s", err)
290290
}
291-
case "persist", "truncate":
292-
if err == nil || err.Error() != `disk I/O error: permission denied` {
293-
t.Fatalf("unexpected error: %s", err)
294-
}
295291
case "wal":
296292
if err == nil || err.Error() != `disk I/O error` {
297293
t.Fatalf("unexpected error: %s", err)

0 commit comments

Comments
 (0)