Bug#16565 mysqld --help --verbose does not order variablesBug#20413 sql_slave_skip_counter is not shown in show variables
Bug#20415 Output of mysqld --help --verbose is incomplete
Bug#25430 variable not found in SELECT @@global.ft_max_word_len;
Bug#32902 plugin variables don't know their names
Bug#34599 MySQLD Option and Variable Reference need to be consistent in formatting!
Bug#34829 No default value for variable and setting default does not raise error
Bug#34834 ? Is accepted as a valid sql mode
Bug#34878 Few variables have default value according to documentation but error occurs
Bug#34883 ft_boolean_syntax cant be assigned from user variable to global var.
Bug#37187 `INFORMATION_SCHEMA`.`GLOBAL_VARIABLES`: inconsistent status
Bug#40988 log_output_basic.test succeeded though syntactically false.
Bug#41010 enum-style command-line options are not honoured (maria.maria-recover fails)
Bug#42103 Setting key_buffer_size to a negative value may lead to very large allocations
Bug#44691 Some plugins configured as MYSQL_PLUGIN_MANDATORY in can be disabled
Bug#44797 plugins w/o command-line options have no disabling option in --help
Bug#46314 string system variables don't support expressions
Bug#46470 sys_vars.max_binlog_cache_size_basic_32 is broken
Bug#46586 When using the plugin interface the type "set" for options caused a crash.
Bug#47212 Crash in DBUG_PRINT in mysqltest.cc when trying to print octal number
Bug#48758 mysqltest crashes on sys_vars.collation_server_basic in gcov builds
Bug#49417 some complaints about mysqld --help --verbose output
Bug#49540 DEFAULT value of binlog_format isn't the default value
Bug#49640 ambiguous option '--skip-skip-myisam' (double skip prefix)
Bug#49644 init_connect and \0
Bug#49645 init_slave and multi-byte characters
Bug#49646 mysql --show-warnings crashes when server dies
CMakeLists.txt:
Bug#44691 Some plugins configured as MYSQL_PLUGIN_MANDATORY in can be disabled
client/mysql.cc:
don't crash with --show-warnings when mysqld dies
config/ac-macros/plugins.m4:
Bug#44691 Some plugins configured as MYSQL_PLUGIN_MANDATORY in can be disabled
include/my_getopt.h:
comments
include/my_pthread.h:
fix double #define
mysql-test/mysql-test-run.pl:
run sys_vars suite by default
properly recognize envirinment variables (e.g. MTR_MAX_SAVE_CORE) set to 0
escape gdb command line arguments
mysql-test/suite/sys_vars/r/rpl_init_slave_func.result:
init_slave+utf8 bug
mysql-test/suite/sys_vars/t/rpl_init_slave_func.test:
init_slave+utf8 bug
mysys/my_getopt.c:
Bug#34599 MySQLD Option and Variable Reference need to be consistent in formatting!
Bug#46586 When using the plugin interface the type "set" for options caused a crash.
Bug#49640 ambiguous option '--skip-skip-myisam' (double skip prefix)
mysys/typelib.c:
support for flagset
sql/ha_ndbcluster.cc:
backport from telco tree
sql/item_func.cc:
Bug#49644 init_connect and \0
Bug#49645 init_slave and multi-byte characters
sql/sql_builtin.cc.in:
Bug#44691 Some plugins configured as MYSQL_PLUGIN_MANDATORY in can be disabled
sql/sql_plugin.cc:
Bug#44691 Some plugins configured as MYSQL_PLUGIN_MANDATORY in can be disabled
Bug#32902 plugin variables don't know their names
Bug#44797 plugins w/o command-line options have no disabling option in --help
sql/sys_vars.cc:
all server variables are defined here
storage/myisam/ft_parser.c:
remove unnecessary updates of param->quot
storage/myisam/ha_myisam.cc:
myisam_* variables belong here
strings/my_vsnprintf.c:
%o and %llx
unittest/mysys/my_vsnprintf-t.c:
%o and %llx tests
vio/viosocket.c:
bugfix: fix @@wait_timeout to work with socket timeouts (vs. alarm thread)
The reason for the deadlock was an improper exit from
MDL_context::wait_for_locks() which caused mysys_var->current_mutex to remain
LOCK_mdl even though LOCK_mdl was no longer held by that connection.
This could for example lead to a deadlock in the following way:
1) INSERT DELAYED tries to open a table but fails, and trying to recover it
calls wait_for_locks().
2) Due to a pending exclusive request, wait_for_locks() fails and exits without
resetting mysys_var->current_mutex for the delayed insert handler thread. So it
continues to point to LOCK_mdl.
3) The handler thread manages to open a table.
4) A different connection takes LOCK_open and tries to take LOCK_mdl.
5) FLUSH TABLES from a third connection notices that the handler thread has a
table open, and tries to kill it. This involves locking mysys_var->current_mutex
while having LOCK_open locked. Since current_mutex mistakenly points to LOCK_mdl,
we have a deadlock.
This patch makes sure MDL_EXIT_COND() is called before exiting wait_for_locks().
This clears mysys->current_mutex which resolves the issue.
An assert is added to recover_from_failed_open_table_attempt() after
wait_for_locks() is called, to check that current_mutex is indeed reset.
With this assert in place, existing tests in (e.g.) mdl_sync.test will fail
without this patch.
-----------------------------------------------------------
2630.28.28 Magne Mahre 2008-12-05
Bug #38661 'all threads hang in "opening tables" or "waiting for table"
and cpu is at 100%'
Concurrent execution of FLUSH TABLES statement and at least two statements
using the same table might have led to live-lock which caused all three
connections to stall and hog 100% of CPU.
tdc_wait_for_old_versions() wrongly assumed that there cannot be a share
with an old version and no used TABLE instances and thus was failing to
perform wait in situation when such old share was cached in MDL subsystem
thanks to a still active metadata lock on the table. So it might have
happened that two or more connections simultaneously executing statements
which involve table being flushed managed to prevent each other from
waiting in this function by keeping shared metadata lock on the table
constantly active (i.e. one of the statements managed to take/hold this
lock while other statements were calling tdc_wait_for_old_versions()).
Thus they were forcing each other to loop infinitely in open_tables() -
close_thread_tables_for_reopen() - tdc_wait_for_old_versions() cycle
causing CPU hogging.
This patch fixes this problem by removing this false assumption from
tdc_wait_for_old_versions().
Note that the problem is specific only for server versions >= 6.0.
No test case is submitted for this test, as the test infrastructure
hasn't got the necessary primitives to test the behaviour. The
manifestation is that throughput will decrease to a low level
(possibly 0) after some time, and stay at that level. Several
transactions will not complete.
Manual testing can be done by running the code submitted by Shane
Bester attached to the bug report. If the bug persists, the
transaction thruput will almost immediately drop to near zero
(shown as the transaction count output from the test program staying
on a close to constant value, instead of increasing rapidly).
----------------------------------------------------
2736.2.10 Michael Widenius 2008-10-22
Fix for bug#39395 Maria: ma_extra.c:286: maria_extra:
Assertion `share->reopen == 1' failed
sql/sql_base.cc:
Race condition in wait_while_table_is_used() where a table used
by another connection could be forced closed, but there was no protection against the other thread re-opening the table and trying to lock it
again before the table was name locked by original thread.
(diagnostics_area)
Execution of CREATE TABLE ... SELECT statement was not atomic in
the sense that concurrent statements trying to affect its target
table might have sneaked in between the moment when the table was
created and moment when it was filled according to SELECT clause.
This resulted in inconsistent binary log, unexpected target table
contents. In cases when concurrent statement was a DDL statement
CREATE TABLE ... SELECT might have failed with ER_CANT_LOCK error.
In more detail:
Due to premature metadata lock downgrade which occured after CREATE
TABLE SELECT statement created table but before it managed to obtain
table-level lock on it other statements were allowed to open, lock
and change target table in the middle of CREATE TABLE SELECT
execution. This also meant that it was possible that CREATE TABLE
SELECT would wait in mysql_lock_tables() when it was called for newly
created table and that this wait could have been aborted by concurrent
DDL. The latter led to execution of unexpected branch of code and
CREATE TABLE SELECT ending with ER_CANT_LOCK error.
The premature downgrade occured because open_table(), which was called
for newly created table, decided that it is OK to downgrade metadata
lock from exclusive to shared since table exists, even although it
was not acquired within this call.
This fix ensures that open_table() does not downgrade metadata lock
if it is not acquired during its current invocation.
Testing:
The bug is exposed in a race condition, and is thus difficult to
expose in a standard mysql-test-run test case. Instead, a stress
test using the Random Query Generator (https://launchpad.net/randgen)
will trip the problem occasionally.
% perl runall.pl \
--basedir=<build dir> \
--mysqld=--table-lock-wait-timeout=5 \
--mysqld=--skip-safemalloc \
--grammar=conf/maria_bulk_insert.yy \
--reporters=ErrorLog,Backtrace,WinPackage \
--mysqld=--log-output=file \
--queries=100000 \
--threads=10 \
--engine=myisam
Note: You will need a debug build to expose the bug
When the bug is tripped, the server will abort and dump core.
Backport from 6.0-codebase (revid: 2617.53.4)
2630.16.14 Sergei Golubchik 2008-08-25
fixed a crash in partition tests
introduced by HA_EXTRA_PREPARE_FOR_DROP patch
sql/sql_base.cc:
Don't call ::extra() for closed tables.
Bug #46654 False deadlock on concurrent DML/DDL with partitions,
inconsistent behavior
The problem was that if one connection is running a multi-statement
transaction which involves a single partitioned table, and another
connection attempts to alter the table, the first connection gets
ER_LOCK_DEADLOCK and cannot proceed anymore, even when the ALTER TABLE
statement in another connection has timed out or failed.
The reason for this was that the prepare phase for ALTER TABLE for
partitioned tables removed all instances of the table from the table
definition cache before it started waiting on the lock. The transaction
running in the first connection would notice this and report ER_LOCK_DEADLOCK.
This patch changes the prep_alter_part_table() ALTER TABLE code so that
tdc_remove_table() is no longer called. Instead, only the TABLE instance
changed by prep_alter_part_table() is marked as needing reopen.
The patch also removes an unnecessary call to tdc_remove_table() from
mysql_unpack_partition() as the changed TABLE object is destroyed by the
caller at a later point.
Test case added in partition_sync.test.
Bug#42546 Backup: RESTORE fails, thinking it finds an existing table
The problem occured when a MDL locking conflict happened for a non-existent
table between a CREATE and a INSERT statement. The code for CREATE
interpreted this lock conflict to mean that the table existed,
which meant that the statement failed when it should not have.
The problem could occur for CREATE TABLE, CREATE TABLE LIKE and
ALTER TABLE RENAME.
This patch fixes the problem for CREATE TABLE and CREATE TABLE LIKE.
It is based on code backported from the mysql-6.1-fk tree written
by Dmitry Lenev. CREATE now uses normal open_and_lock_tables() code
to acquire exclusive locks. This means that for the test case in the bug
description, CREATE will wait until INSERT completes so that it can
get the exclusive lock. This resolves the reported bug.
The patch also prohibits CREATE TABLE and CREATE TABLE LIKE under
LOCK TABLES. Note that this is an incompatible change and must
be reflected in the documentation. Affected test cases have been
updated.
mdl_sync.test contains tests for CREATE TABLE and CREATE TABLE LIKE.
Fixing the issue for ALTER TABLE RENAME is beyond the scope of this
patch. ALTER TABLE cannot be prohibited from working under LOCK TABLES
as this could seriously impact customers and a proper fix would require
a significant rewrite.
------------------------------------------------------------
revno: 2617.68.25
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-next-bg-pre2-2
timestamp: Wed 2009-09-16 18:26:50 +0400
message:
Follow-up for one of pre-requisite patches for fixing bug #30977
"Concurrent statement using stored function and DROP FUNCTION
breaks SBR".
Made enum_mdl_namespace enum part of MDL_key class and removed MDL_
prefix from the names of enum members. In order to do the latter
changed name of PROCEDURE symbol to PROCEDURE_SYM (otherwise macro
which was automatically generated for this symbol conflicted with
MDL_key::PROCEDURE enum member).
------------------------------------------------------------
revno: 2617.68.24
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-next-bg-pre2-2
timestamp: Wed 2009-09-16 17:25:29 +0400
message:
Pre-requisite patch for fixing bug #30977 "Concurrent statement
using stored function and DROP FUNCTION breaks SBR".
Added MDL_request for stored routine as member to Sroutine_hash_entry
in order to be able perform metadata locking for stored routines in
future (Sroutine_hash_entry is an equivalent of TABLE_LIST class for
stored routines).
(WL#4284, follow up fixes).
sql/mdl.cc:
Introduced version of MDL_request::init() method which initializes
lock request using pre-built MDL key.
MDL_key::table_name/table_name_length() getters were
renamed to reflect the fact that MDL_key objects are
now created not only for tables.
sql/mdl.h:
Extended enum_mdl_namespace enum with values which correspond
to namespaces for stored functions and triggers.
Renamed MDL_key::table_name/table_name_length() getters
to MDL_key::name() and name_length() correspondingly to
reflect the fact that MDL_key objects are now created
not only for tables.
Added MDL_key::mdl_namespace() getter.
Also added version of MDL_request::init() method which
initializes lock request using pre-built MDL key.
sql/sp.cc:
Added MDL_request for stored routine as member to Sroutine_hash_entry.
Changed code to use MDL_key from this request as a key for LEX::sroutines
set. Removed separate "key" member from Sroutine_hash_entry as it became
unnecessary.
sql/sp.h:
Added MDL_request for stored routine as member to Sroutine_hash_entry
in order to be able perform metadata locking for stored routines in
future (Sroutine_hash_entry is an equivalent of TABLE_LIST class for
stored routines).
Removed Sroutine_hash_entry::key member as now we can use MDL_key from
this request as a key for LEX::sroutines set.
sql/sp_head.cc:
Removed sp_name::m_sroutines_key member and set_routine_type() method.
Since key for routine in LEX::sroutines set has no longer sp_name::m_qname
as suffix we won't save anything by creating it at sp_name construction
time.
Adjusted sp_name constructor used for creating temporary objects for
lookups in SP-cache to accept MDL_key as parameter and to avoid any
memory allocation.
Finally, removed sp_head::m_soutines_key member for reasons similar
to why sp_name::m_sroutines_key was removed
sql/sp_head.h:
Removed sp_name::m_sroutines_key member and set_routine_type() method.
Since key for routine in LEX::sroutines set has no longer sp_name::m_qname
as suffix we won't save anything by creating it at sp_name construction
time.
Adjusted sp_name constructor used for creating temporary objects for
lookups in SP-cache to accept MDL_key as parameter and to avoid any
memory allocation.
Finally, removed sp_head::m_soutines_key member for reasons similar
to why sp_name::m_sroutines_key was removed.
sql/sql_base.cc:
Adjusted code to the fact that we now use MDL_key from
Sroutine_hash_entry::mdl_request as a key for LEX::sroutines set.
MDL_key::table_name/table_name_length() getters were
renamed to reflect the fact that MDL_key objects are
now created not only for tables.
sql/sql_trigger.cc:
sp_add_used_routine() now takes MDL_key as parameter as now we use
instance of this class as a key for LEX::sroutines set.
revno: 2617.68.23
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-next-bg-pre1
timestamp: Wed 2009-09-16 09:34:42 +0400
message:
Pre-requisite patch for fixing bug #30977 "Concurrent statement
using stored function and DROP FUNCTION breaks SBR".
CREATE TABLE SELECT statements take exclusive metadata lock on table
being created. Invariant of metadata locking subsystem states that
such lock should be taken before taking any kind of shared locks.
Once metadata locks on stored routines are introduced statements like
"CREATE TABLE ... SELECT f1()" will break this invariant by taking
shared locks on routines before exclusive lock on target table.
To avoid this, open_tables() is reworked to process tables which are
directly used by the statement before stored routines are processed.
sql/sql_base.cc:
Refactored open_tables() implementation to process stored routines
only after tables which are directly used by statement were processed.
To achieve this moved handling of routines in open_tables() out of
loop which iterates over tables to a new separate loop. And in its
turn this allowed to split handling of particular table or view to
an auxiliary function, which made code in open_tables() simpler and
more easy to understand.
------------------------------------------------------------
revno: 2617.68.10
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-next-bg46673
timestamp: Tue 2009-09-01 19:57:05 +0400
message:
Fix for bug #46673 "Deadlock between FLUSH TABLES WITH READ LOCK and DML".
Deadlocks occured when one concurrently executed transactions with
several statements modifying data and FLUSH TABLES WITH READ LOCK
statement or SET READ_ONLY=1 statement.
These deadlocks were introduced by the patch for WL 4284: "Transactional
DDL locking"/Bug 989: "If DROP TABLE while there's an active transaction,
wrong binlog order" which has changed FLUSH TABLES WITH READ LOCK/SET
READ_ONLY=1 to wait for pending transactions.
What happened was that FLUSH TABLES WITH READ LOCK blocked all further
statements changing tables by setting global_read_lock global variable
and has started waiting for all pending transactions to complete.
Then one of those transactions tried to executed DML, detected that
global_read_lock non-zero and tried to wait until global read lock will
be released (i.e. global_read_lock becomes 0), indeed, this led to a
deadlock.
Proper solution for this problem should probably involve full integration
of global read lock with metadata locking subsystem (which will allow to
implement waiting for pending transactions without blocking DML in them).
But since it requires significant changes another, short-term solution
for the problem is implemented in this patch.
Basically, this patch restores behavior of FLUSH TABLES WITH READ LOCK/
SET READ_ONLY=1 before the patch for WL 4284/bug 989. By ensuring that
extra references to TABLE_SHARE are not stored for active metadata locks
it changes these statements not to wait for pending transactions.
As result deadlock is eliminated.
Note that this does not change the fact that active FLUSH TABLES WITH
READ LOCK lock or SET READ_ONLY=1 prevent modifications to tables as
they also block transaction commits.
mysql-test/r/flush_block_commit.result:
Adjusted test case after change in FLUSH TABLES WITH READ LOCK behavior
- it is no longer blocked by a pending transaction.
mysql-test/r/mdl_sync.result:
Added test for bug #46673 "Deadlock between FLUSH TABLES WITH READ LOCK
and DML".
mysql-test/r/read_only_innodb.result:
Adjusted test case after change in SET READ_ONLY behavior - it is no
longer blocked by a pending transaction.
mysql-test/t/flush_block_commit.test:
Adjusted test case after change in FLUSH TABLES WITH READ LOCK behavior
- it is no longer blocked by a pending transaction.
mysql-test/t/mdl_sync.test:
Added test for bug #46673 "Deadlock between FLUSH TABLES WITH READ LOCK
and DML".
mysql-test/t/read_only_innodb.test:
Adjusted test case after change in SET READ_ONLY behavior - it is no
longer blocked by a pending transaction.
sql/sql_base.cc:
Disable caching of pointers to TABLE_SHARE objects in MDL subsystem.
This means that transactions holding metadata lock on the table will
no longer have extra reference to the TABLE_SHARE (due to this lock)
and will no longer block concurrent FLUSH TABLES/FLUSH TABLES WITH
READ LOCK. Note that this does not change the fact that FLUSH TABLES
WITH READ LOCK prevents concurrent transactions from modifying data
as it also blocks all commits.
------------------------------------------------------------
revno: 2617.68.7
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-next-bg46044
timestamp: Thu 2009-08-27 10:22:17 +0400
message:
Fix for bug #46044 "MDL deadlock on LOCK TABLE + CREATE TABLE HIGH_PRIORITY
FOR UPDATE".
Deadlock occured when during execution of query to I_S we tried to open
a table or its .FRM in order to get information about it and had to wait
because we have encountered exclusive metadata lock on this table held by
a DDL operation from another connection which in its turn waited for some
resource currently owned by connection executing this I_S query.
For example, this might have happened if one under LOCK TABLES executed I_S
query targeted to particular table (which was not among locked) and also
concurrently tried to create this table using CREATE TABLE SELECT which
had to wait for one of tables locked by the first connection.
Another situation in which deadlock might have occured is when I_S query,
which was executed as part of transaction, tried to get information about
table which just has been dropped by concurrent DROP TABLES executed under
LOCK TABLES and this DROP TABLES for its completion also had to wait
transaction from the first connection.
This problem stemmed from the fact that opening of tables/.FRMs for I_S
filling is happening outside of connection's main MDL_context so code
which tries to detect deadlocks due to conflicting metadata locks doesn't
work in this case. Indeed, this led to deadlocks when during I_S filling
we tried to wait for conflicting metadata lock to go away, while its owner
was waiting for some resource held by connection executing I_S query.
This patch solves this problem by avoiding waiting in such situation.
Instead we skip this table and produce warning that information about
it was omitted from I_S due to concurrent DDL operation. We still wait
for conflicting metadata lock to go away when it is known that deadlock
is not possible (i.e. when connection executing I_S query does not hold
any metadata or table-level locks).
Basically, we apply our standard deadlock avoidance technique for metadata
locks to the process of filling of I_S tables but replace ER_LOCK_DEADLOCK
error with a warning.
Note that this change is supposed to be safe for 'mysqldump' since the
only its mode which is affected by this change is --single-transaction mode
is not safe in the presence of concurrent DDL anyway (and this fact is
documented). Other modes are unaffected because they either use
SHOW TABLES/SELECT * FROM I_S.TABLE_NAMES which do not take any metadata
locks in the process of I_S table filling and thus cannot skip tables or
execute I_S queries for tables which were previously locked by LOCK TABLES
(or in the presence of global read lock) which excludes possibility of
encountering conflicting metadata lock.
mysql-test/r/mdl_sync.result:
Added test for bug #46044 "MDL deadlock on LOCK TABLE + CREATE TABLE
HIGH_PRIORITY FOR UPDATE".
mysql-test/t/mdl_sync.test:
Added test for bug #46044 "MDL deadlock on LOCK TABLE + CREATE TABLE
HIGH_PRIORITY FOR UPDATE".
sql/mysql_priv.h:
Added a new flag for open_table() call which allows it to fail
with an error in cases when conflicting metadata lock is discovered
instead of waiting until this lock goes away.
sql/share/errmsg-utf8.txt:
Added error/warning message to be generated in cases when information
about table is omitted from I_S since there is conflicting metadata lock
on the table.
sql/share/errmsg.txt:
Added error/warning message to be generated in cases when information
about table is omitted from I_S since there is conflicting metadata lock
on the table.
sql/sql_base.cc:
Added a new flag for open_table() call which allows it to fail
with an error in cases when conflicting metadata lock is discovered
instead of waiting until this lock goes away.
sql/sql_show.cc:
When we are opening a table (or just .FRM) in order to fill I_S with
information about this table and encounter conflicting metadata lock
waiting for this lock to go away can lead to a deadlock in some
situations (under LOCK TABLES, within transaction, etc.). To avoid
these deadlocks we detect such situations and don't do waiting.
Instead, we skip table for which we have conflicting metadata lock,
thus omitting information about it from I_S table, and produce an
appropriate warning.
------------------------------------------------------------
revno: 2617.69.37
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-next-bg46748
timestamp: Fri 2009-08-21 18:17:02 +0400
message:
Fix for bug #46748 "Assertion in MDL_context::wait_for_locks()
on INSERT + CREATE TRIGGER".
Concurrent execution of statements involving stored functions or triggers
which were using several tables and DDL statements which affected those
tables on debug build of server might have led to assertion failures in
MDL_context::wait_for_locks(). Non-debug build was not affected.
The problem was that during back-off which happens when open_tables()
encounters conflicting metadata lock for one of the tables being open
we didn't reset MDL_request::ticket value for requests which correspond
to tables from extended prelocking set. Since these requests are part
of of list of requests to be waited for in Open_table_context this broke
assumption that ticket value for them is 0 in MDL_context::wait_for_locks()
and caused assertion failure.
This fix ensures that close_tables_for_reopen(), which performs this back-off
resets MDL_request::ticket value not only for tables directly used by the
statement but also for tables from extended prelocking set, thus satisfying
assumption described above.
mysql-test/r/mdl_sync.result:
Added test case for bug #46748 "Assertion in MDL_context::wait_for_locks()
on INSERT + CREATE TRIGGER".
mysql-test/t/mdl_sync.test:
Added test case for bug #46748 "Assertion in MDL_context::wait_for_locks()
on INSERT + CREATE TRIGGER".
sql/sql_base.cc:
Since metadata lock requests for tables from extended part of prelocking
set are also part of list of requests to be waited for in Open_table_context
in close_tables_for_reopen() we have to reset MDL_request::ticket
values for them to assumptions in MDL_context::wait_for_locks().
Bug #47249 assert in MDL_global_lock::is_lock_type_compatible
This assert could be triggered if LOCK TABLES were used to lock
both a table and a view that used the same table. The table would have
to be first WRITE locked and then READ locked. So "LOCK TABLES v1
WRITE, t1 READ" would eventually trigger the assert, "LOCK TABLES
v1 READ, t1 WRITE" would not. The reason is that the ordering of locks
in the interal representation made a difference when executing
FLUSH TABLE on the table.
During FLUSH TABLE, a lock was upgraded to exclusive. If this lock
was of type MDL_SHARED and not MDL_SHARED_UPGRADABLE, an internal
counter in the MDL subsystem would get out of sync. This would happen
if the *last* mention of the table in LOCK TABLES was a READ lock.
The counter in question is the number exclusive locks (active or intention).
This is used to make sure a global metadata lock is only taken when the
counter is zero (= no conflicts). The counter is increased when a
MDL_EXCLUSIVE or MDL_SHARED_UPGRADABLE lock is taken, but not when
upgrade_shared_lock_to_exclusive() is used to upgrade directly
from MDL_SHARED to MDL_EXCLUSIVE.
This patch fixes the problem by searching for a TABLE instance locked
with MDL_SHARED_UPGRADABLE or MDL_EXCLUSIVE before calling
upgrade_shared_lock_to_exclusive(). The patch also adds an assert checking
that only MDL_SHARED_UPGRADABLE locks are upgraded to exclusive.
Test case added to lock_multi.test.
----------------------------------------------------------
revno: 2617.69.25
committer: Konstantin Osipov <kostja@sun.com>
branch nick: 5.4-42546
timestamp: Fri 2009-08-14 23:52:00 +0400
message:
A cleanup in open_tables() and lock_tables():
change return type of these functions to bool from int,
to follow convention in the rest of the code.
(Part of WL#4284 review fixes).
sql/mysql_priv.h:
Change return type of open_talbes() and lock_tables() from
int to bool.
sql/sql_base.cc:
Change return type of open_tables() and lock_tables() from int to bool.
sql/sql_handler.cc:
Use bool now that open_tables() returns bool.
A pre-requisite patch for Bug#30977 "Concurrent statement using
stored function and DROP FUNCTION breaks SBR".
This patch changes the MDL API by introducing a namespace for
lock keys: MDL_TABLE for tables and views and MDL_PROCEDURE
for stored procedures and functions. The latter is needed for
the fix for Bug#30977.
----------------------------------------------------------
revno: 2617.69.24
committer: Konstantin Osipov <kostja@sun.com>
branch nick: 5.4-42546
timestamp: Fri 2009-08-14 19:22:05 +0400
message:
A pre-requisite for a fix for Bug#42546 "Backup: RESTORE fails, thinking it
finds an existing table"
Back-port from WL 148 "Foreign keys" feature tree a patch
that introduced Prelocking_strategy class -- a way to parameterize
open_tables() behaviour, implemented by Dmitry Lenev.
(Part of WL#4284).
sql/sql_base.cc:
Implement different prelocking strategies. Use an instance of
prelocking_strategy in open_tables().
sql/sql_class.h:
Add declarations for class Prelocking_strategy.
sql/sql_lex.h:
Add a helper method to access last table of the global table list
(lex->query_tables).
sql/sql_parse.cc:
Use a special prelocking strategy when locking tables for LOCK TABLES.
sql/sql_table.cc:
Use normal open_and_lock_tables_derived() in ALTER TABLE.
sql/sql_yacc.yy:
Modify the grammar to not pollute the global table list with tables
that should not be opened.
----------------------------------------------------------
revno: 2617.69.20
committer: Konstantin Osipov <kostja@sun.com>
branch nick: 5.4-4284-1-assert
timestamp: Thu 2009-08-13 18:29:55 +0400
message:
WL#4284 "Transactional DDL locking"
A review fix.
Since WL#4284 implementation separated MDL_request and MDL_ticket,
MDL_request becamse a utility object necessary only to get a ticket.
Store it by-value in TABLE_LIST with the intent to merge
MDL_request::key with table_list->table_name and table_list->db
in future.
Change the MDL subsystem to not require MDL_requests to
stay around till close_thread_tables().
Remove the list of requests from the MDL context.
Requests for shared metadata locks acquired in open_tables()
are only used as a list in recover_from_failed_open_table_attempt(),
which calls mdl_context.wait_for_locks() for this list.
To keep such list for recover_from_failed_open_table_attempt(),
introduce a context class (Open_table_context), that collects
all requests.
A lot of minor cleanups and simplications that became possible
with this change.
sql/event_db_repository.cc:
Remove alloc_mdl_requests(). Now MDL_request instance is a member
of TABLE_LIST, and init_one_table() initializes it.
sql/ha_ndbcluster_binlog.cc:
Remove now unnecessary declaration and initialization
of binlog_mdl_request.
sql/lock.cc:
No need to allocate MDL requests in lock_table_names() now.
sql/log.cc:
Use init_one_table() method, remove alloc_mdl_requests(),
which is now unnecessary.
sql/log_event.cc:
No need to allocate mdl_request separately now.
Use init_one_table() method.
sql/log_event_old.cc:
Update to the new signature of close_tables_for_reopen().
sql/mdl.cc:
Update try_acquire_exclusive_lock() to be more easy to use.
Function lock_table_name_if_not_cached() has been removed.
Make acquire_shared_lock() signature consistent with
try_acquire_exclusive_lock() signature.
Remove methods that are no longer used.
Update comments.
sql/mdl.h:
Implement an assignment operator that doesn't
copy MDL_key (MDL_key::operator= is private and
should remain private).
This is a hack to work-around assignment of TABLE_LIST
by value in several places. Such assignments violate
encapsulation, since only perform a shallow copy.
In most cases these assignments are a hack on their own.
sql/mysql_priv.h:
Update signatures of close_thread_tables() and close_tables_for_reopen().
sql/sp.cc:
Allocate TABLE_LIST in thd->mem_root.
Use init_one_table().
sql/sp_head.cc:
Use init_one_table().
Remove thd->locked_tables_root, it's no longer needed.
sql/sql_acl.cc:
Use init_mdl_requests() and init_one_table().
sql/sql_base.cc:
Update to new signatures of try_acquire_shared_lock() and
try_acquire_exclusive_lock().
Remove lock_table_name_if_not_cached().
Fix a bug in open_ltable() that would not return ER_LOCK_DEADLOCK
in case of a failed lock_tables() and a multi-statement
transaction.
Fix a bug in open_and_lock_tables_derived() that would
not return ER_LOCK_DEADLOCK in case of a multi-statement
transaction and a failure of lock_tables().
Move assignment of enum_open_table_action to a method of Open_table_context, a new class that maintains information
for backoff actions.
Minor rearrangements of the code.
Remove alloc_mdl_requests() in functions that work with system
tables: instead the patch ensures that callers always initialize
TABLE_LIST argument.
sql/sql_class.cc:
THD::locked_tables_root is no more.
sql/sql_class.h:
THD::locked_tables_root is no more.
Add a declaration for Open_table_context class.
sql/sql_delete.cc:
Update to use the simplified MDL API.
sql/sql_handler.cc:
TABLE_LIST::mdl_request is stored by-value now.
Ensure that mdl_request.ticket is NULL for every request
that is passed into MDL, to satisfy MDL asserts.
@ sql/sql_help.cc
Function open_system_tables_for_read() no longer initializes
mdl_requests.
Move TABLE_LIST::mdl_request initialization closer to
TABLE_LIST initialization.
sql/sql_help.cc:
Function open_system_tables_for_read() no longer initializes
mdl_requests.
Move TABLE_LIST::mdl_request initialization closer to
TABLE_LIST initialization.
sql/sql_insert.cc:
Remove assignment by-value of TABLE_LIST in
TABLEOP_HOOKS. We can't carry over a granted
MDL ticket from one table list to another.
sql/sql_parse.cc:
Change alloc_mdl_requests() -> init_mdl_requests().
@todo We can remove init_mdl_requests() altogether
in some places: all places that call add_table_to_list()
already have mdl requests initialized.
sql/sql_plugin.cc:
Use init_one_table().
THD::locked_tables_root is no more.
sql/sql_servers.cc:
Use init_one_table().
sql/sql_show.cc:
Update acquire_high_priority_shared_lock() to use
TABLE_LIST::mdl_request rather than allocate an own.
Fix get_trigger_table_impl() to use init_one_table(),
check for out of memory, follow the coding style.
sql/sql_table.cc:
Update to work with TABLE_LIST::mdl_request by-value.
Remove lock_table_name_if_not_cached().
The code that used to delegate to it is quite simple and
concise without it now.
sql/sql_udf.cc:
Use init_one_table().
sql/sql_update.cc:
Update to use the new signature of close_tables_for_reopen().
sql/table.cc:
Move re-setting of mdl_requests for prepared statements
and stored procedures from close_thread_tables() to
reinit_stmt_before_use().
Change alloc_mdl_requests() to init_mdl_requests().
init_mdl_requests() is a hack that can't be deleted
until we don't have a list-aware TABLE_LIST constructor.
Hopefully its use will be minimal
sql/table.h:
Change alloc_mdl_requests() to init_mdl_requests()
TABLE_LIST::mdl_request is stored by value.
sql/tztime.cc:
We no longer initialize mdl requests in open_system_tables_for*()
functions. Move this initialization closer to initialization
of the rest of TABLE_LIST members.
storage/myisammrg/ha_myisammrg.cc:
Simplify mdl_request initialization.
----------------------------------------------------------
revno: 2617.69.2
committer: Konstantin Osipov <kostja@sun.com>
branch nick: 5.4-azalea-bugfixing
timestamp: Mon 2009-08-03 19:26:04 +0400
message:
A fix and a test case for Bug#45035 "Altering table under LOCK TABLES
results in "Error 1213 Deadlock found...".
If a user had a table locked with LOCK TABLES
for READ and for WRITE in the same connection, ALTER TABLE
could fail.
Root cause analysis:
If a connection issues
LOCK TABLE t1 write, t1 a read, t1 b read;
the new LOCK TABLES code in 6.0 (part of WL 3726) will create
the following list of TABLE_LIST objects
(thd->locked_tables_list->m_locked_tables):
{"t1" "b" tl_read_no_insert}, {"t1" "a" tl_read_no_insert},
{"t1" "t1" tl_write }
Later on, when we try to ALTER table t1, mysql_alter_table()
closes all TABLE instances and releases its thr_lock locks,
keeping only an exclusive metadata lock on t1.
But when ALTER is finished, Locked_table_list::reopen_tables()
tries to restore the original list of open and locked tables.
Before this patch, it used to do so one by one:
Open t1 b, get TL_READ_NO_INSERT lock,
Open t1 a, get TL_READ_NO_INSERT lock
Open t1, try to get TL_WRITE lock, deadlock.
The cause of the deadlock is that thr_lock.c doesn't
resolve the situation when the read list only consists
of locks taken by the same thread, followed by this very
thread trying to take a WRITE lock. Indeed, since
thr_lock_multi always gets a sorted list of locks,
WRITE locks always precede READ locks in the list
to lock.
Don't try to fix thr_lock.c deficiency, keep this
code simple.
Instead, try to take all thr_lock locks at once
in ::reopen_tables().
mysql-test/r/lock.result:
Update results: test case for Bug#45035.
mysql-test/t/lock.test:
Add a test case for Bug#45035.
sql/sql_base.cc:
Take all thr_lock locks at once in Locked_tables_list::reopen_tables().
sql/sql_class.h:
Add a helper array to store tables for mysql_lock_tables()
in reopen_tables().
sql/sql_table.cc:
Update unlink_all_closed_tables() to the new signature.
------------------------------------------------------------
revno: 2617.65.6
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-azalea-bg39674
timestamp: Sat 2009-07-25 00:28:43 +0400
message:
Fix for bug #39674 "On shutdown mdl_destroy() called before
plugin_shutdown()".
Attempt to shutdown PBXT engine plugin led to assertion failure
caused by using already destroyed mutex in metadata locking
subsystem.
This problem stemmed from the fact that we MDL subsystem and
table definition cache were deinitialized before plugin shutdown
while PBXT plugin during its shutdown process accessed tables and
therefore expected them to be in working shape.
This patch solves this problem by moving deinitialization of
these two subsystems after plugins are shut down.
No test case is provided since such test case would require
using PBXT or other plugin which accesses tables during its
shutdown process.
sql/mysql_priv.h:
Introduced table_def_start_shutdown() function which informs
table definition cache that shutdown process has been started
so it has to keep number of TABLE and TABLE_SHARE objects minimal
in order to reduce number of references to pluggable engines.
sql/mysqld.cc:
Destroy table definition cache and meta-data locking subsystem
after shutting down plugins. This allows plugins to work with
tables during their shutdown.
Since table definition cache hold references to storage engine
plugins we have to remove unused tables from it before shutting
down plugins and keep number of these references minimal during
the process (by immediately removing tables opened during this
process from the table definition cache).
sql/sql_base.cc:
Introduced table_def_start_shutdown() function which informs
table definition cache that shutdown process has been started
so it has to keep number of TABLE and TABLE_SHARE objects
minimal in order to reduce number of references to pluggable
engines.
This allows to smoothly shutdown such plugins without completely
prohibiting access to tables/table definition cache while
shutting down other plugins.
2617.31.12, 2617.31.15, 2617.31.15, 2617.31.16, 2617.43.1
- initial changeset that introduced the fix for
Bug#989 and follow up fixes for all test suite failures
introduced in the initial changeset.
------------------------------------------------------------
revno: 2617.31.1
committer: Davi Arnaut <Davi.Arnaut@Sun.COM>
branch nick: 4284-6.0
timestamp: Fri 2009-03-06 19:17:00 -0300
message:
Bug#989: If DROP TABLE while there's an active transaction, wrong binlog order
WL#4284: Transactional DDL locking
Currently the MySQL server does not keep metadata locks on
schema objects for the duration of a transaction, thus failing
to guarantee the integrity of the schema objects being used
during the transaction and to protect then from concurrent
DDL operations. This also poses a problem for replication as
a DDL operation might be replicated even thought there are
active transactions using the object being modified.
The solution is to defer the release of metadata locks until
a active transaction is either committed or rolled back. This
prevents other statements from modifying the table for the
entire duration of the transaction. This provides commitment
ordering for guaranteeing serializability across multiple
transactions.
- Incompatible change:
If MySQL's metadata locking system encounters a lock conflict,
the usual schema is to use the try and back-off technique to
avoid deadlocks -- this schema consists in releasing all locks
and trying to acquire them all in one go.
But in a transactional context this algorithm can't be utilized
as its not possible to release locks acquired during the course
of the transaction without breaking the transaction commitments.
To avoid deadlocks in this case, the ER_LOCK_DEADLOCK will be
returned if a lock conflict is encountered during a transaction.
Let's consider an example:
A transaction has two statements that modify table t1, then table
t2, and then commits. The first statement of the transaction will
acquire a shared metadata lock on table t1, and it will be kept
utill COMMIT to ensure serializability.
At the moment when the second statement attempts to acquire a
shared metadata lock on t2, a concurrent ALTER or DROP statement
might have locked t2 exclusively. The prescription of the current
locking protocol is that the acquirer of the shared lock backs off
-- gives up all his current locks and retries. This implies that
the entire multi-statement transaction has to be rolled back.
- Incompatible change:
FLUSH commands such as FLUSH PRIVILEGES and FLUSH TABLES WITH READ
LOCK won't cause locked tables to be implicitly unlocked anymore.
mysql-test/extra/binlog_tests/drop_table.test:
Add test case for Bug#989.
mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test:
Fix test case to reflect the fact that transactions now hold
metadata locks for the duration of a transaction.
mysql-test/include/mix1.inc:
Fix test case to reflect the fact that transactions now hold
metadata locks for the duration of a transaction.
mysql-test/include/mix2.inc:
Fix test case to reflect the fact that transactions now hold
metadata locks for the duration of a transaction.
mysql-test/r/flush_block_commit.result:
Update test case result (WL#4284).
mysql-test/r/flush_block_commit_notembedded.result:
Update test case result (WL#4284).
mysql-test/r/innodb.result:
Update test case result (WL#4284).
mysql-test/r/innodb_mysql.result:
Update test case result (WL#4284).
mysql-test/r/lock.result:
Add test case result for an effect of WL#4284/Bug#989
(all locks should be released when a connection terminates).
mysql-test/r/mix2_myisam.result:
Update test case result (effects of WL#4284/Bug#989).
mysql-test/r/not_embedded_server.result:
Update test case result (effects of WL#4284/Bug#989).
Add a test case for interaction of WL#4284 and FLUSH PRIVILEGES.
mysql-test/r/partition_innodb_semi_consistent.result:
Update test case result (effects of WL#4284/Bug#989).
mysql-test/r/partition_sync.result:
Temporarily disable the test case for Bug#43867,
which will be fixed by a subsequent backport.
mysql-test/r/ps.result:
Add a test case for effect of PREPARE on transactional
locks: we take a savepoint at beginning of PREAPRE
and release it at the end. Thus PREPARE does not
accumulate metadata locks (Bug#989/WL#4284).
mysql-test/r/read_only_innodb.result:
Update test case result (effects of WL#4284/Bug#989).
mysql-test/suite/binlog/r/binlog_row_drop_tbl.result:
Add a test case result (WL#4284/Bug#989).
mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result:
Update test case result (effects of WL#4284/Bug#989).
mysql-test/suite/binlog/r/binlog_stm_drop_tbl.result:
Add a test case result (WL#4284/Bug#989).
mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result:
Update test case result (effects of WL#4284/Bug#989).
mysql-test/suite/binlog/r/binlog_unsafe.result:
A side effect of Bug#989 -- slightly different table map ids.
mysql-test/suite/binlog/t/binlog_row_drop_tbl.test:
Add a test case for WL#4284/Bug#989.
mysql-test/suite/binlog/t/binlog_stm_drop_tbl.test:
Add a test case for WL#4284/Bug#989.
mysql-test/suite/binlog/t/binlog_stm_row.test:
Update to the new state name. This
is actually a follow up to another patch for WL#4284,
that changes Locked thread state to Table lock.
mysql-test/suite/ndb/r/ndb_index_ordered.result:
Remove result for disabled part of the test case.
mysql-test/suite/ndb/t/disabled.def:
Temporarily disable a test case (Bug#45621).
mysql-test/suite/ndb/t/ndb_index_ordered.test:
Disable a part of a test case (needs update to
reflect semantics of Bug#989).
mysql-test/suite/rpl/t/disabled.def:
Disable tests made meaningless by transactional metadata
locking.
mysql-test/suite/sys_vars/r/autocommit_func.result:
Add a commit (Bug#989).
mysql-test/suite/sys_vars/t/autocommit_func.test:
Add a commit (Bug#989).
mysql-test/t/flush_block_commit.test:
Fix test case to reflect the fact that transactions now hold
metadata locks for the duration of a transaction.
mysql-test/t/flush_block_commit_notembedded.test:
Fix test case to reflect the fact that transactions now hold
metadata locks for the duration of a transaction.
Add a test case for transaction-scope locks and the global
read lock (Bug#989/WL#4284).
mysql-test/t/innodb.test:
Fix test case to reflect the fact that transactions now hold
metadata locks for the duration of a transaction
(effects of Bug#989/WL#4284).
mysql-test/t/lock.test:
Add a test case for Bug#989/WL#4284.
mysql-test/t/not_embedded_server.test:
Add a test case for Bug#989/WL#4284.
mysql-test/t/partition_innodb_semi_consistent.test:
Replace TRUNCATE with DELETE, to not issue
an implicit commit of a transaction, and not depend
on metadata locks.
mysql-test/t/partition_sync.test:
Temporarily disable the test case for Bug#43867,
which needs a fix to be backported from 6.0.
mysql-test/t/ps.test:
Add a test case for semantics of PREPARE and transaction-scope
locks: metadata locks on tables used in PREPARE are enclosed into a
temporary savepoint, taken at the beginning of PREPARE,
and released at the end. Thus PREPARE does not effect
what locks a transaction owns.
mysql-test/t/read_only_innodb.test:
Fix test case to reflect the fact that transactions now hold
metadata locks for the duration of a transaction
(Bug#989/WL#4284).
Wait for the read_only statement to actually flush tables before
sending other concurrent statements that depend on its state.
mysql-test/t/xa.test:
Fix test case to reflect the fact that transactions now hold
metadata locks for the duration of a transaction
(Bug#989/WL#4284).
sql/ha_ndbcluster_binlog.cc:
Backport bits of changes of ha_ndbcluster_binlog.cc
from 6.0, to fix the failing binlog test suite with
WL#4284. WL#4284 implementation does not work
with 5.1 implementation of ndbcluster binlog index.
sql/log_event.cc:
Release metadata locks after issuing a commit.
sql/mdl.cc:
Style changes (WL#4284).
sql/mysql_priv.h:
Rename parameter to match the name used in the definition (WL#4284).
sql/rpl_injector.cc:
Release metadata locks on commit (WL#4284).
sql/rpl_rli.cc:
Remove assert made meaningless, metadata locks are released
at the end of the transaction.
sql/set_var.cc:
Close tables and release locks if autocommit mode is set.
sql/slave.cc:
Release metadata locks after a rollback.
sql/sql_acl.cc:
Don't implicitly unlock locked tables. Issue a implicit commit
at the end and unlock tables.
sql/sql_base.cc:
Defer the release of metadata locks when closing tables
if not required to.
Issue a deadlock error if the locking protocol requires
that a transaction re-acquire its locks.
Release metadata locks when closing tables for reopen.
sql/sql_class.cc:
Release metadata locks if the thread is killed.
sql/sql_parse.cc:
Release metadata locks after implicitly committing a active
transaction, or after explicit commits or rollbacks.
sql/sql_plugin.cc:
Allocate MDL request on the stack as the use of the table
is contained within the function. It will be removed from
the context once close_thread_tables is called at the end
of the function.
sql/sql_prepare.cc:
The problem is that the prepare phase of the CREATE TABLE
statement takes a exclusive metadata lock lock and this can
cause a self-deadlock the thread already holds a shared lock
on the table being that should be created.
The solution is to make the prepare phase take a shared
metadata lock when preparing a CREATE TABLE statement. The
execution of the statement will still acquire a exclusive
lock, but won't cause any problem as it issues a implicit
commit.
After some discussions with stakeholders it has been decided that
metadata locks acquired during a PREPARE statement must be released
once the statement is prepared even if it is prepared within a multi
statement transaction.
sql/sql_servers.cc:
Don't implicitly unlock locked tables. Issue a implicit commit
at the end and unlock tables.
sql/sql_table.cc:
Close table and release metadata locks after a admin operation.
sql/table.h:
The problem is that the prepare phase of the CREATE TABLE
statement takes a exclusive metadata lock lock and this can
cause a self-deadlock the thread already holds a shared lock
on the table being that should be created.
The solution is to make the prepare phase take a shared
metadata lock when preparing a CREATE TABLE statement. The
execution of the statement will still acquire a exclusive
lock, but won't cause any problem as it issues a implicit
commit.
sql/transaction.cc:
Release metadata locks after the implicitly committed due
to a new transaction being started. Also, release metadata
locks acquired after a savepoint if the transaction is rolled
back to the save point.
The problem is that in some cases transaction-long metadata locks
could be released before the transaction was committed. This could
happen when a active transaction was ended by a "START TRANSACTION"
or "BEGIN" statement, in which case the metadata locks would be
released before the actual commit of the active transaction.
The solution is to defer the release of metadata locks to after the
transaction has been implicitly committed. No test case is provided
as the effort to provide one is too disproportional to the size of
the fix.
----------------------------------------------------------
revno: 2617.23.20
committer: Konstantin Osipov <kostja@sun.com>
branch nick: mysql-6.0-runtime
timestamp: Wed 2009-03-04 16:31:31 +0300
message:
WL#4284 "Transactional DDL locking"
Review comments: "Objectify" the MDL API.
MDL_request and MDL_context still need manual construction and
destruction, since they are used in environment that is averse
to constructors/destructors.
sql/mdl.cc:
Improve comments.
Add asserts to backup()/restore_from_backup()/merge() methods.
Fix an order bug in the error path of mdl_acquire_exclusive_locks():
we used to first free a ticket object, and only then exclude
it from the list of tickets.
------------------------------------------------------------
revno: 2617.23.18
committer: Davi Arnaut <Davi.Arnaut@Sun.COM>
branch nick: 4284-6.0
timestamp: Mon 2009-03-02 18:18:26 -0300
message:
Bug#989: If DROP TABLE while there's an active transaction, wrong binlog order
WL#4284: Transactional DDL locking
This is a prerequisite patch:
These changes are intended to split lock requests from granted
locks and to allow the memory and lifetime of granted locks to
be managed within the MDL subsystem. Furthermore, tickets can
now be shared and therefore are used to satisfy multiple lock
requests, but only shared locks can be recursive.
The problem is that the MDL subsystem morphs lock requests into
granted locks locks but does not manage the memory and lifetime
of lock requests, and hence, does not manage the memory of
granted locks either. This can be problematic because it puts the
burden of tracking references on the users of the subsystem and
it can't be easily done in transactional contexts where the locks
have to be kept around for the duration of a transaction.
Another issue is that recursive locks (when the context trying to
acquire a lock already holds a lock on the same object) requires
that each time the lock is granted, a unique lock request/granted
lock structure structure must be kept around until the lock is
released. This can lead to memory leaks in transactional contexts
as locks taken during the transaction should only be released at
the end of the transaction. This also leads to unnecessary wake
ups (broadcasts) in the MDL subsystem if the context still holds
a equivalent of the lock being released.
These issues are exacerbated due to the fact that WL#4284 low-level
design says that the implementation should "2) Store metadata locks
in transaction memory root, rather than statement memory root" but
this is not possible because a memory root, as implemented in mysys,
requires all objects allocated from it to be freed all at once.
This patch combines review input and significant code contributions
from Konstantin Osipov (kostja) and Dmitri Lenev (dlenev).
mysql-test/r/mdl_sync.result:
Add test case result.
mysql-test/t/mdl_sync.test:
Add test case for shared lock upgrade case.
sql/event_db_repository.cc:
Rename mdl_alloc_lock to mdl_request_alloc.
sql/ha_ndbcluster_binlog.cc:
Use new function names to initialize MDL lock requests.
sql/lock.cc:
Rename MDL functions.
sql/log_event.cc:
The MDL request now holds the table and database name data (MDL_KEY).
sql/mdl.cc:
Move the MDL key to the MDL_LOCK structure in order to make the
object suitable for allocation from a fixed-size allocator. This
allows the simplification of the lists in the MDL_LOCK object,
which now are just two, one for granted tickets and other for
waiting (upgraders) tickets.
Recursive requests for a shared lock on the same object can now
be granted using the same lock ticket. This schema is only used
for shared locks because that the only case that matters. This
is used to avoid waste of resources in case a context (connection)
already holds a shared lock on a object.
sql/mdl.h:
Introduce a metadata lock object key which is used to uniquely
identify lock objects.
Separate the structure used to represent pending lock requests
from the structure used to represent granted metadata locks.
Rename functions used to manipulate locks requests in order to
have a more consistent function naming schema.
sql/sp_head.cc:
Rename mdl_alloc_lock to mdl_request_alloc.
sql/sql_acl.cc:
Rename alloc_mdl_locks to alloc_mdl_requests.
sql/sql_base.cc:
Various changes to accommodate that lock requests are separated
from lock tickets (granted locks).
sql/sql_class.h:
Last acquired lock before the savepoint was set.
sql/sql_delete.cc:
Various changes to accommodate that lock requests are separated
from lock tickets (granted locks).
sql/sql_handler.cc:
Various changes to accommodate that lock requests are separated
from lock tickets (granted locks).
sql/sql_insert.cc:
Rename alloc_mdl_locks to alloc_mdl_requests.
sql/sql_parse.cc:
Rename alloc_mdl_locks to alloc_mdl_requests.
sql/sql_plist.h:
Typedef for iterator type.
sql/sql_plugin.cc:
Rename alloc_mdl_locks to alloc_mdl_requests.
sql/sql_servers.cc:
Rename alloc_mdl_locks to alloc_mdl_requests.
sql/sql_show.cc:
Various changes to accommodate that lock requests are separated
from lock tickets (granted locks).
sql/sql_table.cc:
Various changes to accommodate that lock requests are separated
from lock tickets (granted locks).
sql/sql_trigger.cc:
Save reference to the lock ticket so it can be downgraded later.
sql/sql_udf.cc:
Rename alloc_mdl_locks to alloc_mdl_requests.
sql/table.cc:
Rename mdl_alloc_lock to mdl_request_alloc.
sql/table.h:
Separate MDL lock requests from lock tickets (granted locks).
storage/myisammrg/ha_myisammrg.cc:
Rename alloc_mdl_locks to alloc_mdl_requests.
------------------------------------------------------------
revno: 2630.22.3
committer: Davi Arnaut <Davi.Arnaut@Sun.COM>
branch nick: 4284-6.0
timestamp: Thu 2008-08-07 22:33:43 -0300
message:
WL#4284: Transactional DDL locking
Make transaction management more modular through a new interface.
The overall objective of this change is to provide groundwork
for the design of transactional DDL locking by cleaning up the
transaction high level API to better distinguish operations implicit
and explicit, and single statement transaction from operations on
the normal transaction.
Having a a high-level interface for transaction management provides
a better base for implementing transactional concepts that are not
always tied to storage engines and also makes it easier to interect
with other higher level modules of the server.
client/Makefile.am:
Add new file to the build.
libmysqld/CMakeLists.txt:
Add new file to the build.
libmysqld/Makefile.am:
Add new file to the build.
sql/CMakeLists.txt:
Add new file to the build.
sql/Makefile.am:
Add new file to the build.
sql/handler.cc:
Remove multiplexer commit or rollback function. Most callers already
have enough information to decided whether to rollback or commit.
Having plain and well named functions makes it easier to read
and understand code.
sql/handler.h:
Remove wrapper function as the low level transaction functions
shouldn't be called directly anymore.
sql/log_event.cc:
Rename transaction management functions to the new names.
sql/log_event_old.cc:
Rename transaction management functions to the new names.
sql/mysql_priv.h:
Remove obsolete functions for implicit and explicit commit.
sql/rpl_injector.cc:
Rename transaction management functions to the new names.
sql/rpl_rli.cc:
Rename transaction management functions to the new names.
sql/set_var.cc:
Rename transaction management functions to the new names.
sql/slave.cc:
Rename transaction management functions to the new names.
sql/sql_base.cc:
Rename transaction management functions to the new names.
sql/sql_class.cc:
Rename transaction management functions to the new names.
sql/sql_delete.cc:
Rename transaction management functions to the new names.
sql/sql_do.cc:
Rename transaction management functions to the new names.
sql/sql_insert.cc:
Rename transaction management functions to the new names.
sql/sql_parse.cc:
Rename transaction management functions to the new names.
sql/sql_partition.cc:
Rename transaction management functions to the new names.
sql/sql_table.cc:
Rename transaction management functions to the new names.
sql/transaction.cc:
Implement wrapper functions to differentiate operations on
the single statement transaction from the ones operating
on the normal transaction.
sql/transaction.h:
Export new functions for dealing with transaction commands.
----------------------------------------------------------
revno: 2630.4.38
committer: Konstantin Osipov <konstantin@mysql.com>
branch nick: mysql-6.0-4144
timestamp: Wed 2008-06-25 22:07:06 +0400
message:
WL#4144 - Lock MERGE engine children.
Committing a version of the patch merged with WL#3726
on behalf of Ingo.
Step #1: Move locking from parent to children.
MERGE children are now left in the query list of tables
after inserted there in open_tables(). So they are locked
by lock_tables() as all other tables are.
The MERGE parent does not store locks any more. It appears
in a MYSQL_LOCK with zero lock data. This is kind of a "dummy"
lock.
All other lock handling is also done directly on the children.
To protect against parent or child modifications during LOCK
TABLES, the children are detached after every statement and
attached before every statement, even under LOCK TABLES.
The children table list is removed from the query list of tables
on every detach and on close of the parent.
Step #2: Move MERGE specific functionality from SQL layer
into table handler.
Functionality moved from SQL layer (mainly sql_base.cc)
to the table handler (ha_myisammrg.cc).
Unnecessary code is removed from the SQL layer.
Step #3: Moved all MERGE specific members from TABLE
to ha_myisammrg.
Moved members from TABLE to ha_myisammrg.
Renamed some mebers.
Fixed comments.
Step #4: Valgrind and coverage testing
Valgrind did not uncover new problems.
Added purecov comments.
Added a new test for DATA/INDEX DIRECTORY options.
Changed handling of ::reset() for non-attached children.
Fixed the merge-big test.
Step #5: Fixed crashes detected during review
Changed detection when to attach/detach.
Added new tests.
Backport also the fix for Bug#44040 "MySQL allows creating a
MERGE table upon VIEWs but crashes when using it"
include/my_base.h:
WL#4144 - Lock MERGE engine children
Added HA_EXTRA_ADD_CHILDREN_LIST and HA_EXTRA_IS_ATTACHED_CHILDREN
for MERGE table support
mysql-test/r/merge.result:
WL#4144 - Lock MERGE engine children
Fixed test result.
mysql-test/t/disabled.def:
Enable merge.test, which now is working again (WL#4144).
mysql-test/t/merge-big.test:
Fix the messages for wait_condition (merge with WL#3726).
mysql-test/t/merge.test:
WL#4144 - Lock MERGE engine children
Fixed one test to meet coding standards for tests
(upper case keywords, engine names as in SHOW ENGINES).
Fixed error codes.
Added a test for DATA/INDEX DIRECTORY.
mysys/thr_lock.c:
WL#4144 - Lock MERGE engine children
Added purecov comments.
sql/ha_partition.cc:
WL#4144 - Lock MERGE engine children
Added MERGE specific extra operations to ha_partition::extra().
Extended comments.
Changed function comment to doxygen style.
Fixed nomenclature: 'parameter' -> 'operation'.
sql/mysql_priv.h:
WL#4144 - Lock MERGE engine children
Removed declarations for removed functions.
sql/sql_base.cc:
WL#4144 - Lock MERGE engine children
Leave the children in the query list of tables after open_tables().
Set proper back links (prev_global).
Attach MERGE children before and detach them after every
statement. Even under LOCK TABLES.
Remove children from the query list when they are detached.
Remove lock forwarding from children to parent.
Moved MERGE specific functions to ha_myisammrg.cc.
Added purecov comments.
Backport the fix for Bug#44040 "MySQL allows creating a MERGE table upon VIEWs but crashes when using it"
sql/sql_table.cc:
WL#4144 - Lock MERGE engine children
Changed detection of MERGE tables.
sql/table.cc:
WL#4144 - Lock MERGE engine children
Moved is_children_attached() method from TABLE to ha_myisammrg.
sql/table.h:
WL#4144 - Lock MERGE engine children
Moved all MERGE specific members from TABLE to ha_myisammrg.
storage/myisammrg/ha_myisammrg.cc:
WL#4144 - Lock MERGE engine children
Set proper back links in the child list (prev_global).
Added a function for removal of the child list from the query list.
Remove children from the query list when the parent is closed.
Make parent lock handling a dummy (zero locks).
Moved MERGE specific functionality from SQL layer to here.
Moved all MERGE specific members from TABLE to ha_myisammrg.
Renamed children list pointers.
Added initialization and free for the children list mem_root.
Fixed comments.
Added purecov comments.
storage/myisammrg/ha_myisammrg.h:
WL#4144 - Lock MERGE engine children
Added method add_children_list().
Moved all MERGE specific members from TABLE to ha_myisammrg.
Renamed children list pointers.
Added a mem_root for the children list.
storage/myisammrg/myrg_extra.c:
WL#4144 - Lock MERGE engine children
Changed handling of ::reset() for non-attached children.
----------------------------------------------------------
revno: 2630.4.36
committer: Konstantin Osipov <konstantin@mysql.com>
branch nick: mysql-6.0-3726
timestamp: Wed 2008-06-25 17:03:37 +0400
message:
As per discussion with Serg and Dmitri, remove the code
that is trying to emulate LOCK TABLES when locking tables for prelocking.
This code was worked around by the engines, and has no effect.
We may still have to do something to ensure that statement-based
replication is consistent in MVCC engines, or other engines
that downgrade table level locks, but this will have to be done
somehow differently.
sql/sql_base.cc:
Do not try to emulate LOCK TABLES when locking tables for
pre-locking.
------------------------------------------------------------
revno: 2630.4.33
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-6.0-3726-w2
timestamp: Fri 2008-06-20 17:11:20 +0400
message:
WL#3726 "DDL locking for all metadata objects".
After-review fixes in progress.
Minimized dependency of mdl.cc on other modules (particularly
made it independant of mysql_priv.h) in order to be able
write unit tests for metadata locking subsystem.
sql/ha_ndbcluster_binlog.cc:
Use newly introduced MAX_MDLKEY_LENGTH constant for allocating
buffer for object key for metadata locking subsystem.
sql/log_event.cc:
Use newly introduced MAX_MDLKEY_LENGTH constant for allocating
buffer for object key for metadata locking subsystem.
sql/mdl.cc:
Removed dependency on THD class (and thus on mysql_priv.h)
by using direct access to members of st_my_thread_var instead
of accessing THD::killed/enter_cond()/exit_cond().
sql/mdl.h:
Added MAX_MDLKEY_LENGTH constant to be used for allocating
buffers for key for metadata locking subsystem.
Added declarations of server kernel functions used by metadata
locking subsystem to mdl.h in order to decrease dependency of
mdl.cc on other files.
sql/mysql_priv.h:
Moved declaration of notify_thread_having_shared_lock() to the
mdl.h (also renamed it to make clear in metadata locking code
that it is a callback to SQL-layer).
sql/sql_base.cc:
Renamed notify_thread_having_shared_lock() to make it clear
in metadata locking subsystem code that it is a callback
to SQL layer.
sql/sql_handler.cc:
Use newly introduced MAX_MDLKEY_LENGTH constant for allocating
buffer for object key for metadata locking subsystem.
sql/sql_show.cc:
Use newly introduced MAX_MDLKEY_LENGTH constant for allocating
buffer for object key for metadata locking subsystem.
------------------------------------------------------------
revno: 2630.4.32
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-6.0-3726-w2
timestamp: Thu 2008-06-19 16:39:58 +0400
message:
WL#3726 "DDL locking for all metadata objects".
After-review fixes in progress.
Ensure that metadata locking subsystem properly handles
out-of-memory conditions. Clarified MDL interface by
separating release of locks and removal of lock requests
from the context.
sql/lock.cc:
mdl_release_lock(), mdl_acquire_exclusive_locks() and
mdl_try_acquire_exclusive_lock() are no longer responsible
for removal of metadata lock requests from the context.
One should explicitly call mdl_remove_all_locks() and
mdl_remove_lock() to do this.
sql/mdl.cc:
Ensured that metadata locking subsystem properly handles
out-of-memory conditions.
Introduced new MDL_INITIALIZED state for metadata lock
request which is used in all cases when lock is not acquired
and we have not associated request with object respesenting
lock.
MDL_PENDING is now only used for requests for exclusive locks
which are added to the MDL_LOCK::waiting_exclusive queue.
mdl_release_lock(), mdl_acquire_exclusive_locks() and
mdl_try_acquire_exclusive_lock() are no longer responsible
for removal of metadata lock requests from the context.
One should explicitly call mdl_remove_all_locks() and
newly introduced mdl_remove_lock() to do this.
Also renamed mdl_release_all_locks_for_name() to
emphasize that it also actually removes lock requests
from the context.
Finally mdl_try_acquire_exclusive_lock() is now returs
information about encountered lock conflict in separate
out parameter since its return value is used for distinguishing
between error (e.g. due to OOM) and success.
sql/mdl.h:
Introduced new MDL_INITIALIZED state for metadata lock
request which is used in all cases when lock is not acquired
and we have not associated request with object respesenting
lock.
MDL_PENDING is now only used for requests for exclusive locks
which are added to the MDL_LOCK::waiting_exclusive queue.
mdl_release_lock(), mdl_acquire_exclusive_locks() and
mdl_try_acquire_exclusive_lock() are no longer responsible
for removal of metadata lock requests from the context.
One should explicitly call mdl_remove_all_locks() and
newly introduced mdl_remove_lock() to do this.
Also renamed mdl_release_all_locks_for_name() to
emphasize that it also actually removes lock requests
from the context.
Finally mdl_try_acquire_exclusive_lock() is now returs
information about encountered lock conflict in separate
out parameter since its return value is used for distinguishing
between error (e.g. due to OOM) and success.
sql/sql_base.cc:
mdl_release_lock(), mdl_acquire_exclusive_locks() and mdl_try_acquire_exclusive_lock() are no longer responsible
for removal of metadata lock requests from the context.
One should explicitly call mdl_remove_all_locks() and
mdl_remove_lock() to do this.
Also adjusted open_table() to ensure that it
releases/removes metadata locks in case of error
after adding/acquiring them (unless keeping these
lock requests is required for recovering action).
sql/sql_delete.cc:
mdl_release_lock(), mdl_acquire_exclusive_locks() and mdl_try_acquire_exclusive_lock() are no longer responsible
for removal of metadata lock requests from the context.
One should explicitly call mdl_remove_all_locks() and
mdl_remove_lock() to do this.
sql/sql_handler.cc:
mdl_release_lock(), mdl_acquire_exclusive_locks() and mdl_try_acquire_exclusive_lock() are no longer responsible
for removal of metadata lock requests from the context.
One should explicitly call mdl_remove_all_locks() and
mdl_remove_lock() to do this.
sql/sql_show.cc:
mdl_release_lock(), mdl_acquire_exclusive_locks() and mdl_try_acquire_exclusive_lock() are no longer responsible
for removal of metadata lock requests from the context.
One should explicitly call mdl_remove_all_locks() and
mdl_remove_lock() to do this.
sql/sql_table.cc:
Renamed mdl_release_all_locks_for_name() to emphasize
that it also actually removes lock requests from the context.
mdl_release_lock(), mdl_acquire_exclusive_locks() and mdl_try_acquire_exclusive_lock() are no longer responsible
for removal of metadata lock requests from the context.
One should explicitly call mdl_remove_all_locks() and
mdl_remove_lock() to do this.
Finally mdl_try_acquire_exclusive_lock() is now returs
information about encountered lock conflict in separate
out parameter since its return value is used for distinguishing
between error (e.g. due to OOM) and success.
----------------------------------------------------------
revno: 2630.4.31
committer: Konstantin Osipov <konstantin@mysql.com>
branch nick: mysql-6.0-3726
timestamp: Thu 2008-06-12 06:23:08 +0400
message:
Extend the signature of TABLE_LIST::init_one_table() to
initialize lengths
This is part of WL#3726 post-review fixes.