Ejemplo n.º 1
0
Archivo: repl.cpp Proyecto: lamphp/ssdb
uint64_t PersistentSyncLogQueue::find_seq_at_pos(int pos){
	Synclog log;
	if(find_by_pos(pos, &log) == 0){
		return 0;
	}
	return log.seq();
}
Ejemplo n.º 2
0
Archivo: repl.cpp Proyecto: lamphp/ssdb
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);
}
Ejemplo n.º 3
0
Archivo: repl.cpp Proyecto: lamphp/ssdb
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);
}
Ejemplo n.º 4
0
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;
}