diff options
author | Davi Arnaut <Davi.Arnaut@Sun.COM> | 2009-04-03 16:11:54 -0300 |
---|---|---|
committer | Davi Arnaut <Davi.Arnaut@Sun.COM> | 2009-04-03 16:11:54 -0300 |
commit | 8b3567d2cf3e22ff85d1193580f36193b5285ae3 (patch) | |
tree | b11bced0612f7135d287c919aace0baf06344d69 /sql/sql_lex.h | |
parent | 153cdd06b772a29163f215b4026fec4422edc082 (diff) | |
download | mariadb-git-8b3567d2cf3e22ff85d1193580f36193b5285ae3.tar.gz |
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.
mysql-test/r/lock_multi.result:
Add test case result for Bug#43230
mysql-test/t/lock_multi.test:
Add test case for Bug#43230
sql/sql_lex.cc:
Initialize flag.
sql/sql_lex.h:
Add a flag to the lexer.
sql/sql_parse.cc:
Wait for the global read lock is a write lock is going to be
taken. The wait is done before opening tables.
sql/sql_yacc.yy:
Protect against the GRL if its a SELECT .. FOR UPDATE or LOCK TABLES
.. WRITE statement.
Diffstat (limited to 'sql/sql_lex.h')
-rw-r--r-- | sql/sql_lex.h | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 9f020f4adc5..3e762581e04 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -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() |