Skip to content

Commit 1fbfab5

Browse files
author
Sujatha Sivakumar
committed
Bug#21485997: WRONG INSTRUMENTATION OF CLASS GTID_SET
Analysis: ======== At runtime, some GTID_SET objects are instrumented with a performance schema mutex key of 0, which is incorrect (not instrumented). The root cause is the declaration of constructors, like: Gtid_set(Sid_map *sid_map, Checkable_rwlock *sid_lock= NULL #ifdef HAVE_PSI_INTERFACE ,PSI_mutex_key free_intervals_mutex_key= 0 #endif ); The issue is giving a default value of 0 when the mutex key is not passed. This allows some caller to not pass any key, causing a bug. Fix: === Moved the PSI_mutex_key from Gtid_state class to Gtid_set class.
1 parent 33051ec commit 1fbfab5

File tree

7 files changed

+22
-56
lines changed

7 files changed

+22
-56
lines changed

client/mysqlbinlog.cc

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#define MYSQL_CLIENT
3232
#undef MYSQL_SERVER
33+
#define DISABLE_PSI_MUTEX
3334
#include "client_priv.h"
3435
#include "my_default.h"
3536
#include <my_time.h>

mysql-test/suite/binlog/r/binlog_group_commit_gtid_order.result

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ CREATE TABLE t2 (c1 INT) Engine=InnoDB;
44
SET @free_intervals_mutex_before= (
55
SELECT COUNT_STAR
66
FROM performance_schema.events_waits_summary_global_by_event_name WHERE
7-
EVENT_NAME='wait/synch/mutex/sql/Gtid_state::gtid_executed::free_intervals_mutex');
7+
EVENT_NAME='wait/synch/mutex/sql/Gtid_set::gtid_executed::free_intervals_mutex');
88
SET GLOBAL binlog_group_commit_sync_delay=1000000;
99
# Create two new connections: con1 and con2
1010
# At con1
@@ -23,7 +23,7 @@ include/assert.inc ["No gaps should exist in gtid_executed after the second inse
2323
SET @free_intervals_mutex_after= (
2424
SELECT COUNT_STAR
2525
FROM performance_schema.events_waits_summary_global_by_event_name WHERE
26-
EVENT_NAME='wait/synch/mutex/sql/Gtid_state::gtid_executed::free_intervals_mutex');
26+
EVENT_NAME='wait/synch/mutex/sql/Gtid_set::gtid_executed::free_intervals_mutex');
2727
include/assert.inc ["gtid_executed::free_intervals_mutex wasn't used"]
2828
SET GLOBAL binlog_group_commit_sync_delay=0;
2929
DROP TABLE t1, t2;

mysql-test/suite/binlog/t/binlog_group_commit_gtid_order.test

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ CREATE TABLE t2 (c1 INT) Engine=InnoDB;
3737
SET @free_intervals_mutex_before= (
3838
SELECT COUNT_STAR
3939
FROM performance_schema.events_waits_summary_global_by_event_name WHERE
40-
EVENT_NAME='wait/synch/mutex/sql/Gtid_state::gtid_executed::free_intervals_mutex');
40+
EVENT_NAME='wait/synch/mutex/sql/Gtid_set::gtid_executed::free_intervals_mutex');
4141

4242
# Set group commit parameters
4343
--eval SET GLOBAL binlog_group_commit_sync_delay=$delay
@@ -110,7 +110,7 @@ SET DEBUG_SYNC='now SIGNAL go_con1';
110110
SET @free_intervals_mutex_after= (
111111
SELECT COUNT_STAR
112112
FROM performance_schema.events_waits_summary_global_by_event_name WHERE
113-
EVENT_NAME='wait/synch/mutex/sql/Gtid_state::gtid_executed::free_intervals_mutex');
113+
EVENT_NAME='wait/synch/mutex/sql/Gtid_set::gtid_executed::free_intervals_mutex');
114114
--let $assert_text= "gtid_executed::free_intervals_mutex wasn't used"
115115
--let $assert_cond= @free_intervals_mutex_before = @free_intervals_mutex_after
116116
--source include/assert.inc

