mirror of
https://github.com/percona/pg_stat_monitor.git
synced 2026-02-04 05:56:21 +00:00
PG-244: Fix race condition in get_next_wbucket().
The if condition bellow in geta_next_wbucket() was subject to a race condition: if ((current_usec - pgss->prev_bucket_usec) > (PGSM_BUCKET_TIME * 1000 * 1000)) Two or more threads/processes could easily evaluate this condition to true, thus executing more than once the block that would calculate a new bucket id, clear/move old entries in the pgss_query_hash and pgss_hash hash tables. To avoid this problem, we define prev_bucket_usec and current_wbucket variables as atomic and execute a loop to check if another thread has updated prev_bucket_usec before the current one.
This commit is contained in:
@@ -301,16 +301,16 @@ typedef struct pgssEntry
|
||||
*/
|
||||
typedef struct pgssSharedState
|
||||
{
|
||||
LWLock *lock; /* protects hashtable search/modification */
|
||||
double cur_median_usage; /* current median usage in hashtable */
|
||||
slock_t mutex; /* protects following fields only: */
|
||||
Size extent; /* current extent of query file */
|
||||
int64 n_writers; /* number of active writers to query file */
|
||||
uint64 current_wbucket;
|
||||
uint64 prev_bucket_usec;
|
||||
uint64 bucket_entry[MAX_BUCKETS];
|
||||
int64 query_buf_size_bucket;
|
||||
char bucket_start_time[MAX_BUCKETS][60]; /* start time of the bucket */
|
||||
LWLock *lock; /* protects hashtable search/modification */
|
||||
double cur_median_usage; /* current median usage in hashtable */
|
||||
slock_t mutex; /* protects following fields only: */
|
||||
Size extent; /* current extent of query file */
|
||||
int64 n_writers; /* number of active writers to query file */
|
||||
pg_atomic_uint64 current_wbucket;
|
||||
pg_atomic_uint64 prev_bucket_usec;
|
||||
uint64 bucket_entry[MAX_BUCKETS];
|
||||
int64 query_buf_size_bucket;
|
||||
char bucket_start_time[MAX_BUCKETS][60]; /* start time of the bucket */
|
||||
} pgssSharedState;
|
||||
|
||||
#define ResetSharedState(x) \
|
||||
@@ -318,8 +318,8 @@ do { \
|
||||
x->cur_median_usage = ASSUMED_MEDIAN_INIT; \
|
||||
x->cur_median_usage = ASSUMED_MEDIAN_INIT; \
|
||||
x->n_writers = 0; \
|
||||
x->current_wbucket = 0; \
|
||||
x->prev_bucket_usec = 0; \
|
||||
pg_atomic_init_u64(&x->current_wbucket, 0); \
|
||||
pg_atomic_init_u64(&x->prev_bucket_usec, 0); \
|
||||
memset(&x->bucket_entry, 0, MAX_BUCKETS * sizeof(uint64)); \
|
||||
} while(0)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user