YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/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