Commit graph

69 commits

Author SHA1 Message Date
Jon Olav Hauglid
7fd30bf610 Bug #51240 ALTER TABLE of a locked MERGE table fails
The problem was that ALTER TABLE on a merge table which was locked 
using LOCK TABLE ... WRITE, by mistake gave 
ER_TABLE_NOT_LOCKED_FOR_WRITE.

During opening of the table to be ALTERed, open_table() tried to
get an upgradable metadata lock. In LOCK TABLEs mode, this lock
must already exist (i.e. taken by LOCK TABLE) as new locks of this
type cannot be acquired for fear of deadlock. So in LOCK TABLEs
mode, open_table() tried to find an existing upgradable lock for
the table to be altered.

The problem was that open_table() also tried to find upgradable
metadata locks for children of merge tables even if no such
locks are needed to execute ALTER TABLE on merge tables.

This patch fixes the problem by making sure that open tables code
only searches for upgradable metadata locks for the merge table
and not for the merge children tables. 

The patch also fixes a related bug where an upgradable metadata
lock was aquired outside of LOCK TABLEs mode even if the table in
question was temporary. This bug meant that LOCK TABLES or DDL on
temporary tables by mistake could be blocked/aborted by locks held
on base tables with the same table name by other connections.

Test cases added to merge.test and lock_multi.test.
2010-02-26 13:40:25 +01:00
Dmitry Lenev
eb0f09712e Fix for bug #51134 "Crash in MDL_lock::destroy on a concurrent
DDL workload".

When a RENAME TABLE or LOCK TABLE ... WRITE statement which
mentioned the same table several times were aborted during 
the process of acquring metadata locks (due to deadlock 
which was discovered or because of KILL statement) server 
might have crashed.

When attempt to acquire all locks requested had failed we
went through the list of requests and released locks which
we have managed to acquire by that moment one by one. Since 
in the scenario described above list of requests contained 
duplicates this led to releasing the same ticket twice and 
a crash as result.

This patch solves the problem by employing different approach
to releasing locks in case of failure to acquire all locks
requested. 
Now we take a MDL savepoint before starting acquiring locks 
and simply rollback to it if things go bad.

mysql-test/r/lock_multi.result:
  Updated test results (see lock_multi.test).
mysql-test/t/lock_multi.test:
  Added test case for bug #51134 "Crash in MDL_lock::destroy
  on a concurrent DDL workload".
sql/mdl.cc:
  MDL_context::acquire_locks():
    When attempt to acquire all locks requested has failed do
    not go through the list of requests and release locks which
    we have managed to acquire one by one. 
    Since list of requests can contain duplicates such approach
    may lead to releasing the same ticket twice and a crash as
    result.
    Instead use the following approach - take a MDL savepoint
    before starting acquiring locks and simply rollback to it
    if things go bad.
2010-02-15 13:23:34 +03:00
Jon Olav Hauglid
3d6a89e792 Bug #45225 Locking: hang if drop table with no timeout
This patch introduces timeouts for metadata locks. 

The timeout is specified in seconds using the new dynamic system 
variable  "lock_wait_timeout" which has both GLOBAL and SESSION
scopes. Allowed values range from 1 to 31536000 seconds (= 1 year). 
The default value is 1 year.

The new server parameter "lock-wait-timeout" can be used to set
the default value parameter upon server startup.

"lock_wait_timeout" applies to all statements that use metadata locks.
These include DML and DDL operations on tables, views, stored procedures
and stored functions. They also include LOCK TABLES, FLUSH TABLES WITH
READ LOCK and HANDLER statements.

The patch also changes thr_lock.c code (table data locks used by MyISAM
and other simplistic engines) to use the same system variable.
InnoDB row locks are unaffected.

One exception to the handling of the "lock_wait_timeout" variable
is delayed inserts. All delayed inserts are executed with a timeout
of 1 year regardless of the setting for the global variable. As the
connection issuing the delayed insert gets no notification of 
delayed insert timeouts, we want to avoid unnecessary timeouts.

It's important to note that the timeout value is used for each lock
acquired and that one statement can take more than one lock.
A statement can therefore block for longer than the lock_wait_timeout 
value before reporting a timeout error. When lock timeout occurs, 
ER_LOCK_WAIT_TIMEOUT is reported.

Test case added to lock_multi.test.


include/my_pthread.h:
  Added macros for comparing two timespec structs.
include/thr_lock.h:
  Introduced timeouts for thr_lock.c locks.
mysql-test/r/mysqld--help-notwin.result:
  Updated result file with the new server variable.
mysql-test/r/mysqld--help-win.result:
  Updated result file with the new server variable.
mysql-test/suite/sys_vars/r/lock_wait_timeout_basic.result:
  Added basic test for the new server variable.
mysql-test/suite/sys_vars/t/lock_wait_timeout_basic.test:
  Added basic test for the new server variable.
mysys/thr_lock.c:
  Introduced timeouts for thr_lock.c locks.
sql/mdl.cc:
  Introduced timeouts for metadata locks.
sql/mdl.h:
  Introduced timeouts for metadata locks.
sql/sql_base.cc:
  Introduced timeouts in tdc_wait_for_old_versions().
sql/sql_class.h:
  Added new server variable lock_wait_timeout.
sql/sys_vars.cc:
  Added new server variable lock_wait_timeout.
2010-02-11 11:23:39 +01:00
Dmitry Lenev
8018ec5adb Fix for bug #50913 "Deadlock between open_and_lock_tables_derived
and MDL".

Concurrent execution of a multi-DELETE statement and ALTER
TABLE statement which affected one of the tables used in
the multi-DELETE sometimes led to deadlock.
Similar deadlocks might have occured when one performed
INSERT/UPDATE/DELETE on a view and concurrently executed
ALTER TABLE for the view's underlying table, or when one
concurrently executed TRUNCATE TABLE for InnoDB table and
ALTER TABLE for the same table.

These deadlocks were caused by a discrepancy between types of
metadata and thr_lock.cc locks acquired by those statements.

What happened was that multi-DELETE/TRUNCATE/DML-through-the-
view statement in the first connection acquired SR lock on a
table, then ALTER TABLE would come in in the second connection
and acquire SNW metadata lock and TL_WRITE_ALLOW_READ
thr_lock.c lock and then would start waiting for the first
connection during lock upgrade. After that the statement in
the first connection would try to acquire TL_WRITE lock on
table and would start waiting for the second connection,
creating a deadlock.

This patch solves this problem by ensuring that we acquire
SW metadata lock in all cases in which we acquiring write
thr_lock.c lock. This guarantees that deadlocks like the
one described above won't occur since all lock conflicts
in such situation are resolved within MDL subsystem.

This patch also adds assert which should guarantee that
such situations won't arise in future.

mysql-test/r/lock_multi.result:
  Added main test for bug #50913 "Deadlock between
  open_and_lock_tables_derived and MDL".
mysql-test/r/mdl_sync.result:
  Added additional coverage for bug #50913 "Deadlock
  between open_and_lock_tables_derived and MDL".
mysql-test/t/lock_multi.test:
  Added main test for bug #50913 "Deadlock between
  open_and_lock_tables_derived and MDL".
mysql-test/t/mdl_sync.test:
  Added additional coverage for bug #50913 "Deadlock
  between open_and_lock_tables_derived and MDL".
sql/lock.cc:
  Added assert that enforces that when we are locking
  a non-temporary table we have an appropriate type of
  metadata lock on this table.
sql/mysql_priv.h:
  Added separate flag for open_tables() to be able specify that
  SH metadata locks on table to be open should be acquired.
  We can no longer use MYSQL_LOCK_IGNORE_FLUSH flag for this
  as in addition to use in I_S implementation it is also used
  for opening system tables. Since in the latter case we also
  acquire thr_lock.c locks using SH metadata lock in it instead
  of SR or SW locks may lead to deadlock.
sql/sql_base.cc:
  When opening tables don't interpret MYSQL_LOCK_IGNORE_FLUSH
  flag as request to acquire SH metadata locks. This flag is
  also used for opening system tables for which we also take
  thr_lock.c locks and thus proper metadata lock to take in
  this case is SR or SW lock (otherwise deadlocks can occur).
  In cases when SH lock is really required (e.g. when tables
  are open by I_S implementation) we rely on that newly
  introduced MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL flag is
  used.
sql/sql_delete.cc:
  mysql_truncate_by_delete():
    Adjust type of metadata lock to be requested after changing
    type of thr_lock.c lock for table list element from one
    which was set in parser to TL_WRITE.
    This removes discrepancy between types of these locks which
    allowed deadlocks to creep in.
sql/sql_handler.cc:
  When closing table which was open by HANDLER statement clear
  TABLE::open_by_handler flag. This allows to use this flag as
  a reliable indication that TABLE instance was open by HANDLER
  statement in assert which was added to mysql_lock_tables().
sql/sql_parse.cc:
  multi_delete_set_locks_and_link_aux_tables():
    Adjust type of metadata lock to be requested after changing
    type of thr_lock.c lock for table list element from one
    which was set in parser to TL_WRITE.
    This removes discrepancy between types of these locks which
    allowed deadlocks to creep in.
sql/sql_show.cc:
  Use newly introduced MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL
  flag in order to acquire SH metadata locks when opening tables
  in I_S implementation.
sql/sql_update.cc:
  Added comment explaining why in multi-update after deciding
  that we need weaker thr_lock.c lock on a table we don't
  downgrade metadata lock on it.
sql/sql_view.cc:
  When merging view into main statement adjust type of metadata
  lock to be requested after changing type of thr_lock.c lock
  for table. This removes discrepancy between types of these
  locks which allowed deadlocks to creep in.
2010-02-08 23:19:55 +03:00
Konstantin Osipov
c6c1ddabaf Merge next-mr -> next-4284. 2010-02-02 12:22:17 +03:00
Dmitry Lenev
eba5d30e67 Implement new type-of-operation-aware metadata locks.
Add a wait-for graph based deadlock detector to the
MDL subsystem.

Fixes bug #46272 "MySQL 5.4.4, new MDL: unnecessary deadlock" and
bug #37346 "innodb does not detect deadlock between update and
alter table".

The first bug manifested itself as an unwarranted abort of a
transaction with ER_LOCK_DEADLOCK error by a concurrent ALTER
statement, when this transaction tried to repeat use of a
table, which it has already used in a similar fashion before
ALTER started.

The second bug showed up as a deadlock between table-level
locks and InnoDB row locks, which was "detected" only after
innodb_lock_wait_timeout timeout.

A transaction would start using the table and modify a few
rows.
Then ALTER TABLE would come in, and start copying rows
into a temporary table. Eventually it would stumble on
the modified records and get blocked on a row lock.
The first transaction would try to do more updates, and get
blocked on thr_lock.c lock.
This situation of circular wait would only get resolved
by a timeout.

Both these bugs stemmed from inadequate solutions to the
problem of deadlocks occurring between different
locking subsystems.

In the first case we tried to avoid deadlocks between metadata
locking and table-level locking subsystems, when upgrading shared
metadata lock to exclusive one.
Transactions holding the shared lock on the table and waiting for
some table-level lock used to be aborted too aggressively.

We also allowed ALTER TABLE to start in presence of transactions
that modify the subject table. ALTER TABLE acquires
TL_WRITE_ALLOW_READ lock at start, and that block all writes
against the table (naturally, we don't want any writes to be lost
when switching the old and the new table). TL_WRITE_ALLOW_READ
lock, in turn, would block the started transaction on thr_lock.c
lock, should they do more updates. This, again, lead to the need
to abort such transactions.

The second bug occurred simply because we didn't have any
mechanism to detect deadlocks between the table-level locks
in thr_lock.c and row-level locks in InnoDB, other than
innodb_lock_wait_timeout.