mysql-test/suite/perfschema/r/dml_setup_instruments.result

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ NAME ENABLED TIMED
77
wait/synch/mutex/sql/Commit_order_manager::m_mutex YES YES
88
wait/synch/mutex/sql/Cost_constant_cache::LOCK_cost_const YES YES
99
wait/synch/mutex/sql/Event_scheduler::LOCK_scheduler_state YES YES
10+
wait/synch/mutex/sql/Gtid_set::gtid_executed::free_intervals_mutex YES YES
1011
wait/synch/mutex/sql/Gtid_state YES YES
11-
wait/synch/mutex/sql/Gtid_state::gtid_executed::free_intervals_mutex YES YES
1212
wait/synch/mutex/sql/hash_filo::lock YES YES
1313
wait/synch/mutex/sql/key_mts_gaq_LOCK YES YES
1414
wait/synch/mutex/sql/key_mts_temp_table_LOCK YES YES

sql/mysqld.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -8253,7 +8253,7 @@ PSI_mutex_key key_BINLOG_LOCK_sync_queue;
82538253
PSI_mutex_key key_BINLOG_LOCK_xids;
82548254
PSI_mutex_key
82558255
key_hash_filo_lock, key_LOCK_msr_map,
8256-
Gtid_state::key_gtid_executed_free_intervals_mutex,
8256+
Gtid_set::key_gtid_executed_free_intervals_mutex,
82578257
key_LOCK_crypt, key_LOCK_error_log,
82588258
key_LOCK_gdl, key_LOCK_global_system_variables,
82598259
key_LOCK_manager,
@@ -8329,7 +8329,7 @@ static PSI_mutex_info all_server_mutexes[]=
83298329
{ &key_RELAYLOG_LOCK_xids, "MYSQL_RELAY_LOG::LOCK_xids", 0},
83308330
{ &key_hash_filo_lock, "hash_filo::lock", 0},
83318331
{ &key_LOCK_msr_map, "LOCK_msr_map", PSI_FLAG_GLOBAL},
8332-
{ &Gtid_state::key_gtid_executed_free_intervals_mutex, "Gtid_state::gtid_executed::free_intervals_mutex", 0 },
8332+
{ &Gtid_set::key_gtid_executed_free_intervals_mutex, "Gtid_set::gtid_executed::free_intervals_mutex", 0 },
83338333
{ &key_LOCK_crypt, "LOCK_crypt", PSI_FLAG_GLOBAL},
83348334
{ &key_LOCK_error_log, "LOCK_error_log", PSI_FLAG_GLOBAL},
83358335
{ &key_LOCK_gdl, "LOCK_gdl", PSI_FLAG_GLOBAL},

sql/rpl_gtid.h

