1
0
Fork 0

Merge pull request #752 from rqlite/consolidate-db-func

Consolidate database creation functions
master
Philip O'Toole 4 years ago committed by GitHub
commit d7b6586311
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -247,19 +247,17 @@ func (s *Store) Open(enableBootstrap bool) error {
// there are no commands in the log, then this is the only opportunity to // there are no commands in the log, then this is the only opportunity to
// create that on-disk database file before Raft initializes. // create that on-disk database file before Raft initializes.
if !s.dbConf.Memory && !s.snapsExistOnOpen && s.lastCommandIdxOnOpen == 0 { if !s.dbConf.Memory && !s.snapsExistOnOpen && s.lastCommandIdxOnOpen == 0 {
db, err := s.openOnDisk() s.db, err = s.openOnDisk(nil)
if err != nil { if err != nil {
return fmt.Errorf("failed to open on-disk database") return fmt.Errorf("failed to open on-disk database")
} }
s.db = db
s.onDiskCreated = true s.onDiskCreated = true
} else { } else {
// We need an in-memory database, at least for bootstrapping purposes. // We need an in-memory database, at least for bootstrapping purposes.
db, err := s.openInMemory() s.db, err = s.openInMemory(nil)
if err != nil { if err != nil {
return fmt.Errorf("failed to open in-memory database") return fmt.Errorf("failed to open in-memory database")
} }
s.db = db
} }
// Instantiate the Raft system. // Instantiate the Raft system.
@ -796,27 +794,30 @@ func (s *Store) setMetadata(id string, md map[string]string) error {
return nil return nil
} }
// openOnDisk opens an empty in-memory database at the Store's configured path. // openInMemory returns an in-memory database. If b is non-nil, then the
func (s *Store) openInMemory() (*sql.DB, error) { // database will be initialized with the contents of b.
db, err := sql.OpenInMemoryWithDSN(s.dbConf.DSN) func (s *Store) openInMemory(b []byte) (db *sql.DB, err error) {
if err != nil { if b == nil {
return nil, err db, err = sql.OpenInMemoryWithDSN(s.dbConf.DSN)
} else {
db, err = sql.DeserializeInMemoryWithDSN(b, s.dbConf.DSN)
} }
return db, nil return
} }
// openOnDisk opens an empty on-disk database at the Store's configured path. // openOnDisk opens an on-disk database file at the Store's configured path. If
func (s *Store) openOnDisk() (*sql.DB, error) { // b is non-nil, any preexisting file will first be overwritten with those contents.
// Explicitly remove any pre-existing SQLite database file as it will be // Otherwise any pre-existing file will be removed before the database is opened.
// completely rebuilt from committed log entries (and possibly a snapshot). func (s *Store) openOnDisk(b []byte) (*sql.DB, error) {
if err := os.Remove(s.dbPath); err != nil && !os.IsNotExist(err) { if err := os.Remove(s.dbPath); err != nil && !os.IsNotExist(err) {
return nil, err return nil, err
} }
db, err := sql.OpenWithDSN(s.dbPath, s.dbConf.DSN) if b != nil {
if err != nil { if err := ioutil.WriteFile(s.dbPath, b, 0660); err != nil {
return nil, err return nil, err
} }
return db, nil }
return sql.OpenWithDSN(s.dbPath, s.dbConf.DSN)
} }
// setLogInfo records some key indexs about the log. // setLogInfo records some key indexs about the log.
@ -946,15 +947,9 @@ func (s *Store) Apply(l *raft.Log) (e interface{}) {
e = &fsmGenericResponse{error: fmt.Errorf("close failed: %s", err)} e = &fsmGenericResponse{error: fmt.Errorf("close failed: %s", err)}
return return
} }
// Write new database to file on disk // Open a new on-disk database.
s.db, err = s.openOnDisk(b)
if err := ioutil.WriteFile(s.dbPath, b, 0660); err != nil { if err := ioutil.WriteFile(s.dbPath, b, 0660); err != nil {
e = &fsmGenericResponse{error: fmt.Errorf("write failed: %s", err)}
return
}
// Re-open it.
s.db, err = sql.OpenWithDSN(s.dbPath, s.dbConf.DSN)
if err != nil {
e = &fsmGenericResponse{error: fmt.Errorf("open on-disk failed: %s", err)} e = &fsmGenericResponse{error: fmt.Errorf("open on-disk failed: %s", err)}
} }
s.onDiskCreated = true s.onDiskCreated = true
@ -1145,20 +1140,19 @@ func (s *Store) Restore(rc io.ReadCloser) error {
offset += int64(sz) offset += int64(sz)
} }
if err := s.db.Close(); err != nil {
return fmt.Errorf("failed to close pre-restore database: %s", err)
}
var db *sql.DB var db *sql.DB
if !s.dbConf.Memory && s.lastCommandIdxOnOpen == 0 { if !s.dbConf.Memory && s.lastCommandIdxOnOpen == 0 {
// A snapshot clearly exists (this function has been called) but there // A snapshot clearly exists (this function has been called) but there
// are no command entries in the log -- so Apply will not be called. // are no command entries in the log -- so Apply will not be called.
// Therefore this is the last opportunity to create the on-disk database // Therefore this is the last opportunity to create the on-disk database
// before Raft starts. // before Raft starts.
if err := ioutil.WriteFile(s.dbPath, database, 0660); err != nil { db, err = s.openOnDisk(database)
return err
}
// Re-open it.
db, err = sql.OpenWithDSN(s.dbPath, s.dbConf.DSN)
if err != nil { if err != nil {
return fmt.Errorf("open with DSN: %s", err) return fmt.Errorf("open on-disk file during restore: %s", err)
} }
s.onDiskCreated = true s.onDiskCreated = true
s.logger.Println("successfully switched to on-disk database due to restore") s.logger.Println("successfully switched to on-disk database due to restore")
@ -1168,14 +1162,10 @@ func (s *Store) Restore(rc io.ReadCloser) error {
// command entries in the log. So by sticking with an in-memory database // command entries in the log. So by sticking with an in-memory database
// those entries will be applied in the fastest possible manner. We will // those entries will be applied in the fastest possible manner. We will
// defer creation of any database on disk until the Apply function. // defer creation of any database on disk until the Apply function.
db, err = sql.DeserializeInMemoryWithDSN(database, s.dbConf.DSN) db, err = s.openInMemory(database)
if err != nil { if err != nil {
return fmt.Errorf("DeserializeInMemoryWithDSN with DSN: %s", err) return fmt.Errorf("openInMemory: %s", err)
}
} }
if err := s.db.Close(); err != nil {
return fmt.Errorf("failed to close pre-restore database: %s", err)
} }
s.db = db s.db = db

Loading…
Cancel
Save