This patch solves both these problems by moving lock conflicts
which are causing these deadlocks into the metadata locking
subsystem, thus making it possible to avoid or detect such
deadlocks inside MDL.

To do this we introduce new type-of-operation-aware metadata
locks, which allow MDL subsystem to know not only the fact that
transaction has used or is going to use some object but also what
kind of operation it has carried out or going to carry out on the
object.

This, along with the addition of a special kind of upgradable
metadata lock, allows ALTER TABLE to wait until all
transactions which has updated the table to go away.
This solves the second issue.
Another special type of upgradable metadata lock is acquired
by LOCK TABLE WRITE. This second lock type allows to solve the
first issue, since abortion of table-level locks in event of
DDL under LOCK TABLES becomes also unnecessary.

Below follows the list of incompatible changes introduced by
this patch:

- From now on, ALTER TABLE and CREATE/DROP TRIGGER SQL (i.e. those
  statements that acquire TL_WRITE_ALLOW_READ lock)
  wait for all transactions which has *updated* the table to
  complete.

- From now on, LOCK TABLES ... WRITE, REPAIR/OPTIMIZE TABLE
  (i.e. all statements which acquire TL_WRITE table-level lock) wait
  for all transaction which *updated or read* from the table
  to complete.
  As a consequence, innodb_table_locks=0 option no longer applies
  to LOCK TABLES ... WRITE.

- DROP DATABASE, DROP TABLE, RENAME TABLE no longer abort
  statements or transactions which use tables being dropped or
  renamed, and instead wait for these transactions to complete.

- Since LOCK TABLES WRITE now takes a special metadata lock,
  not compatible with with reads or writes against the subject table
  and transaction-wide, thr_lock.c deadlock avoidance algorithm
  that used to ensure absence of deadlocks between LOCK TABLES
  WRITE and other statements is no longer sufficient, even for
  MyISAM. The wait-for graph based deadlock detector of MDL
  subsystem may sometimes be necessary and is involved. This may
  lead to ER_LOCK_DEADLOCK error produced for multi-statement
  transactions even if these only use MyISAM:

  session 1:         session 2:
  begin;

  update t1 ...      lock table t2 write, t1 write;
                     -- gets a lock on t2, blocks on t1

  update t2 ...
  (ER_LOCK_DEADLOCK)

- Finally,  support of LOW_PRIORITY option for LOCK TABLES ... WRITE
  was abandoned.
  LOCK TABLE ... LOW_PRIORITY WRITE from now on has the same
  priority as the usual LOCK TABLE ... WRITE.
  SELECT HIGH PRIORITY no longer trumps LOCK TABLE ... WRITE  in
  the wait queue.

- We do not take upgradable metadata locks on implicitly
  locked tables. So if one has, say, a view v1 that uses
  table t1, and issues:
  LOCK TABLE v1 WRITE;
  FLUSH TABLE t1; -- (or just 'FLUSH TABLES'),
  an error is produced.
  In order to be able to perform DDL on a table under LOCK TABLES,
  the table must be locked explicitly in the LOCK TABLES list.

mysql-test/include/handler.inc:
  Adjusted test case to trigger an execution path on which bug 41110
  "crash with handler command when used concurrently with alter
  table" and bug 41112 "crash in mysql_ha_close_table/get_lock_data
  with alter table" were originally discovered. Left old test case
  which no longer triggers this execution path for the sake of
  coverage.
  Added test coverage for HANDLER SQL statements and type-aware
  metadata locks.
  Added a test for the global shared lock and HANDLER SQL.
  Updated tests to take into account that the old simple deadlock
  detection heuristics was replaced with a graph-based deadlock
  detector.
mysql-test/r/debug_sync.result:
  Updated results (see debug_sync.test).
mysql-test/r/handler_innodb.result:
  Updated results (see handler.inc test).
mysql-test/r/handler_myisam.result:
  Updated results (see handler.inc test).
mysql-test/r/innodb-lock.result:
  Updated results (see innodb-lock.test).
mysql-test/r/innodb_mysql_lock.result:
  Updated results (see innodb_mysql_lock.test).
mysql-test/r/lock.result:
  Updated results (see lock.test).
mysql-test/r/lock_multi.result:
  Updated results (see lock_multi.test).
mysql-test/r/lock_sync.result:
  Updated results (see lock_sync.test).
mysql-test/r/mdl_sync.result:
  Updated results (see mdl_sync.test).
mysql-test/r/sp-threads.result:
  SHOW PROCESSLIST output has changed due to the fact that waiting
  for LOCK TABLES WRITE now happens within metadata locking
  subsystem.
mysql-test/r/truncate_coverage.result:
  Updated results (see truncate_coverage.test).
mysql-test/suite/funcs_1/datadict/processlist_val.inc:
  SELECT FROM I_S.PROCESSLIST output has changed due to fact that
  waiting for LOCK TABLES WRITE now happens within metadata locking
  subsystem.
mysql-test/suite/funcs_1/r/processlist_val_no_prot.result:
  SELECT FROM I_S.PROCESSLIST output has changed due to fact that
  waiting for LOCK TABLES WRITE now happens within metadata locking
  subsystem.
mysql-test/suite/rpl/t/rpl_sp.test:
  Updated to a new SHOW PROCESSLIST state name.
mysql-test/t/debug_sync.test:
  Use LOCK TABLES READ instead of LOCK TABLES WRITE as the latter
  no longer allows to trigger execution path involving waiting on
  thr_lock.c lock and therefore reaching debug sync-point covered
  by this test.
mysql-test/t/innodb-lock.test:
  Adjusted test case to the fact that innodb_table_locks=0 option is
  no longer supported, since LOCK TABLES WRITE handles all its
  conflicts within MDL subsystem.
mysql-test/t/innodb_mysql_lock.test:
  Added test for bug #37346 "innodb does not detect deadlock between
  update and alter table".
mysql-test/t/lock.test:
  Added test coverage which checks the fact that we no longer support
  DDL under LOCK TABLES on tables which were locked implicitly.
  Adjusted existing test cases accordingly.
mysql-test/t/lock_multi.test:
  Added test for bug #46272 "MySQL 5.4.4, new MDL: unnecessary
  deadlock".  Adjusted other test cases to take into account the
  fact that waiting for LOCK TABLES ... WRITE now happens within MDL
  subsystem.
mysql-test/t/lock_sync.test:
  Since LOCK TABLES ... WRITE now takes SNRW metadata lock for
  tables locked explicitly we have to implicitly lock InnoDB tables
  (through view) to trigger the table-level lock conflict between
  TL_WRITE and TL_WRITE_ALLOW_WRITE.
mysql-test/t/mdl_sync.test:
  Added basic test coverage for type-of-operation-aware metadata
  locks. Also covered with tests some use cases involving HANDLER
  statements in which a deadlock could arise.
  Adjusted existing tests to take type-of-operation-aware MDL into
  account.
mysql-test/t/multi_update.test:
  Update to a new SHOW PROCESSLIST state name.
mysql-test/t/truncate_coverage.test:
  Adjusted test case after making LOCK TABLES WRITE to wait until
  transactions that use the table to be locked are completed.
  Updated to the changed name of DEBUG_SYNC point.
sql/handler.cc:
  Global read lock functionality has been
  moved into a class.
sql/lock.cc:
  Global read lock functionality has been
  moved into a class.
  Updated code to use the new MDL API.
sql/mdl.cc:
  Introduced new type-of-operation aware metadata locks.
  To do this:
  - Changed MDL_lock to use one list for waiting requests and one
    list for granted requests. For each list, added a bitmap
    that holds information what lock types a list contains.
    Added a helper class MDL_lock::List to manipulate with granted
    and waited lists while keeping the bitmaps in sync
    with list contents.
  - Changed lock-compatibility functions to use bitmaps that
    define compatibility.
  - Introduced a graph based deadlock detector inspired by
    waiting_threads.c from Maria implementation.
  - Now that we have a deadlock detector, and no longer have
    a global lock to protect individual lock objects, but rather
    use an rw lock per object, removed redundant code for upgrade,
    and the global read lock. Changed the MDL API to
    no longer require the caller to acquire the global
    intention exclusive lock by means of a separate method.
    Removed a few more methods that became redundant.
  - Removed deadlock detection heuristic, it has been made
    obsolete by the deadlock detector.
  - With operation-type-aware metadata locks, MDL subsystem has
    become aware of potential conflicts between DDL and open
    transactions. This made it possible to remove calls to
    mysql_abort_transactions_with_shared_lock() from acquisition
    paths for exclusive lock and lock upgrade. Now we can simply
    wait for these transactions to complete without fear of
    deadlock. Function mysql_lock_abort() has also become
    unnecessary for all conflicting cases except when a DDL
    conflicts with a connection that has an open HANDLER.
sql/mdl.h:
  Introduced new type-of-operation aware metadata locks.
  Introduced a graph based deadlock detector and supporting
  methods.
  Added comments.
  God rid of redundant API calls.
  Renamed m_lt_or_ha_sentinel to m_trans_sentinel,
  since now it guards the global read lock as well as
  LOCK TABLES and HANDLER locks.
sql/mysql_priv.h:
  Moved the global read lock functionality into a
  class.
  Added MYSQL_OPEN_FORCE_SHARED_MDL flag which forces
  open_tables() to take MDL_SHARED on tables instead of
  metadata locks specified in the parser. We use this to
  allow PREPARE run concurrently in presence of
  LOCK TABLES ... WRITE.
  Added signature for find_table_for_mdl_ugprade().
sql/set_var.cc:
  Global read lock functionality has been
  moved into a class.
sql/sp_head.cc:
  When creating TABLE_LIST elements for prelocking or
  system tables set the type of request for metadata
  lock according to the operation that will be performed
  on the table.
sql/sql_base.cc:
  - Updated code to use the new MDL API.
  - In order to avoid locks starvation we take upgradable
    locks all at once. As result implicitly locked tables no
    longer get an upgradable lock. Consequently DDL and FLUSH
    TABLES for such tables is prohibited.
    find_write_locked_table() was replaced by
    find_table_for_mdl_upgrade() function.
    open_table() was adjusted to return TABLE instance with
    upgradable ticket when necessary.
  - We no longer wait for all locks on OT_WAIT back off
    action -- only on the lock that caused the wait
    conflict. Moreover, now we distinguish cases when we
    have to wait due to conflict in MDL and old version
    of table in TDC.
  - Upate mysql_notify_threads_having_share_locks()
    to only abort thr_lock.c waits of threads that
    have open HANDLERs, since lock conflicts with only
    these threads now can lead to deadlocks not detectable
    by the MDL deadlock detector.
  - Remove mysql_abort_transactions_with_shared_locks()
    which is no longer needed.
sql/sql_class.cc:
  Global read lock functionality has been moved into a class.
  Re-arranged code in THD::cleanup() to simplify assert.
sql/sql_class.h:
  Introduced class to incapsulate global read lock
  functionality.
  Now sentinel in MDL subsystem guards the global read lock
  as well as LOCK TABLES and HANDLER locks. Adjusted code
  accordingly.
sql/sql_db.cc:
  Global read lock functionality has been moved into a class.
sql/sql_delete.cc:
  We no longer acquire upgradable metadata locks on tables
  which are locked by LOCK TABLES implicitly. As result
  TRUNCATE TABLE is no longer allowed for such tables.
  Updated code to use the new MDL API.
sql/sql_handler.cc:
  Inform MDL_context about presence of open HANDLERs.
  Since HANLDERs break MDL protocol by acquiring table-level
  lock while holding only S metadata lock on a table MDL
  subsystem should take special care about such contexts (Now
  this is the only case when mysql_lock_abort() is used).
