1
0
Fork 0

Finish snapshot restore

Compiles, but not tested.
master
Philip O Toole 9 years ago
parent a47da4065f
commit b638fa7b87

@ -36,7 +36,7 @@ type Store struct {
raftDir string
raftBind string
mu sync.Mutex
mu sync.RWMutex// Sync access between queries and snapshots.
raft *raft.Raft // The consensus mechanism
dbConf *sql.Config
@ -156,6 +156,10 @@ func (s *Store) Execute(queries []string, tx bool) ([]*sql.Result, error) {
// Query execute queries that return rows.
func (s *Store) Query(queries []string, tx bool) ([]*sql.Rows, error) {
// Allow concurrent queries.
s.mu.RLock()
defer s.mu.RUnlock()
r, err := s.db.Query(queries, tx)
return r, err
}
@ -193,11 +197,16 @@ func (f *fsm) Apply(l *raft.Log) interface{} {
}
// Snapshot returns a snapshot of the database. The caller must ensure that
// no transaction is taking place during this call.
// no transaction is taking place during this call. Hashsicorp Raft guarantees
// that this function will not be called concurrently with Apply.
//
// http://sqlite.org/howtocorrupt.html states it is safe to do this
// as long as no transaction is in progress.
func (f *fsm) Snapshot() (raft.FSMSnapshot, error) {
// Ensure only one snapshot can take place at once, and block all queries.
f.mu.Lock()
defer f.mu.Unlock()
b, err := ioutil.ReadFile(f.dbPath)
if err != nil {
log.Printf("Failed to generate snapshot: %s", err.Error())
@ -208,10 +217,25 @@ func (f *fsm) Snapshot() (raft.FSMSnapshot, error) {
// Restore restores the database to a previous state.
func (f *fsm) Restore(rc io.ReadCloser) error {
// Need to write bytes to SQLite file.
// Open it with desired DSN params.
// Implies the Open call above, should always blow away existing database, since
// it will be restored completely from log, or from log and remaining log entries.
if err := os.Remove(f.dbPath); err != nil && !os.IsNotExist(err) {
return err
}
b, err := ioutil.ReadAll(rc)
if err != nil {
return err
}
if err := ioutil.WriteFile(f.dbPath, b, 0660); err != nil {
return err
}
db, err := sql.OpenWithConfiguration(f.dbPath, f.dbConf)
if err != nil {
return err
}
f.db = db
return nil
}

Loading…
Cancel
Save