Skip to content

Commit 50ff737

Browse files
[yugabyte#23741] docdb: Fix cloning of colocated databases with only parent table
Summary: A colocated database might have only the parent table if all user tables were dropped. Import snapshot will fail to find the corresponding running parent table if we try to clone right now. This diff excludes the parent table when generating backup entries if there are no user tables. Test Plan: `./yb_build.sh release --cxx-test integration-tests_minicluster-snapshot-test --gtest_filter PgCloneColocationTest.NoColocatedChildTables` Reviewers: mhaddad Reviewed By: mhaddad Subscribers: ybase Differential Revision: https://phorge.dev.yugabyte.com/D37695
1 parent 02ced43 commit 50ff737

File tree

2 files changed

+34
-8
lines changed

2 files changed

+34
-8
lines changed

src/yb/integration-tests/minicluster-snapshot-test.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,5 +1032,23 @@ TEST_P(PgCloneTestWithColocatedDBParam, YB_DISABLE_TEST_IN_SANITIZERS(CloneOfClo
10321032
ASSERT_RESULT(ConnectToDB(kTargetNamespaceName2));
10331033
}
10341034

1035+
TEST_F(PgCloneColocationTest, YB_DISABLE_TEST_IN_SANITIZERS(NoColocatedChildTables)) {
1036+
ASSERT_OK(source_conn_->Execute("CREATE TABLE t2(k int, v1 int) WITH (COLOCATION = false)"));
1037+
ASSERT_OK(source_conn_->Execute("DROP TABLE t1"));
1038+
auto no_child_tables_time = ASSERT_RESULT(GetCurrentTime()).ToInt64();
1039+
ASSERT_OK(source_conn_->Execute("DROP TABLE t2"));
1040+
1041+
// Clone to a time when there are no colocated child tables.
1042+
ASSERT_OK(source_conn_->ExecuteFormat(
1043+
"CREATE DATABASE $0 TEMPLATE $1 AS OF $2", kTargetNamespaceName1, kSourceNamespaceName,
1044+
no_child_tables_time));
1045+
ASSERT_RESULT(ConnectToDB(kTargetNamespaceName1));
1046+
1047+
// Clone to a time when there are no tables.
1048+
ASSERT_OK(source_conn_->ExecuteFormat(
1049+
"CREATE DATABASE $0 TEMPLATE $1", kTargetNamespaceName2, kSourceNamespaceName));
1050+
ASSERT_RESULT(ConnectToDB(kTargetNamespaceName2));
1051+
}
1052+
10351053
} // namespace master
10361054
} // namespace yb

src/yb/master/catalog_manager_ext.cc

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,25 +1209,30 @@ Result<RepeatedPtrField<BackupRowEntryPB>> CatalogManager::GetBackupEntriesAsOfT
12091209
// partitions' start keys.
12101210
std::map<TableId, TableWithTabletsEntries> tables_to_tablets;
12111211
std::optional<std::string> colocation_parent_table_id;
1212+
bool found_colocated_user_table = false;
12121213
docdb::DocRowwiseIterator tables_iter = docdb::DocRowwiseIterator(
12131214
projection, doc_read_cntxt, TransactionOperationContext(), doc_db,
12141215
docdb::ReadOperationData::FromSingleReadTime(read_time), db_pending_op);
12151216
RETURN_NOT_OK(EnumerateSysCatalog(
12161217
&tables_iter, doc_read_cntxt.schema(), SysRowEntryType::TABLE,
1217-
[&source_ns_id, &tables_to_tablets, &colocation_parent_table_id](
1218+
[&source_ns_id, &tables_to_tablets, &colocation_parent_table_id, &found_colocated_user_table](
12181219
const Slice& id, const Slice& data) -> Status {
12191220
auto pb = VERIFY_RESULT(pb_util::ParseFromSlice<SysTablesEntryPB>(data));
12201221
if (pb.namespace_id() == source_ns_id && pb.state() == SysTablesEntryPB::RUNNING &&
12211222
pb.hide_state() == SysTablesEntryPB_HideState_VISIBLE &&
12221223
!pb.schema().table_properties().is_ysql_catalog_table()) {
12231224
VLOG_WITH_FUNC(1) << "Found SysTablesEntryPB: " << pb.ShortDebugString();
1224-
if (IsColocatedDbParentTableId(id.ToBuffer()) ||
1225-
IsColocatedDbTablegroupParentTableId(id.ToBuffer())) {
1226-
colocation_parent_table_id = id.ToBuffer();
1225+
const auto id_str = id.ToBuffer();
1226+
if (pb.colocated()) {
1227+
if (IsColocationParentTableId(id_str)) {
1228+
colocation_parent_table_id = id_str;
1229+
} else {
1230+
found_colocated_user_table = true;
1231+
}
12271232
}
12281233
// Tables and tablets will be added to backup entries at the end.
12291234
tables_to_tablets.insert(std::make_pair(
1230-
id.ToBuffer(), TableWithTabletsEntries(pb, SysTabletsEntriesWithIds())));
1235+
id_str, TableWithTabletsEntries(pb, SysTabletsEntriesWithIds())));
12311236
}
12321237
return Status::OK();
12331238
}));
@@ -1261,11 +1266,14 @@ Result<RepeatedPtrField<BackupRowEntryPB>> CatalogManager::GetBackupEntriesAsOfT
12611266
for (auto& sys_table_entry : tables_to_tablets) {
12621267
sys_table_entry.second.OrderTabletsByPartitions();
12631268
}
1264-
// Populate the backup_entries with SysTablesEntry and SysTabletsEntry
1269+
// Populate the backup_entries with SysTablesEntry and SysTabletsEntry.
12651270
// Start with the colocation_parent_table_id if the database is colocated.
12661271
if (colocation_parent_table_id) {
1267-
tables_to_tablets[colocation_parent_table_id.value()].AddToBackupEntries(
1268-
colocation_parent_table_id.value(), &backup_entries);
1272+
// Only create the colocated parent table if there are colocated user tables.
1273+
if (found_colocated_user_table) {
1274+
tables_to_tablets[colocation_parent_table_id.value()].AddToBackupEntries(
1275+
colocation_parent_table_id.value(), &backup_entries);
1276+
}
12691277
tables_to_tablets.erase(colocation_parent_table_id.value());
12701278
}
12711279
for (auto& sys_table_entry : tables_to_tablets) {

0 commit comments

Comments
 (0)