sql/sql_parse.cc:
  Global read lock functionality has been moved into a class.
  Do not take upgradable metadata locks when opening tables
  for CREATE TABLE SELECT as it is not necessary and limits
  concurrency.
  When initializing TABLE_LIST objects before adding them
  to the table list set the type of request for metadata lock
  according to the operation that will be performed on the
  table.
  We no longer acquire upgradable metadata locks on tables
  which are locked by LOCK TABLES implicitly. As result FLUSH
  TABLES is no longer allowed for such tables.
sql/sql_prepare.cc:
  Use MYSQL_OPEN_FORCE_SHARED_MDL flag when opening
  tables during PREPARE. This allows PREPARE to run
  concurrently in presence of LOCK TABLES ... WRITE.
sql/sql_rename.cc:
  Global read lock functionality has been moved into a class.
sql/sql_show.cc:
  Updated code to use the new MDL API.
sql/sql_table.cc:
  Global read lock functionality has been moved into a class.
  We no longer acquire upgradable metadata locks on tables
  which are locked by LOCK TABLES implicitly. As result DROP
  TABLE is no longer allowed for such tables.
  Updated code to use the new MDL API.
sql/sql_trigger.cc:
  Global read lock functionality has been moved into a class.
  We no longer acquire upgradable metadata locks on tables
  which are locked by LOCK TABLES implicitly. As result
  CREATE/DROP TRIGGER is no longer allowed for such tables.
  Updated code to use the new MDL API.
sql/sql_view.cc:
  Global read lock functionality has been moved into a class.
  Fixed results of wrong merge that led to misuse of GLR API.
  CREATE VIEW statement is not a commit statement.
sql/table.cc:
  When resetting TABLE_LIST objects for PS or SP re-execution
  set the type of request for metadata lock according to the
  operation that will be performed on the table. Do the same
  in auxiliary function initializing metadata lock requests
  in a table list.
sql/table.h:
  When initializing TABLE_LIST objects set the type of request
  for metadata lock according to the operation that will be
  performed on the table.
sql/transaction.cc:
  Global read lock functionality has been moved into a class.
2010-02-01 14:43:06 +03:00
Mikael Ronstrom
efc20b24fc Post-merge fix: wait for statement result before disconnecting. Otherwise the statement might affect unrelated tests. mysql-test/t/lock_multi.test, Reap statement status 2009-12-19 08:37:08 +01:00
Jon Olav Hauglid
5e1dfa4c06 Backport of revno: 2617.71.1
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.
2009-12-10 11:53:20 +01:00
Jon Olav Hauglid
fcae99271a Backport of revno: 2617.68.39
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.
2009-12-09 10:44:01 +01:00
Konstantin Osipov
cd155be564 Backport of:
------------------------------------------------------------
revno: 3035.4.1
committer: Davi Arnaut <Davi.Arnaut@Sun.COM>
branch nick: 39897-6.0
timestamp: Thu 2009-01-15 12:17:57 -0200
message:
Bug#39897: lock_multi fails in pushbuild: timeout waiting for processlist

The problem is that relying on the "Table lock" thread state in
its current position to detect that a thread is waiting on a lock
is race prone. The "Table lock" state change happens before the
thread actually tries to grab a lock on a table.

The solution is to move the "Table lock" state so that its set
only when a thread is actually going to wait for a lock. The state
change happens after the thread fails to grab the lock (because it
is owned by other thread) and proceeds to wait on a condition.

This is considered part of work related to WL#4284 "Transactional
DDL locking"
Warning: this patch contains an incompatible change. 
When waiting on a lock in thr_lock.c, the server used to display "Locked"
processlist state. After this patch, the state is "Table lock".
The new state was actually intended to be display since year 2002,
when Monty added it. But up until removal of thd->locked boolean
member, this state was ignored by SHOW PROCESSLIST code.  

mysql-test/r/lock_multi.result:
  A style fix.
mysql-test/r/sp-threads.result:
  Changed output of SHOW PROCESSLIST (new wait state).
mysql-test/t/lock_multi.test:
  Use a more accurate state description when waiting inside thr_lock.c.
mysql-test/t/lock_sync.test:
  Use a more accurate state description when waiting inside thr_lock.c.
mysql-test/t/multi_update.test:
  Use a more accurate state description when waiting inside thr_lock.c.
mysql-test/t/query_cache_28249.test:
  Use a more accurate state description when waiting inside thr_lock.c.
mysql-test/t/sp_notembedded.test:
  Use a more accurate state description when waiting inside thr_lock.c.
mysql-test/t/status.test:
  Use a more accurate state description when waiting inside thr_lock.c.
mysys/thr_lock.c:
  Update thread state while waiting for a table lock.
sql/lock.cc:
  State change was moved inside thr_lock.c.
2009-12-03 23:08:27 +03:00
Konstantin Osipov
eff3780dd8 Initial import of WL#3726 "DDL locking for all metadata objects".
Backport of:
------------------------------------------------------------
revno: 2630.4.1
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-6.0-3726-w
timestamp: Fri 2008-05-23 17:54:03 +0400
message:
  WL#3726 "DDL locking for all metadata objects".

  After review fixes in progress.
------------------------------------------------------------

This is the first patch in series. It transforms the metadata 
locking subsystem to use a dedicated module (mdl.h,cc). No 
significant changes in the locking protocol. 
The import passes the test suite with the exception of 
deprecated/removed 6.0 features, and MERGE tables. The latter
are subject to a fix by WL#4144.
Unfortunately, the original changeset comments got lost in a merge,
thus this import has its own (largely insufficient) comments.

This patch fixes Bug#25144 "replication / binlog with view breaks".
Warning: this patch introduces an incompatible change:
Under LOCK TABLES, it's no longer possible to FLUSH a table that 
was not locked for WRITE.
Under LOCK TABLES, it's no longer possible to DROP a table or
VIEW that was not locked for WRITE.

******
Backport of:
------------------------------------------------------------
revno: 2630.4.2
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-6.0-3726-w
timestamp: Sat 2008-05-24 14:03:45 +0400
message:
  WL#3726 "DDL locking for all metadata objects".

  After review fixes in progress.

******
Backport of:
------------------------------------------------------------
revno: 2630.4.3
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-6.0-3726-w
timestamp: Sat 2008-05-24 14:08:51 +0400
message:
  WL#3726 "DDL locking for all metadata objects"

  Fixed failing Windows builds by adding mdl.cc to the lists
  of files needed to build server/libmysqld on Windows.

******
Backport of:
------------------------------------------------------------
revno: 2630.4.4
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-6.0-3726-w
timestamp: Sat 2008-05-24 21:57:58 +0400
message:
  WL#3726 "DDL locking for all metadata objects".

  Fix for assert failures in kill.test which occured when one
  tried to kill ALTER TABLE statement on merge table while it
  was waiting in wait_while_table_is_used() for other connections
  to close this table.

  These assert failures stemmed from the fact that cleanup code
  in this case assumed that temporary table representing new
  version of table was open with adding to THD::temporary_tables
  list while code which were opening this temporary table wasn't
  always fulfilling this.

  This patch changes code that opens new version of table to
  always do this linking in. It also streamlines cleanup process
  for cases when error occurs while we have new version of table
  open.

******
WL#3726 "DDL locking for all metadata objects"
Add libmysqld/mdl.cc to .bzrignore.
******
Backport of:
------------------------------------------------------------
revno: 2630.4.6
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-6.0-3726-w
timestamp: Sun 2008-05-25 00:33:22 +0400
message:
  WL#3726 "DDL locking for all metadata objects".

  Addition to the fix of assert failures in kill.test caused by
  changes for this worklog.


Make sure we close the new table only once.

.bzrignore:
  Add libmysqld/mdl.cc
libmysqld/CMakeLists.txt:
  Added mdl.cc to the list of files needed for building of libmysqld.
libmysqld/Makefile.am:
  Added files implementing new meta-data locking subsystem to the server.
mysql-test/include/handler.inc:
  Use separate connection for waiting while threads performing DDL
  operations conflicting with open HANDLER tables reach blocked
  state. This is required because now we check and close tables open
  by HANDLER statements in this connection conflicting with DDL in
  another each time open_tables() is called and thus select from I_S
  which is used for waiting will unblock DDL operations if issued
  from connection with open HANDLERs.
mysql-test/r/create.result:
  Adjusted test case after change in implementation of CREATE TABLE
  ... SELECT.  We no longer have special check in open_table() which
  catches the case when we select from the table created. Instead we
  rely on unique_table() call which happens after opening and
  locking all tables.
mysql-test/r/flush.result:
  FLUSH TABLES WITH READ LOCK can no longer happen under LOCK
  TABLES.  Updated test accordingly.
mysql-test/r/flush_table.result:
  Under LOCK TABLES we no longer allow to do FLUSH TABLES for tables
  locked for read. Updated test accordingly.
mysql-test/r/handler_innodb.result:
  Use separate connection for waiting while threads performing DDL
  operations conflicting with open HANDLER tables reach blocked
  state. This is required because now we check and close tables open
  by HANDLER statements in this connection conflicting with DDL in
  another each time open_tables() is called and thus select from I_S
  which is used for waiting will unblock DDL operations if issued
  from connection with open HANDLERs.
mysql-test/r/handler_myisam.result:
  Use separate connection for waiting while threads performing DDL
  operations conflicting with open HANDLER tables reach blocked
  state. This is required because now we check and close tables open
  by HANDLER statements in this connection conflicting with DDL in
  another each time open_tables() is called and thus select from I_S
  which is used for waiting will unblock DDL operations if issued
  from connection with open HANDLERs.
mysql-test/r/information_schema.result:
  Additional test for WL#3726 "DDL locking for all metadata
  objects".  Check that we use high-priority metadata lock requests
  when filling I_S tables.
  
  Rearrange tests to match 6.0 better (fewer merge conflicts).
mysql-test/r/kill.result:
  Added tests checking that DDL and DML statements waiting for
  metadata locks can be interrupted by KILL command.
mysql-test/r/lock.result:
  One no longer is allowed to do DROP VIEW under LOCK TABLES even if
  this view is locked by LOCK TABLES. The problem is that in such
  situation write locks on view are not mutually exclusive so
  upgrading metadata lock which is required for dropping of view
  will lead to deadlock.
mysql-test/r/partition_column_prune.result:
  Update results (same results in 6.0), WL#3726
mysql-test/r/partition_pruning.result:
  Update results (same results in 6.0), WL#3726
mysql-test/r/ps_ddl.result:
  We no longer invalidate prepared CREATE TABLE ... SELECT statement
  if target table changes. This is OK since it is not strictly
  necessary.
  
  
  The first change is wrong, is caused by FLUSH TABLE
  now flushing all unused tables. This is a regression that
  Dmitri fixed in 6.0 in a follow up patch.
mysql-test/r/sp.result:
  Under LOCK TABLES we no longer allow accessing views which were
  not explicitly locked. To access view we need to obtain metadata
  lock on it and doing this under LOCK TABLES may lead to deadlocks.
mysql-test/r/view.result:
  One no longer is allowed to do DROP VIEW under LOCK TABLES even if
  this view is locked by LOCK TABLES. The problem is that in such
  situation even "write locks" on view are not mutually exclusive so
  upgrading metadata lock which is required for dropping of view
  will lead to deadlock
mysql-test/r/view_grant.result:
  ALTER VIEW implementation was changed to open a view only after
  checking that user which does alter has appropriate privileges on
  it. This means that in case when user's privileges are
  insufficient for this we won't check that new view definer is the
  same as original one or user performing alter has SUPER privilege.
  Adjusted test case accordingly.
mysql-test/r/view_multi.result:
  Added test case for bug#25144 "replication / binlog with view
  breaks".
