void Slave::HandleRedisCommand(Channel* ch, RedisCommandFrame& cmd) { int flag = ARDB_PROCESS_REPL_WRITE; if (m_slave_state == SLAVE_STATE_SYNCED || m_slave_state == SLAVE_STATE_LOADING_DUMP_DATA) { flag |= ARDB_PROCESS_FORCE_REPLICATION; } else { flag |= ARDB_PROCESS_WITHOUT_REPLICATION; } DEBUG_LOG("Recv master cmd %s at %lld at flag:%d at state:%d", cmd.ToString().c_str(), m_backlog.GetReplEndOffset(), flag, m_slave_state); if (m_slave_state == SLAVE_STATE_WAITING_PSYNC_REPLY && m_server_type == ARDB_DB_SERVER_TYPE) { if (!strcasecmp(cmd.GetCommand().c_str(), "FULLSYNCED")) { uint64 offset, cksm; string_touint64(cmd.GetArguments()[0], offset); string_touint64(cmd.GetArguments()[1], cksm); m_backlog.SetChecksum(cksm); ASSERT(offset == m_backlog.GetReplEndOffset()); //m_backlog.SetReplOffset(offset); m_slave_state = SLAVE_STATE_SYNCED; //Disconnect all slaves when all data resynced m_serv->m_master_serv.DisconnectAllSlaves(); return; } } if (!strcasecmp(cmd.GetCommand().c_str(), "PING")) { m_ping_recved_time = time(NULL); } else if (!strcasecmp(cmd.GetCommand().c_str(), "SELECT")) { DBID id = 0; string_touint32(cmd.GetArguments()[0], id); m_backlog.SetCurrentDBID(id); } GetArdbConnContext(); m_actx->is_slave_conn = true; m_actx->conn = ch; if (strcasecmp(cmd.GetCommand().c_str(), "SELECT") && strcasecmp(cmd.GetCommand().c_str(), "__SET__") && strcasecmp(cmd.GetCommand().c_str(), "__DEL__")) { if (!m_include_dbs.empty() && m_include_dbs.count(m_actx->currentDB) == 0) { flag |= ARDB_PROCESS_FEED_REPLICATION_ONLY; } if (!m_exclude_dbs.empty() && m_exclude_dbs.count(m_actx->currentDB) > 0) { flag |= ARDB_PROCESS_FEED_REPLICATION_ONLY; } } m_serv->ProcessRedisCommand(*m_actx, cmd, flag); }
void Master::AddSlave(Channel* slave, RedisCommandFrame& cmd) { INFO_LOG("[Master]Recv sync command:%s", cmd.ToString().c_str()); slave->Flush(); SlaveConn& conn = GetSlaveConn(slave); if (!strcasecmp(cmd.GetCommand().c_str(), "sync")) { //Redis 2.6/2.4 send 'sync' conn.isRedisSlave = true; conn.sync_offset = -1; } else { conn.server_key = cmd.GetArguments()[0]; const std::string& offset_str = cmd.GetArguments()[1]; if (!string_toint64(offset_str, conn.sync_offset)) { ERROR_LOG("Invalid offset argument:%s", offset_str.c_str()); slave->Close(); return; } conn.isRedisSlave = true; for (uint32 i = 2; i < cmd.GetArguments().size(); i += 2) { if (cmd.GetArguments()[i] == "cksm") { conn.isRedisSlave = false; if (!string_touint64(cmd.GetArguments()[i + 1], conn.sync_cksm)) { ERROR_LOG("Invalid checksum argument:%s", cmd.GetArguments()[i + 1].c_str()); slave->Close(); return; } } } } slave->GetService().DetachChannel(slave, true); if (g_repl->GetIOServ().IsInLoopThread()) { AddSlave(&conn); } else { g_repl->GetIOServ().AsyncIO(0, OnAddSlave, &conn); } }