Skip to content

Commit 02e2cc0

Browse files
ikrestovstaticlibs
authored andcommitted
fix: concurrent mysql catalog loading access (1.4)
This is a backport of the PR #197 to `v1.4-andium` stable branch. Based on postgresql extension entry/loading lock guards.
1 parent 346e500 commit 02e2cc0

File tree

2 files changed

+16
-9
lines changed

2 files changed

+16
-9
lines changed

src/include/storage/mysql_catalog_set.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,18 @@ class MySQLCatalogSet {
3030
protected:
3131
virtual void LoadEntries(ClientContext &context) = 0;
3232

33+
void TryLoadEntries(ClientContext &context);
34+
3335
void EraseEntryInternal(const string &name);
3436

3537
protected:
3638
Catalog &catalog;
3739

3840
private:
3941
mutex entry_lock;
42+
mutex load_lock;
4043
case_insensitive_map_t<unique_ptr<CatalogEntry>> entries;
41-
bool is_loaded;
44+
atomic<bool> is_loaded;
4245
};
4346

4447
class MySQLInSchemaSet : public MySQLCatalogSet {

src/storage/mysql_catalog_set.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@ MySQLCatalogSet::MySQLCatalogSet(Catalog &catalog) : catalog(catalog), is_loaded
99
}
1010

1111
optional_ptr<CatalogEntry> MySQLCatalogSet::GetEntry(ClientContext &context, const string &name) {
12-
if (!is_loaded) {
13-
is_loaded = true;
14-
LoadEntries(context);
15-
}
12+
TryLoadEntries(context);
1613
lock_guard<mutex> l(entry_lock);
1714
auto entry = entries.find(name);
1815
if (entry == entries.end()) {
@@ -21,6 +18,15 @@ optional_ptr<CatalogEntry> MySQLCatalogSet::GetEntry(ClientContext &context, con
2118
return entry->second.get();
2219
}
2320

21+
void MySQLCatalogSet::TryLoadEntries(ClientContext &context) {
22+
lock_guard<mutex> l(load_lock);
23+
if (is_loaded) {
24+
return;
25+
}
26+
is_loaded = true;
27+
LoadEntries(context);
28+
}
29+
2430
void MySQLCatalogSet::DropEntry(ClientContext &context, DropInfo &info) {
2531
string drop_query = "DROP ";
2632
drop_query += CatalogTypeToString(info.type) + " ";
@@ -46,10 +52,7 @@ void MySQLCatalogSet::EraseEntryInternal(const string &name) {
4652
}
4753

4854
void MySQLCatalogSet::Scan(ClientContext &context, const std::function<void(CatalogEntry &)> &callback) {
49-
if (!is_loaded) {
50-
is_loaded = true;
51-
LoadEntries(context);
52-
}
55+
TryLoadEntries(context);
5356
lock_guard<mutex> l(entry_lock);
5457
for (auto &entry : entries) {
5558
callback(*entry.second);
@@ -67,6 +70,7 @@ optional_ptr<CatalogEntry> MySQLCatalogSet::CreateEntry(unique_ptr<CatalogEntry>
6770
}
6871

6972
void MySQLCatalogSet::ClearEntries() {
73+
lock_guard<mutex> l(entry_lock);
7074
entries.clear();
7175
is_loaded = false;
7276
}

0 commit comments

Comments
 (0)