mysql-test/suite/rpl/t/disabled.def:
  Disable test for deprecated features (they don't work with new MDL).
mysql-test/t/create.test:
  Adjusted test case after change in implementation of CREATE TABLE
  ... SELECT.  We no longer have special check in open_table() which
  catches the case when we select from the table created. Instead we
  rely on unique_table() call which happens after opening and
  locking all tables.
mysql-test/t/disabled.def:
  Disable merge.test, subject of WL#4144
mysql-test/t/flush.test:
  
  FLUSH TABLES WITH READ LOCK can no longer happen under LOCK
  TABLES.  Updated test accordingly.
mysql-test/t/flush_table.test:
  Under LOCK TABLES we no longer allow to do FLUSH TABLES for tables
  locked for read. Updated test accordingly.
mysql-test/t/information_schema.test:
  Additional test for WL#3726 "DDL locking for all metadata
  objects".  Check that we use high-priority metadata lock requests
  when filling I_S tables.
  
  Rearrange the results for easier merges with 6.0.
mysql-test/t/kill.test:
  Added tests checking that DDL and DML statements waiting for
  metadata locks can be interrupted by KILL command.
mysql-test/t/lock.test:
  One no longer is allowed to do DROP VIEW under LOCK TABLES even if
  this view is locked by LOCK TABLES. The problem is that in such
  situation write locks on view are not mutually exclusive so
  upgrading metadata lock which is required for dropping of view
  will lead to deadlock.
mysql-test/t/lock_multi.test:
  Adjusted test case to the changes of status in various places
  caused by change in implementation FLUSH TABLES WITH READ LOCK,
  which is now takes global metadata lock before flushing tables and
  therefore waits on at these places.
mysql-test/t/ps_ddl.test:
  We no longer invalidate prepared CREATE TABLE ... SELECT statement
  if target table changes. This is OK since it is not strictly
  necessary.
  
  
  The first change is wrong, is caused by FLUSH TABLE
  now flushing all unused tables. This is a regression that
  Dmitri fixed in 6.0 in a follow up patch.
mysql-test/t/sp.test:
  Under LOCK TABLES we no longer allow accessing views which were
  not explicitly locked. To access view we need to obtain metadata
  lock on it and doing this under LOCK TABLES may lead to deadlocks.
mysql-test/t/trigger_notembedded.test:
  Adjusted test case to the changes of status in various places
  caused by change in implementation FLUSH TABLES WITH READ LOCK,
  which is now takes global metadata lock before flushing tables and
  therefore waits on at these places.
mysql-test/t/view.test:
  One no longer is allowed to do DROP VIEW under LOCK TABLES even if
  this view is locked by LOCK TABLES. The problem is that in such
  situation even "write locks" on view are not mutually exclusive so
  upgrading metadata lock which is required for dropping of view
  will lead to deadlock.
mysql-test/t/view_grant.test:
  ALTER VIEW implementation was changed to open a view only after
  checking that user which does alter has appropriate privileges on
  it. This means that in case when user's privileges are
  insufficient for this we won't check that new view definer is the
  same as original one or user performing alter has SUPER privilege.
  Adjusted test case accordingly.
mysql-test/t/view_multi.test:
  Added test case for bug#25144 "replication / binlog with view
  breaks".
sql/CMakeLists.txt:
  Added mdl.cc to the list of files needed for building of server.
sql/Makefile.am:
  Added files implementing new meta-data locking subsystem to the
  server.
sql/event_db_repository.cc:
  
  Allocate metadata lock requests objects (MDL_LOCK) on execution
  memory root in cases when TABLE_LIST objects is also allocated
  there or on stack.
sql/ha_ndbcluster.cc:
  Adjusted code to work nicely with new metadata locking subsystem.
  close_cached_tables() no longer has wait_for_placeholder argument.
  Instead of relying on this parameter and related behavior FLUSH
  TABLES WITH READ LOCK now takes global shared metadata lock.
sql/ha_ndbcluster_binlog.cc:
  Adjusted code to work with new metadata locking subsystem.
  close_cached_tables() no longer has wait_for_placeholder argument.
  Instead of relying on this parameter and related behavior FLUSH
  TABLES WITH READ LOCK now takes global shared metadata lock.
sql/handler.cc:
  update_frm_version():
    Directly update TABLE_SHARE::mysql_version member instead of
    going through all TABLE instances for this table (old code was a
    legacy from pre-table-definition-cache days).
sql/lock.cc:
  Use new metadata locking subsystem. Threw away most of functions
  related to name locking as now one is supposed to use metadata
  locking API instead.  In lock_global_read_lock() and
  unlock_global_read_lock() in order to avoid problems with global
  read lock sneaking in at the moment when we perform FLUSH TABLES
  or ALTER TABLE under LOCK TABLES and when tables being reopened
  are protected only by metadata locks we also have to take global
  shared meta data lock.
sql/log_event.cc:
  Adjusted code to work with new metadata locking subsystem.  For
  tables open by slave thread for applying RBR events allocate
  memory for lock request object in the same chunk of memory as
  TABLE_LIST objects for them. In order to ensure that we keep these
  objects around until tables are open always close tables before
  calling Relay_log_info::clear_tables_to_lock(). Use new auxiliary
  Relay_log_info::slave_close_thread_tables() method to enforce
  this.
sql/log_event_old.cc:
  Adjusted code to work with new metadata locking subsystem.  Since
  for tables open by slave thread for applying RBR events memory for
  lock request object is allocated in the same chunk of memory as
  TABLE_LIST objects for them we have to ensure that we keep these
  objects around until tables are open. To ensure this we always
  close tables before calling
  Relay_log_info::clear_tables_to_lock(). To enfore this we use
  new auxiliary Relay_log_info::slave_close_thread_tables()
  method.
sql/mdl.cc:
  Implemented new metadata locking subsystem and API described in
  WL3726 "DDL locking for all metadata objects".
sql/mdl.h:
  Implemented new metadata locking subsystem and API described in
  WL3726 "DDL locking for all metadata objects".
sql/mysql_priv.h:
  - close_thread_tables()/close_tables_for_reopen() now has one more
    argument which indicates that metadata locks should be released
    but not removed from the context in order to be used later in
    mdl_wait_for_locks() and tdc_wait_for_old_version().
  - close_cached_table() routine is no longer public.
  - Thread waiting in wait_while_table_is_used() can be now killed
    so this function returns boolean to make caller aware of such
    situation.
  - We no longer have  table cache as separate entity instead used
    and unused TABLE instances are linked to TABLE_SHARE objects in
    table definition cache.
  - Now third argument of open_table() is also used for requesting
    table repair or auto-discovery of table's new definition. So its
    type was changed from bool to enum.
  - Added tdc_open_view() function for opening view by getting its
    definition from disk (and table cache in future).
  - reopen_name_locked_table() no longer needs "link_in" argument as
    now we have exclusive metadata locks instead of dummy TABLE
    instances when this function is called.
  - find_locked_table() now takes head of list of TABLE instances
    instead of always scanning through THD::open_tables list. Also
    added find_write_locked_table() auxiliary.
  - reopen_tables(), close_cached_tables() no longer have
    mark_share_as_old and wait_for_placeholder arguments. Instead of
    relying on this parameters and related behavior FLUSH TABLES
    WITH READ LOCK now takes global shared metadata lock.
  - We no longer need drop_locked_tables() and
    abort_locked_tables().
  - mysql_ha_rm_tables() now always assume that LOCK_open is not
    acquired by caller.
  - Added notify_thread_having_shared_lock() callback invoked by
    metadata locking subsystem when acquiring an exclusive lock, for
    each thread that has a conflicting shared metadata lock.
  - Introduced expel_table_from_cache() as replacement for
    remove_table_from_cache() (the main difference is that this new
    function assumes that caller follows metadata locking protocol
    and never waits).
  - Threw away most of functions related to name locking. One should
    use new metadata locking subsystem and API instead.
sql/mysqld.cc:
  Got rid of call initializing/deinitializing table cache since now
  it is embedded into table definition cache. Added calls for
  initializing/ deinitializing metadata locking subsystem.
sql/rpl_rli.cc:
  Introduced auxiliary Relay_log_info::slave_close_thread_tables()
  method which is used for enforcing that we always close tables
  open for RBR before deallocating TABLE_LIST elements and MDL_LOCK
  objects for them.
sql/rpl_rli.h:
  Introduced auxiliary Relay_log_info::slave_close_thread_tables()
  method which is used for enforcing that we always close tables
  open for RBR before deallocating TABLE_LIST elements and MDL_LOCK
  objects for them.
sql/set_var.cc:
  close_cached_tables() no longer has wait_for_placeholder argument.
  Instead of relying on this parameter and related behavior FLUSH
  TABLES WITH READ LOCK now takes global shared metadata lock.
sql/sp_head.cc:
  For tables added to the statement's table list by prelocking
  algorithm we allocate these objects either on the same memory as
  corresponding table list elements or on THD::locked_tables_root
  (if we are building table list for LOCK TABLES).
sql/sql_acl.cc:
  Allocate metadata lock requests objects (MDL_LOCK) on execution
  memory root in cases when we use stack TABLE_LIST objects to open
  tables.  Got rid of redundant code by using unlock_locked_tables()
  function.
sql/sql_base.cc:
  Changed code to use new MDL subsystem. Got rid of separate table
  cache.  Now used and unused TABLE instances are linked to the
  TABLE_SHAREs in table definition cache.
  
  check_unused():
    Adjusted code to the fact that we no longer have separate table
    cache.  Removed dead code.
  table_def_free():
    Free TABLE instances referenced from TABLE_SHARE objects before
    destroying table definition cache.
  get_table_share():
    Added assert which ensures that noone will be able to access
    table (and its share) without acquiring some kind of metadata
    lock first.
  close_handle_and_leave_table_as_lock():
    Adjusted code to the fact that TABLE instances now are linked to
    list in TABLE_SHARE.
  list_open_tables():
    Changed this function to use table definition cache instead of
    table cache.
  free_cache_entry():
    Unlink freed TABLE elements from the list of all TABLE instances
    for the table in TABLE_SHARE.
  kill_delayed_thread_for_table():
    Added auxiliary for killing delayed insert threads for
    particular table.
  close_cached_tables():
    Got rid of wait_for_refresh argument as we now rely on global
    shared metadata lock to prevent FLUSH WITH READ LOCK sneaking in
    when we are reopening tables. Heavily reworked this function to
    use new MDL code and not to rely on separate table cache entity.
  close_open_tables():
    We no longer have separate table cache.
  close_thread_tables():
    Release metadata locks after closing all tables. Added skip_mdl
    argument which allows us not to remove metadata lock requests
    from the context in case when we are going to use this requests
    later in mdl_wait_for_locks() and tdc_wait_for_old_versions().
  close_thread_table()/close_table_for_reopen():
    Since we no longer have separate table cache and all TABLE
    instances are linked to TABLE_SHARE objects in table definition
    cache we have to link/unlink TABLE object to/from appropriate
    lists in the share.
  name_lock_locked_table():
   Moved redundant code to find_write_locked_table() function and
    adjusted code to the fact that wait_while_table_is_used() can
    now return with an error if our thread is killed.
  reopen_table_entry():
    We no longer need "link_in" argument as with MDL we no longer
    call this function with dummy TABLE object pre-allocated and
    added to the THD::open_tables. Also now we add newly-open TABLE
    instance to the list of share's used TABLE instances.
  table_cache_insert_placeholder():
    Got rid of name-locking legacy.
  lock_table_name_if_not_cached():
    Moved to sql_table.cc the only place where it is used. It was
    also reimplemented using new MDL API.
  open_table():
    - Reworked this function to use new MDL subsystem.
    - Changed code to deal with table definition cache directly
      instead of going through separate table cache.
    - Now third argument is also used for requesting table repair
      or auto-discovery of table's new definition. So its type was
      changed from bool to enum.
  find_locked_table()/find_write_locked_table():
    Accept head of list of TABLE objects as first argument and use
    this list instead of always searching in THD::open_tables list.
    Also added auxiliary for finding write-locked locked tables.
  reopen_table():
    Adjusted function to work with new MDL subsystem and to properly
    manuipulate with lists of used/unused TABLE instaces in
    TABLE_SHARE.
  reopen_tables():
    Removed mark_share_as_old parameter. Instead of relying on it
    and related behavior FLUSH TABLES WITH READ LOCK now takes
    global shared metadata lock. Changed code after removing
    separate table cache.
  drop_locked_tables()/abort_locked_tables():
    Got rid of functions which are no longer needed.
    unlock_locked_tables():
    Moved this function from sql_parse.cc and changed it to release
    memory which was used for allocating metadata lock requests for
    tables open and locked by LOCK TABLES.
  tdc_open_view():
    Intoduced function for opening a view by getting its definition
    from disk (and table cache in future).
  reopen_table_entry():
    Introduced function for opening table definitions while holding
    exclusive metatadata lock on it.
  open_unireg_entry():
   Got rid of this function. Most of its functionality is relocated
    to open_table() and open_table_fini() functions, and some of it
    to reopen_table_entry() and tdc_open_view(). Also code
    resposible for auto-repair and auto-discovery of tables was
    moved to separate function.
  open_table_entry_fini():
    Introduced function which contains common actions which finalize
    process of TABLE object creation.
  auto_repair_table():
    Moved code responsible for auto-repair of table being opened
    here.
  handle_failed_open_table_attempt()
    Moved code responsible for handling failing attempt to open
    table to one place (retry due to lock conflict/old version,
    auto-discovery and repair).
  open_tables():
    - Flush open HANDLER tables if they have old version of if there
      is conflicting metadata lock against them (before this moment
      we had this code in open_table()).
    - When we open view which should be processed via derived table
      on the second execution of prepared statement or stored
      routine we still should call open_table() for it in order to
      obtain metadata lock on it and prepare its security context.
    - In cases when we discover that some special handling of
      failure to open table is needed call
      handle_failed_open_table_attempt() which handles all such
      scenarios.
  open_ltable():
    Handling of various special scenarios of failure to open a table
    was moved to separate handle_failed_open_table_attempt()
    function.
  remove_db_from_cache():
    Removed this function as it is no longer used.
  notify_thread_having_shared_lock():
    Added callback which is invoked by MDL subsystem when acquiring
    an exclusive lock, for each thread that has a conflicting shared
    metadata lock.
  expel_table_from_cache():
    Introduced function for removing unused TABLE instances. Unlike
    remove_table_from_cache() it relies on caller following MDL
    protocol and having appropriate locks when calling it and thus
    does not do any waiting if table is still in use.
  tdc_wait_for_old_version():
    Added function which allows open_tables() to wait in cases when
    we discover that we should back-off due to presence of old
    version of table.
  abort_and_upgrade_lock():
    Use new MDL calls.
  mysql_wait_completed_table():
    Got rid of unused function.
  open_system_tables_for_read/for_update()/performance_schema_table():
    Allocate MDL_LOCK objects on execution memory root in cases when
    TABLE_LIST objects for corresponding tables is allocated on
    stack.
  close_performance_schema_table():
    Release metadata locks after closing tables.
  ******
  Use I_P_List for free/used tables list in the table share.
sql/sql_binlog.cc:
  Use Relay_log_info::slave_close_thread_tables() method to enforce
  that we always close tables open for RBR before deallocating
  TABLE_LIST elements and MDL_LOCK objects for them.
sql/sql_class.cc:
  Added meta-data locking contexts as part of Open_tables_state
  context.  Also introduced THD::locked_tables_root memory root
  which is to be used for allocating MDL_LOCK objects for tables in
  LOCK TABLES statement (end of lifetime for such objects is UNLOCK
  TABLES so we can't use statement or execution root for them).
sql/sql_class.h:
  Added meta-data locking contexts as part of Open_tables_state
  context.  Also introduced THD::locked_tables_root memory root
  which is to be used for allocating MDL_LOCK objects for tables in
  LOCK TABLES statement (end of lifetime for such objects is UNLOCK
  TABLES so we can't use statement or execution root for them).
  
  Note: handler_mdl_context and locked_tables_root and
  mdl_el_root will be removed by subsequent patches.
sql/sql_db.cc:
  mysql_rm_db() does not really need to call remove_db_from_cache()
  as it drops each table in the database using
  mysql_rm_table_part2(), which performs all necessary operations on
  table (definition) cache.
sql/sql_delete.cc:
  Use the new metadata locking API for TRUNCATE.
sql/sql_handler.cc:
  Changed HANDLER implementation to use new metadata locking
  subsystem.  Note that MDL_LOCK objects for HANDLER tables are
  allocated in the same chunk of heap memory as TABLE_LIST object
  for those tables.
sql/sql_insert.cc:
  mysql_insert():
    find_locked_table() now takes head of list of TABLE object as
    its argument instead of always scanning through THD::open_tables
    list.
  handle_delayed_insert():
    Allocate metadata lock request object for table open by delayed
    insert thread on execution memroot.  create_table_from_items():
    We no longer allocate dummy TABLE objects for tables being
    created if they don't exist. As consequence
    reopen_name_locked_table() no longer has link_in argument.
    open_table() now has one more argument which is not relevant for
    temporary tables.
sql/sql_parse.cc:
  - Moved unlock_locked_tables() routine to sql_base.cc and made
    available it in other files. Got rid of some redundant code by
    using this function.
  - Replaced boolean TABLE_LIST::create member with enum
    open_table_type member.
  - Use special memory root for allocating MDL_LOCK objects for
    tables open and locked by LOCK TABLES (these object should live
    till UNLOCK TABLES so we can't allocate them on statement nor
    execution memory root). Also properly set metadata lock
    upgradability attribure for those tables.
  - Under LOCK TABLES it is no longer allowed to flush tables which
    are not write-locked as this breaks metadata locking protocol
    and thus potentially might lead to deadlock.
  - Added auxiliary adjust_mdl_locks_upgradability() function.
sql/sql_partition.cc:
  Adjusted code to the fact that reopen_tables() no longer has
  "mark_share_as_old" argument. Got rid of comments which are no
  longer true.
sql/sql_plist.h:
  Added I_P_List template class for parametrized intrusive doubly
  linked lists and I_P_List_iterator for corresponding iterator.
  Unlike for I_List<> list elements of such list can participate in
  several lists. Unlike List<> such lists are doubly-linked and
  intrusive.
sql/sql_plugin.cc:
  Allocate metadata lock requests objects (MDL_LOCK) on execution
  memory root in cases when we use stack TABLE_LIST objects to open
  tables.
sql/sql_prepare.cc:
  Replaced boolean TABLE_LIST::create member with enum
  open_table_type member.  This allows easily handle situation in
  which instead of opening the table we want only to take exclusive
  metadata lock on it.
sql/sql_rename.cc:
  Use new metadata locking subsystem in implementation of RENAME
  TABLE.
sql/sql_servers.cc:
  Allocate metadata lock requests objects (MDL_LOCK) on execution
  memory root in cases when we use stack TABLE_LIST objects to open
  tables. Got rid of redundant code by using unlock_locked_tables()
  function.
sql/sql_show.cc:
  Acquire shared metadata lock when we are getting information for
  I_S table directly from TABLE_SHARE without doing full-blown table
  open.  We use high priority lock request in this situation in
  order to avoid deadlocks.
  Also allocate metadata lock requests objects (MDL_LOCK) on
  execution memory root in cases when TABLE_LIST objects are also
  allocated there
sql/sql_table.cc:
  mysql_rm_table():
    Removed comment which is no longer relevant.
  mysql_rm_table_part2():
    Now caller of mysql_ha_rm_tables() should not own LOCK_open.
    Adjusted code to use new metadata locking subsystem instead of
    name-locks.
  lock_table_name_if_not_cached():
    Moved this function from sql_base.cc to this file and
    reimplemented it using metadata locking API.
  mysql_create_table():
    Adjusted code to use new MDL API.
  wait_while_table_is_used():
    Changed function to use new MDL subsystem. Made thread waiting
    in it killable (this also led to introduction of return value so
    caller can distinguish successful executions from situations
    when waiting was aborted).
  close_cached_tables():
    Thread waiting in this function is killable now. As result it
    has return value for distinguishing between succes and failure.
    Got rid of redundant boradcast_refresh() call.
  prepare_for_repair():
    Use MDL subsystem instead of name-locks.
  mysql_admin_table():
    mysql_ha_rm_tables() now always assumes that caller doesn't own
    LOCK_open.
  mysql_repair_table():
    We should mark all elements of table list as requiring
    upgradable metadata locks.
  mysql_create_table_like():
    Use new MDL subsystem instead of name-locks.
  create_temporary_tables():
    We don't need to obtain metadata locks when creating temporary
    table.
  mysql_fast_or_online_alter_table():
    Thread waiting in wait_while_table_is_used() is now killable.
  mysql_alter_table():
    Adjusted code to work with new MDL subsystem and to the fact
    that threads waiting in what_while_table_is_used() and
    close_cached_table() are now killable.
sql/sql_test.cc:
  We no longer have separate table cache. TABLE instances are now
  associated with/linked to TABLE_SHARE objects in table definition
  cache.
sql/sql_trigger.cc:
  Adjusted code to work with new metadata locking subsystem.  Also
  reopen_tables() no longer has mark_share_as_old argument (Instead
  of relying on this parameter and related behavior FLUSH TABLES
  WITH READ LOCK now takes global shared metadata lock).
sql/sql_udf.cc:
  Allocate metadata lock requests objects (MDL_LOCK) on execution
  memory root in cases when we use stack TABLE_LIST objects to open
  tables.
sql/sql_update.cc:
  Adjusted code to work with new meta-data locking subsystem.
sql/sql_view.cc:
  Added proper meta-data locking to implementations of
  CREATE/ALTER/DROP VIEW statements. Now we obtain exclusive
  meta-data lock on a view before creating/ changing/dropping it.
  This ensures that all concurrent statements that use this view
  will finish before our statement will proceed and therefore we
  will get correct order of statements in the binary log.
  Also ensure that TABLE_LIST::mdl_upgradable attribute is properly
  propagated for underlying tables of view.
sql/table.cc:
  Added auxiliary alloc_mdl_locks() function for allocating metadata
  lock request objects for all elements of table list.
sql/table.h:
  TABLE_SHARE:
    Got rid of unused members. Introduced members for storing lists
    of used and unused TABLE objects for this share.
  TABLE:
    Added members for linking TABLE objects into per-share lists of
    used and unused TABLE instances. Added member for holding
    pointer to metadata lock for this table.
  TABLE_LIST:
    Replaced boolean TABLE_LIST::create member with enum
    open_table_type member.  This allows easily handle situation in
    which instead of opening the table we want only to take
    exclusive meta-data lock on it (we need this in order to handle
    ALTER VIEW and CREATE VIEW statements).
    Introduced new mdl_upgradable member for marking elements of
    table list for which we need to take upgradable shared metadata
    lock instead of plain shared metadata lock.  Added pointer for
    holding pointer to MDL_LOCK for the table.
  Added auxiliary alloc_mdl_locks() function for allocating metadata
  lock requests objects for all elements of table list.  Added
  auxiliary set_all_mdl_upgradable() function for marking all
  elements in table list as requiring upgradable metadata locks.
storage/myisammrg/ha_myisammrg.cc:
  Allocate MDL_LOCK objects for underlying tables of MERGE table.
  To be reworked once Ingo pushes his patch for WL4144.
2009-11-30 18:55:03 +03:00
Konstantin Osipov
98c4476b49 Backport of:
------------------------------------------------------------
revno: 2476.1116.1
committer: davi@mysql.com/endora.local
timestamp: Fri 2007-12-14 10:10:19 -0200
message:
DROP TABLE under LOCK TABLES simultaneous to a FLUSH TABLES
WITH READ LOCK (global read lock) can lead to a deadlock.

The solution is to not wait for the global read lock if the
thread is holding any locked tables.

Related to bugs 23713 and 32395. This issues is being fixed
only on 6.0 because it depends on the fix for bug 25858 --
which was fixed only on 6.0.
2009-11-20 23:12:57 +03:00
Konstantin Osipov
1b34d593b5 Backport of:
------------------------------------------------------------
revno: 2476.784.3
committer: davi@moksha.local
timestamp: Tue 2007-10-02 21:27:31 -0300
message:
Bug#25858 Some DROP TABLE under LOCK TABLES can cause deadlocks
        
When a client (connection) holds a lock on a table and attempts to
drop (obtain a exclusive lock) on a second table that is already
held by a second client and the second client then attempts to
drop the table that is held by the first client, leads to a
circular wait deadlock. This scenario is very similar to trying to
drop (or rename) a table while holding read locks and are
correctly forbidden.
        
The solution is to allow a drop table operation to continue only
if the table being dropped is write (exclusively) locked, or if
the table is temporary, or if the client is not holding any
locks. Using this scheme prevents the creation of a circular
chain in which each client is waiting for one table that the
next client in the chain is holding.
            
This is incompatible change, as can be seen by number of tests
cases that needed to be fixed, but is consistent with respect to
behavior of the different scenarios in which the circular wait
might happen.

mysql-test/r/drop.result:
  Test case result for Bug#25858
mysql-test/r/group_by.result:
  Fix test case result wrt drop table under lock tables -- unlock tables
  before dropping table.
mysql-test/r/insert_notembedded.result:
  Fix test case result wrt drop table under lock tables -- unlock tables
  before dropping table
mysql-test/r/lock.result:
  Fix test case result wrt drop table under lock tables -- unlock tables
  before dropping table.
mysql-test/r/lock_multi.result:
  Fix test case result wrt drop table under lock tables -- unlock tables
  before dropping table.
mysql-test/r/myisam.result:
  Fix test case result wrt drop table under lock tables -- unlock tables
  before dropping table.
mysql-test/r/view.result:
  Fix test case result wrt drop table under lock tables -- unlock tables
  before dropping table.
mysql-test/t/drop.test:
  Add test case for Bug#25858
mysql-test/t/group_by.test:
  Fix test case: unlock tables in preparation for a drop table. In some
  circumstances, dropping tables while holding locks leads to a deadlock.
mysql-test/t/insert_notembedded.test:
  Fix test case: unlock tables in preparation for a drop table. In some
  circumstances, dropping tables while holding locks leads to a deadlock.
mysql-test/t/lock.test:
  Fix test case: unlock tables in preparation for a drop table. In some
  circumstances, dropping tables while holding locks leads to a deadlock.
mysql-test/t/lock_multi.test:
  Fix test case: unlock tables in preparation for a drop table. In some
  circumstances, dropping tables while holding locks leads to a deadlock.
mysql-test/t/myisam.test:
  Fix test case: unlock tables in preparation for a drop table. In some
  circumstances, dropping tables while holding locks leads to a deadlock.
mysql-test/t/query_cache_notembedded.test:
  Fix test case: unlock tables in preparation for a drop table. In some
  circumstances, dropping tables while holding locks leads to a deadlock.
mysql-test/t/view.test:
  Fix test case: unlock tables in preparation for a drop table. In some
  circumstances, dropping tables while holding locks leads to a deadlock.
sql/lock.cc:
  When trying to obtain a name lock under lock tables, ensure that the table is properly exclusively locked and fail otherwise.
2009-11-20 22:51:12 +03:00
Davi Arnaut
33a02e3f92 Backport of Bug#47304 to mysql-next-mr
------------------------------------------------------------
revno: 3624
revision-id: jon.hauglid@sun.com-20090928163426-2lg1gofzz44xzzxf
parent: alik@sun.com-20090928050057-r0a62x9czr01q7oe
committer: Jon Olav Hauglid <jon.hauglid@sun.com>
branch nick: mysql-6.0-codebase-bugfixing-bug47304
timestamp: Mon 2009-09-28 18:34:26 +0200
message:
  Bug #47304 Test main.mdl_sync fails on embedded server

  The problem was that SHOW PROCESSLIST was trying to access
  a thread that was not properly running and therefore had an 
  uninitialized mutex.

  This patch explicitly resets thd->mysys_var after each embedded
  server command to prevent the mutex from being accessed in an
  illegal state.

  The patch also re-enables lock_multi.test and mdl_sync.test for 
  embedded server as they had been disabled because of this bug.
2009-11-10 12:23:55 -02:00
Davi Arnaut
54bf80b633 Merge Bug#43230 into mysql-5.1-bugteam 2009-04-03 16:46:00 -03:00
Davi Arnaut
72e978828e 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.
2009-04-03 16:11:54 -03:00
Matthias Leich
fbb90c66d7 Merge of fixes into actual tree 2009-03-23 21:19:41 +01:00
Matthias Leich
0b2f4c56c6 Merge 5.0 -> 5.1 of fix for the bugs 43015 and 43065 2009-03-23 17:08:48 +01:00
Matthias Leich
5eb0b4819c Fix for Bug#43015 and Bug#43065
Details for Bug#43015 main.lock_multi: Weak code (sleeps etc.)
   -------------------------------------------------------------
   - The fix for bug 42003 already removed a lot of the weaknesses mentioned.
   - Tests showed that there are unfortunately no improvements of this tests
     in MySQL 5.1 which could be ported back to 5.0.
   - Remove a superfluous "--sleep 1" around line 195

   Details for Bug#43065 main.lock_multi: This test is too big if the disk is slow
   -------------------------------------------------------------------------------
   - move the subtests for the bugs 38499 and 36691 into separate scripts
   - runtime under excessive parallel I/O load after applying the fix
     lock_multi           [ pass ]          22887
     lock_multi_bug38499  [ pass ]         536926
     lock_multi_bug38691  [ pass ]         258498
2009-03-23 15:22:31 +01:00
Matthias Leich
2417d31045 Merge 5.0 -> 5.1 of fix for Bug#42003 and Bug#43114 2009-03-06 15:56:17 +01:00
Matthias Leich
0183d4d842 Merge of fix for Bug#42003 and Bug#43114 into more actual GCA tree
modifications according to the reviews are included
2009-03-05 14:35:03 +01:00
Matthias Leich
140cc614c9 Last slice of fix for Bug#42003 tests missing the disconnect of connections <> default
+ Fix for Bug#43114 wait_until_count_sessions too restrictive, random PB failures
+ Removal of a lot of other weaknesses found
+ modifications according to review
2009-03-03 21:34:18 +01:00
Gleb Shchepa
0c20c0f12f manual merge 5.0-5.1.29-rc --> 5.1-5.1.29-rc 2008-10-09 20:57:41 +05:00
Gleb Shchepa
a83f5b18ef Bug#38499: flush tables and multitable table update with
derived table cause crash

When a multi-UPDATE command fails to lock some table, and
subsequently succeeds, the tables need to be reopened if
they were altered. But the reopening procedure failed for
derived tables.

Extra cleanup has been added.


mysql-test/r/lock_multi.result:
  Added test case for bug #38499.
mysql-test/t/lock_multi.test:
  Added test case for bug #38499.
sql/sql_union.cc:
  Bug#38499: flush tables and multitable table update with
             derived table cause crash
  
  Obsolete assertion has been removed.
sql/sql_update.cc:
  Bug#38499: flush tables and multitable table update with
             derived table cause crash
  
  Extra cleanup for derived tables has been added:
  1) unit.cleanup(),
  2) unit->reinit_exec_mechanism().
2008-10-09 20:24:31 +05:00
Gleb Shchepa
39996b44cc manual merge 5.0-5.1.29-rc --> 5.1-5.1.29-rc 2008-10-08 02:52:49 +05:00
Gleb Shchepa
f48b42e776 Bug #38691: segfault/abort in ``UPDATE ...JOIN'' while
``FLUSH TABLES WITH READ LOCK''

Concurrent execution of 1) multitable update with a
NATURAL/USING join and 2) a such query as "FLUSH TABLES
WITH READ LOCK" or "ALTER TABLE" of updating table led
to a server crash.


