/Users/deen/code/yugabyte-db/src/yb/master/catalog_loaders.cc
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 | | |
33 | | #include "yb/master/catalog_loaders.h" |
34 | | |
35 | | #include "yb/master/master_util.h" |
36 | | #include "yb/master/ysql_transaction_ddl.h" |
37 | | |
38 | | #include "yb/util/status_format.h" |
39 | | #include "yb/util/status_log.h" |
40 | | |
41 | | DEFINE_bool(master_ignore_deleted_on_load, true, |
42 | | "Whether the Master should ignore deleted tables & tablets on restart. " |
43 | | "This reduces failover time at the expense of garbage data." ); |
44 | | |
45 | | namespace yb { |
46 | | namespace master { |
47 | | |
48 | | using namespace std::placeholders; |
49 | | |
50 | | //////////////////////////////////////////////////////////// |
51 | | // Table Loader |
52 | | //////////////////////////////////////////////////////////// |
53 | | |
54 | 210k | bool ShouldLoadObject(const SysTablesEntryPB& metadata) { |
55 | | // TODO: We need to properly remove deleted tables. This can happen async of master loading. |
56 | 210k | return !FLAGS_master_ignore_deleted_on_load || metadata.state() != SysTablesEntryPB::DELETED; |
57 | 210k | } |
58 | | |
59 | 210k | Status TableLoader::Visit(const TableId& table_id, const SysTablesEntryPB& metadata) { |
60 | | // TODO: We need to properly remove deleted tables. This can happen async of master loading. |
61 | 210k | if (!ShouldLoadObject(metadata)) { |
62 | 36 | return Status::OK(); |
63 | 36 | } |
64 | | |
65 | 0 | CHECK(!ContainsKey(*catalog_manager_->table_ids_map_, table_id)) |
66 | 0 | << "Table already exists: " << table_id; |
67 | | |
68 | | // Setup the table info. |
69 | 210k | scoped_refptr<TableInfo> table = catalog_manager_->NewTableInfo(table_id); |
70 | 210k | auto l = table->LockForWrite(); |
71 | 210k | auto& pb = l.mutable_data()->pb; |
72 | 210k | pb.CopyFrom(metadata); |
73 | | |
74 | 210k | if (pb.table_type() == TableType::REDIS_TABLE_TYPE && pb.name() == kGlobalTransactionsTableName) { |
75 | 0 | pb.set_table_type(TableType::TRANSACTION_STATUS_TABLE_TYPE); |
76 | 0 | } |
77 | | |
78 | | // Add the table to the IDs map and to the name map (if the table is not deleted). Do not |
79 | | // add Postgres tables to the name map as the table name is not unique in a namespace. |
80 | 210k | auto table_ids_map_checkout = catalog_manager_->table_ids_map_.CheckOut(); |
81 | 210k | (*table_ids_map_checkout)[table->id()] = table; |
82 | 210k | if (!l->started_deleting() && !l->started_hiding()) { |
83 | 210k | if (l->table_type() != PGSQL_TABLE_TYPE) { |
84 | 7.20k | catalog_manager_->table_names_map_[{l->namespace_id(), l->name()}] = table; |
85 | 7.20k | } |
86 | 210k | if (l->table_type() == TRANSACTION_STATUS_TABLE_TYPE) { |
87 | 8 | catalog_manager_->transaction_table_ids_set_.insert(table_id); |
88 | 8 | } |
89 | 210k | } |
90 | | |
91 | 210k | l.Commit(); |
92 | 210k | catalog_manager_->HandleNewTableId(table->id()); |
93 | | |
94 | | // Tables created as part of a Transaction should check transaction status and be deleted |
95 | | // if the transaction is aborted. |
96 | 210k | if (metadata.has_transaction()) { |
97 | 1 | LOG(INFO) << "Enqueuing table for Transaction Verification: " << table->ToString(); |
98 | 1 | TransactionMetadata txn = VERIFY_RESULT(TransactionMetadata::FromPB(metadata.transaction())); |
99 | 1 | std::function<Status(bool)> when_done = |
100 | 1 | std::bind(&CatalogManager::VerifyTablePgLayer, catalog_manager_, table, _1); |
101 | 1 | WARN_NOT_OK(catalog_manager_->background_tasks_thread_pool_->SubmitFunc( |
102 | 1 | std::bind(&YsqlTransactionDdl::VerifyTransaction, catalog_manager_->ysql_transaction_.get(), |
103 | 1 | txn, when_done)), |
104 | 1 | "Could not submit VerifyTransaction to thread pool"); |
105 | 1 | } |
106 | | |
107 | 210k | LOG(INFO) << "Loaded metadata for table " << table->ToString() << ", state: " |
108 | 210k | << SysTablesEntryPB::State_Name(metadata.state()); |
109 | 0 | VLOG(1) << "Metadata for table " << table->ToString() << ": " << metadata.ShortDebugString(); |
110 | | |
111 | 210k | return Status::OK(); |
112 | 210k | } |
113 | | |
114 | | //////////////////////////////////////////////////////////// |
115 | | // Tablet Loader |
116 | | //////////////////////////////////////////////////////////// |
117 | | |
118 | 7.90k | bool ShouldLoadObject(const SysTabletsEntryPB& pb) { |
119 | 7.90k | return true; |
120 | 7.90k | } |
121 | | |
122 | 7.90k | Status TabletLoader::Visit(const TabletId& tablet_id, const SysTabletsEntryPB& metadata) { |
123 | 7.90k | if (!ShouldLoadObject(metadata)) { |
124 | 0 | return Status::OK(); |
125 | 0 | } |
126 | | |
127 | | // Lookup the table. |
128 | 7.90k | TableInfoPtr first_table = FindPtrOrNull(*catalog_manager_->table_ids_map_, metadata.table_id()); |
129 | | |
130 | | // TODO: We need to properly remove deleted tablets. This can happen async of master loading. |
131 | 7.90k | if (!first_table) { |
132 | 275 | if (metadata.state() != SysTabletsEntryPB::DELETED) { |
133 | 0 | LOG(DFATAL) << "Unexpected Tablet state for " << tablet_id << ": " |
134 | 0 | << SysTabletsEntryPB::State_Name(metadata.state()) |
135 | 0 | << ", unknown table for this tablet: " << metadata.table_id(); |
136 | 0 | } |
137 | 275 | return Status::OK(); |
138 | 275 | } |
139 | | |
140 | | // Setup the tablet info. |
141 | 7.63k | std::vector<TableId> table_ids; |
142 | 7.63k | bool tablet_deleted; |
143 | 7.63k | bool listed_as_hidden; |
144 | 7.63k | TabletInfoPtr tablet(new TabletInfo(first_table, tablet_id)); |
145 | 7.63k | { |
146 | 7.63k | auto l = tablet->LockForWrite(); |
147 | 7.63k | l.mutable_data()->pb.CopyFrom(metadata); |
148 | | |
149 | | // Add the tablet to the tablet manager. |
150 | 7.63k | auto tablet_map_checkout = catalog_manager_->tablet_map_.CheckOut(); |
151 | 7.63k | auto inserted = tablet_map_checkout->emplace(tablet->tablet_id(), tablet).second; |
152 | 7.63k | if (!inserted) { |
153 | 0 | return STATUS_FORMAT( |
154 | 0 | IllegalState, "Loaded tablet that already in map: $0", tablet->tablet_id()); |
155 | 0 | } |
156 | | |
157 | 218k | for (int k = 0; k < metadata.table_ids_size(); ++k) { |
158 | 210k | table_ids.push_back(metadata.table_ids(k)); |
159 | 210k | } |
160 | | |
161 | | // This is for backwards compatibility: we want to ensure that the table_ids |
162 | | // list contains the first table that created the tablet. If the table_ids field |
163 | | // was empty, we "upgrade" the master to support this new invariant. |
164 | 7.63k | if (metadata.table_ids_size() == 0) { |
165 | 0 | l.mutable_data()->pb.add_table_ids(metadata.table_id()); |
166 | 0 | Status s = catalog_manager_->sys_catalog_->Upsert( |
167 | 0 | catalog_manager_->leader_ready_term(), tablet); |
168 | 0 | if (PREDICT_FALSE(!s.ok())) { |
169 | 0 | return STATUS_FORMAT( |
170 | 0 | IllegalState, "An error occurred while inserting to sys-tablets: $0", s); |
171 | 0 | } |
172 | 0 | table_ids.push_back(metadata.table_id()); |
173 | 0 | } |
174 | | |
175 | 7.63k | tablet_deleted = l.mutable_data()->is_deleted(); |
176 | 7.63k | listed_as_hidden = l.mutable_data()->ListedAsHidden(); |
177 | | |
178 | | // Assume we need to delete this tablet until we find an active table using this tablet. |
179 | 7.63k | bool should_delete_tablet = !tablet_deleted; |
180 | | |
181 | 210k | for (const auto& table_id : table_ids) { |
182 | 210k | TableInfoPtr table = FindPtrOrNull(*catalog_manager_->table_ids_map_, table_id); |
183 | | |
184 | 210k | if (table == nullptr) { |
185 | | // If the table is missing and the tablet is in "preparing" state |
186 | | // may mean that the table was not created (maybe due to a failed write |
187 | | // for the sys-tablets). The cleaner will remove. |
188 | 0 | auto tablet_state = l->pb.state(); |
189 | 0 | if (tablet_state == SysTabletsEntryPB::PREPARING) { |
190 | 0 | LOG(WARNING) << "Missing table " << table_id << " required by tablet " << tablet_id |
191 | 0 | << " (probably a failed table creation: the tablet was not assigned)"; |
192 | 0 | return Status::OK(); |
193 | 0 | } |
194 | | |
195 | | // Otherwise, something is wrong... |
196 | 0 | LOG(WARNING) << "Missing table " << table_id << " required by tablet " << tablet_id |
197 | 0 | << ", metadata: " << metadata.DebugString() |
198 | 0 | << ", tables: " << yb::ToString(*catalog_manager_->table_ids_map_); |
199 | | // If we ignore deleted tables, then a missing table can be expected and we continue. |
200 | 0 | if (PREDICT_TRUE(FLAGS_master_ignore_deleted_on_load)) { |
201 | 0 | continue; |
202 | 0 | } |
203 | | // Otherwise, we need to surface the corruption. |
204 | 0 | return STATUS(Corruption, "Missing table for tablet: ", tablet_id); |
205 | 0 | } |
206 | | |
207 | | // Add the tablet to the Table. |
208 | 210k | if (!tablet_deleted) { |
209 | | // Any table listed under the sys catalog tablet, is by definition a system table. |
210 | | // This is the easiest place to mark these as system tables, as we'll only go over |
211 | | // sys_catalog tablet once and can mark in memory all the relevant tables. |
212 | 210k | if (tablet_id == kSysCatalogTabletId) { |
213 | 203k | table->set_is_system(); |
214 | 203k | } |
215 | 210k | table->AddTablet(tablet.get()); |
216 | 210k | } |
217 | | |
218 | 210k | auto tl = table->LockForRead(); |
219 | 210k | if (!tl->started_deleting()) { |
220 | | // Found an active table. |
221 | 210k | should_delete_tablet = false; |
222 | 210k | } |
223 | 210k | } |
224 | | |
225 | | |
226 | 7.63k | if (should_delete_tablet) { |
227 | 80 | LOG(WARNING) |
228 | 80 | << "Deleting tablet " << tablet->id() << " for table " << first_table->ToString(); |
229 | 80 | string deletion_msg = "Tablet deleted at " + LocalTimeAsString(); |
230 | 80 | l.mutable_data()->set_state(SysTabletsEntryPB::DELETED, deletion_msg); |
231 | 80 | RETURN_NOT_OK_PREPEND(catalog_manager_->sys_catalog()->Upsert(term_, tablet), |
232 | 80 | Format("Error deleting tablet $0", tablet->id())); |
233 | 80 | } |
234 | | |
235 | 7.63k | l.Commit(); |
236 | 7.63k | } |
237 | | |
238 | | // Add the tablet to colocated_tablet_ids_map_ if the tablet is colocated. |
239 | 7.63k | if (first_table->IsColocatedParentTable()) { |
240 | 0 | catalog_manager_->colocated_tablet_ids_map_[first_table->namespace_id()] = |
241 | 0 | catalog_manager_->tablet_map_->find(tablet_id)->second; |
242 | 0 | } |
243 | | |
244 | | // Add the tablet to tablegroup_tablet_ids_map_ if the tablet is a tablegroup parent. |
245 | 7.63k | if (first_table->IsTablegroupParentTable()) { |
246 | 1 | catalog_manager_->tablegroup_tablet_ids_map_[first_table->namespace_id()] |
247 | 1 | [first_table->id().substr(0, 32)] = catalog_manager_->tablet_map_->find(tablet_id)->second; |
248 | | |
249 | 1 | TablegroupInfo *tg = new TablegroupInfo(first_table->id().substr(0, 32), |
250 | 1 | first_table->namespace_id()); |
251 | | |
252 | | // Loop through table_ids again to add them to our tablegroup info. |
253 | 1 | for (auto table_id : table_ids) { |
254 | 1 | tg->AddChildTable(table_id); |
255 | 1 | } |
256 | 1 | catalog_manager_->tablegroup_ids_map_[first_table->id().substr(0, 32)] = tg; |
257 | 1 | } |
258 | | |
259 | 7.63k | LOG(INFO) << "Loaded metadata for " << (tablet_deleted ? "deleted " : "") |
260 | 7.63k | << "tablet " << tablet_id |
261 | 7.63k | << " (first table " << first_table->ToString() << ")"; |
262 | | |
263 | 0 | VLOG(1) << "Metadata for tablet " << tablet_id << ": " << metadata.ShortDebugString(); |
264 | | |
265 | 7.63k | if (listed_as_hidden) { |
266 | 0 | catalog_manager_->hidden_tablets_.push_back(tablet); |
267 | 0 | } |
268 | | |
269 | 7.63k | return Status::OK(); |
270 | 7.63k | } |
271 | | |
272 | | //////////////////////////////////////////////////////////// |
273 | | // Namespace Loader |
274 | | //////////////////////////////////////////////////////////// |
275 | | |
276 | 3.13k | bool ShouldLoadObject(const SysNamespaceEntryPB& metadata) { |
277 | 3.13k | return true; |
278 | 3.13k | } |
279 | | |
280 | 3.13k | Status NamespaceLoader::Visit(const NamespaceId& ns_id, const SysNamespaceEntryPB& metadata) { |
281 | 3.13k | if (!ShouldLoadObject(metadata)) { |
282 | 0 | return Status::OK(); |
283 | 0 | } |
284 | | |
285 | 0 | CHECK(!ContainsKey(catalog_manager_->namespace_ids_map_, ns_id)) |
286 | 0 | << "Namespace already exists: " << ns_id; |
287 | | |
288 | | // Setup the namespace info. |
289 | 3.13k | scoped_refptr<NamespaceInfo> ns = new NamespaceInfo(ns_id); |
290 | 3.13k | auto l = ns->LockForWrite(); |
291 | 3.13k | const auto& pb_data = l->pb; |
292 | | |
293 | 3.13k | l.mutable_data()->pb.CopyFrom(metadata); |
294 | | |
295 | 3.13k | if (!pb_data.has_database_type() || pb_data.database_type() == YQL_DATABASE_UNKNOWN) { |
296 | 0 | LOG(INFO) << "Updating database type of namespace " << pb_data.name(); |
297 | 0 | l.mutable_data()->pb.set_database_type(GetDefaultDatabaseType(pb_data.name())); |
298 | 0 | } |
299 | | |
300 | | // When upgrading, we won't have persisted this new field. |
301 | | // TODO: Persist this change to disk instead of just changing memory. |
302 | 3.13k | auto state = metadata.state(); |
303 | 3.13k | if (!metadata.has_state()) { |
304 | 0 | state = SysNamespaceEntryPB::RUNNING; |
305 | 0 | LOG(INFO) << "Changing metadata without state to RUNNING: " << ns->ToString(); |
306 | 0 | l.mutable_data()->pb.set_state(state); |
307 | 0 | } |
308 | | |
309 | 3.13k | switch(state) { |
310 | 3.13k | case SysNamespaceEntryPB::RUNNING: |
311 | | // Add the namespace to the IDs map and to the name map (if the namespace is not deleted). |
312 | 3.13k | catalog_manager_->namespace_ids_map_[ns_id] = ns; |
313 | 3.13k | if (!pb_data.name().empty()) { |
314 | 3.13k | catalog_manager_->namespace_names_mapper_[pb_data.database_type()][pb_data.name()] = ns; |
315 | 0 | } else { |
316 | 0 | LOG(WARNING) << "Namespace with id " << ns_id << " has empty name"; |
317 | 0 | } |
318 | 3.13k | l.Commit(); |
319 | 3.13k | LOG(INFO) << "Loaded metadata for namespace " << ns->ToString(); |
320 | | |
321 | | // Namespaces created as part of a Transaction should check transaction status and be deleted |
322 | | // if the transaction is aborted. |
323 | 3.13k | if (metadata.has_transaction()) { |
324 | 0 | LOG(INFO) << "Enqueuing keyspace for Transaction Verification: " << ns->ToString(); |
325 | 0 | TransactionMetadata txn = VERIFY_RESULT( |
326 | 0 | TransactionMetadata::FromPB(metadata.transaction())); |
327 | 0 | std::function<Status(bool)> when_done = |
328 | 0 | std::bind(&CatalogManager::VerifyNamespacePgLayer, catalog_manager_, ns, _1); |
329 | 0 | WARN_NOT_OK(catalog_manager_->background_tasks_thread_pool_->SubmitFunc( |
330 | 0 | std::bind(&YsqlTransactionDdl::VerifyTransaction, |
331 | 0 | catalog_manager_->ysql_transaction_.get(), txn, when_done)), |
332 | 0 | "Could not submit VerifyTransaction to thread pool"); |
333 | 0 | } |
334 | 3.13k | break; |
335 | 1 | case SysNamespaceEntryPB::PREPARING: |
336 | | // PREPARING means the server restarted before completing NS creation. |
337 | | // Consider it FAILED & remove any partially-created data. |
338 | 1 | FALLTHROUGH_INTENDED; |
339 | 1 | case SysNamespaceEntryPB::FAILED: |
340 | 1 | LOG(INFO) << "Transitioning failed namespace (state=" << metadata.state() |
341 | 1 | << ") to DELETING: " << ns->ToString(); |
342 | 1 | l.mutable_data()->pb.set_state(SysNamespaceEntryPB::DELETING); |
343 | 1 | FALLTHROUGH_INTENDED; |
344 | 1 | case SysNamespaceEntryPB::DELETING: |
345 | 1 | catalog_manager_->namespace_ids_map_[ns_id] = ns; |
346 | 1 | if (!pb_data.name().empty()) { |
347 | 1 | catalog_manager_->namespace_names_mapper_[pb_data.database_type()][pb_data.name()] = ns; |
348 | 0 | } else { |
349 | 0 | LOG(WARNING) << "Namespace with id " << ns_id << " has empty name"; |
350 | 0 | } |
351 | 1 | l.Commit(); |
352 | 1 | LOG(INFO) << "Loaded metadata to DELETE namespace " << ns->ToString(); |
353 | 1 | if (ns->database_type() != YQL_DATABASE_PGSQL) { |
354 | 0 | WARN_NOT_OK(catalog_manager_->background_tasks_thread_pool_->SubmitFunc( |
355 | 0 | std::bind(&CatalogManager::DeleteYcqlDatabaseAsync, catalog_manager_, ns)), |
356 | 0 | "Could not submit DeleteYcqlDatabaseAsync to thread pool"); |
357 | 1 | } else { |
358 | 1 | WARN_NOT_OK(catalog_manager_->background_tasks_thread_pool_->SubmitFunc( |
359 | 1 | std::bind(&CatalogManager::DeleteYsqlDatabaseAsync, catalog_manager_, ns)), |
360 | 1 | "Could not submit DeleteYsqlDatabaseAsync to thread pool"); |
361 | 1 | } |
362 | 1 | break; |
363 | 1 | case SysNamespaceEntryPB::DELETED: |
364 | 1 | LOG(INFO) << "Skipping metadata for namespace (state=" << metadata.state() |
365 | 1 | << "): " << ns->ToString(); |
366 | | // Garbage collection. Async remove the Namespace from the SysCatalog. |
367 | | // No in-memory state needed since tablet deletes have already been processed. |
368 | 1 | WARN_NOT_OK(catalog_manager_->background_tasks_thread_pool_->SubmitFunc( |
369 | 1 | std::bind(&CatalogManager::DeleteYsqlDatabaseAsync, catalog_manager_, ns)), |
370 | 1 | "Could not submit DeleteYsqlDatabaseAsync to thread pool"); |
371 | 1 | break; |
372 | 0 | default: |
373 | 0 | FATAL_INVALID_ENUM_VALUE(SysNamespaceEntryPB_State, state); |
374 | 3.13k | } |
375 | | |
376 | 0 | VLOG(1) << "Metadata for namespace " << ns->ToString() << ": " << metadata.ShortDebugString(); |
377 | | |
378 | 3.13k | return Status::OK(); |
379 | 3.13k | } |
380 | | |
381 | | //////////////////////////////////////////////////////////// |
382 | | // User-Defined Type Loader |
383 | | //////////////////////////////////////////////////////////// |
384 | | |
385 | 0 | Status UDTypeLoader::Visit(const UDTypeId& udtype_id, const SysUDTypeEntryPB& metadata) { |
386 | 0 | CHECK(!ContainsKey(catalog_manager_->udtype_ids_map_, udtype_id)) |
387 | 0 | << "Type already exists: " << udtype_id; |
388 | | |
389 | | // Setup the table info. |
390 | 0 | UDTypeInfo* const udtype = new UDTypeInfo(udtype_id); |
391 | 0 | { |
392 | 0 | auto l = udtype->LockForWrite(); |
393 | 0 | l.mutable_data()->pb.CopyFrom(metadata); |
394 | | |
395 | | // Add the used-defined type to the IDs map and to the name map (if the type is not deleted). |
396 | 0 | catalog_manager_->udtype_ids_map_[udtype->id()] = udtype; |
397 | 0 | if (!l->name().empty()) { // If name is set (non-empty) then type is not deleted. |
398 | 0 | catalog_manager_->udtype_names_map_[{l->namespace_id(), l->name()}] = udtype; |
399 | 0 | } |
400 | |
|
401 | 0 | l.Commit(); |
402 | 0 | } |
403 | |
|
404 | 0 | LOG(INFO) << "Loaded metadata for type " << udtype->ToString(); |
405 | 0 | VLOG(1) << "Metadata for type " << udtype->ToString() << ": " << metadata.ShortDebugString(); |
406 | |
|
407 | 0 | return Status::OK(); |
408 | 0 | } |
409 | | |
410 | | //////////////////////////////////////////////////////////// |
411 | | // Config Loader |
412 | | //////////////////////////////////////////////////////////// |
413 | | |
414 | | Status ClusterConfigLoader::Visit( |
415 | 421 | const std::string& unused_id, const SysClusterConfigEntryPB& metadata) { |
416 | | // Debug confirm that there is no cluster_config_ set. This also ensures that this does not |
417 | | // visit multiple rows. Should update this, if we decide to have multiple IDs set as well. |
418 | 0 | DCHECK(!catalog_manager_->cluster_config_) << "Already have config data!"; |
419 | | |
420 | | // Prepare the config object. |
421 | 421 | ClusterConfigInfo* config = new ClusterConfigInfo(); |
422 | 421 | { |
423 | 421 | auto l = config->LockForWrite(); |
424 | 421 | l.mutable_data()->pb.CopyFrom(metadata); |
425 | | |
426 | | |
427 | | |
428 | | // Update in memory state. |
429 | 421 | catalog_manager_->cluster_config_ = config; |
430 | 421 | l.Commit(); |
431 | 421 | } |
432 | | |
433 | 421 | return Status::OK(); |
434 | 421 | } |
435 | | |
436 | | //////////////////////////////////////////////////////////// |
437 | | // Redis Config Loader |
438 | | //////////////////////////////////////////////////////////// |
439 | | |
440 | 0 | Status RedisConfigLoader::Visit(const std::string& key, const SysRedisConfigEntryPB& metadata) { |
441 | 0 | CHECK(!ContainsKey(catalog_manager_->redis_config_map_, key)) |
442 | 0 | << "Redis Config with key already exists: " << key; |
443 | | // Prepare the config object. |
444 | 0 | RedisConfigInfo* config = new RedisConfigInfo(key); |
445 | 0 | { |
446 | 0 | auto l = config->LockForWrite(); |
447 | 0 | l.mutable_data()->pb.CopyFrom(metadata); |
448 | 0 | catalog_manager_->redis_config_map_[key] = config; |
449 | 0 | l.Commit(); |
450 | 0 | } |
451 | 0 | return Status::OK(); |
452 | 0 | } |
453 | | |
454 | | //////////////////////////////////////////////////////////// |
455 | | // Role Loader |
456 | | //////////////////////////////////////////////////////////// |
457 | | |
458 | 421 | Status RoleLoader::Visit(const RoleName& role_name, const SysRoleEntryPB& metadata) { |
459 | 421 | RoleInfo* const role = new RoleInfo(role_name); |
460 | 421 | { |
461 | 421 | auto l = role->LockForWrite(); |
462 | 421 | l.mutable_data()->pb.CopyFrom(metadata); |
463 | 421 | catalog_manager_->permissions_manager()->AddRoleUnlocked( |
464 | 421 | role_name, make_scoped_refptr<RoleInfo>(role)); |
465 | | |
466 | 421 | l.Commit(); |
467 | 421 | } |
468 | | |
469 | 421 | LOG(INFO) << "Loaded metadata for role " << role->id(); |
470 | 0 | VLOG(1) << "Metadata for role " << role->id() << ": " << metadata.ShortDebugString(); |
471 | | |
472 | 421 | return Status::OK(); |
473 | 421 | } |
474 | | |
475 | | //////////////////////////////////////////////////////////// |
476 | | // Sys Config Loader |
477 | | //////////////////////////////////////////////////////////// |
478 | | |
479 | 1.26k | Status SysConfigLoader::Visit(const string& config_type, const SysConfigEntryPB& metadata) { |
480 | 1.26k | SysConfigInfo* const config = new SysConfigInfo(config_type); |
481 | 1.26k | { |
482 | 1.26k | auto l = config->LockForWrite(); |
483 | 1.26k | l.mutable_data()->pb.CopyFrom(metadata); |
484 | | |
485 | 1.26k | if (config_type == kSecurityConfigType) { |
486 | 422 | catalog_manager_->permissions_manager()->SetSecurityConfigOnLoadUnlocked(config); |
487 | 844 | } else if (config_type == kYsqlCatalogConfigType) { |
488 | 0 | LOG_IF(WARNING, catalog_manager_->ysql_catalog_config_ != nullptr) |
489 | 0 | << "Multiple sys config type " << config_type << " found"; |
490 | 422 | catalog_manager_->ysql_catalog_config_ = config; |
491 | 422 | } else if (config_type == kTransactionTablesConfigType) { |
492 | 0 | LOG_IF(WARNING, catalog_manager_->transaction_tables_config_ != nullptr) |
493 | 0 | << "Multiple sys config type " << config_type << " found"; |
494 | 422 | catalog_manager_->transaction_tables_config_ = config; |
495 | 422 | } |
496 | | |
497 | 1.26k | l.Commit(); |
498 | 1.26k | } |
499 | | |
500 | 1.26k | LOG(INFO) << "Loaded sys config type " << config_type; |
501 | 1.26k | return Status::OK(); |
502 | 1.26k | } |
503 | | |
504 | | } // namespace master |
505 | | } // namespace yb |