Skip to content

Commit 05e2386

Browse files
committed
Bug#22551677 SIGNAL 11 IN LF_PINBOX_PUT_PINS
Before this fix, the following query: SET GLOBAL offline_mode = ON could cause the server to crash. The root cause is actually complex, as described below. 1) A session A is connected, and performing network io, typically waiting for the next command to execute. The performance schema socket instrumentation is enabled, so that pfs_start_socket_wait() / pfs_end_socket_wait() are executed. 2) A session B executes SET GLOBAL offline_mode = ON, which terminates session A. In particular, session B forcefully closes the socket used by session A. 3) Session A and session B are different threads, but they both execute performance schema instrumented code against the same socket. 4) Because a socket is "owned" by a thread, the instrumentation in pfs_start/end_socket_wait() uses the same PFS_thread (of thread A) in both thread A and B. This leads to race conditions when using member m_events_waits_current. 5) Because PFS_thread::m_events_waits_current can be damaged with race conditions, the m_events_waits_current pointer can point outside of the waits array. Using this pointer to populate current waits can damage other members of the PFS_thread structure, most notably LF_HASH pins. 6) Upon thread disconnect, using a corrupted LF_HASH pin when calling lf_hash_put_pins leads to a crash. --- The fix for this issue is to use the current thread, not the socket owner, in the performance schema socket instrumenttion. Also, asserts have been added to detect similar failures. With the asserts, the original issue, which was spurious and only occured rarely, is not detected systematically.
1 parent 87a6953 commit 05e2386

File tree

1 file changed

+31
-4
lines changed

1 file changed

+31
-4
lines changed

storage/perfschema/pfs.cc

+31-4
Original file line numberDiff line numberDiff line change
@@ -3093,9 +3093,9 @@ pfs_start_table_io_wait_v1(PSI_table_locker_state *state,
30933093
if (! pfs_table->m_io_enabled)
30943094
return NULL;
30953095

3096-
PFS_thread *pfs_thread= pfs_table->m_thread_owner;
3096+
PFS_thread *pfs_thread= my_thread_get_THR_PFS();
30973097

3098-
DBUG_ASSERT(pfs_thread == my_thread_get_THR_PFS());
3098+
DBUG_ASSERT(pfs_thread == pfs_table->m_thread_owner);
30993099

31003100
uint flags;
31013101
ulonglong timer_start= 0;
@@ -3198,7 +3198,9 @@ pfs_start_table_lock_wait_v1(PSI_table_locker_state *state,
31983198
if (! pfs_table->m_lock_enabled)
31993199
return NULL;
32003200

3201-
PFS_thread *pfs_thread= pfs_table->m_thread_owner;
3201+
PFS_thread *pfs_thread= my_thread_get_THR_PFS();
3202+
3203+
DBUG_ASSERT(pfs_thread == pfs_table->m_thread_owner);
32023204

32033205
PFS_TL_LOCK_TYPE lock_type;
32043206

@@ -3611,7 +3613,12 @@ pfs_start_socket_wait_v1(PSI_socket_locker_state *state,
36113613

36123614
if (flag_thread_instrumentation)
36133615
{
3614-
PFS_thread *pfs_thread= pfs_socket->m_thread_owner;
3616+
/*
3617+
Do not use pfs_socket->m_thread_owner here,
3618+
as different threads may use concurrently the same socket,
3619+
for example during a KILL.
3620+
*/
3621+
PFS_thread *pfs_thread= my_thread_get_THR_PFS();
36153622

36163623
if (unlikely(pfs_thread == NULL))
36173624
return NULL;
@@ -3983,6 +3990,8 @@ void pfs_end_idle_wait_v1(PSI_idle_locker* locker)
39833990
if (thread->m_flag_events_waits_history_long)
39843991
insert_events_waits_history_long(wait);
39853992
thread->m_events_waits_current--;
3993+
3994+
DBUG_ASSERT(wait == thread->m_events_waits_current);
39863995
}
39873996
}
39883997

@@ -4067,6 +4076,8 @@ void pfs_end_mutex_wait_v1(PSI_mutex_locker* locker, int rc)
40674076
if (thread->m_flag_events_waits_history_long)
40684077
insert_events_waits_history_long(wait);
40694078
thread->m_events_waits_current--;
4079+
4080+
DBUG_ASSERT(wait == thread->m_events_waits_current);
40704081
}
40714082
}
40724083
}
@@ -4146,6 +4157,8 @@ void pfs_end_rwlock_rdwait_v1(PSI_rwlock_locker* locker, int rc)
41464157
if (thread->m_flag_events_waits_history_long)
41474158
insert_events_waits_history_long(wait);
41484159
thread->m_events_waits_current--;
4160+
4161+
DBUG_ASSERT(wait == thread->m_events_waits_current);
41494162
}
41504163
}
41514164
}
@@ -4223,6 +4236,8 @@ void pfs_end_rwlock_wrwait_v1(PSI_rwlock_locker* locker, int rc)
42234236
if (thread->m_flag_events_waits_history_long)
42244237
insert_events_waits_history_long(wait);
42254238
thread->m_events_waits_current--;
4239+
4240+
DBUG_ASSERT(wait == thread->m_events_waits_current);
42264241
}
42274242
}
42284243
}
@@ -4287,6 +4302,8 @@ void pfs_end_cond_wait_v1(PSI_cond_locker* locker, int rc)
42874302
if (thread->m_flag_events_waits_history_long)
42884303
insert_events_waits_history_long(wait);
42894304
thread->m_events_waits_current--;
4305+
4306+
DBUG_ASSERT(wait == thread->m_events_waits_current);
42904307
}
42914308
}
42924309
}
@@ -4382,6 +4399,8 @@ void pfs_end_table_io_wait_v1(PSI_table_locker* locker, ulonglong numrows)
43824399
if (thread->m_flag_events_waits_history_long)
43834400
insert_events_waits_history_long(wait);
43844401
thread->m_events_waits_current--;
4402+
4403+
DBUG_ASSERT(wait == thread->m_events_waits_current);
43854404
}
43864405
}
43874406