The mysql_multi_update_prepare() function call is optimized
to lock updating tables only, so it postpones locking to
the last, and if locking fails, it does cleanup of modified
syntax structures and repeats a query analysis.  However,
that cleanup procedure was incomplete for NATURAL/USING join
syntax data: 1) some Field_item items pointed into freed
table structures, and 2) the TABLE_LIST::join_columns fields
was not reset.

Major change:
  short-living Field *Natural_join_column::table_field has
  been replaced with long-living Item*.


mysql-test/r/lock_multi.result:
  Added test case for bug #38691.
mysql-test/t/lock_multi.test:
  Added test case for bug #38691.
sql/item.cc:
  Bug #38691: segfault/abort in ``UPDATE ...JOIN'' while
            ``FLUSH TABLES WITH READ LOCK''
  
  The Item_field constructor has been modified to allocate
  and copy original database/table/field names always (not
  during PS preparation/1st execution only), because
  an initialization of Item_field items with a pointer to
  short-living Field structures is a common practice.
sql/sql_base.cc:
  Bug #38691: segfault/abort in ``UPDATE ...JOIN'' while
            ``FLUSH TABLES WITH READ LOCK''
  
  1) Type adjustment for Natural_join_column::table_field
     (Field to Item_field);
  2) The setup_natural_join_row_types function has been
     updated to take into account new
     first_natural_join_processing flag to skip unnecessary
     reinitialization of Natural_join_column::join_columns
     during table reopening after lock_tables() failure
     (like the 'first_execution' flag for PS).
