mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Bug#43230: SELECT ... FOR UPDATE can hang with FLUSH TABLES WITH READ LOCK indefinitely
The problem is that a SELECT .. FOR UPDATE statement might open a table and later wait for a impeding global read lock without noticing whether it is holding a table that is being waited upon the the flush phase of the process that took the global read lock. The same problem also affected the following statements: LOCK TABLES .. WRITE UPDATE .. SET (update and multi-table update) TRUNCATE TABLE .. LOAD DATA .. The solution is to make the above statements wait for a impending global read lock before opening the tables. If there is no impending global read lock, the statement raises a temporary protection against global read locks and progresses smoothly towards completion. Important notice: the patch does not try to address all possible cases, only those which are common and can be fixed unintrusively enough for 5.0.
This commit is contained in:
@ -1176,6 +1176,22 @@ typedef struct st_lex : public Query_tables_list
|
||||
|
||||
bool escape_used;
|
||||
|
||||
/*
|
||||
Special case for SELECT .. FOR UPDATE and LOCK TABLES .. WRITE.
|
||||
|
||||
Protect from a impending GRL as otherwise the thread might deadlock
|
||||
if it starts waiting for the GRL in mysql_lock_tables.
|
||||
|
||||
The protection is needed because there is a race between setting
|
||||
the global read lock and waiting for all open tables to be closed.
|
||||
The problem is a circular wait where a thread holding "old" open
|
||||
tables will wait for the global read lock to be released while the
|
||||
thread holding the global read lock will wait for all "old" open
|
||||
tables to be closed -- the flush part of flush tables with read
|
||||
lock.
|
||||
*/
|
||||
bool protect_against_global_read_lock;
|
||||
|
||||
st_lex();
|
||||
|
||||
virtual ~st_lex()
|
||||
|
Reference in New Issue
Block a user