YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/tserver/remote_bootstrap_session.h
Line
Count
Source (jump to first uncovered line)
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
//
18
// The following only applies to changes made to this file as part of YugaByte development.
19
//
20
// Portions Copyright (c) YugaByte, Inc.
21
//
22
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
23
// in compliance with the License.  You may obtain a copy of the License at
24
//
25
// http://www.apache.org/licenses/LICENSE-2.0
26
//
27
// Unless required by applicable law or agreed to in writing, software distributed under the License
28
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
29
// or implied.  See the License for the specific language governing permissions and limitations
30
// under the License.
31
//
32
#ifndef YB_TSERVER_REMOTE_BOOTSTRAP_SESSION_H_
33
#define YB_TSERVER_REMOTE_BOOTSTRAP_SESSION_H_
34
35
#include <array>
36
#include <memory>
37
#include <string>
38
#include <unordered_map>
39
#include <vector>
40
41
#include "yb/consensus/log_anchor_registry.h"
42
#include "yb/consensus/metadata.pb.h"
43
44
#include "yb/gutil/macros.h"
45
#include "yb/gutil/ref_counted.h"
46
47
#include "yb/tserver/remote_bootstrap.pb.h"
48
49
#include "yb/util/status_fwd.h"
50
#include "yb/util/locks.h"
51
#include "yb/util/net/rate_limiter.h"
52
53
namespace yb {
54
55
class Env;
56
class FsManager;
57
class RandomAccessFile;
58
59
namespace tablet {
60
class TabletPeer;
61
} // namespace tablet
62
63
namespace tserver {
64
65
class TabletPeerLookupIf;
66
67
struct GetDataPieceInfo {
68
  // Input
69
  uint64_t offset;
70
  int64_t client_maxlen;
71
72
  // Output
73
  std::string data;
74
  uint64_t data_size;
75
  RemoteBootstrapErrorPB::Code error_code;
76
77
4.82k
  int64_t bytes_remaining() const {
78
4.82k
    return data_size - offset;
79
4.82k
  }
80
};
81
82
class RemoteBootstrapSource {
83
 public:
84
  virtual CHECKED_STATUS Init() = 0;
85
  virtual CHECKED_STATUS ValidateDataId(const DataIdPB& data_id) = 0;
86
  virtual CHECKED_STATUS GetDataPiece(const DataIdPB& data_id, GetDataPieceInfo* info) = 0;
87
88
960
  virtual ~RemoteBootstrapSource() = default;
89
};
90
91
// A potential Learner must establish a RemoteBootstrapSession with the leader in order
92
// to fetch the needed superblock, blocks, and log segments.
93
// This class is refcounted to make it easy to remove it from the session map
94
// on expiration while it is in use by another thread.
95
class RemoteBootstrapSession : public RefCountedThreadSafe<RemoteBootstrapSession> {
96
 public:
97
  RemoteBootstrapSession(const std::shared_ptr<tablet::TabletPeer>& tablet_peer,
98
                         std::string session_id, std::string requestor_uuid,
99
                         const std::atomic<int>* nsessions);
100
101
  // Initialize the session, including anchoring files (TODO) and fetching the
102
  // tablet superblock and list of WAL segments.
103
  CHECKED_STATUS Init();
104
105
  // Return ID of tablet corresponding to this session.
106
  const std::string& tablet_id() const;
107
108
  // Return UUID of the requestor that initiated this session.
109
  const std::string& requestor_uuid() const;
110
111
  CHECKED_STATUS GetDataPiece(const DataIdPB& data_id, GetDataPieceInfo* info);
112
113
  CHECKED_STATUS ValidateDataId(const DataIdPB& data_id);
114
115
0
  MonoTime start_time() { return start_time_; }
116
117
1.44k
  const tablet::RaftGroupReplicaSuperBlockPB& tablet_superblock() const {
118
1.44k
    return tablet_superblock_; }
119
120
1.44k
  const consensus::ConsensusStatePB& initial_committed_cstate() const {
121
1.44k
    return initial_committed_cstate_;
122
1.44k
  }
123
124
1.44k
  const log::SegmentSequence& log_segments() const { return log_segments_; }
125
126
  void SetSuccess();
127
128
  bool Succeeded();
129
130
  // Change the peer's role to VOTER.
131
  CHECKED_STATUS ChangeRole();
132
133
  void InitRateLimiter();
134
135
  void EnsureRateLimiterIsInitialized();
136
137
10.6k
  RateLimiter& rate_limiter() { return rate_limiter_; }
138
139
  static const std::string kCheckpointsDir;
140
141
  // Get a piece of a RocksDB file.
142
  // The behavior and params are very similar to GetLogSegmentPiece(), but this one
143
  // is only for sending rocksdb files.
144
  static CHECKED_STATUS GetFilePiece(
145
      const std::string& path, const std::string& file_name, Env* env, GetDataPieceInfo* info);
146
147
 private:
148
  friend class RefCountedThreadSafe<RemoteBootstrapSession>;
149
150
  FRIEND_TEST(RemoteBootstrapRocksDBTest, TestCheckpointDirectory);
151
  FRIEND_TEST(RemoteBootstrapRocksDBTest, CheckSuperBlockHasRocksDBFields);
152
  FRIEND_TEST(RemoteBootstrapRocksDBTest, CheckSuperBlockHasSnapshotFields);
153
  FRIEND_TEST(RemoteBootstrapRocksDBTest, TestNonExistentRocksDBFile);
154
155
  virtual ~RemoteBootstrapSession();
156
157
  template <class Source>
158
1.44k
  void AddSource() {
159
1.44k
    sources_[Source::id_type()] = std::make_unique<Source>(tablet_peer_, &tablet_superblock_);
160
1.44k
  }
161
162
  // Snapshot the log segment's length and put it into segment map.
163
  CHECKED_STATUS OpenLogSegment(uint64_t segment_seqno, RemoteBootstrapErrorPB::Code* error_code)
164
      REQUIRES(mutex_);
165
166
  // Unregister log anchor, if it's registered.
167
  CHECKED_STATUS UnregisterAnchorIfNeededUnlocked();
168
169
  // Helper API to set initial_committed_cstate_.
170
  CHECKED_STATUS SetInitialCommittedState();
171
172
  // Get a piece of a log segment.
173
  // If maxlen is 0, we use a system-selected length for the data piece.
174
  // *data is set to a std::string containing the data. Ownership of this object
175
  // is passed to the caller. A string is used because the RPC interface is
176
  // sending data serialized as protobuf and we want to minimize copying.
177
  // On error, Status is set to a non-OK value and error_code is filled in.
178
  //
179
  // This method is thread-safe.
180
  CHECKED_STATUS GetLogSegmentPiece(uint64_t segment_seqno, GetDataPieceInfo* info);
181
182
  // Get a piece of a RocksDB checkpoint file.
183
  CHECKED_STATUS GetRocksDBFilePiece(const std::string& file_name, GetDataPieceInfo* info);
184
185
  Env* env() const;
186
187
  RemoteBootstrapSource* Source(DataIdPB::IdType id_type) const;
188
189
  std::shared_ptr<tablet::TabletPeer> tablet_peer_;
190
  const std::string session_id_;
191
  const std::string requestor_uuid_;
192
193
  mutable std::mutex mutex_;
194
195
  std::shared_ptr<RandomAccessFile> opened_log_segment_file_ GUARDED_BY(mutex_);
196
  int64_t opened_log_segment_file_size_ GUARDED_BY(mutex_) = -1;
197
  uint64_t opened_log_segment_seqno_ GUARDED_BY(mutex_) = 0;
198
  bool opened_log_segment_active_ GUARDED_BY(mutex_) = false;
199
200
  tablet::RaftGroupReplicaSuperBlockPB tablet_superblock_;
201
202
  consensus::ConsensusStatePB initial_committed_cstate_;
203
204
  // The sequence of log segments that will be sent in the course of this
205
  // session.
206
  log::SegmentSequence log_segments_;
207
208
  log::LogAnchor log_anchor_;
209
  int64_t log_anchor_index_ GUARDED_BY(mutex_) = 0;
210
211
  // We need to know whether this ended succesfully before changing the peer's member type from
212
  // PRE_VOTER to VOTER.
213
  bool succeeded_ GUARDED_BY(mutex_) = false;
214
215
  // Directory where the checkpoint files are stored for this session (only for rocksdb).
216
  std::string checkpoint_dir_;
217
218
  // Time when this session was initialized.
219
  MonoTime start_time_;
220
221
  // Used to limit the transmission rate.
222
  RateLimiter rate_limiter_;
223
224
  // Pointer to the counter for of the number of sessions in RemoteBootstrapService. Used to
225
  // calculate the rate for the rate limiter.
226
  const std::atomic<int>* nsessions_;
227
228
  std::array<std::unique_ptr<RemoteBootstrapSource>, DataIdPB::IdType_ARRAYSIZE> sources_;
229
230
  DISALLOW_COPY_AND_ASSIGN(RemoteBootstrapSession);
231
};
232
233
} // namespace tserver
234
} // namespace yb
235
236
#endif // YB_TSERVER_REMOTE_BOOTSTRAP_SESSION_H_