sql/sql_lex.cc:
  Bug #38691: segfault/abort in ``UPDATE ...JOIN'' while
            ``FLUSH TABLES WITH READ LOCK''
  
  Initialization of the new
  st_select_lex::first_natural_join_processing flag has
  been added.
sql/sql_lex.h:
  Bug #38691: segfault/abort in ``UPDATE ...JOIN'' while
            ``FLUSH TABLES WITH READ LOCK''
  
  The st_select_lex::first_natural_join_processing flag
  has been added to skip unnecessary rebuilding of
  NATURAL/USING JOIN structures during table reopening
  after lock_tables failure.
sql/sql_update.cc:
  Bug #38691: segfault/abort in ``UPDATE ...JOIN'' while
            ``FLUSH TABLES WITH READ LOCK''
  
  Extra cleanup calls have been added to reset
  Natural_join_column::table_field items.
sql/table.cc:
  Bug #38691: segfault/abort in ``UPDATE ...JOIN'' while
            ``FLUSH TABLES WITH READ LOCK''
  
  Type adjustment for Natural_join_column::table_field
  (Field to Item_field).
sql/table.h:
  Bug #38691: segfault/abort in ``UPDATE ...JOIN'' while
            ``FLUSH TABLES WITH READ LOCK''
  
  Type of the Natural_join_column::table_field field has
  been changed from Field that points into short-living
  TABLE memory to long-living Item_field that can be
  linked to (fixed) reopened table.
2008-10-08 02:34:00 +05:00
unknown
c3801d9627 Fix lock_multi test case failure related to
concurrent inserts.


mysql-test/t/lock_multi.test:
  Wait for the concurrent insert to finish.
2008-02-22 10:35:08 -02:00
unknown
ee42ff6398 Bug#34311 main.lock_multi.test fails
Re-enable the test case for Bug 30331.


mysql-test/r/lock_multi.result:
  Update the test case result for Bug#30331
mysql-test/t/lock_multi.test:
  Re-enable the test case for Bug#30331
2008-02-06 09:40:59 -02:00
unknown
4df3bc0c3d Disabling test case.
Bug 34311: main.lock_multi.test fails.


mysql-test/r/lock_multi.result:
  Update result file.
