int Slave::proc(const std::vector<Bytes> &req){ Binlog log; if(log.load(req[0].Slice()) == -1){ log_error("invalid binlog!"); return 0; } if(log.type() != BinlogType::NOOP){ if(this->is_mirror){ log_debug("[mirror] %s", log.dumps().c_str()); }else{ log_debug("[sync] %s", log.dumps().c_str()); } } switch(log.type()){ case BinlogType::NOOP: return this->proc_noop(log, req); break; case BinlogType::COPY: return this->proc_copy(log, req); break; case BinlogType::SYNC: case BinlogType::MIRROR: return this->proc_sync(log, req); break; default: break; } return 0; }
int Slave::proc(const std::vector<Bytes> &req){ Binlog log; if(log.load_format_key(req[0]) == -1){ log_error("invalid binlog!"); return 0; } const char *sync_type = this->is_mirror? "mirror" : "sync"; switch(log.type()){ case BinlogType::NOOP: return this->proc_noop(log, req); break; case BinlogType::COPY:{ status = COPY; if(++copy_count % 1000 == 1){ log_info("copy_count: %" PRIu64 ", last_seq: %" PRIu64 ", seq: %" PRIu64 "", copy_count, this->last_seq, log.seq()); } if(req.size() >= 2){ log_debug("[%s] %s [%d]", sync_type, log.dumps().c_str(), req[1].size()); }else{ log_debug("[%s] %s", sync_type, log.dumps().c_str()); } this->proc_copy(log, req); break; } case BinlogType::SYNC: case BinlogType::MIRROR:{ status = SYNC; if(++sync_count % 1000 == 1){ log_info("sync_count: %" PRIu64 ", last_seq: %" PRIu64 ", seq: %" PRIu64 "", sync_count, this->last_seq, log.seq()); } if(req.size() >= 2){ log_debug("[%s] %s [%d]", sync_type, log.dumps().c_str(), req[1].size()); }else{ log_debug("[%s] %s", sync_type, log.dumps().c_str()); } this->proc_sync(log, req); break; } default: break; } return 0; }
int Slave::proc(const std::vector<Bytes> &req){ Binlog log; if(log.load(req[0].Slice()) == -1){ log_error("invalid binlog!"); return 0; } switch(log.type()){ case BinlogType::NOOP: return this->proc_noop(log, req); break; case BinlogType::COPY:{ if(++copy_count % 1000 == 1){ log_info("copy_count: %" PRIu64 ", last_seq: %" PRIu64 ", seq: %" PRIu64 "", copy_count, this->last_seq, log.seq()); } if(this->is_mirror){ log_trace("[mirror] %s", log.dumps().c_str()); }else{ log_trace("[sync] %s", log.dumps().c_str()); } return this->proc_copy(log, req); break; } case BinlogType::SYNC: case BinlogType::MIRROR:{ if(++sync_count % 1000 == 1){ log_info("sync_count: %" PRIu64 ", last_seq: %" PRIu64 ", seq: %" PRIu64 "", sync_count, this->last_seq, log.seq()); } if(this->is_mirror){ log_debug("[mirror] %s", log.dumps().c_str()); }else{ log_debug("[sync] %s", log.dumps().c_str()); } return this->proc_sync(log, req); break; } default: break; } return 0; }
int BackendSync::Client::sync(BinlogQueue *logs) { Binlog log; while(1) { int ret = 0; uint64_t expect_seq = this->last_seq + 1; if(this->status == Client::COPY && this->last_seq == 0) { ret = logs->find_last(&log); } else { ret = logs->find_next(expect_seq, &log); } if(ret == 0) { return 0; } if(this->status == Client::COPY && log.key() > this->last_key) { log_debug("fd: %d, last_key: '%s', drop: %s", link->fd(), hexmem(this->last_key.data(), this->last_key.size()).c_str(), log.dumps().c_str()); this->last_seq = log.seq(); // WARN: When there are writes behind last_key, we MUST create // a new iterator, because iterator will not know this key. // Because iterator ONLY iterates throught keys written before // iterator is created. if(this->iter) { delete this->iter; this->iter = NULL; } continue; } if(this->last_seq != 0 && log.seq() != expect_seq) { log_warn("%s:%d fd: %d, OUT_OF_SYNC! log.seq: %" PRIu64 ", expect_seq: %" PRIu64 "", link->remote_ip, link->remote_port, link->fd(), log.seq(), expect_seq ); this->status = Client::OUT_OF_SYNC; return 1; } // update last_seq this->last_seq = log.seq(); char type = log.type(); if(type == BinlogType::MIRROR && this->is_mirror) { if(this->last_seq - this->last_noop_seq >= 1000) { this->noop(); return 1; } else { continue; } } break; } int ret = 0; std::string val; switch(log.cmd()) { case BinlogCommand::KSET: case BinlogCommand::HSET: case BinlogCommand::ZSET: case BinlogCommand::QSET: case BinlogCommand::QPUSH_BACK: case BinlogCommand::QPUSH_FRONT: ret = backend->ssdb->raw_get(log.key(), &val); if(ret == -1) { log_error("fd: %d, raw_get error!", link->fd()); } else if(ret == 0) { //log_debug("%s", hexmem(log.key().data(), log.key().size()).c_str()); log_trace("fd: %d, skip not found: %s", link->fd(), log.dumps().c_str()); } else { log_trace("fd: %d, %s", link->fd(), log.dumps().c_str()); link->send(log.repr(), val); } break; case BinlogCommand::KDEL: case BinlogCommand::HDEL: case BinlogCommand::ZDEL: case BinlogCommand::QPOP_BACK: case BinlogCommand::QPOP_FRONT: log_trace("fd: %d, %s", link->fd(), log.dumps().c_str()); link->send(log.repr()); break; } return 1; }
int BackendSync::Client::sync(BinlogQueue *logs){ Binlog log; while(1){ int ret = 0; uint64_t expect_seq = this->last_seq + 1; if(this->status == Client::COPY && this->last_seq == 0){ ret = logs->find_last(&log); }else{ ret = logs->find_next(expect_seq, &log); } if(ret == 0){ return 0; } // writes that are out of copied range will be discarded. if(this->status == Client::COPY && log.key() > this->last_key){ log_trace("fd: %d, last_key: '%s', drop: %s", link->fd(), hexmem(this->last_key.data(), this->last_key.size()).c_str(), log.dumps().c_str()); this->last_seq = log.seq(); //if(this->iter){ // delete this->iter; // this->iter = NULL; //} continue; } if(this->last_seq != 0 && log.seq() != expect_seq){ log_warn("fd: %d, OUT_OF_SYNC! log.seq: %" PRIu64", expect_seq: %" PRIu64"", link->fd(), log.seq(), expect_seq ); this->status = Client::OUT_OF_SYNC; return 1; } // update last_seq this->last_seq = log.seq(); char type = log.type(); if(type == BinlogType::MIRROR && this->is_mirror){ if(this->last_seq - this->last_noop_seq >= 1000){ this->noop(); return 1; }else{ continue; } } break; } int ret = 0; std::string val; switch(log.cmd()){ case BinlogCommand::KSET: case BinlogCommand::HSET: case BinlogCommand::ZSET: ret = backend->ssdb->raw_get(log.key(), &val); if(ret == -1){ log_error("fd: %d, raw_get error!", link->fd()); }else if(ret == 0){ //log_debug("%s", hexmem(log.key().data(), log.key().size()).c_str()); log_trace("fd: %d, skip not found: %s", link->fd(), log.dumps().c_str()); }else{ log_trace("fd: %d, %s", link->fd(), log.dumps().c_str()); link->send(log.repr(), val); } break; case BinlogCommand::KDEL: case BinlogCommand::HDEL: case BinlogCommand::ZDEL: log_trace("fd: %d, %s", link->fd(), log.dumps().c_str()); link->send(log.repr()); break; } return 1; }