+7-23
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,9 @@ struct Gtid
10771077
class Gtid_set
10781078
{
10791079
public:
1080+
#ifdef HAVE_PSI_INTERFACE
1081+
static PSI_mutex_key key_gtid_executed_free_intervals_mutex;
1082+
#endif
10801083
/**
10811084
Constructs a new, empty Gtid_set.
10821085
@@ -1088,11 +1091,7 @@ class Gtid_set
10881091
@param free_intervals_mutex_key Performance_schema instrumentation
10891092
key to use for the free_intervals mutex.
10901093
*/
1091-
Gtid_set(Sid_map *sid_map, Checkable_rwlock *sid_lock= NULL
1092-
#ifdef HAVE_PSI_INTERFACE
1093-
,PSI_mutex_key free_intervals_mutex_key= 0
1094-
#endif
1095-
);
1094+
Gtid_set(Sid_map *sid_map, Checkable_rwlock *sid_lock= NULL);
10961095
/**
10971096
Constructs a new Gtid_set that contains the groups in the given string, in the same format as add_gtid_text(char *).
10981097
@@ -1112,18 +1111,10 @@ class Gtid_set
11121111
there will be a short period when the lock is not held at all.
11131112
*/
11141113
Gtid_set(Sid_map *sid_map, const char *text, enum_return_status *status,
1115-
Checkable_rwlock *sid_lock= NULL
1116-
#ifdef HAVE_PSI_INTERFACE
1117-
,PSI_mutex_key free_intervals_mutex_key= 0
1118-
#endif
1119-
);
1114+
Checkable_rwlock *sid_lock= NULL);
11201115
private:
11211116
/// Worker for the constructor.
1122-
void init(
1123-
#ifdef HAVE_PSI_INTERFACE
1124-
PSI_mutex_key free_intervals_mutex_key
1125-
#endif
1126-
);
1117+
void init();
11271118
public:
11281119
/// Destroy this Gtid_set.
11291120
~Gtid_set();
@@ -2349,9 +2340,6 @@ class Owned_gtids
23492340
class Gtid_state
23502341
{
23512342
public:
2352-
#ifdef HAVE_PSI_INTERFACE
2353-
static PSI_mutex_key key_gtid_executed_free_intervals_mutex;
2354-
#endif
23552343
/**
23562344
Constructs a new Gtid_state object.
23572345
@@ -2364,11 +2352,7 @@ class Gtid_state
23642352
sid_map(_sid_map),
23652353
sid_locks(sid_lock),
23662354
lost_gtids(sid_map, sid_lock),
2367-
executed_gtids(sid_map, sid_lock
2368-
#ifdef HAVE_PSI_INTERFACE
2369-
,key_gtid_executed_free_intervals_mutex
2370-
#endif
2371-
),
2355+
executed_gtids(sid_map, sid_lock),
23722356
gtids_only_in_table(sid_map, sid_lock),
23732357
previous_gtids_logged(sid_map, sid_lock),
23742358
owned_gtids(sid_lock) {}

sql/rpl_gtid_set.cc

+7-26
Original file line numberDiff line numberDiff line change
@@ -55,54 +55,35 @@ const Gtid_set::String_format Gtid_set::commented_string_format=
5555
};
5656

5757

58-
Gtid_set::Gtid_set(Sid_map *_sid_map, Checkable_rwlock *_sid_lock
59-
#ifdef HAVE_PSI_INTERFACE
60-
,PSI_mutex_key free_intervals_mutex_key
61-
#endif
62-
)
58+
Gtid_set::Gtid_set(Sid_map *_sid_map, Checkable_rwlock *_sid_lock)
6359
: sid_lock(_sid_lock), sid_map(_sid_map),
6460
m_intervals(key_memory_Gtid_set_Interval_chunk)
6561
{
66-
init(
67-
#ifdef HAVE_PSI_INTERFACE
68-
free_intervals_mutex_key
69-
#endif
70-
);
62+
init();
7163
}
7264

7365

7466
Gtid_set::Gtid_set(Sid_map *_sid_map, const char *text,
75-
enum_return_status *status, Checkable_rwlock *_sid_lock
76-
#ifdef HAVE_PSI_INTERFACE
77-
,PSI_mutex_key free_intervals_mutex_key
78-
#endif
79-
)
67+
enum_return_status *status, Checkable_rwlock *_sid_lock)
8068
: sid_lock(_sid_lock), sid_map(_sid_map),
8169
m_intervals(key_memory_Gtid_set_Interval_chunk)
8270
{
8371
DBUG_ASSERT(_sid_map != NULL);
84-
init(
85-
#ifdef HAVE_PSI_INTERFACE
86-
free_intervals_mutex_key
87-
#endif
88-
);
72+
init();
8973
*status= add_gtid_text(text);
9074
}
9175

9276

93-
void Gtid_set::init(
94-
#ifdef HAVE_PSI_INTERFACE
95-
PSI_mutex_key free_intervals_mutex_key
96-
#endif
97-
)
77+
void Gtid_set::init()
9878
{
9979
DBUG_ENTER("Gtid_set::init");
10080
cached_string_length= -1;
10181
cached_string_format= NULL;
10282
chunks= NULL;
10383
free_intervals= NULL;
10484
if (sid_lock)
105-
mysql_mutex_init(free_intervals_mutex_key, &free_intervals_mutex, NULL);
85+
mysql_mutex_init(key_gtid_executed_free_intervals_mutex,
86+
&free_intervals_mutex, NULL);
10687
#ifndef DBUG_OFF
10788
n_chunks= 0;
10889
#endif

0 commit comments

Comments
 (0)