mysql-test/t/lock_multi.test:
  Disabled test case for Bug#30331.
2008-02-05 18:08:02 +03:00
unknown
b46d5d6b2f Fix test case of Bug 30331
mysql-test/r/lock_multi.result:
  Update test case result.
mysql-test/t/lock_multi.test:
  Don't print the value of Table_lock_waited, check the
  precedence instead. Unlock the table before dropping.
2008-01-29 10:37:44 -02:00
unknown
cdc66b12c5 Remove spurious commented out test line.
mysql-test/t/lock_multi.test:
  Remove spurious test line.
2008-01-28 11:21:39 -02:00
unknown
3d5e32b27d Bug#30331 Table_locks_waited shows inaccurate values
The problem is that the Table_locks_waited was incremented only
when the lock request succeed. If a thread waiting for the lock
gets killed or the lock request is aborted, the variable would
not be incremented, leading to inaccurate values in the variable.

The solution is to increment the Table_locks_waited whenever the
lock request is queued. This reflects better the intended behavior
of the variable -- show how many times a lock was waited.


mysql-test/r/lock_multi.result:
  Add test case result for Bug#30331
mysql-test/t/lock_multi.test:
  Add test case for Bug#30331
mysys/thr_lock.c:
  Increment locks_waited whenever the thread is supposed
  to wait for the lock.
2008-01-28 10:52:41 -02:00
unknown
e5a397e28f Bug#32395 Alter table under a impending global read lock causes a server crash
The problem is that some DDL statements (ALTER TABLE, CREATE
TRIGGER, FLUSH TABLES, ...) when under LOCK TABLES need to
momentarily drop the lock, reopen the table and grab the write
lock again (using reopen_tables). When grabbing the lock again,
reopen_tables doesn't pass a flag to mysql_lock_tables in
order to ignore the impending global read lock, which causes a
assertion because LOCK_open is being hold. Also dropping the
lock must not signal to any threads that the table has been
relinquished (related to the locking/flushing protocol).

The solution is to correct the way the table is reopenned
and the locks grabbed. When reopening the table and under
LOCK TABLES, the table version should be set to 0 so other
threads have to wait for the table. When grabbing the lock,
any other flush should be ignored because it's theoretically
a atomic operation. The chosen solution also fixes a potential
discrepancy between binlog and GRL (global read lock) because
table placeholders were being ignored, now a FLUSH TABLES WITH
READ LOCK will properly for table with open placeholders.

It's also important to mention that this patch doesn't fix
a potential deadlock if one uses two GRLs under LOCK TABLES
concurrently.


mysql-test/r/lock_multi.result:
  Add test case result for Bug#32395
mysql-test/r/trigger_notembedded.result:
  Add test case result for Bug#32395
mysql-test/t/lock_multi.test:
  Add test case for Bug#32395
mysql-test/t/trigger_notembedded.test:
  Enable test case for Bug#32395
sql/ha_ndbcluster.cc:
  Update close_cached_tables usage.
sql/ha_ndbcluster_binlog.cc:
  Update close_cached_tables usage.
sql/mysql_priv.h:
  Update close_cache_tables prototype.
sql/set_var.cc:
  Update close_cached_tables usage and set flag to wait for
  tables with placeholders. This is one of the places where
  a GRL can be obtained.
sql/sql_base.cc:
  Preserve old version for write locked tables and ignore
  pending flushes and update close_cache_tables to take
  into account name locked tables.
sql/sql_parse.cc:
  Update close_cached_tables usage and pass flag so that
  name locked tables are waited for.
sql/sql_table.cc:
  Protect the table against a impending GRL if under LOCK TABLES.
2007-12-12 19:44:14 -02:00
unknown
4b00263596 Bug#31479 Bad lock interaction if CREATE TABLE LIKE is killed
Kill of a CREATE TABLE source_table LIKE statement waiting for a
name-lock on the source table causes a bad lock interaction.

The mysql_create_like_table() has a bug that if the connection is
killed while waiting for the name-lock on the source table, it will
jump to the wrong error path and try to unlock the source table and
LOCK_open, but both weren't locked.

The solution is to simple return when the name lock request is killed,
it's safe to do so because no lock was acquired and no cleanup is needed.

Original bug report also contains description of other problems
related to this scenario but they either already fixed in 5.1 or
will be addressed separately (see bug report for details).


mysql-test/r/lock_multi.result:
  Add test case result for Bug#31479
mysql-test/t/lock_multi.test:
  Add test case for Bug#31479
sql/sql_table.cc:
  Rerturn TRUE when the lock gets killed.
2007-11-28 10:18:01 -02:00
unknown
8bdb043f08 Bug#25856 (HANDLER table OPEN in one connection lock DROP TABLE in another one)
mysql_ha_open calls mysql_ha_close on the error path (unsupported) to close the (opened) table before inserting it into the tables hash list handler_tables_hash) but mysql_ha_close only closes tables which are on the hash list, causing the table to be left open and locked.

This change moves the table close logic into a separate function that is always called on the error path of mysql_ha_open or on a normal handler close (mysql_ha_close).


mysql-test/r/lock_multi.result:
  Bug#25856 test result
mysql-test/t/lock_multi.test:
  Bug#25856 test case
sql/sql_handler.cc:
  Move the table close logic into a separate function that is always called on the error path of mysql_ha_open or on a normal handler close.
2007-08-17 11:34:12 -03:00
unknown
a3877a11c1 A fix for Bug#29049 lock_multi fails in rare case.
The patch changes the test case only.
The fix is to replace all 'sleep's with wait_condition. This makes
the test deterministic and also ~300 times faster.


mysql-test/r/lock_multi.result:
  Update result.
mysql-test/t/lock_multi.test:
  A fix for Bug#29049 lock_multi fails in rare case.
  Replace all 'sleep's with wait_condition. This makes
  the test deterministic and also ~300 times faster.
2007-08-11 14:07:49 +04:00
unknown
8860704088 Added test for bug #21281 "Pending write lock is incorrectly removed
when its statement being KILLed". The bug itself was fixed by separate
patch in 5.0 tree.


mysql-test/r/lock_multi.result:
  Added test for bug #21281 "Pending write lock is incorrectly removed
  when its statement being KILLed".
mysql-test/t/lock_multi.test:
  Added test for bug #21281 "Pending write lock is incorrectly removed
  when its statement being KILLed".
2007-08-05 13:55:37 +04:00
unknown
6133ee079a Bug#20166 mysql-test-run.pl does not test system privilege tables creation
- Updates for 5.1


mysql-test/t/lock_multi.test:
  Test need anonymous users
mysql-test/t/rpl_temporary.test:
  Test need anonymous users
scripts/mysql_system_tables.sql:
  Update mysql_system_tables.sql for 5.1
2007-02-27 11:39:29 +01:00
unknown
5d4e0417ad Bug#20166 mysql-test-run.pl does not test system privilege tables creation
- Use mysql_system_tables.sql to create MySQL system tables in
   all places where we create them(mysql_install_db, mysql-test-run-pl
   and mysql_fix_privilege_tables.sql)


BitKeeper/deleted/.del-init_db.sql:
  Rename: mysql-test/init_db.sql -> BitKeeper/deleted/.del-init_db.sql
BitKeeper/deleted/.del-init_db.sql~a77d572c39d5a1f8:
  Rename: mysql-test/lib/init_db.sql -> BitKeeper/deleted/.del-init_db.sql~a77d572c39d5a1f8
BitKeeper/deleted/.del-mysql_create_system_tables.sh:
  Rename: scripts/mysql_create_system_tables.sh -> BitKeeper/deleted/.del-mysql_create_system_tables.sh
BitKeeper/etc/ignore:
  Added scripts/mysql_fix_privilege_tables.sql to the ignore list
mysql-test/Makefile.am:
  lib/init_db.sql has been removed
mysql-test/mysql-test-run.pl:
  - Build var/tmp/bootstrap.sql from mysql_system_tables.sql,
  mysql_test_data_timezone.sql and fill_help_tables.sql and use
  it when bootsraping the system tables to use during test.
mysql-test/r/create.result:
  Update result file
mysql-test/r/derived.result:
  Update result file
mysql-test/r/join.result:
  Update result file
mysql-test/r/mysql_upgrade.result:
  Update result file
mysql-test/r/sp-security.result:
  Update result file
mysql-test/t/create.test:
  Add user mysqltest_1 before trying to connect as that user - no
  anon users by default anymore
mysql-test/t/derived.test:
  Add user mysqltest_1 before trying to connect as that user - no
  anon users by default anymore
mysql-test/t/grant2.test:
  Add anonymous users for part of thes that need it.
mysql-test/t/grant_cache.test:
  Add anonymous users for part of thes that need it.
mysql-test/t/init_connect.test:
  Add anonymous users for part of thes that need it.
mysql-test/t/lock_multi.test:
  Add anonymous users for part of thes that need it.
mysql-test/t/ndb_basic.test:
  Connect as "root", blank user will take currently logged in
  username
mysql-test/t/ndb_index_ordered.test:
  Connect as "root", blank user will take currently logged in
  username
mysql-test/t/ndb_multi.test:
  Connect as "root", blank user will take currently logged in
  username
mysql-test/t/overflow.test:
  Connect as root - no anonymous users by default anymore
mysql-test/t/rpl_temporary.test:
  Add anonymous users for the test
mysql-test/t/xa.test:
  Connect as "root", blank user wil pick currently logged in user
scripts/Makefile.am:
  Remove mysql_create_system_tables.sh
  Add mysql_system_tables.sql and mysql_test_data_timezone.sql
  Build mysql_fix_privilege_tables.sql from mysql_system_tables.sql
  and mysql_fix_privilege_tables.sql.in
scripts/mysql_fix_privilege_tables.sh:
  Update message describing what the script does
scripts/mysql_fix_privilege_tables.sql.in:
  Remove the part that creates system tables as that will be added to
  mysql_fix_privileg_tables.sql from mysql_system_tables.sql
  Change all comments to use #
scripts/mysql_install_db.sh:
  Use mysql_system_tables.sql to create the MySQL system tables
  Update comments and indentation
  Add more descriptive comments about --windows switch
  Reduce number of hardcoded names for the SQL files the script
  looks for
mysql-test/include/add_anonymous_users.inc:
  New BitKeeper file ``mysql-test/include/add_anonymous_users.inc''
mysql-test/include/delete_anonymous_users.inc:
  New BitKeeper file ``mysql-test/include/delete_anonymous_users.inc''
scripts/mysql_system_tables.sql:
  New BitKeeper file ``scripts/mysql_system_tables.sql''
scripts/mysql_test_data_timezone.sql:
  New BitKeeper file ``scripts/mysql_test_data_timezone.sql''
2007-02-26 11:49:24 +01:00
unknown
1aa1efdbd3 Merge hf@192.168.21.12:work/embt/my50-embt
into  mysql.com:/d2/hf/my51-embt


libmysqld/lib_sql.cc:
  Auto merged
mysql-test/include/federated.inc:
  Auto merged
mysql-test/mysql-test-run.pl:
  Auto merged
mysql-test/r/flush_block_commit.result:
  Auto merged
mysql-test/t/flush_block_commit.test:
  Auto merged
mysql-test/t/innodb.test:
  Auto merged
mysql-test/t/join.test:
  Auto merged
mysql-test/t/status.test:
  Auto merged
mysql-test/t/trigger.test:
  Auto merged
sql/item_func.cc:
  Auto merged
sql/item_strfunc.cc:
  Auto merged
mysql-test/t/lock_multi.test:
  Auto merged
2006-12-26 20:22:17 +04:00
unknown
bf075d8259 lock_multi disabled
mysql-test/t/lock_multi.test:
  doesn't work in embedded server
2006-12-26 20:22:16 +04:00
unknown
45989298ee Merge mysql.com:/home/hf/work/mysql-5.0-mrg
into  mysql.com:/home/hf/work/mysql-5.1-mrg


