Skip to content

Commit c3ad3b3

Browse files
Artem FadeevDaniil Anisimov
authored andcommitted
Fix race condition in cleanup_aqo_database
1 parent 9a969c3 commit c3ad3b3

File tree

1 file changed

+22
-16
lines changed

1 file changed

+22
-16
lines changed

storage.c

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ static void data_load(const char *filename, deform_record_t callback, void *ctx)
9797
static size_t _compute_data_dsa(const DataEntry *entry);
9898

9999
static bool _aqo_stat_remove(uint64 queryid);
100-
static bool _aqo_queries_remove(uint64 queryid);
100+
static bool _aqo_queries_remove(uint64 queryid, bool lock);
101101
static bool _aqo_qtexts_remove(uint64 queryid);
102102
static bool _aqo_data_remove(data_key *key);
103103
static bool nearest_neighbor(double **matrix, int old_rows, double *neighbor, int cols);
@@ -1186,7 +1186,7 @@ aqo_qtext_store(uint64 queryid, const char *query_string, bool *dsa_valid)
11861186
* that caller recognize it and don't try to call us more.
11871187
*/
11881188
(void) hash_search(qtexts_htab, &queryid, HASH_REMOVE, NULL);
1189-
_aqo_queries_remove(queryid);
1189+
_aqo_queries_remove(queryid, true);
11901190
LWLockRelease(&aqo_state->qtexts_lock);
11911191
if (dsa_valid)
11921192
*dsa_valid = false;
@@ -1284,12 +1284,19 @@ _aqo_stat_remove(uint64 queryid)
12841284
}
12851285

12861286
static bool
1287-
_aqo_queries_remove(uint64 queryid)
1287+
_aqo_queries_remove(uint64 queryid, bool lock)
12881288
{
12891289
bool found;
12901290

1291-
Assert(!LWLockHeldByMe(&aqo_state->queries_lock));
1292-
LWLockAcquire(&aqo_state->queries_lock, LW_EXCLUSIVE);
1291+
if (lock)
1292+
{
1293+
LWLockAcquire(&aqo_state->queries_lock, LW_EXCLUSIVE);
1294+
}
1295+
else
1296+
{
1297+
Assert(LWLockHeldByMeInMode(&aqo_state->queries_lock, LW_EXCLUSIVE));
1298+
}
1299+
12931300
(void) hash_search(queries_htab, &queryid, HASH_FIND, &found);
12941301

12951302
if (found)
@@ -1298,7 +1305,8 @@ _aqo_queries_remove(uint64 queryid)
12981305
aqo_state->queries_changed = true;
12991306
}
13001307

1301-
LWLockRelease(&aqo_state->queries_lock);
1308+
if (lock)
1309+
LWLockRelease(&aqo_state->queries_lock);
13021310
return found;
13031311
}
13041312

@@ -2324,10 +2332,7 @@ cleanup_aqo_database(bool gentle, int *fs_num, int *fss_num)
23242332
*fs_num = 0;
23252333
*fss_num = 0;
23262334

2327-
/*
2328-
* It's a long haul. So, make seq scan without any lock. It is possible
2329-
* because only this operation can delete data from hash table.
2330-
*/
2335+
LWLockAcquire(&aqo_state->queries_lock, LW_EXCLUSIVE);
23312336
hash_seq_init(&hash_seq, queries_htab);
23322337
while ((entry = hash_seq_search(&hash_seq)) != NULL)
23332338
{
@@ -2338,6 +2343,7 @@ cleanup_aqo_database(bool gentle, int *fs_num, int *fss_num)
23382343
ListCell *lc;
23392344

23402345
/* Scan aqo_data for any junk records related to this FS */
2346+
LWLockAcquire(&aqo_state->data_lock, LW_SHARED);
23412347
hash_seq_init(&hash_seq2, data_htab);
23422348
while ((dentry = hash_seq_search(&hash_seq2)) != NULL)
23432349
{
@@ -2347,8 +2353,6 @@ cleanup_aqo_database(bool gentle, int *fs_num, int *fss_num)
23472353
/* Another FS */
23482354
continue;
23492355

2350-
LWLockAcquire(&aqo_state->data_lock, LW_SHARED);
2351-
23522356
Assert(DsaPointerIsValid(dentry->data_dp));
23532357
ptr = dsa_get_address(data_dsa, dentry->data_dp);
23542358

@@ -2388,10 +2392,10 @@ cleanup_aqo_database(bool gentle, int *fs_num, int *fss_num)
23882392
UINT64_FORMAT" fss=%d",
23892393
dentry->key.fs, (int32) dentry->key.fss)));
23902394
}
2391-
2392-
LWLockRelease(&aqo_state->data_lock);
23932395
}
23942396

2397+
LWLockRelease(&aqo_state->data_lock);
2398+
23952399
/*
23962400
* In forced mode remove all child FSSes even some of them are still
23972401
* link to existed tables.
@@ -2419,10 +2423,12 @@ cleanup_aqo_database(bool gentle, int *fs_num, int *fss_num)
24192423
_aqo_qtexts_remove(entry->queryid);
24202424

24212425
/* Query class preferences */
2422-
(*fs_num) += (int) _aqo_queries_remove(entry->queryid);
2426+
(*fs_num) += (int) _aqo_queries_remove(entry->queryid, false);
24232427
}
24242428
}
24252429

2430+
LWLockRelease(&aqo_state->queries_lock);
2431+
24262432
/*
24272433
* The best place to flush updated AQO storage: calling the routine, user
24282434
* realizes how heavy it is.
@@ -2504,7 +2510,7 @@ aqo_drop_class(PG_FUNCTION_ARGS)
25042510
"id = "INT64_FORMAT", fs = "UINT64_FORMAT".", (int64) queryid, fs);
25052511

25062512
/* Now, remove all data related to the class */
2507-
_aqo_queries_remove(queryid);
2513+
_aqo_queries_remove(queryid, true);
25082514
_aqo_stat_remove(queryid);
25092515
_aqo_qtexts_remove(queryid);
25102516
cnt = _aqo_data_clean(fs);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy