uint64_t PersistentSyncLogQueue::find_seq_at_pos(int pos){ Synclog log; if(find_by_pos(pos, &log) == 0){ return 0; } return log.seq(); }
void PersistentSyncLogQueue::put(const Synclog &log){ Locking l(&mutex); int idx = this->index(this->size); std::string key_buf = encode_key(idx); leveldb::Slice b(log.data(), log.size()); leveldb::Status s; s = meta_db->Put(write_options, key_buf, b); if(!s.ok()){ log_error("meta_db set error: %s", s.ToString().c_str()); }else{ if(this->size < this->total){ if(this->size == 0){ this->seq_min = log.seq(); } this->size ++; }else{ this->seq_min ++; this->start = this->index(+1); } } this->seq_max = log.seq(); log_trace("start: %d, size: %d, min: %llu, max: %llu", start, size, seq_min, seq_max); }
void MemorySyncLogQueue::put(const Synclog &log){ Locking l(&mutex); int idx = this->index(this->size); this->ptr[idx] = log; if(this->size < this->total){ if(this->size == 0){ this->seq_min = log.seq(); } this->size ++; }else{ this->seq_min ++; this->start = this->index(+1); } this->seq_max = log.seq(); log_trace("start: %d, size: %d, min: %llu, max: %llu", start, size, seq_min, seq_max); }
int BackendSync::Client::sync(SyncLogQueue *logs){ Buffer *output = link->output; uint64_t expect_seq = this->last_seq + 1; Synclog log; int ret; if(this->status == Client::DUMP && this->last_seq == 0){ ret = logs->find_last(&log); }else{ ret = logs->find(expect_seq, &log); } if(ret == 0){ return 0; } /* log_trace("fd: %d, seq: %llu, key: %s", link->fd(), log.seq(), hexmem(log.key().data(), log.key().size()).c_str()); */ // writes that are out of dumped range will be discarded. if(this->iter && log.key() > this->last_key){ // update last_seq this->last_seq = log.seq(); log_trace("fd: %d, seq: %llu, drop: %s, last_key: %s", link->fd(), log.seq(), hexmem(log.key().data(), log.key().size()).c_str(), hexmem(this->last_key.data(), this->last_key.size()).c_str()); return 1; } if(this->last_seq != 0 && log.seq() != expect_seq){ log_warn("fd: %d, OUT_OF_SYNC! seq: %llu, last_seq: %llu", link->fd(), log.seq(), expect_seq ); this->status = Client::OUT_OF_SYNC; return 1; } // update last_seq this->last_seq = log.seq(); char seq_buf[20]; snprintf(seq_buf, sizeof(seq_buf), "%llu", log.seq()); char log_type = log.type(); // a synclog from a mirror server will not be send to another mirror server if(this->is_mirror && (log_type == Synclog::MIRROR_SET || log_type == Synclog::MIRROR_DEL)){ if(this->last_seq - this->last_noop_seq >= logs->total/2){ this->last_noop_seq = this->last_seq; log_trace("fd: %d, sync noop %llu", link->fd(), log.seq()); output->append_record("noop"); output->append_record(seq_buf); output->append('\n'); } }else if(log_type == Synclog::SET || log_type == Synclog::MIRROR_SET){ std::string val; int ret = backend->ssdb->raw_get(log.key(), &val); if(ret == -1){ log_error("raw_get error!"); }else if(ret == 0){ log_trace("skip not found: %s", hexmem(log.key().data(), log.key().size()).c_str()); // not found, ignore }else{ log_trace("fd: %d, sync_set %llu %s", link->fd(), log.seq(), hexmem(log.key().data(), log.key().size()).c_str()); output->append_record("sync_set"); output->append_record(seq_buf); output->append_record(log.key()); output->append_record(val); output->append('\n'); } }else if(log_type == Synclog::DEL || log_type == Synclog::MIRROR_DEL){ log_trace("fd: %d, sync_del %llu %s", link->fd(), log.seq(), hexmem(log.key().data(), log.key().size()).c_str()); output->append_record("sync_del"); output->append_record(seq_buf); output->append_record(log.key()); output->append('\n'); }else{ log_error("unknown sync log type: %d", log.type()); } return 1; }