Skip to content

Commit d2a53ed

Browse files
committed
[yugabyte#24929] DocDB: Fix CleanupHiddenTables COW lock
Summary: `CleanupHiddenTables` is calling `Upsert` on entries without holding a COW lock which causes a segmentation fault or bad data read. Changing the order so that we always hold the write lock. Fixes yugabyte#24929 Jira: DB-14070 Test Plan: Jenkins Reviewers: slingam, zdrudi Reviewed By: zdrudi Subscribers: ybase Differential Revision: https://phorge.dev.yugabyte.com/D40063
1 parent d68d61d commit d2a53ed

File tree

2 files changed

+12
-13
lines changed

2 files changed

+12
-13
lines changed

src/yb/master/catalog_manager_ext.cc

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2904,18 +2904,19 @@ void CatalogManager::CleanupHiddenTables(
29042904
std::vector<TableInfo::WriteLock> locks;
29052905
for (const auto& table : expired_tables) {
29062906
auto write_lock = table->LockForWrite();
2907-
if (write_lock->started_deleting()) {
2908-
continue;
2907+
if (!write_lock->started_deleting()) {
2908+
// Because tablets for hidden tables are deleted first, there is nothing left to delete
2909+
// besides the table metadata itself now. So we skip the DELETING state and transition
2910+
// directly to DELETED.
2911+
write_lock.mutable_data()->set_state(
2912+
SysTablesEntryPB::DELETED, Format("Cleanup hidden table at $0", LocalTimeAsString()));
2913+
LOG_WITH_PREFIX(INFO) << Format(
2914+
"Cleaning up hidden table $0: $1", table->name(), AsString(table));
29092915
}
2910-
// Because tablets for hidden tables are deleted first, there is nothing left to delete besides
2911-
// the table metadata itself now. So we skip the DELETING state and transition directly to
2912-
// DELETED.
2913-
write_lock.mutable_data()->set_state(
2914-
SysTablesEntryPB::DELETED, Format("Cleanup hidden table at $0", LocalTimeAsString()));
2915-
LOG_WITH_PREFIX(INFO) << Format(
2916-
"Cleaning up hidden table $0: $1", table->name(), AsString(table));
2916+
29172917
locks.push_back(std::move(write_lock));
29182918
}
2919+
29192920
if (locks.empty()) {
29202921
return;
29212922
}

src/yb/util/cow_object.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,10 @@ class CowObject {
115115
State* mutable_dirty() {
116116
DCHECK(lock_.HasWriteLock());
117117
is_dirty_ = true;
118-
return DCHECK_NOTNULL(dirty_state_.get());
118+
return CHECK_NOTNULL(dirty_state_.get());
119119
}
120120

121-
const State& dirty() const {
122-
return *DCHECK_NOTNULL(dirty_state_.get());
123-
}
121+
const State& dirty() const { return *CHECK_NOTNULL(dirty_state_.get()); }
124122

125123
bool is_dirty() const {
126124
DCHECK(lock_.HasReaders() || lock_.HasWriteLock());

0 commit comments

Comments
 (0)