MCPcopy Create free account
hub / github.com/apache/kvrocks / Execute

Method Execute

src/commands/cmd_replication.cc:60–116  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

58 }
59
60 Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override {
61 INFO(
62 "Slave {}, listening port: {}, announce ip: {} asks for synchronization "
63 "with next sequence: {}, replication id: {}, and local sequence: {}",
64 conn->GetAddr(), conn->GetListeningPort(), conn->GetAnnounceIP(), next_repl_seq_,
65 (replica_replid_.length() ? replica_replid_ : "not supported"), srv->storage->LatestSeqNumber());
66 bool need_full_sync = false;
67
68 // Check replication id of the last sequence log
69 if (new_psync_ && srv->GetConfig()->use_rsid_psync) {
70 std::string replid_in_wal = srv->storage->GetReplIdFromWalBySeq(next_repl_seq_ - 1);
71 INFO("Replication id in WAL: {}", replid_in_wal);
72
73 // We check replication id only when WAL has this sequence, since there may be no WAL,
74 // Or WAL may have nothing when starting from db of old version kvrocks.
75 if (replid_in_wal.length() == kReplIdLength && replid_in_wal != replica_replid_) {
76 *output = "wrong replication id of the last log";
77 need_full_sync = true;
78 }
79 }
80
81 // Check Log sequence
82 if (!need_full_sync && !checkWALBoundary(srv->storage, next_repl_seq_).IsOK()) {
83 *output = "sequence out of range, please use fullsync";
84 need_full_sync = true;
85 }
86
87 if (need_full_sync) {
88 srv->stats.IncrPSyncErrCount();
89 return {Status::RedisExecErr, *output};
90 }
91
92 // Server would spawn a new thread to sync the batch, and connection would
93 // be taken over, so should never trigger any event in worker thread.
94 conn->Detach();
95 conn->EnableFlag(redis::Connection::kSlave);
96 auto s = util::SockSetBlocking(conn->GetFD(), 1);
97 if (!s.IsOK()) {
98 conn->EnableFlag(redis::Connection::kCloseAsync);
99 return s.Prefixed("failed to set blocking mode on socket");
100 }
101
102 srv->stats.IncrPSyncOKCount();
103 s = srv->AddSlave(conn, next_repl_seq_);
104 if (!s.IsOK()) {
105 std::string err = redis::Error(s);
106 s = util::SockSend(conn->GetFD(), err, conn->GetBufferEvent());
107 if (!s.IsOK()) {
108 WARN("failed to send error message to the replica: {}", s.Msg());
109 }
110 conn->EnableFlag(redis::Connection::kCloseAsync);
111 WARN("Failed to add replica: {} to start incremental syncing", conn->GetAddr());
112 } else {
113 INFO("New replica: {} was added, start incremental syncing", conn->GetAddr());
114 }
115 return s;
116 }
117

Callers

nothing calls this directly

Calls 15

SockSetBlockingFunction · 0.85
ErrorFunction · 0.85
SockSendFunction · 0.85
GetAddrMethod · 0.80
GetListeningPortMethod · 0.80
GetAnnounceIPMethod · 0.80
LatestSeqNumberMethod · 0.80
GetReplIdFromWalBySeqMethod · 0.80
IncrPSyncErrCountMethod · 0.80
DetachMethod · 0.80
EnableFlagMethod · 0.80
GetFDMethod · 0.80

Tested by

no test coverage detected