示例#1
0
文件: slave.cpp 项目: chenld/ssdb
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;
}
示例#2
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;
}
示例#3
0
文件: slave.cpp 项目: 29n/ssdb
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;
}
示例#4
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;
}
示例#5
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;
		}
		// 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;
}