@@ -4451,6 +4470,8 @@ void pfs_end_table_lock_wait_v1(PSI_table_locker* locker)
44514470
if (thread->m_flag_events_waits_history_long)
44524471
insert_events_waits_history_long(wait);
44534472
thread->m_events_waits_current--;
4473+
4474+
DBUG_ASSERT(wait == thread->m_events_waits_current);
44544475
}
44554476
}
44564477

@@ -4723,6 +4744,8 @@ void pfs_end_file_wait_v1(PSI_file_locker *locker,
47234744
if (thread->m_flag_events_waits_history_long)
47244745
insert_events_waits_history_long(wait);
47254746
thread->m_events_waits_current--;
4747+
4748+
DBUG_ASSERT(wait == thread->m_events_waits_current);
47264749
}
47274750
}
47284751
}
@@ -6307,6 +6330,8 @@ void pfs_end_socket_wait_v1(PSI_socket_locker *locker, size_t byte_count)
63076330
if (thread->m_flag_events_waits_history_long)
63086331
insert_events_waits_history_long(wait);
63096332
thread->m_events_waits_current--;
6333+
6334+
DBUG_ASSERT(wait == thread->m_events_waits_current);
63106335
}
63116336
}
63126337

@@ -7039,6 +7064,8 @@ pfs_end_metadata_wait_v1(PSI_metadata_locker *locker,
70397064
if (thread->m_flag_events_waits_history_long)
70407065
insert_events_waits_history_long(wait);
70417066
thread->m_events_waits_current--;
7067+
7068+
DBUG_ASSERT(wait == thread->m_events_waits_current);
70427069
}
70437070
}
70447071
else

0 commit comments

Comments
 (0)