Makefile.am:
  Auto merged
client/mysqltest.c:
  Auto merged
include/mysql.h:
  Auto merged
BitKeeper/deleted/.del-bdb-deadlock.test:
  Auto merged
libmysql/libmysql.c:
  Auto merged
libmysqld/lib_sql.cc:
  Auto merged
mysql-test/r/order_by.result:
  Auto merged
mysql-test/r/subselect.result:
  Auto merged
mysql-test/t/lock_multi.test:
  Auto merged
mysql-test/t/rename.test:
  Auto merged
mysql-test/t/show_check.test:
  Auto merged
mysql-test/t/status.test:
  Auto merged
mysql-test/t/subselect.test:
  Auto merged
sql/item_subselect.cc:
  Auto merged
sql/item_subselect.h:
  Auto merged
sql/protocol.cc:
  Auto merged
sql-common/client.c:
  Auto merged
sql/protocol.h:
  Auto merged
sql/sql_class.h:
  Auto merged
mysql-test/include/deadlock.inc:
  SCCS merged
mysql-test/t/disabled.def:
  merging
sql/item.cc:
  merging
2006-11-17 18:27:28 +04:00
unknown
e971334ece Merge mysql.com:/home/hf/work/mysql-4.1-mrg
into  mysql.com:/home/hf/work/mysql-5.0-mrg


client/mysqltest.c:
  Auto merged
mysql-test/t/flush.test:
  Auto merged
mysql-test/t/flush_block_commit.test:
  Auto merged
mysql-test/t/innodb-deadlock.test:
  Auto merged
mysql-test/t/innodb-lock.test:
  Auto merged
mysql-test/t/lock_multi.test:
  Auto merged
mysql-test/t/rename.test:
  Auto merged
mysql-test/t/show_check.test:
  Auto merged
mysql-test/t/status.test:
  Auto merged
sql/item.cc:
  Auto merged
sql/protocol.h:
  Auto merged
sql-common/client.c:
  Auto merged
Makefile.am:
  merging
BitKeeper/deleted/.del-mysql_client.test:
  merging
include/mysql.h:
  SCCS merged
libmysql/libmysql.c:
  merging
libmysqld/lib_sql.cc:
  merging
mysql-test/r/order_by.result:
  SCCS merged
mysql-test/r/subselect.result:
  SCCS merged
mysql-test/t/order_by.test:
  merging
mysql-test/t/subselect.test:
  SCCS merged
sql/item_subselect.cc:
  merging
sql/item_subselect.h:
  merging
sql/protocol.cc:
  merging
sql/sql_class.h:
  merging
2006-11-16 23:16:44 +04:00
unknown
4ddb48c619 WL#3475 (Threads for the embedded server in mysqltest)
Necessary code added to mysqltest.c.
Disabled tests are available now.


client/mysqltest.c:
  do_send_query function implemented, so now 'send' command will be
  run in separate thread for the embedded server.
  Mutex and condition added to the 'connection' struct for syncronisation
  purposes. Yes it'd be easier if we had pthread_join() command
libmysql/libmysql.c:
  this isn't actually needed and causes problems in embedded server
mysql-test/t/bdb-deadlock.test:
  test is available for the embedded server now
mysql-test/t/flush.test:
  test is available for the embedded server now
mysql-test/t/flush_block_commit.test:
  test is available for the embedded server now
mysql-test/t/innodb-deadlock.test:
  test is available for the embedded server now
mysql-test/t/innodb-lock.test:
  test is available for the embedded server now
mysql-test/t/lock_multi.test:
  test is available for the embedded server now
mysql-test/t/rename.test:
  test is available for the embedded server now
mysql-test/t/show_check.test:
  test is available for the embedded server now
mysql-test/t/status.test:
  test is available for the embedded server now
2006-10-23 15:02:51 +05:00
unknown
e933e64769 Merge siva.hindu.god:/usr/home/tim/m/bk/50
into  siva.hindu.god:/usr/home/tim/m/bk/51


client/mysqldump.c:
  Auto merged
client/mysqltest.c:
  Auto merged
mysql-test/extra/rpl_tests/rpl_log.test:
  Auto merged
mysql-test/extra/rpl_tests/rpl_max_relay_size.test:
  Auto merged
mysql-test/lib/mtr_cases.pl:
  Auto merged
mysql-test/mysql-test-run.pl:
  Auto merged
mysql-test/lib/mtr_misc.pl:
  Auto merged
mysql-test/r/mysqltest.result:
  Auto merged
mysql-test/r/rpl_000015.result:
  Auto merged
mysql-test/r/rpl_change_master.result:
  Auto merged
mysql-test/r/rpl_err_ignoredtable.result:
  Auto merged
mysql-test/r/rpl_loaddata.result:
  Auto merged
mysql-test/r/rpl_replicate_do.result:
  Auto merged
mysql-test/r/rpl_stm_log.result:
  Auto merged
mysql-test/r/rpl_stm_max_relay_size.result:
  Auto merged
mysql-test/t/create.test:
  Auto merged
mysql-test/t/lock_multi.test:
  Auto merged
mysql-test/t/mysqltest.test:
  Auto merged
mysql-test/t/rpl_000015.test:
  Auto merged
mysql-test/t/rpl_change_master.test:
  Auto merged
mysql-test/t/rpl_drop_db.test:
  Auto merged
mysql-test/t/rpl_err_ignoredtable.test:
  Auto merged
mysql-test/t/rpl_loaddata.test:
  Auto merged
mysql-test/t/rpl_replicate_do.test:
  Auto merged
mysql-test/t/rpl_stm_log-master.opt:
  Auto merged
mysql-test/t/view.test:
  Auto merged
sql/sql_class.cc:
  Auto merged
mysql-test/include/mix1.inc:
  Manual merge (use local)
mysql-test/r/create.result:
  SCCS merged
mysql-test/r/innodb_mysql.result:
  !bkm
  Manual merge (use local)
mysql-test/t/sp.test:
  Manual merge (use local)
2006-10-20 13:53:39 -06:00
unknown
d8d57c77b1 Bug#22436 Four tests require "innodb" to be configured, fail in "classic" build
- Disable warnings when creating the "innodb" tables if it works anyway.
 - Move test that are really innodb dependent to innodb_mysql 


mysql-test/r/create.result:
  Move the innodb dependent test to innodb_mysql.test
mysql-test/r/innodb_mysql.result:
  Move the innodb dependent test to innodb_mysql.test
mysql-test/t/create.test:
  Move the innodb dependent test to innodb_mysql.test
mysql-test/t/innodb_mysql.test:
  Move the innodb dependent test to innodb_mysql.test
mysql-test/t/lock_multi.test:
  Disable warnings while creating the innodb table. If innodb is not available, the table will be created with default engine and thus create a warning. Regardless of this, test output should be the same.
mysql-test/t/sp.test:
  Disable warnings while creating the innodb table. If innodb is not available, the table will be created with default engine and thus create a warning. Regardless of this, test output should be the same.
mysql-test/t/view.test:
  Disable warnings while creating the innodb table. If innodb is not available, the table will be created with default engine and thus create a warning. Regardless of this, test output should be the same.
2006-09-28 15:13:40 +02:00
unknown
bb576ed217 After merge fix 2006-07-04 12:34:23 +02:00
unknown
597ee0392c Merge mysql.com:/home/mydev/mysql-5.0-tmp_merge
into  mysql.com:/home/mydev/mysql-5.1-amerge


mysys/thr_lock.c:
  Auto merged
sql/mysql_priv.h:
  Auto merged
sql/sql_handler.cc:
  Auto merged
sql/sql_insert.cc:
  Auto merged
mysql-test/r/lock_multi.result:
  Manual merge
mysql-test/t/lock_multi.test:
  Manual merge
sql/lock.cc:
  Manual merge
sql/sql_base.cc:
  Manual merge
sql/sql_parse.cc:
  Manual merge
sql/sql_table.cc:
  Manual merge
2006-07-04 10:02:11 +02:00
unknown
1c2a13b894 Bug#16986 - Deadlock condition with MyISAM tables
Addendum fixes after changing the condition variable
for the global read lock.

The stress test suite revealed some deadlocks. Some were
related to the new condition variable (COND_global_read_lock)
and some were general problems with the global read lock.

It is now necessary to signal COND_global_read_lock whenever 
COND_refresh is signalled.

We need to wait for the release of a global read lock if one 
is set before every operation that requires a write lock.
But we must not wait if we have locked tables by LOCK TABLES.
After setting a global read lock a thread waits until all
write locks are released.


mysql-test/r/lock_multi.result:
  Bug#16986 - Deadlock condition with MyISAM tables
  Addendum fixes after changing the condition variable
  for the global read lock.
  Added test results.
mysql-test/t/lock_multi.test:
  Bug#16986 - Deadlock condition with MyISAM tables
  Addendum fixes after changing the condition variable
  for the global read lock.
  Added tests for possible deadlocks that did not occur
  with the stress test suite.
mysys/thr_lock.c:
  Bug#16986 - Deadlock condition with MyISAM tables
  Addendum fixes after changing the condition variable
  for the global read lock.
  Added a protection against an infinite loop that occurs
  with the test case for Bug #20662.
sql/lock.cc:
  Bug#16986 - Deadlock condition with MyISAM tables
  Addendum fixes after changing the condition variable
  for the global read lock.
  Signal COND_global_read_lock whenever COND_refresh
  is signalled by using the new function broadcast_refresh().
  Added the definition of a new function that signals 
  COND_global_read_lock whenever COND_refresh is signalled.
sql/mysql_priv.h:
  Bug#16986 - Deadlock condition with MyISAM tables
  Addendum fixes after changing the condition variable
  for the global read lock.
  Added a declaration for a new function that signals 
  COND_global_read_lock whenever COND_refresh is signalled.
sql/sql_base.cc:
  Bug#16986 - Deadlock condition with MyISAM tables
  Addendum fixes after changing the condition variable
  for the global read lock.
  Signal COND_global_read_lock whenever COND_refresh
  is signalled by using the new function broadcast_refresh().
sql/sql_handler.cc:
  Bug#16986 - Deadlock condition with MyISAM tables
  Addendum fixes after changing the condition variable
  for the global read lock.
  Signal COND_global_read_lock whenever COND_refresh
  is signalled by using the new function broadcast_refresh().
sql/sql_insert.cc:
  Bug#16986 - Deadlock condition with MyISAM tables
  Addendum fixes after changing the condition variable
  for the global read lock.
  Removed global read lock handling from inside of 
  INSERT DELAYED. It is handled on a higher level now.
sql/sql_parse.cc:
  Bug#16986 - Deadlock condition with MyISAM tables
  Addendum fixes after changing the condition variable
  for the global read lock.
  Wait for the release of a global read lock if one is set
  before every operation that requires a write lock.
  But don't wait if locked tables exist already.
sql/sql_table.cc:
  Bug#16986 - Deadlock condition with MyISAM tables
  Addendum fixes after changing the condition variable
  for the global read lock.
  Removed global read lock handling from inside of 
  CREATE TABLE. It is handled on a higher level now.
  Signal COND_global_read_lock whenever COND_refresh
  is signalled by using the new function broadcast_refresh().
2006-06-26 19:14:35 +02:00
unknown
b02748fd5c Merge mysql.com:/home/emurphy/src/bk-clean/tmp_merge
into  mysql.com:/home/emurphy/src/bk-clean/mysql-5.1


mysql-test/r/func_time.result:
  Auto merged
sql/item_cmpfunc.cc:
  Auto merged
mysql-test/r/lock_multi.result:
  manual merge
mysql-test/t/lock_multi.test:
  manual merge
sql/ha_innodb.cc:
  manual merge
2006-06-23 17:27:54 -04:00