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_client.h
Line
Count
Source
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_CLIENT_H
33
#define YB_TSERVER_REMOTE_BOOTSTRAP_CLIENT_H
34
35
#include <atomic>
36
#include <string>
37
#include <memory>
38
#include <vector>
39
#include <unordered_map>
40
41
#include <gtest/gtest_prod.h>
42
43
#include "yb/consensus/consensus_fwd.h"
44
#include "yb/gutil/macros.h"
45
#include "yb/gutil/ref_counted.h"
46
#include "yb/rpc/rpc_fwd.h"
47
#include "yb/tserver/remote_bootstrap.pb.h"
48
#include "yb/tserver/remote_bootstrap_file_downloader.h"
49
#include "yb/util/status_fwd.h"
50
51
namespace yb {
52
53
class BlockIdPB;
54
class Env;
55
class FsManager;
56
class HostPort;
57
class RemoteBootstrapITest;
58
59
namespace consensus {
60
class ConsensusMetadata;
61
class ConsensusStatePB;
62
class RaftConfigPB;
63
class RaftPeerPB;
64
} // namespace consensus
65
66
namespace tablet {
67
class RaftGroupMetadata;
68
class TabletPeer;
69
class TabletStatusListener;
70
class RaftGroupReplicaSuperBlockPB;
71
} // namespace tablet
72
73
namespace tserver {
74
class DataIdPB;
75
class DataChunkPB;
76
class RemoteBootstrapServiceProxy;
77
class TSTabletManager;
78
79
class RemoteBootstrapComponent {
80
 public:
81
  virtual CHECKED_STATUS CreateDirectories(const std::string& db_dir, FsManager* fs) = 0;
82
  virtual CHECKED_STATUS Download() = 0;
83
84
1.43k
  virtual ~RemoteBootstrapComponent() = default;
85
};
86
87
// Client class for using remote bootstrap to copy a tablet from another host.
88
// This class is not thread-safe.
89
//
90
// TODO:
91
// * Parallelize download of blocks and WAL segments.
92
//
93
class RemoteBootstrapClient {
94
 public:
95
96
  // Construct the remote bootstrap client.
97
  // 'fs_manager' and 'messenger' must remain valid until this object is destroyed.
98
  RemoteBootstrapClient(std::string tablet_id, FsManager* fs_manager);
99
100
  // Attempt to clean up resources on the remote end by sending an
101
  // EndRemoteBootstrapSession() RPC
102
  ~RemoteBootstrapClient();
103
104
  // Pass in the existing metadata for a tombstoned tablet, which will be
105
  // replaced if validation checks pass in Start().
106
  // 'meta' is the metadata for the tombstoned tablet and 'caller_term' is the
107
  // term provided by the caller (assumed to be the current leader of the
108
  // consensus config) for validation purposes.
109
  // If the consensus metadata exists on disk for this tablet, and if
110
  // 'caller_term' is lower than the current term stored in that consensus
111
  // metadata, then this method will fail with a Status::InvalidArgument error.
112
  CHECKED_STATUS SetTabletToReplace(const scoped_refptr<tablet::RaftGroupMetadata>& meta,
113
                                    int64_t caller_term);
114
115
  // Start up a remote bootstrap session to bootstrap from the specified
116
  // bootstrap peer. Place a new superblock indicating that remote bootstrap is
117
  // in progress. If the 'metadata' pointer is passed as NULL, it is ignored,
118
  // otherwise the RaftGroupMetadata object resulting from the initial remote
119
  // bootstrap response is returned.
120
  // ts_manager pointer allows the bootstrap function to assign non-random
121
  // data and wal directories for the bootstrapped tablets.
122
  // TODO: Rename these parameters to bootstrap_source_*.
123
  CHECKED_STATUS Start(const std::string& bootstrap_peer_uuid,
124
                       rpc::ProxyCache* proxy_cache,
125
                       const HostPort& bootstrap_peer_addr,
126
                       scoped_refptr<tablet::RaftGroupMetadata>* metadata,
127
                       TSTabletManager* ts_manager = nullptr);
128
129
  // Runs a "full" remote bootstrap, copying the physical layout of a tablet
130
  // from the leader of the specified consensus configuration.
131
  CHECKED_STATUS FetchAll(tablet::TabletStatusListener* status_listener);
132
133
  // After downloading all files successfully, write out the completed
134
  // replacement superblock.
135
  CHECKED_STATUS Finish();
136
137
  // Verify that the remote bootstrap was completed successfully by verifying that the ChangeConfig
138
  // request was propagated.
139
  CHECKED_STATUS VerifyChangeRoleSucceeded(
140
      const std::shared_ptr<consensus::Consensus>& shared_consensus);
141
142
  // Removes session at server.
143
  CHECKED_STATUS Remove();
144
145
 private:
146
  FRIEND_TEST(RemoteBootstrapRocksDBClientTest, TestBeginEndSession);
147
  friend class yb::RemoteBootstrapITest;
148
149
  template <class Component>
150
1.44k
  void AddComponent() {
151
1.44k
    components_.push_back(std::make_unique<Component>(&downloader_, &new_superblock_));
152
1.44k
  }
153
154
  // Update the bootstrap StatusListener with a message.
155
  // The string "RemoteBootstrap: " will be prepended to each message.
156
  void UpdateStatusMessage(const std::string& message);
157
158
  // Download all WAL files sequentially.
159
  CHECKED_STATUS DownloadWALs();
160
161
  // Download a single WAL file.
162
  // Assumes the WAL directories have already been created.
163
  // WAL file is opened with options so that it will fsync() on close.
164
  CHECKED_STATUS DownloadWAL(uint64_t wal_segment_seqno);
165
166
  // Write out the Consensus Metadata file based on the ConsensusStatePB
167
  // downloaded as part of initiating the remote bootstrap session.
168
  CHECKED_STATUS WriteConsensusMetadata();
169
170
  CHECKED_STATUS CreateTabletDirectories(const std::string& db_dir, FsManager* fs);
171
172
  CHECKED_STATUS DownloadRocksDBFiles();
173
174
  // End the remote bootstrap session.
175
  CHECKED_STATUS EndRemoteSession();
176
177
  // Return standard log prefix.
178
20.8k
  const std::string& LogPrefix() const {
179
20.8k
    return log_prefix_;
180
20.8k
  }
181
182
7.72k
  const std::string& session_id() const {
183
7.72k
    return downloader_.session_id();
184
7.72k
  }
185
186
139M
  FsManager& fs_manager() const {
187
139M
    return downloader_.fs_manager();
188
139M
  }
189
190
  Env& env() const;
191
192
  const std::string& permanent_uuid() const;
193
194
  // Set-once members.
195
  const std::string tablet_id_;
196
197
  // State flags that enforce the progress of remote bootstrap.
198
  bool started_ = false;            // Session started.
199
  // Total number of remote bootstrap sessions. Used to calculate the transmission rate across all
200
  // the sessions.
201
  bool downloaded_wal_ = false;     // WAL segments downloaded.
202
  bool downloaded_blocks_ = false;  // Data blocks downloaded.
203
  bool downloaded_rocksdb_files_ = false;
204
205
  // Session-specific data items.
206
  bool replace_tombstoned_tablet_ = false;
207
208
  bool remove_required_ = false;
209
210
  // Local tablet metadata file.
211
  scoped_refptr<tablet::RaftGroupMetadata> meta_;
212
213
  // Local Consensus metadata file. This may initially be NULL if this is
214
  // bootstrapping a new replica (rather than replacing an old one).
215
  std::unique_ptr<consensus::ConsensusMetadata> cmeta_;
216
217
  tablet::TabletStatusListener* status_listener_ = nullptr;
218
  std::shared_ptr<RemoteBootstrapServiceProxy> proxy_;
219
  std::unique_ptr<tablet::RaftGroupReplicaSuperBlockPB> superblock_;
220
  tablet::RaftGroupReplicaSuperBlockPB new_superblock_;
221
  std::unique_ptr<consensus::ConsensusStatePB> remote_committed_cstate_;
222
  tablet::TabletDataState remote_tablet_data_state_;
223
224
  std::vector<uint64_t> wal_seqnos_;
225
226
  // Components of this remote bootstrap client.
227
  std::vector<std::unique_ptr<RemoteBootstrapComponent>> components_;
228
229
  // First available WAL segment.
230
  uint64_t first_wal_seqno_ = 0;
231
232
  int64_t start_time_micros_ = 0;
233
234
  // We track whether this session succeeded and send this information as part of the
235
  // EndRemoteBootstrapSessionRequestPB request.
236
  bool succeeded_ = false;
237
238
  const std::string log_prefix_;
239
  RemoteBootstrapFileDownloader downloader_;
240
241
  DISALLOW_COPY_AND_ASSIGN(RemoteBootstrapClient);
242
};
243
244
} // namespace tserver
245
} // namespace yb
246
247
#endif // YB_TSERVER_REMOTE_BOOTSTRAP_CLIENT_H