func (l *Ledis) handleReplication() error { l.wLock.Lock() defer l.wLock.Unlock() defer AsyncNotify(l.rDoneCh) rl := &rpl.Log{} var err error for { if err = l.r.NextNeedCommitLog(rl); err != nil { if err != rpl.ErrNoBehindLog { log.Errorf("get next commit log err, %s", err.Error) return err } else { return nil } } else { l.rbatch.Rollback() if rl.Compression == 1 { //todo optimize if rl.Data, err = snappy.Decode(nil, rl.Data); err != nil { log.Errorf("decode log error %s", err.Error()) return err } } if bd, err := store.NewBatchData(rl.Data); err != nil { log.Errorf("decode batch log error %s", err.Error()) return err } else if err = bd.Replay(l.rbatch); err != nil { log.Errorf("replay batch log error %s", err.Error()) } l.commitLock.Lock() if err = l.rbatch.Commit(); err != nil { log.Errorf("commit log error %s", err.Error()) } else if err = l.r.UpdateCommitID(rl.ID); err != nil { log.Errorf("update commit id error %s", err.Error()) } l.commitLock.Unlock() if err != nil { return err } } } }
// clear all data and load dump file to db func (l *Ledis) LoadDump(r io.Reader) (*DumpHead, error) { l.wLock.Lock() defer l.wLock.Unlock() var err error if err = l.flushAll(); err != nil { return nil, err } rb := bufio.NewReaderSize(r, 4096) h := new(DumpHead) if err = h.Read(rb); err != nil { return nil, err } var keyLen uint16 var valueLen uint32 var keyBuf bytes.Buffer var valueBuf bytes.Buffer deKeyBuf := make([]byte, 4096) deValueBuf := make([]byte, 4096) var key, value []byte wb := l.ldb.NewWriteBatch() defer wb.Close() n := 0 for { if err = binary.Read(rb, binary.BigEndian, &keyLen); err != nil && err != io.EOF { return nil, err } else if err == io.EOF { break } if _, err = io.CopyN(&keyBuf, rb, int64(keyLen)); err != nil { return nil, err } if key, err = snappy.Decode(deKeyBuf, keyBuf.Bytes()); err != nil { return nil, err } if err = binary.Read(rb, binary.BigEndian, &valueLen); err != nil { return nil, err } if _, err = io.CopyN(&valueBuf, rb, int64(valueLen)); err != nil { return nil, err } if value, err = snappy.Decode(deValueBuf, valueBuf.Bytes()); err != nil { return nil, err } wb.Put(key, value) n++ if n%1024 == 0 { if err = wb.Commit(); err != nil { return nil, err } } // if err = l.ldb.Put(key, value); err != nil { // return nil, err // } keyBuf.Reset() valueBuf.Reset() } if err = wb.Commit(); err != nil { return nil, err } deKeyBuf = nil deValueBuf = nil if l.r != nil { if err := l.r.UpdateCommitID(h.CommitID); err != nil { return nil, err } } return h, nil }