From b9e9bd93e879fc3ffc86ae7a99f9c1dbc90daa46 Mon Sep 17 00:00:00 2001 From: Ben Johnson Date: Tue, 10 Nov 2020 12:10:46 -0700 Subject: [PATCH] Add recovery logging --- db.go | 42 ++++++++++++++++++++++++++---------------- file_system.go | 1 - node.go | 8 -------- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/db.go b/db.go index dc8f926..46379b3 100644 --- a/db.go +++ b/db.go @@ -58,6 +58,11 @@ func (db *DB) Path() string { return db.path } +// AbsPath returns the full path to the database. +func (db *DB) AbsPath() string { + return filepath.Join(db.fs.TargetPath, db.path) +} + // WALPath returns the full path to the real WAL. func (db *DB) WALPath() string { return filepath.Join(db.fs.TargetPath, db.path+"-wal") @@ -101,28 +106,34 @@ func (db *DB) Open() (err error) { return err } db.logger = log.New(db.logFile, "", log.LstdFlags) - - db.logger.Printf("open: %s", db.path) + db.logger.Printf("opening: path=%s", db.path) // If database file exists, read & set the header. if err := db.readHeader(); os.IsNotExist(err) { + db.logger.Printf("opening: db not found") db.setHeader(nil) // invalidate header for missing file } else if err != nil { + db.logger.Printf("opening: cannot read db header: %s", err) db.setHeader(nil) // invalidate header - db.logger.Printf("cannot read db header: %s", err) } // If WAL is enabled & WAL file exists, attempt to recover. - if db.isWALEnabled { - if err := db.recoverWAL(); err != nil { - return fmt.Errorf("recover wal: %w", err) - } + if err := db.recover(); err != nil { + return fmt.Errorf("recover wal: %w", err) } + db.logger.Printf("open: %s", db.path) + return nil } -func (db *DB) recoverWAL() error { +func (db *DB) recover() error { + // Ignore if the DB is invalid. + if !db.valid() { + db.logger.Printf("recovering: invalid db, skipping; valid-header:%v wal-enabled=%v", db.isHeaderValid, db.isWALEnabled) + return nil + } + // Check for the existence of the real & shadow WAL. // We need to sync up between the two. hasShadowWAL, err := db.shadowWALExists() @@ -134,13 +145,6 @@ func (db *DB) recoverWAL() error { return fmt.Errorf("check real wal: %w", err) } - // Neither the real WAL or shadow WAL exist so no pages have been written - // since the DB's journal mode has been set to "wal". In this case, do - // nothing and wait for the first WAL write to occur. - if !hasShadowWAL && !hasRealWAL { - return nil - } - if hasRealWAL { if hasShadowWAL { return db.recoverRealAndShadowWALs() @@ -151,11 +155,15 @@ func (db *DB) recoverWAL() error { if hasShadowWAL { return db.recoverShadowWALOnly() } + + db.logger.Printf("recovering: no WALs available, skipping") return nil // no-op, wait for first WAL write } // recoverRealWALOnly copies the real WAL to the active shadow WAL. func (db *DB) recoverRealWALOnly() error { + db.logger.Printf("recovering: real WAL only") + // Open real WAL to read from. r, err := os.Open(db.WALPath()) if err != nil { @@ -259,11 +267,13 @@ func (db *DB) createActiveShadowWAL(hdr sqlite.WALHeader) (f *os.File, err error // recoverShadowWALOnly verifies the last page in the shadow WAL matches the // contents of the database page. func (db *DB) recoverShadowWALOnly() error { + db.logger.Printf("recovering: shadow WAL only") panic("TODO") } // recoverRealAndShadowWALs verifies the last page of the real & shadow WALs match. func (db *DB) recoverRealAndShadowWALs() error { + db.logger.Printf("recovering: real & shadow WAL") panic("TODO") } @@ -281,7 +291,7 @@ func (db *DB) Close() (err error) { // readHeader reads the SQLite header and sets the initial DB flags. func (db *DB) readHeader() error { - f, err := os.Open(db.path) + f, err := os.Open(db.AbsPath()) if err != nil { return err } diff --git a/file_system.go b/file_system.go index 41913c7..577b39f 100644 --- a/file_system.go +++ b/file_system.go @@ -74,7 +74,6 @@ func (f *FileSystem) DB(path string) *DB { f.mu.RLock() defer f.mu.RUnlock() db := f.dbs[path] - println("dbg/fs.db?", path, db != nil) return db } diff --git a/node.go b/node.go index 359512e..5abb289 100644 --- a/node.go +++ b/node.go @@ -59,7 +59,6 @@ func (n *Node) srcpath() string { // DB returns the DB object associated with the node, if any. // If node points to a "-wal" file then the associated DB is returned. func (n *Node) DB() *DB { - println("dbg/node.db", n.path, n.fs != nil, n.path == "") if strings.HasPrefix(n.path, sqlite.WALSuffix) { return n.fs.DB(strings.TrimSuffix(n.path, sqlite.WALSuffix)) } @@ -103,12 +102,6 @@ func (n *Node) Attr(ctx context.Context, a *fuse.Attr) (err error) { // Lookup need not to handle the names "." and "..". func (n *Node) Lookup(ctx context.Context, name string) (_ fs.Node, err error) { path := filepath.Join(n.path, name) - - // Meta directories should not be visible. - if IsMetaDir(path) { - return nil, syscall.ENOENT - } - srcpath := filepath.Join(n.fs.TargetPath, path) if _, err := os.Stat(srcpath); os.IsNotExist(err) { return nil, syscall.ENOENT @@ -293,7 +286,6 @@ func (n *Node) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenR if err != nil { return nil, err } - println("dbg/open") return NewHandle(n, f), nil }