Commit graph

233 commits

Author SHA1 Message Date
Konstantin Osipov
29c4873ad5 Commit on behalf of Dmitry Lenev.
Merge his patch for Bug#52044 into 5.5, and apply 
review comments.
2010-08-12 17:50:23 +04:00
Konstantin Osipov
36290c0923 A pre-requisite patch for the fix for Bug#52044.
This patch also fixes Bug#55452 "SET PASSWORD is
replicated twice in RBR mode".

The goal of this patch is to remove the release of 
metadata locks from close_thread_tables().
This is necessary to not mistakenly release
the locks in the course of a multi-step
operation that involves multiple close_thread_tables()
or close_tables_for_reopen().

On the same token, move statement commit outside 
close_thread_tables().

Other cleanups:
Cleanup COM_FIELD_LIST.
Don't call close_thread_tables() in COM_SHUTDOWN -- there
are no open tables there that can be closed (we leave
the locked tables mode in THD destructor, and this
close_thread_tables() won't leave it anyway).

Make open_and_lock_tables() and open_and_lock_tables_derived()
call close_thread_tables() upon failure.
Remove the calls to close_thread_tables() that are now
unnecessary.

Simplify the back off condition in Open_table_context.

Streamline metadata lock handling in LOCK TABLES 
implementation.

Add asserts to ensure correct life cycle of 
statement transaction in a session.

Remove a piece of dead code that has also become redundant
after the fix for Bug 37521.

mysql-test/r/variables.result:
  Update results: set @@autocommit and statement transaction/
  prelocked mode.
mysql-test/r/view.result:
  A harmless change in CHECK TABLE <view> status for a broken view.
  If previously a failure to prelock all functions used in a view 
  would leave the connection in LTM_PRELOCKED mode, now we call
  close_thread_tables() from open_and_lock_tables()
  and leave prelocked mode, thus some check in mysql_admin_table() that
  works only in prelocked/locked tables mode is no longer activated.
mysql-test/suite/rpl/r/rpl_row_implicit_commit_binlog.result:
  Fixed Bug#55452 "SET PASSWORD is replicated twice in
  RBR mode": extra binlog events are gone from the
  binary log.
mysql-test/t/variables.test:
  Add a test case: set autocommit and statement transaction/prelocked
  mode.
sql/event_data_objects.cc:
  Simplify code in Event_job_data::execute().
  Move sp_head memory management to lex_end().
sql/event_db_repository.cc:
  Move the release of metadata locks outside
  close_thread_tables().
  Make sure we call close_thread_tables() when
  open_and_lock_tables() fails and remove extra
  code from the events data dictionary.
  Use close_mysql_tables(), a new internal
  function to properly close mysql.* tables
  in the data dictionary.
  Contract Event_db_repository::drop_events_by_field,
  drop_schema_events into one function.
  When dropping all events in a schema,
  make sure we don't mistakenly release all
  locks acquired by DROP DATABASE. These
  include locks on the database name
  and the global intention exclusive
  metadata lock.
sql/event_db_repository.h:
  Function open_event_table() does not require an instance 
  of Event_db_repository.
sql/events.cc:
  Use close_mysql_tables() instead of close_thread_tables()
  to bootstrap events, since the latter no longer
  releases metadata locks.
sql/ha_ndbcluster.cc:
  - mysql_rm_table_part2 no longer releases
  acquired metadata locks. Do it in the caller.
sql/ha_ndbcluster_binlog.cc:
  Deploy the new protocol for closing thread
  tables in run_query() and ndb_binlog_index
  code.
sql/handler.cc:
  Assert that we never call ha_commit_trans/
  ha_rollback_trans in sub-statement, which
  is now the case.
sql/handler.h:
  Add an accessor to check whether THD_TRANS object
  is empty (has no transaction started).
sql/log.cc:
  Update a comment.
sql/log_event.cc:
  Since now we commit/rollback statement transaction in 
  mysql_execute_command(), we need a mechanism to communicate
  from Query_log_event::do_apply_event() to mysql_execute_command()
  that the statement transaction should be rolled back, not committed.
  Ideally it would be a virtual method of THD. I hesitate
  to make THD a virtual base class in this already large patch.
  Use a thd->variables.option_bits for now.
  
  Remove a call to close_thread_tables() from the slave IO
  thread. It doesn't open any tables, and the protocol
  for closing thread tables is more complicated now.
  
  Make sure we properly close thread tables, however, 
  in Load_data_log_event, which doesn't
  follow the standard server execution procedure
  with mysql_execute_command().
  @todo: this piece should use Server_runnable
  framework instead.
  Remove an unnecessary call to mysql_unlock_tables().
sql/rpl_rli.cc:
  Update Relay_log_info::slave_close_thread_tables()
  to follow the new close protocol.
sql/set_var.cc:
  Remove an unused header.
sql/slave.cc:
  Remove an unnecessary call to
  close_thread_tables().
sql/sp.cc:
  Remove unnecessary calls to close_thread_tables()
  from SP DDL implementation. The tables will
  be closed by the caller, in mysql_execute_command().
  When dropping all routines in a database, make sure
  to not mistakenly drop all metadata locks acquired
  so far, they include the scoped lock on the schema.
sql/sp_head.cc:
  Correct the protocol that closes thread tables
  in an SP instruction.
  Clear lex->sphead before cleaning up lex
  with lex_end to make sure that we don't
  delete the sphead twice. It's considered
  to be "cleaner" and more in line with
  future changes than calling delete lex->sphead
  in other places that cleanup the lex.
sql/sp_head.h:
  When destroying m_lex_keeper of an instruction,
  don't delete the sphead that all lex objects
  share. 
  @todo: don't store a reference to routine's sp_head
  instance in instruction's lex.
sql/sql_acl.cc:
  Don't call close_thread_tables() where the caller will
  do that for us.
  Fix Bug#55452 "SET PASSWORD is replicated twice in RBR 
  mode" by disabling RBR replication in change_password()
  function.
  Use close_mysql_tables() in bootstrap and ACL reload
  code to make sure we release all metadata locks.
sql/sql_base.cc:
  This is the main part of the patch:
  - remove manipulation with thd->transaction
  and thd->mdl_context from close_thread_tables().
  Now this function is only responsible for closing
  tables, nothing else.
  This is necessary to be able to easily use
  close_thread_tables() in procedures, that
  involve multiple open/close tables, which all
  need to be protected continuously by metadata
  locks.
  Add asserts ensuring that TABLE object
  is only used when is protected by a metadata lock.
  Simplify the back off condition of Open_table_context,
  we no longer need to look at the autocommit mode.
  Make open_and_lock_tables() and open_normal_and_derived_tables()
  close thread tables and release metadata locks acquired so-far 
  upon failure. This simplifies their usage.
  Implement close_mysql_tables().
sql/sql_base.h:
  Add declaration for close_mysql_tables().
sql/sql_class.cc:
  Remove a piece of dead code that has also become redundant
  after the fix for Bug 37521.
  The code became dead when my_eof() was made a non-protocol method,
  but a method that merely modifies the diagnostics area.
  The code became redundant with the fix for Bug#37521, when 
  we started to cal close_thread_tables() before
  Protocol::end_statement().
sql/sql_do.cc:
  Do nothing in DO if inside a substatement
  (the assert moved out of trans_rollback_stmt).
sql/sql_handler.cc:
  Add comments.
sql/sql_insert.cc:
  Remove dead code. 
  Release metadata locks explicitly at the
  end of the delayed insert thread.
sql/sql_lex.cc:
  Add destruction of lex->sphead to lex_end(),
  lex "reset" method called at the end of each statement.
sql/sql_parse.cc:
  Move close_thread_tables() and other related
  cleanups to mysql_execute_command()
  from dispatch_command(). This has become
  possible after the fix for Bug#37521.
  Mark federated SERVER statements as DDL.
  
  Next step: make sure that we don't store
  eof packet in the query cache, and move
  the query cache code outside mysql_parse.
  
  Brush up the code of COM_FIELD_LIST.
  Remove unnecessary calls to close_thread_tables().
  
  When killing a query, don't report "OK"
  if it was a suicide.
sql/sql_parse.h:
  Remove declaration of a function that is now static.
sql/sql_partition.cc:
  Remove an unnecessary call to close_thread_tables().
sql/sql_plugin.cc:
  open_and_lock_tables() will clean up
  after itself after a failure.
  Move close_thread_tables() above
  end: label, and replace with close_mysql_tables(),
  which will also release the metadata lock
  on mysql.plugin.
sql/sql_prepare.cc:
  Now that we no longer release locks in close_thread_tables()
  statement prepare code has become more straightforward.
  Remove the now redundant check for thd->killed() (used
  only by the backup project) from Execute_server_runnable.
  Reorder code to take into account that now mysql_execute_command()
  performs lex->unit.cleanup() and close_thread_tables().
sql/sql_priv.h:
  Add a new option to server options to interact
  between the slave SQL thread and execution
  framework (hack). @todo: use a virtual
  method of class THD instead.
sql/sql_servers.cc:
  Due to Bug 25705 replication of 
  DROP/CREATE/ALTER SERVER is broken.
  Make sure at least we do not attempt to 
  replicate these statements using RBR,
  as this violates the assert in close_mysql_tables().
sql/sql_table.cc:
  Do not release metadata locks in mysql_rm_table_part2,
  this is done by the caller.
  Do not call close_thread_tables() in mysql_create_table(),
  this is done by the caller. 
  Fix a bug in DROP TABLE under LOCK TABLES when,
  upon error in wait_while_table_is_used() we would mistakenly
  release the metadata lock on a non-dropped table.
  Explicitly release metadata locks when doing an implicit
  commit.
sql/sql_trigger.cc:
  Now that we delete lex->sphead in lex_end(),
  zero the trigger's sphead in lex after loading
  the trigger, to avoid double deletion.
sql/sql_udf.cc:
  Use close_mysql_tables() instead of close_thread_tables().
sql/sys_vars.cc:
  Remove code added in scope of WL#4284 which would
  break when we perform set @@session.autocommit along
  with setting other variables and using tables or functions.
  A test case added to variables.test.
sql/transaction.cc:
  Add asserts.
sql/tztime.cc:
  Use close_mysql_tables() rather than close_thread_tables().
2010-07-27 14:25:53 +04:00
Jon Olav Hauglid
f45523188e merge from mysql-trunk-bugfixing 2010-07-13 10:39:24 +02:00
Davi Arnaut
f56dd32bf7 Bug#34043: Server loops excessively in _checkchunk() when safemalloc is enabled
Essentially, the problem is that safemalloc is excruciatingly
slow as it checks all allocated blocks for overrun at each
memory management primitive, yielding a almost exponential
slowdown for the memory management functions (malloc, realloc,
free). The overrun check basically consists of verifying some
bytes of a block for certain magic keys, which catches some
simple forms of overrun. Another minor problem is violation
of aliasing rules and that its own internal list of blocks
is prone to corruption.

Another issue with safemalloc is rather the maintenance cost
as the tool has a significant impact on the server code.
Given the magnitude of memory debuggers available nowadays,
especially those that are provided with the platform malloc
implementation, maintenance of a in-house and largely obsolete
memory debugger becomes a burden that is not worth the effort
due to its slowness and lack of support for detecting more
common forms of heap corruption.

Since there are third-party tools that can provide the same
functionality at a lower or comparable performance cost, the
solution is to simply remove safemalloc. Third-party tools
can provide the same functionality at a lower or comparable
performance cost. 

The removal of safemalloc also allows a simplification of the
malloc wrappers, removing quite a bit of kludge: redefinition
of my_malloc, my_free and the removal of the unused second
argument of my_free. Since free() always check whether the
supplied pointer is null, redudant checks are also removed.

Also, this patch adds unit testing for my_malloc and moves
my_realloc implementation into the same file as the other
memory allocation primitives.

client/mysqldump.c:
  Pass my_free directly as its signature is compatible with the
  callback type -- which wasn't the case for free_table_ent.
2010-07-08 18:20:08 -03:00
Jon Olav Hauglid
132ccf93d8 Bug #54401 assert in Diagnostics_area::set_eof_status , HANDLER
This assert checks that the server does not try to send EOF to the
client if there has been some error during processing. This to make
sure that the error is in fact sent to the client.

The problem was that any errors during processing of WHERE conditions
in HANDLER ... READ statements where not detected by the handler code.
The handler code therefore still tried to send EOF to the client,
triggering the assert. The bug was only noticeable in debug builds.

This patch fixes the problem by making sure that the handler code
checks for errors during condition processing and acts accordingly.
2010-07-05 13:59:34 +02:00
Konstantin Osipov
cc6dabba37 Merge trunk-bugfixing -> trunk-runtime 2010-06-17 17:31:51 +04:00
Ramil Kalimullin
3844367f2b Automerge. 2010-06-11 19:36:57 +04:00
Ramil Kalimullin
f4b7c50d6e Fix for bug #54007: assert in ha_myisam::index_next, HANDLER
Problem: the server missed the fact that one can read from 
2 indexes alternately using HANDLER interface.

Fix: check if the same (initialized) index is involved
reading next/prev values from the index.


mysql-test/r/handler_myisam.result:
  Fix for bug #54007: assert in ha_myisam::index_next, HANDLER
    - test result.
mysql-test/t/handler_myisam.test:
  Fix for bug #54007: assert in ha_myisam::index_next, HANDLER
    - test case.
sql/sql_handler.cc:
  Fix for bug #54007: assert in ha_myisam::index_next, HANDLER
    - check if we use the same (initialized) index 
  to read next/prev values from the index.
2010-06-09 14:45:04 +04:00
Konstantin Osipov
8d42534182 A review comment for WL#4441 " LOCK_open: Remove requirement of
mutex protecting thd->open_tables".

We should not manipulate with table->s->version outside the 
table definition cache code, but use the TDC API
to achieve the desired result.

Fix one violation: close_all_tables_for_name().

sql/sql_base.cc:
  Use tdc_remove_table(TDC_RT_REMOVE_ALL) to expel the
  table share in close_all_tables_for_name, rather
  than manipulate with the table cache explicitly.
  
  Make sure that close_cached_tables() calls 
  close_all_tables_for_name() after closing all the involved
  handlers. The rest of the code was inspected to
  make sure that mysql_ha_rm_tables() is called.
sql/sql_handler.cc:
  Add a method to close all HANDLER cursors for a list
  of tables.
sql/sql_handler.h:
  Add declaration for mysql_ha_flush_tables().
2010-06-09 12:39:09 +04:00
Konstantin Osipov
d4f1abaad2 WL#4441 "LOCK_open: Remove requirement of mutex protecting
thd->open_tables"

thd->open_tables list is not normally accessed concurrently
except for one case: when the connection has open SQL
HANDLER tables, and we want to perform a DDL on the table,
we want to abort waits on MyISAM thr_lock of those connections
that prevent the DDL from proceeding, and iterate
over thd->open_tables list to find out the tables on which
the thread is waiting.

In 5.5 we mostly use deadlock detection and soft deadlock 
prevention, as opposed to "hard" deadlock prevention
of 5.1, which would abort any transaction that
may cause a deadlock. The only remaining case when
neither deadlock detection nor deadlock prevention
is implemented in 5.5 is HANDLER SQL, where we use
old good thr_lock_abort() technique form 5.1. 

Thus, replace use of LOCK_open to protect thd->open_tables
with thd->LOCK_ha_data (a lock protecting various session
private data).

This is a port of the work done for 5.5.4 for review
and inclusion into 5.5.5.

sql/sql_base.cc:
  Use thd->LOCK_ha_data (systematically) to set
  thd->open_tables.
sql/sql_class.h:
  Implement THD::set_open_tables().
sql/sql_cursor.cc:
  Use thd->LOCK_ha_data (systematically) to set
  thd->open_tables.
sql/sql_handler.cc:
  Use thd->LOCK_ha_data (systematically) to set
  thd->open_tables.
  Acquisition of LOCK_open is moved inside close_thread_table().
sql/sql_table.cc:
  Acquisition of LOCK_open is moved inside close_thread_tables().
2010-06-08 12:08:46 +04:00
Mats Kindahl
23d8586dbf WL#5030: Split and remove mysql_priv.h
This patch:

- Moves all definitions from the mysql_priv.h file into
  header files for the component where the variable is
  defined
- Creates header files if the component lacks one
- Eliminates all include directives from mysql_priv.h
- Eliminates all circular include cycles
- Rename time.cc to sql_time.cc
- Rename mysql_priv.h to sql_priv.h
2010-03-31 16:05:33 +02:00
Konstantin Osipov
09b7a0d115 A post-review fix for type-aware metadata locks.
DDL no longer aborts mysql_lock_tables(), and hence
we no longer need to support need_reopen flag of this
call. 
Remove the flag, and all the code in the server
that was responsible for handling the case when
it was set. This allowed to simplify: 
open_and_lock_tables_derived(), the delayed thread,
multi-update.

Rename MYSQL_LOCK_IGNORE_FLUSH to MYSQL_OPEN_IGNORE_FLUSH,
since we now only support this flag in open_table().

Rename MYSQL_LOCK_PERF_SCHEMA to MYSQL_LOCK_LOG_TABLE,
to avoid confusion.

Move the wait for the global read lock for cases
when we do updates in SELECT f1() or DO (UPDATE) to 
open_table() from mysql_lock_tables(). When waiting
for the read lock, we could raise need_reopen flag,
which is no longer present in mysql_lock_tables().
Since the block responsible for waiting for GRL
was moved, MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK
was renamed to MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK.


mysql-test/r/mdl_sync.result:
  Update test results (see comments for mdl_sync.test).
mysql-test/t/mdl_sync.test:
  Update tests: an abort mysql_lock_tables() called for an
  INSERT no longer auto-closes SQL HANDLERS, since it
  no longer leads to back-off and retry.
sql/ha_ndbcluster_binlog.cc:
  Remove unused variables.
sql/lock.cc:
  Remove support for need_reopen parameter of mysql_lock_tables().
  Update comments.
sql/log_event_old.cc:
  Remove the loop responsible for handling need_reopen
  out parameter of mysql_lock_tables().
sql/mysql_priv.h:
  Update open and lock tables flag names.
sql/share/errmsg-utf8.txt:
  Add a new error message to report when
  thr_multi_lock() is aborted.
sql/sql_base.cc:
  Update comments. Rename MYSQL_LOCK_IGNORE_FLUSH
  to MYSQL_OPEN_IGNORE_FLUSH.
sql/sql_class.h:
  Remove unused code.
sql/sql_db.cc:
  Remove an unused bit of code.
sql/sql_handler.cc:
  For backward compatibility, we still want to back off and
  retry when a call to mysql_lock_tables() is aborted
  from within an SQL HANDLER. Write an internal error
  handler to support the case.
sql/sql_insert.cc:
  Call mysql_lock_tables() no longer has need_reopen
  out parameter. Simplify the code by removing 
  the crud that took care of it.
  MYSQL_LOCK_IGNORE_FLUSH is now only supported by
  open_tables().
sql/sql_show.cc:
  Rename MYSQL_LOCK_IGNORE_FLUSH to MYSQL_OPEN_IGNORE_FLUSH
sql/sql_table.cc:
  Remove an unused parameter.
sql/sql_update.cc:
  Remove the need_reopen loop from multi-update.
  We no also longer need to cleanup the parse tree in case
  when mysql_lock_tables() is aborted and thus an infinite
  source of multi-update bugs is gone.
sql/tztime.cc:
  Rename MYSQL_LOCK_IGNORE_FLUSH to MYSQL_OPEN_IGNORE_FLUSH,
  since from now on this flag is only supported by open_table().
2010-03-16 00:20:20 +03:00
Konstantin Osipov
7116431a8a A review comment for the fix for Bug#46672.
Remove unnecessary need_reopen loops.
2010-03-13 13:58:27 +03:00
Jon Olav Hauglid
3f1a9baf0b Bug #51355 handler stmt cause assertion in
bool MDL_context::try_acquire_lock(MDL_request*)

This assert was triggered in the following way:
1) HANDLER OPEN t1 from connection 1
2) DROP TABLE t1 from connection 2. This will block due to the metadata lock
held by the open handler in connection 1.
3) DML statement (e.g. INSERT) from connection 1. This will close the table
opened by the HANDLER in 1) and release its metadata lock. This is done due
to the pending exclusive metadata lock from 2). 
4) DROP TABLE t1 from connection 2 now completes and removes table t1.
5) HANDLER READ from connection 1. Since the handler table was closed in 3),
the handler code will try to reopen the table. First a new metadata lock on
t1 will be granted before the command fails since the table was removed in 4).
6) HANDLER READ from connection 1. This caused the assert.

The reason for the assert was that the MDL_request's pointer to the lock
ticket was not reset when the statement failed. HANDLER READ then tried to
acquire a lock using the same MDL_request object, triggering the assert.
This bug was only noticeable on debug builds and did not cause any problems
on release builds.

This patch fixes the problem by assuring that the pointer to the metadata 
lock ticket is reset when reopening of handler tables fails.

Test case added to handler.inc
2010-02-25 18:08:12 +01:00
Dmitry Lenev
d5a498abc6 Fix for bug #50908 "Assertion `handler_tables_hash.records == 0'
failed in enter_locked_tables_mode".

Server was aborted due to assertion failure when one tried to 
execute statement requiring prelocking (i.e. firing triggers
or using stored functions) while having open HANDLERs.

The problem was that THD::enter_locked_tables_mode() method
which was called at the beginning of execution of prelocked 
statement assumed there are no open HANDLERs. It had to do 
so because corresponding THD::leave_locked_tables_mode()
method was unable to properly restore MDL sentinel when
leaving LOCK TABLES/prelocked mode in the presence of open 
HANDLERs.

This patch solves this problem by changing the latter method
to properly restore MDL sentinel and thus removing need for 
this assumption. As a side-effect, it lifts unjustified
limitation by allowing to keep HANDLERs open when entering 
LOCK TABLES mode.

mysql-test/include/handler.inc:
  Adjusted tests after making LOCK TABLES not to close
  open HANDLERs. Added coverage for bug #50908
  "Assertion `handler_tables_hash.records == 0' failed
  in enter_locked_tables_mode".
mysql-test/r/handler_innodb.result:
  Updated test results (see include/handler.inc).
mysql-test/r/handler_myisam.result:
  Updated test results (see include/handler.inc).
sql/mysql_priv.h:
  Introduced mysql_ha_move_tickets_after_trans_sentinel()
  routine which allows to move tickets for metadata locks
  corresponding to open HANDLERs after transaction sentinel.
sql/sql_class.cc:
  Changed THD::leave_locked_tables_mode() to correctly restore 
  MDL sentinel value in the presence of open HANDLERs.
sql/sql_class.h:
  Removed assert from THD::enter_locked_tables_mode() as we
  no longer have to close HANDLERs when entering LOCK TABLES 
  or prelocked modes. Instead we keep them open and correctly
  restore MDL sentinel value after leaving them.
  Removal of assert also fixes problem from the bug report.
sql/sql_handler.cc:
  Introduced mysql_ha_move_tickets_after_trans_sentinel()
  routine which allows to move tickets for metadata locks
  corresponding to open HANDLERs after transaction sentinel.
sql/sql_parse.cc:
  We no longer have to close HANDLERs when entering LOCK TABLES 
  mode. Instead we keep them open and simply correctly restore 
  MDL sentinel value after leaving this mode.
2010-02-12 10:05:43 +03: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
Jon Olav Hauglid
82f4494125 Bug #50907 Assertion `hash_tables->table->next == __null' on
HANDLER OPEN

The problem was a too restrictive assert in the code for 
HANDLER ... OPEN and HANDLER ... READ that checked table->next
to verify that we didn't open views or merge tables.

This pointer is also used to link temporary tables together
(see thd->temporary_tables). In this case TABLE::next can be
set even if we're trying to open a single table.

This patch adjust the two asserts to also check for the presence
of temporary tables.

Test case added to handler_myisam.test.
2010-02-05 15:52:17 +01:00
Konstantin Osipov
665100b69d Merge next-mr -> next-4284. 2010-02-02 02:22:16 +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
Konstantin Osipov
dfdbc84585 A prerequisite patch for the fix for Bug#46224
"HANDLER statements within a transaction might lead to deadlocks".
Introduce a notion of a sentinel to MDL_context. A sentinel
is a ticket that separates all tickets in the context into two
groups: before and after it. Currently we can have (and need) only
one designated sentinel -- it separates all locks taken by LOCK
TABLE or HANDLER statement, which must survive COMMIT and ROLLBACK
and all other locks, which must be released at COMMIT or ROLLBACK.
The tricky part is maintaining the sentinel up to date when
someone release its corresponding ticket. This can happen, e.g.
if someone issues DROP TABLE under LOCK TABLES (generally,
see all calls to release_all_locks_for_name()).
MDL_context::release_ticket() is modified to take care of it.

******
A fix and a test case for Bug#46224 "HANDLER statements within a
transaction might lead to deadlocks".

An attempt to mix HANDLER SQL statements, which are transaction-
agnostic, an open multi-statement transaction,
and DDL against the involved tables (in a concurrent connection) 
could lead to a deadlock. The deadlock would occur when
HANDLER OPEN or HANDLER READ would have to wait on a conflicting
metadata lock. If the connection that issued HANDLER statement
also had other metadata locks (say, acquired in scope of a 
transaction), a classical deadlock situation of mutual wait
could occur.

Incompatible change: entering LOCK TABLES mode automatically
closes all open HANDLERs in the current connection.

Incompatible change: previously an attempt to wait on a lock
in a connection that has an open HANDLER statement could wait
indefinitely/deadlock. After this patch, an error ER_LOCK_DEADLOCK
is produced.

The idea of the fix is to merge thd->handler_mdl_context
with the main mdl_context of the connection, used for transactional
locks. This makes deadlock detection possible, since all waits
with locks are "visible" and available to analysis in a single
MDL context of the connection.

Since HANDLER locks and transactional locks have a different life
cycle -- HANDLERs are explicitly open and closed, and so
are HANDLER locks, explicitly acquired and released, whereas
transactional locks "accumulate" till the end of a transaction
and are released only with COMMIT, ROLLBACK and ROLLBACK TO SAVEPOINT,
a concept of "sentinel" was introduced to MDL_context.
All locks, HANDLER and others, reside in the same linked list.
However, a selected element of the list separates locks with
different life cycle. HANDLER locks always reside at the
end of the list, after the sentinel. Transactional locks are
prepended to the beginning of the list, before the sentinel.
Thus, ROLLBACK, COMMIT or ROLLBACK TO SAVEPOINT, only
release those locks that reside before the sentinel. HANDLER locks
must be released explicitly as part of HANDLER CLOSE statement,
or an implicit close. 
The same approach with sentinel
is also employed for LOCK TABLES locks. Since HANDLER and LOCK TABLES
statement has never worked together, the implementation is
made simple and only maintains one sentinel, which is used either
for HANDLER locks, or for LOCK TABLES locks.


mysql-test/include/handler.inc:
  Add test coverage for Bug#46224 "HANDLER statements within a
  transaction might lead to deadlocks".
  Extended HANDLER coverage to cover a mix of HANDLER, transactions
  and DDL statements.
mysql-test/r/handler_innodb.result:
  Update results (Bug#46224).
mysql-test/r/handler_myisam.result:
  Update results (Bug#46224).
sql/lock.cc:
  Remove thd->some_tables_deleted, it's never used.
sql/log_event.cc:
  No need to check for thd->locked_tables_mode, 
  it's done inside release_transactional_locks().
sql/mdl.cc:
  Implement the concept of HANDLER and LOCK TABLES "sentinel".
  Implement a method to clone an acquired ticket.
  Do not return tickets beyond the sentinel when acquiring
  locks, create a copy.
  Remove methods to merge and backup MDL_context, they are now
  not used (Hurra!). This opens a path to a proper constructor
  and destructor of class MDL_context (to be done in a separate
  patch).
  Modify find_ticket() to provide information about where
  the ticket position is with regard to the sentinel.
sql/mdl.h:
  Add declarations necessary for the implementation of the concept
  of "sentinel", a dedicated ticket separating transactional and
  non-transactional locks.
sql/mysql_priv.h:
  Add mark_tmp_table_for_reuse() declaration, 
  a function to "close" a single session (temporary) table.
sql/sql_base.cc:
  Remove thd->some_tables_deleted.
  Modify deadlock-prevention asserts and deadlock detection
  heuristics to take into account that from now on HANDLER locks
  reside in the same locking context.
  Add broadcast_refresh() to mysql_notify_thread_having_shared_lock():
  this is necessary for the case when a thread having a shared lock
  is asleep in tdc_wait_for_old_versions(). This situation is only
  possible with HANDLER t1 OPEN; FLUSH TABLE (since all over code paths
  that lead to tdc_wait_for_old_versions() always have an
  empty MDL_context). Previously the server would simply deadlock
  in this situation.
sql/sql_class.cc:
  Remove now unused member "THD::some_tables_deleted". 
  Move mysql_ha_cleanup() a few lines above in THD::cleanup() 
  to make sure that all handlers are closed when it's time to 
  destroy the MDL_context of this connection.
  Remove handler_mdl_context and handler_tables.
sql/sql_class.h:
  Remove THD::handler_tables, THD::handler_mdl_context,
  THD::some_tables_deleted.
sql/sql_handler.cc:
  Remove thd->handler_tables.
  Remove thd->handler_mdl_context.
  Rewrite mysql_ha_open() to have no special provision for MERGE
  tables, now that we don't have to manipulate with thd->handler_tables
  it's easy to do.
  Remove dead code.
  Fix a bug in mysql_ha_flush() when we would always flush
  a temporary HANDLER when mysql_ha_flush() is called (actually
  mysql_ha_flush() never needs to flush temporary tables).
sql/sql_insert.cc:
  Update a comment, no more thd->some_tables_deleted.
sql/sql_parse.cc:
  Implement an incompatible change: entering LOCK TABLES closes
  active HANDLERs, if any.
  Now that we have a sentinel, we don't need to check
  for thd->locked_tables_mode when releasing metadata locks in
  COMMIT/ROLLBACK.
sql/sql_plist.h:
  Add new (now necessary) methods to the list class.
sql/sql_prepare.cc:
  Make sure we don't release HANDLER locks when rollback to a
  savepoint, set to not keep locks taken at PREPARE.
sql/sql_servers.cc:
  Update to a new signature of MDL_context::release_all_locks().
sql/sql_table.cc:
  Remove thd->some_tables_deleted.
sql/transaction.cc:
  Add comments. 
  Make sure rollback to (MDL) savepoint works under LOCK TABLES and
  with HANDLER tables.
2009-12-22 19:09:15 +03:00
Marc Alff
0531f85e16 Merge cleanup 2009-12-11 12:45:44 -07:00
Jon Olav Hauglid
fb6b5ee462 Backport of revno: 2617.68.37
Bug #46654 False deadlock on concurrent DML/DDL with partitions, 
           inconsistent behavior

The problem was that if one connection is running a multi-statement 
transaction which involves a single partitioned table, and another 
connection attempts to alter the table, the first connection gets 
ER_LOCK_DEADLOCK and cannot proceed anymore, even when the ALTER TABLE 
statement in another connection has timed out or failed.

The reason for this was that the prepare phase for ALTER TABLE for 
partitioned tables removed all instances of the table from the table 
definition cache before it started waiting on the lock. The transaction 
running in the first connection would notice this and report ER_LOCK_DEADLOCK. 

This patch changes the prep_alter_part_table() ALTER TABLE code so that 
tdc_remove_table() is no longer called. Instead, only the TABLE instance
changed by prep_alter_part_table() is marked as needing reopen.

The patch also removes an unnecessary call to tdc_remove_table() from 
mysql_unpack_partition() as the changed TABLE object is destroyed by the 
caller at a later point.

Test case added in partition_sync.test.
2009-12-10 14:26:00 +01:00
Konstantin Osipov
f129367288 Merge with next-4284. 2009-12-10 11:41:03 +03:00
Konstantin Osipov
f26f632b44 Backport of:
------------------------------------------------------------
revno: 2617.68.25
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-next-bg-pre2-2
timestamp: Wed 2009-09-16 18:26:50 +0400
message:
  Follow-up for one of pre-requisite patches for fixing bug #30977
  "Concurrent statement using stored function and DROP FUNCTION
  breaks SBR".

  Made enum_mdl_namespace enum part of MDL_key class and removed MDL_
  prefix from the names of enum members. In order to do the latter
  changed name of PROCEDURE symbol to PROCEDURE_SYM (otherwise macro
  which was automatically generated for this symbol conflicted with
  MDL_key::PROCEDURE enum member).
2009-12-10 11:21:38 +03:00
Marc Alff
c082955f06 WL#2360 Performance schema
Part III: mysys instrumentation
2009-12-09 20:19:51 -07:00
unknown
832ad46641 Backport of revno: 2617.68.36
---------------------------------------------

This is a patch for bug#47098 assert in MDL_context::destroy on
HANDLER <damaged merge table> OPEN.
      
The assert occurs in MDL_context::destroy when the connection is terminated,
because all mdl_tickets have not been released.
MERGE tables do not support being opened using the HANDLER ... OPEN command,
and trying to do so will result in an error. In the event of an error, all
tables that are opened, should be closed again. The fix for bug#45781 made
sure that this also works for MERGE tables, which causes multiple tables to
be opened.
This fix extends the fix for bug#45781, by ensuring that also all locks are
released, when MERGE tables are involved.

mysql-test/r/merge.result:
  The result of the test.
mysql-test/t/merge.test:
  Added a test based on the bug report, as well as a test of the more general
  scenario.
sql/sql_handler.cc:
  Added code to release all the locks.
2009-12-09 14:41:56 +01:00
Konstantin Osipov
351b912e85 Backport of:
----------------------------------------------------------
revno: 2617.69.25
committer: Konstantin Osipov <kostja@sun.com>
branch nick: 5.4-42546
timestamp: Fri 2009-08-14 23:52:00 +0400
message:
  A cleanup in open_tables() and lock_tables():
  change return type of these functions to bool from int,
  to follow convention in the rest of the code.
(Part of WL#4284 review fixes).

sql/mysql_priv.h:
  Change return type of open_talbes() and lock_tables() from
  int to bool.
sql/sql_base.cc:
  Change return type of open_tables() and lock_tables() from int to bool.
sql/sql_handler.cc:
  Use bool now that open_tables() returns bool.
2009-12-09 12:04:55 +03:00
Jon Olav Hauglid
546e16ebd8 Backport of revno: 2617.69.40
A pre-requisite patch for Bug#30977 "Concurrent statement using 
stored function and DROP FUNCTION breaks SBR".

This patch changes the MDL API by introducing a namespace for
lock keys: MDL_TABLE for tables and views and MDL_PROCEDURE
for stored procedures and functions. The latter is needed for
the fix for Bug#30977.
2009-12-09 09:51:20 +01:00
Jon Olav Hauglid
19ff2445b1 Backport of revno: 2617.68.9
Bug #43272 HANDLER SQL command does not work under LOCK TABLES

HANDLER commands are now explicitly disallowed in LOCK TABLES mode.

Before, HANDLER OPEN gave the misleading error message: "Table x was 
not locked with LOCK TABLES". This patch changes HANDLER OPEN/READ/CLOSE 
to give ER_LOCK_OR_ACTIVE_TRANSACTION "Can't execute the given command 
because you have active locked tables or an active transaction" in
LOCK TABLES mode.

Test case added to lock.test.
2009-12-08 15:56:06 +01:00
Konstantin Osipov
ce5c87a3d3 Backport of:
----------------------------------------------------------
revno: 2617.69.20
committer: Konstantin Osipov <kostja@sun.com>
branch nick: 5.4-4284-1-assert
timestamp: Thu 2009-08-13 18:29:55 +0400
message:
  WL#4284 "Transactional DDL locking"
  A review fix.
  Since WL#4284 implementation separated MDL_request and MDL_ticket,
  MDL_request becamse a utility object necessary only to get a ticket.
  Store it by-value in TABLE_LIST with the intent to merge
  MDL_request::key with table_list->table_name and table_list->db
  in future.
  Change the MDL subsystem to not require MDL_requests to
  stay around till close_thread_tables().
  Remove the list of requests from the MDL context.
  Requests for shared metadata locks acquired in open_tables()
  are only used as a list in recover_from_failed_open_table_attempt(),
  which calls mdl_context.wait_for_locks() for this list.
  To keep such list for recover_from_failed_open_table_attempt(),
  introduce a context class (Open_table_context), that collects
  all requests.
  A lot of minor cleanups and simplications that became possible
  with this change.


sql/event_db_repository.cc:
  Remove alloc_mdl_requests(). Now MDL_request instance is a member
  of TABLE_LIST, and init_one_table() initializes it.
sql/ha_ndbcluster_binlog.cc:
  Remove now unnecessary declaration and initialization
  of binlog_mdl_request.
sql/lock.cc:
  No need to allocate MDL requests in lock_table_names() now.
sql/log.cc:
  Use init_one_table() method, remove alloc_mdl_requests(),
  which is now unnecessary.
sql/log_event.cc:
  No need to allocate mdl_request separately now.
  Use init_one_table() method.
sql/log_event_old.cc:
  Update to the new signature of close_tables_for_reopen().
sql/mdl.cc:
  Update try_acquire_exclusive_lock() to be more easy to use.
  Function lock_table_name_if_not_cached() has been removed.
  Make acquire_shared_lock() signature consistent with
  try_acquire_exclusive_lock() signature.
  Remove methods that are no longer used.
  Update comments.
sql/mdl.h:
  Implement an assignment operator that doesn't
  copy MDL_key (MDL_key::operator= is private and
  should remain private).
  This is a hack to work-around assignment of TABLE_LIST
  by value in several places. Such assignments violate
  encapsulation, since only perform a shallow copy.
  In most cases these assignments are a hack on their own.
sql/mysql_priv.h:
  Update signatures of close_thread_tables() and close_tables_for_reopen().
sql/sp.cc:
  Allocate TABLE_LIST in thd->mem_root.
  Use init_one_table().
sql/sp_head.cc:
  Use init_one_table().
  Remove thd->locked_tables_root, it's no longer needed.
sql/sql_acl.cc:
  Use init_mdl_requests() and init_one_table().
sql/sql_base.cc:
  Update to new signatures of try_acquire_shared_lock() and
  try_acquire_exclusive_lock().
  Remove lock_table_name_if_not_cached().
  Fix a bug in open_ltable() that would not return ER_LOCK_DEADLOCK
  in case of a failed lock_tables() and a multi-statement
  transaction.
  Fix a bug in open_and_lock_tables_derived() that would
  not return ER_LOCK_DEADLOCK in case of a multi-statement
  transaction and a failure of lock_tables().
  Move assignment of enum_open_table_action to a method of Open_table_context, a new class that maintains information
  for backoff actions.
  Minor rearrangements of the code.
  Remove alloc_mdl_requests() in functions that work with system
  tables: instead the patch ensures that callers always initialize
  TABLE_LIST argument.
sql/sql_class.cc:
  THD::locked_tables_root is no more.
sql/sql_class.h:
  THD::locked_tables_root is no more.
  Add a declaration for Open_table_context class.
sql/sql_delete.cc:
  Update to use the simplified MDL API.
sql/sql_handler.cc:
  TABLE_LIST::mdl_request is stored by-value now.
  Ensure that mdl_request.ticket is NULL for every request
  that is passed into MDL, to satisfy MDL asserts.
  @ sql/sql_help.cc
  Function open_system_tables_for_read() no longer initializes
  mdl_requests.
  Move TABLE_LIST::mdl_request initialization closer to
  TABLE_LIST initialization.
sql/sql_help.cc:
  Function open_system_tables_for_read() no longer initializes
  mdl_requests.
  Move TABLE_LIST::mdl_request initialization closer to
  TABLE_LIST initialization.
sql/sql_insert.cc:
  Remove assignment by-value of TABLE_LIST in
  TABLEOP_HOOKS. We can't carry over a granted
  MDL ticket from one table list to another.
sql/sql_parse.cc:
  Change alloc_mdl_requests() -> init_mdl_requests().
  @todo We can remove init_mdl_requests() altogether
  in some places: all places that call add_table_to_list()
  already have mdl requests initialized.
sql/sql_plugin.cc:
  Use init_one_table().
  THD::locked_tables_root is no more.
sql/sql_servers.cc:
  Use init_one_table().
sql/sql_show.cc:
  Update acquire_high_priority_shared_lock() to use
  TABLE_LIST::mdl_request rather than allocate an own.
  Fix get_trigger_table_impl() to use init_one_table(),
  check for out of memory, follow the coding style.
sql/sql_table.cc:
  Update to work with TABLE_LIST::mdl_request by-value.
  Remove lock_table_name_if_not_cached().
  The code that used to delegate to it is quite simple and
  concise without it now.
sql/sql_udf.cc:
  Use init_one_table().
sql/sql_update.cc:
  Update to use the new signature of close_tables_for_reopen().
sql/table.cc:
  Move re-setting of mdl_requests for prepared statements
  and stored procedures from close_thread_tables() to
  reinit_stmt_before_use().
  Change alloc_mdl_requests() to init_mdl_requests().
  init_mdl_requests() is a hack that can't be deleted
  until we don't have a list-aware TABLE_LIST constructor.
  Hopefully its use will be minimal
sql/table.h:
  Change alloc_mdl_requests() to init_mdl_requests()
  TABLE_LIST::mdl_request is stored by value.
sql/tztime.cc:
  We no longer initialize mdl requests in open_system_tables_for*()
  functions. Move this initialization closer to initialization
  of the rest of TABLE_LIST members.
storage/myisammrg/ha_myisammrg.cc:
  Simplify mdl_request initialization.
2009-12-08 12:57:07 +03:00
Konstantin Osipov
a9013f8fba Backport of:
----------------------------------------------------------
revno: 2617.23.20
committer: Konstantin Osipov <kostja@sun.com>
branch nick: mysql-6.0-runtime
timestamp: Wed 2009-03-04 16:31:31 +0300
message:
  WL#4284 "Transactional DDL locking"
  Review comments: "Objectify" the MDL API.
  MDL_request and MDL_context still need manual construction and
  destruction, since they are used in environment that is averse
  to constructors/destructors.


sql/mdl.cc:
  Improve comments.
  Add asserts to backup()/restore_from_backup()/merge() methods.
  Fix an order bug in the error path of mdl_acquire_exclusive_locks():
  we used to first free a ticket object, and only then exclude
  it from the list of tickets.
2009-12-04 02:52:05 +03:00
Konstantin Osipov
f477e66ec5 Backport of:
------------------------------------------------------------
revno: 2617.23.18
committer: Davi Arnaut <Davi.Arnaut@Sun.COM>
branch nick: 4284-6.0
timestamp: Mon 2009-03-02 18:18:26 -0300
message:
Bug#989: If DROP TABLE while there's an active transaction, wrong binlog order
WL#4284: Transactional DDL locking

This is a prerequisite patch:

These changes are intended to split lock requests from granted
locks and to allow the memory and lifetime of granted locks to
be managed within the MDL subsystem. Furthermore, tickets can
now be shared and therefore are used to satisfy multiple lock
requests, but only shared locks can be recursive.

The problem is that the MDL subsystem morphs lock requests into
granted locks locks but does not manage the memory and lifetime
of lock requests, and hence, does not manage the memory of
granted locks either. This can be problematic because it puts the
burden of tracking references on the users of the subsystem and
it can't be easily done in transactional contexts where the locks
have to be kept around for the duration of a transaction.

Another issue is that recursive locks (when the context trying to
acquire a lock already holds a lock on the same object) requires
that each time the lock is granted, a unique lock request/granted
lock structure structure must be kept around until the lock is
released. This can lead to memory leaks in transactional contexts
as locks taken during the transaction should only be released at
the end of the transaction. This also leads to unnecessary wake
ups (broadcasts) in the MDL subsystem if the context still holds
a equivalent of the lock being released.

These issues are exacerbated due to the fact that WL#4284 low-level
design says that the implementation should "2) Store metadata locks
in transaction memory root, rather than statement memory root" but
this is not possible because a memory root, as implemented in mysys,
requires all objects allocated from it to be freed all at once.

This patch combines review input and significant code contributions
from Konstantin Osipov (kostja) and Dmitri Lenev (dlenev).


mysql-test/r/mdl_sync.result:
  Add test case result.
mysql-test/t/mdl_sync.test:
  Add test case for shared lock upgrade case.
sql/event_db_repository.cc:
  Rename mdl_alloc_lock to mdl_request_alloc.
sql/ha_ndbcluster_binlog.cc:
  Use new function names to initialize MDL lock requests.
sql/lock.cc:
  Rename MDL functions.
sql/log_event.cc:
  The MDL request now holds the table and database name data (MDL_KEY).
sql/mdl.cc:
  Move the MDL key to the MDL_LOCK structure in order to make the
  object suitable for allocation from a fixed-size allocator. This
  allows the simplification of the lists in the MDL_LOCK object,
  which now are just two, one for granted tickets and other for
  waiting (upgraders) tickets.
  
  Recursive requests for a shared lock on the same object can now
  be granted using the same lock ticket. This schema is only used
  for shared locks because that the only case that matters. This
  is used to avoid waste of resources in case a context (connection)
  already holds a shared lock on a object.
sql/mdl.h:
  Introduce a metadata lock object key which is used  to uniquely
  identify lock objects.
  
  Separate the structure used to represent pending lock requests
  from the structure used to represent granted metadata locks.
  
  Rename functions used to manipulate locks requests in order to
  have a more consistent function naming schema.
sql/sp_head.cc:
  Rename mdl_alloc_lock to mdl_request_alloc.
sql/sql_acl.cc:
  Rename alloc_mdl_locks to alloc_mdl_requests.
sql/sql_base.cc:
  Various changes to accommodate that lock requests are separated
  from lock tickets (granted locks).
sql/sql_class.h:
  Last acquired lock before the savepoint was set.
sql/sql_delete.cc:
  Various changes to accommodate that lock requests are separated
  from lock tickets (granted locks).
sql/sql_handler.cc:
  Various changes to accommodate that lock requests are separated
  from lock tickets (granted locks).
sql/sql_insert.cc:
  Rename alloc_mdl_locks to alloc_mdl_requests.
sql/sql_parse.cc:
  Rename alloc_mdl_locks to alloc_mdl_requests.
sql/sql_plist.h:
  Typedef for iterator type.
sql/sql_plugin.cc:
  Rename alloc_mdl_locks to alloc_mdl_requests.
sql/sql_servers.cc:
  Rename alloc_mdl_locks to alloc_mdl_requests.
sql/sql_show.cc:
  Various changes to accommodate that lock requests are separated
  from lock tickets (granted locks).
sql/sql_table.cc:
  Various changes to accommodate that lock requests are separated
  from lock tickets (granted locks).
sql/sql_trigger.cc:
  Save reference to the lock ticket so it can be downgraded later.
sql/sql_udf.cc:
  Rename alloc_mdl_locks to alloc_mdl_requests.
sql/table.cc:
  Rename mdl_alloc_lock to mdl_request_alloc.
sql/table.h:
  Separate MDL lock requests from lock tickets (granted locks).
storage/myisammrg/ha_myisammrg.cc:
  Rename alloc_mdl_locks to alloc_mdl_requests.
2009-12-04 02:29:40 +03:00
Konstantin Osipov
124cda8a0a Backport of:
------------------------------------------------------------
revno: 2630.4.33
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-6.0-3726-w2
timestamp: Fri 2008-06-20 17:11:20 +0400
message:
  WL#3726 "DDL locking for all metadata objects".

  After-review fixes in progress.

  Minimized dependency of mdl.cc on other modules (particularly
  made it independant of mysql_priv.h) in order to be able
  write unit tests for metadata locking subsystem.


sql/ha_ndbcluster_binlog.cc:
  Use newly introduced MAX_MDLKEY_LENGTH constant for allocating
  buffer for object key for metadata locking subsystem.
sql/log_event.cc:
  Use newly introduced MAX_MDLKEY_LENGTH constant for allocating
  buffer for object key for metadata locking subsystem.
sql/mdl.cc:
  Removed dependency on THD class (and thus on mysql_priv.h)
  by using direct access to members of st_my_thread_var instead
  of accessing THD::killed/enter_cond()/exit_cond().
sql/mdl.h:
  Added MAX_MDLKEY_LENGTH constant to be used for allocating
  buffers for key for metadata locking subsystem.
  Added declarations of server kernel functions used by metadata
  locking subsystem to mdl.h in order to decrease dependency of
  mdl.cc on other files.
sql/mysql_priv.h:
  Moved declaration of notify_thread_having_shared_lock() to the
  mdl.h (also renamed it to make clear in metadata locking code
  that it is a callback to SQL-layer).
sql/sql_base.cc:
  Renamed notify_thread_having_shared_lock() to make it clear
  in metadata locking subsystem code that it is a callback
  to SQL layer.
sql/sql_handler.cc:
  Use newly introduced MAX_MDLKEY_LENGTH constant for allocating
  buffer for object key for metadata locking subsystem.
sql/sql_show.cc:
  Use newly introduced MAX_MDLKEY_LENGTH constant for allocating
  buffer for object key for metadata locking subsystem.
2009-12-02 19:31:57 +03:00
Konstantin Osipov
e3b3907c4f Backport of:
------------------------------------------------------------
revno: 2630.4.32
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-6.0-3726-w2
timestamp: Thu 2008-06-19 16:39:58 +0400
message:
  WL#3726 "DDL locking for all metadata objects".

  After-review fixes in progress.

  Ensure that metadata locking subsystem properly handles
  out-of-memory conditions. Clarified MDL interface by
  separating release of locks and removal of lock requests
  from the context.

sql/lock.cc:
  mdl_release_lock(), mdl_acquire_exclusive_locks() and 
  mdl_try_acquire_exclusive_lock() are no longer responsible
  for removal of metadata lock requests from the context.
  One should explicitly call mdl_remove_all_locks() and
  mdl_remove_lock() to do this.
sql/mdl.cc:
  Ensured that metadata locking subsystem properly handles
  out-of-memory conditions.
  Introduced new MDL_INITIALIZED state for metadata lock
  request which is used in all cases when lock is not acquired 
  and we have not associated request with object respesenting 
  lock.
  
  MDL_PENDING is now only used for requests for exclusive locks
  which are added to the MDL_LOCK::waiting_exclusive queue.
  mdl_release_lock(), mdl_acquire_exclusive_locks() and 
  mdl_try_acquire_exclusive_lock() are no longer responsible
  for removal of metadata lock requests from the context.
  One should explicitly call mdl_remove_all_locks() and
  newly introduced mdl_remove_lock() to do this.
  Also renamed mdl_release_all_locks_for_name() to 
  emphasize that it also actually removes lock requests
  from the context.
  
  Finally mdl_try_acquire_exclusive_lock() is now returs
  information about encountered lock conflict in separate
  out parameter since its return value is used for distinguishing
  between error (e.g. due to OOM) and success.
sql/mdl.h:
  Introduced new MDL_INITIALIZED state for metadata lock
  request which is used in all cases when lock is not acquired 
  and we have not associated request with object respesenting 
  lock.
  
  MDL_PENDING is now only used for requests for exclusive locks
  which are added to the MDL_LOCK::waiting_exclusive queue.
  mdl_release_lock(), mdl_acquire_exclusive_locks() and 
  mdl_try_acquire_exclusive_lock() are no longer responsible
  for removal of metadata lock requests from the context.
  One should explicitly call mdl_remove_all_locks() and
  newly introduced mdl_remove_lock() to do this.
  Also renamed mdl_release_all_locks_for_name() to 
  emphasize that it also actually removes lock requests
  from the context.
  
  Finally mdl_try_acquire_exclusive_lock() is now returs
  information about encountered lock conflict in separate
  out parameter since its return value is used for distinguishing
  between error (e.g. due to OOM) and success.
sql/sql_base.cc:
  mdl_release_lock(), mdl_acquire_exclusive_locks() and mdl_try_acquire_exclusive_lock() are no longer responsible
  for removal of metadata lock requests from the context.
  One should explicitly call mdl_remove_all_locks() and
  mdl_remove_lock() to do this.
  Also adjusted open_table() to ensure that it 
  releases/removes metadata locks in case of error 
  after adding/acquiring them (unless keeping these
  lock requests is required for recovering action).
sql/sql_delete.cc:
  mdl_release_lock(), mdl_acquire_exclusive_locks() and mdl_try_acquire_exclusive_lock() are no longer responsible
  for removal of metadata lock requests from the context.
  One should explicitly call mdl_remove_all_locks() and
  mdl_remove_lock() to do this.
sql/sql_handler.cc:
  mdl_release_lock(), mdl_acquire_exclusive_locks() and mdl_try_acquire_exclusive_lock() are no longer responsible
  for removal of metadata lock requests from the context.
  One should explicitly call mdl_remove_all_locks() and
  mdl_remove_lock() to do this.
sql/sql_show.cc:
  mdl_release_lock(), mdl_acquire_exclusive_locks() and mdl_try_acquire_exclusive_lock() are no longer responsible
  for removal of metadata lock requests from the context.
  One should explicitly call mdl_remove_all_locks() and
  mdl_remove_lock() to do this.
sql/sql_table.cc:
  Renamed mdl_release_all_locks_for_name() to emphasize
  that it also actually removes lock requests from the context.
  mdl_release_lock(), mdl_acquire_exclusive_locks() and mdl_try_acquire_exclusive_lock() are no longer responsible
  for removal of metadata lock requests from the context.
  One should explicitly call mdl_remove_all_locks() and
  mdl_remove_lock() to do this.
  Finally mdl_try_acquire_exclusive_lock() is now returs
  information about encountered lock conflict in separate
  out parameter since its return value is used for distinguishing
  between error (e.g. due to OOM) and success.
2009-12-02 19:15:40 +03:00
Konstantin Osipov
1480dafe2f Backport of:
------------------------------------------------------------
revno: 2630.8.3
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-6.0-3726-w4
timestamp: Thu 2008-06-05 10:48:36 +0400
message:
  WL#3726 "DDL locking for all metadata objects".

  After-review fixes in progress.

  Adjust some comments that were using old terminology
  (name locks instead of exclusive metadata locks), brought
  some of them up-to-date with current situation in code.


sql/sql_base.cc:
  Adjusted comments to use proper terminology.
sql/sql_delete.cc:
  Adjusted comments to use proper terminology.
sql/sql_handler.cc:
  Adjusted comments to use proper terminology.
sql/sql_partition.cc:
  Adjusted comments to use proper terminology also fixed
  one comment to correspond to what really happens in code.
sql/sql_show.cc:
  Adjusted comments to use proper terminology.
sql/sql_table.cc:
  Adjusted comments to use proper terminology, brought
   one of them up-to-date with current situation.
sql/sql_trigger.cc:
  Adjusted comments to use proper terminology.
sql/table.h:
  Removed two unused members of TABLE_SHARE struct.
2009-12-01 16:51:50 +03:00
Konstantin Osipov
e23046d1bc Backport of:
------------------------------------------------------------
revno: 2630.4.17
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-6.0-3726-w2
timestamp: Thu 2008-05-29 16:52:56 +0400
message:
  WL#3726 "DDL locking for all metadata objects".

  After review fixes in progress.

  "The great correction of names".

  Renamed MDL_LOCK and MDL_LOCK_DATA classes to make usage of
  these names in metadata locking subsystem consistent with
  other parts of server (i.e. thr_lock.cc). Now we MDL_LOCK_DATA
  corresponds to request for a lock and MDL_LOCK to the lock
  itself. Adjusted code in MDL subsystem and other places
  using these classes accordingly.
  Did similar thing for GLOBAL_MDL_LOCK_DATA class and also
  changed name of its members to correspond to names of
  MDL_LOCK_DATA members.
  Finally got rid of usage of one letter variables in MDL
  code since it makes code harder to search in (according
  to reviewer).
2009-12-01 01:33:22 +03:00
Konstantin Osipov
cf45b61a6a Backport of:
------------------------------------------------------------
revno: 2630.4.16
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-6.0-3726-w
timestamp: Thu 2008-05-29 09:45:02 +0400
message:
  WL#3726 "DDL locking for all metadata objects".

  After review changes in progress.

  Tweaked some comments and did some renames to
  avoid ambiguites.


sql/mysql_priv.h:
  Removed name_lock_locked_table() function.
sql/sql_base.cc:
  Got rid of name_lock_locked_table() function after replacing
  the only call to it with its body.
  Simplified open_table() code by making "action" argument
  mandatory (i.e. one now should always pass non-0 pointer
  in this argument).
  Renamed TABLE_LIST::open_table_type to open_type to
  avoid confusing it with type of table.
  Adjusted comments according to review.
sql/sql_handler.cc:
  Added comment clarifying in which cases we can have TABLE::mdl_lock
  set to 0.
sql/sql_insert.cc:
  Now the 4th argument of open_table() is mandatory (it makes
  no sense to complicate open_table() code when we can simply
  pass dummy variable).
sql/sql_parse.cc:
  Renamed TABLE_LIST::open_table_type to open_type to
  avoid confusing it with type of table.
sql/sql_prepare.cc:
  Renamed TABLE_LIST::open_table_type to open_type to
  avoid confusing it with type of table.
sql/sql_table.cc:
  Now the 4th argument of open_table() is mandatory (it makes
  no sense to complicate open_table() code when we can simply
  pass dummy variable).
sql/sql_trigger.cc:
  Replaced the only call to name_lock_locked_table() function
  with its body.
sql/sql_view.cc:
  Renamed TABLE_LIST::open_table_type to open_type to
  avoid confusing it with type of table.
sql/table.h:
  Renamed TABLE_LIST::open_table_type to open_type (to
  avoid confusing it with type of table) and improved
  comments describing this member.
2009-12-01 01:13:06 +03:00
Konstantin Osipov
0dcead9f61 Backport of:
------------------------------------------------------------
revno: 2630.4.14
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-6.0-3726-w
timestamp: Wed 2008-05-28 12:16:03 +0400
message:
  WL#3726 "DDL locking for all metadata objects".

  After review fixes in progress. Removed unused code and
  adjusted names of functions/methods to better reflect
  their current function.


sql/mysql_priv.h:
  Changed names of close_data_files_and_morph_locks() and
  close_handle_and_leave_table_as_lock() to better reflect
  their current function (locking is now responsibility
  of metadata locking subsystem).
sql/sql_base.cc:
  Changed names of close_data_files_and_morph_locks() and
  close_handle_and_leave_table_as_lock() to better reflect
  their current function (locking is now responsibility
  of metadata locking subsystem). Also adjusted comments
  describing these functions.
  Got rid of TABLE::open_placeholder since it is no longer
  used (its value is never read anywhere).
  TABLE::needs_reopen_or_name_lock() was renamed to needs_reopen()
  since we no longer use name-locks
sql/sql_handler.cc:
  TABLE::needs_reopen_or_name_lock() was renamed to needs_reopen()
  since we no longer use name-locks.
sql/sql_insert.cc:
  TABLE::needs_reopen_or_name_lock() was renamed to needs_reopen()
  since we no longer use name-locks
sql/sql_partition.cc:
  Changed name of close_data_files_and_morph_locks() to
  better reflect its current function (locking is now
  responsibility of metadata locking subsystem).
sql/sql_table.cc:
  Changed names of close_data_files_and_morph_locks() and
  close_handle_and_leave_table_as_lock() to better reflect
  their current function (locking is now responsibility
  of metadata locking subsystem).
  Got rid of TABLE::open_placeholder since it is no longer
  used.
sql/sql_trigger.cc:
  Changed name of close_data_files_and_morph_locks() to
  better reflect its current function (locking is now
  responsibility of metadata locking subsystem).
sql/table.h:
  Got rid of TABLE::open_placeholder which is no longer used
  altough its value was set in several places no code reads it).
  Removed unused TABLE::is_name_opened() method.
  Finally TABLE::needs_reopen_or_name_lock() was renamed to
  needs_reopen() since we no longer use name-locks.
2009-12-01 01:01:27 +03:00
Konstantin Osipov
aeebede195 Backport of:
------------------------------------------------------------
revno: 2630.4.11
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-6.0-3726-w
timestamp: Tue 2008-05-27 21:31:53 +0400
message:
  WL#3726 "DDL locking for all metadata objects".

  After review fixes in progress.

  Changed mysql_lock_tables() to be no longer responsible for
  reopening table if waiting for the lock on it was aborted.
  This allows to get rid of several annoying functions.


sql/ha_ndbcluster_binlog.cc:
  lock_tables() now also accepts set of options to be passed to
  mysql_lock_tables().
sql/lock.cc:
  Changed mysql_lock_tables() always requests caller to reopen
  table instead doing this on its own when waiting for lock was
  aborted. This allows us to get rid of several functions which
  were used in rare cases and significantly complicated our life.
sql/log_event_old.cc:
  lock_tables() now also accepts set of options to be passed
  to mysql_lock_tables().
sql/mysql_priv.h:
  Now mysql_lock_tables() always requests caller to reopen
  table instead doing this on its own when waiting for lock was
  aborted. So we no longer need wait_for_tables() and
  table_is_used() functions and MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN
  flag.
  open_and_lock_table_derived() and lock_tables() now accept
  options to be passed to open_tables() and mysql_lock_tables()
  calls.
sql/sql_base.cc:
  Since now mysql_lock_tables() always requests caller to
  reopen table instead doing this on its own when waiting for
  lock was aborted we no longer need wait_for_tables(),
  table_is_used() and close_old_data_files() functions.
  open_and_lock_table_derived() and lock_tables() now accept
  options to be passed to open_tables() and mysql_lock_tables()
  calls. This was needed in order to get rid of redundant code
  in open_system_tables_for_read() function.
sql/sql_handler.cc:
  mysql_lock_tables() is now always requests reopen if waiting
  for lock is aborted. MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN flag
  was removed.
sql/sql_insert.cc:
  handle_delayed_insert():
  Since mysql_lock_tables() is no longer responsible for
  reopening tables when waiting for lock was aborted we have
  to handle such situation outside of this function. To simplify
  this extracted code opening table for delayed insert thread to
  separate method of Delayed_insert class.
sql/sql_update.cc:
  lock_tables() now also accepts set of options to be passed
  to mysql_lock_tables().
2009-11-30 22:03:37 +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
9a9e8d2311 Backport of:
----------------------------------------------------------------------
ChangeSet@1.2571, 2008-04-08 12:30:06+02:00, vvaintroub@wva. +122 -0
  Bug#32082 : definition of VOID in my_global.h conflicts with Windows
  SDK headers
  
  VOID macro is now removed. Its usage is replaced with void cast.
  In some cases, where cast does not make much sense (pthread_*, printf, 
  hash_delete, my_seek), cast is ommited.


client/mysqladmin.cc:
  Bug#32082 : remove VOID macro
client/mysqldump.c:
  Bug#32082 : remove VOID macro
client/mysqlimport.c:
  Bug#32082 : remove VOID macro
client/mysqlslap.c:
  Bug#32082 : remove VOID macro
client/mysqltest.cc:
  Bug#32082 : remove VOID macro
client/sql_string.cc:
  Bug#32082 : remove VOID macro
extra/comp_err.c:
  Bug#32082 : remove VOID macro
extra/replace.c:
  Bug#32082 : remove VOID macro
include/my_alarm.h:
  Bug#32082 : remove VOID macro
include/my_global.h:
  Bug#32082 : remove VOID macro
libmysql/libmysql.c:
  Bug#32082 : remove VOID macro
mysys/errors.c:
  Bug#32082 : remove VOID macro
mysys/hash.c:
  Bug#32082 : remove VOID macro
mysys/mf_iocache2.c:
  Bug#32082 : remove VOID macro
mysys/mf_loadpath.c:
  Bug#32082 : remove VOID macro
mysys/mf_path.c:
  Bug#32082 : remove VOID macro
mysys/my_append.c:
  Bug#32082 : remove VOID macro
mysys/my_clock.c:
  Bug#32082 : remove VOID macro
mysys/my_copy.c:
  Bug#32082 : remove VOID macro
mysys/my_fstream.c:
  Bug#32082 : remove VOID macro
mysys/my_getwd.c:
  Bug#32082 : remove VOID macro
mysys/my_lib.c:
  Bug#32082 : remove VOID macro
mysys/my_lockmem.c:
  Bug#32082 : remove VOID macro
mysys/my_pthread.c:
  Bug#32082 : remove VOID macro
mysys/my_redel.c:
  Bug#32082 : remove VOID macro
mysys/stacktrace.c:
  Bug#32082 : remove VOID macro
mysys/thr_alarm.c:
  Bug#32082 : remove VOID macro
mysys/thr_lock.c:
  Bug#32082 : remove VOID macro
sql/derror.cc:
  Bug#32082 : remove VOID macro
sql/des_key_file.cc:
  Bug#32082 : remove VOID macro
sql/discover.cc:
  Bug#32082 : remove VOID macro
sql/field.cc:
  Bug#32082 : remove VOID macro
sql/filesort.cc:
  Bug#32082 : remove VOID macro
sql/ha_ndbcluster.cc:
  Bug#32082 : remove VOID macro
sql/ha_partition.cc:
  Bug#32082 : remove VOID macro
sql/handler.cc:
  Bug#32082 : remove VOID macro
sql/hostname.cc:
  Bug#32082 : remove VOID macro
sql/init.cc:
  Bug#32082 : remove VOID macro
sql/item.cc:
  Bug#32082 : remove VOID macro
sql/item_cmpfunc.cc:
  Bug#32082 : remove VOID macro
sql/item_strfunc.cc:
  Bug#32082 : remove VOID macro
sql/lock.cc:
  Bug#32082 : remove VOID macro
sql/log.cc:
  Bug#32082 : remove VOID macro
sql/log_event.cc:
  Bug#32082 : remove VOID macro
sql/mysqld.cc:
  Bug#32082 : remove VOID macro
sql/opt_range.h:
  Bug#32082 : remove VOID macro
sql/protocol.cc:
  Bug#32082 : remove VOID macro
sql/records.cc:
  Bug#32082 : remove VOID macro
sql/sp_head.cc:
  Bug#32082 : remove VOID macro
sql/sp_pcontext.cc:
  Bug#32082 : remove VOID macro
sql/sql_acl.cc:
  Bug#32082 : remove VOID macro
sql/sql_base.cc:
  Bug#32082 : remove VOID macro
sql/sql_cache.cc:
  Bug#32082 : remove VOID macro
sql/sql_connect.cc:
  Bug#32082 : remove VOID macro
sql/sql_db.cc:
  Bug#32082 : remove VOID macro
sql/sql_delete.cc:
  Bug#32082 : remove VOID macro
sql/sql_handler.cc:
  Bug#32082 : remove VOID macro
sql/sql_insert.cc:
  Bug#32082 : remove VOID macro
sql/sql_map.cc:
  Bug#32082 : remove VOID macro
sql/sql_parse.cc:
  Bug#32082 : remove VOID macro
sql/sql_select.cc:
  Bug#32082 : remove VOID macro
sql/sql_servers.cc:
  Bug#32082 : remove VOID macro
sql/sql_show.cc:
  Bug#32082 : remove VOID macro
sql/sql_string.cc:
  Bug#32082 : remove VOID macro
sql/sql_table.cc:
  Bug#32082 : remove VOID macro
sql/sql_test.cc:
  Bug#32082 : remove VOID macro
sql/sql_trigger.cc:
  Bug#32082 : remove VOID macro
sql/sql_update.cc:
  Bug#32082 : remove VOID macro
sql/sql_view.cc:
  Bug#32082 : remove VOID macro
sql/table.cc:
  Bug#32082 : remove VOID macro
sql/tztime.cc:
  Bug#32082 : remove VOID macro
sql/udf_example.c:
  Bug#32082 : remove VOID macro
sql/uniques.cc:
  Bug#32082 : remove VOID macro
sql/unireg.cc:
  Bug#32082 : remove VOID macro
storage/archive/ha_archive.cc:
  Bug#32082 : remove VOID macro
storage/blackhole/ha_blackhole.cc:
  Bug#32082 : remove VOID macro
storage/csv/ha_tina.cc:
  Bug#32082 : remove VOID macro
storage/csv/transparent_file.cc:
  Bug#32082 : remove VOID macro
storage/example/ha_example.cc:
  Bug#32082 : remove VOID macro
storage/federated/ha_federated.cc:
  Bug#32082 : remove VOID macro
storage/heap/hp_clear.c:
  Bug#32082 : remove VOID macro
storage/heap/hp_create.c:
  Bug#32082 : remove VOID macro
storage/heap/hp_test1.c:
  Bug#32082 : remove VOID macro
storage/heap/hp_test2.c:
  Bug#32082 : remove VOID macro
storage/innobase/handler/ha_innodb.cc:
  Bug#32082 : remove VOID macro
storage/myisam/ft_eval.c:
  Bug#32082 : remove VOID macro
storage/myisam/ha_myisam.cc:
  Bug#32082 : remove VOID macro
storage/myisam/mi_changed.c:
  Bug#32082 : remove VOID macro
storage/myisam/mi_check.c:
  Bug#32082 : remove VOID macro
storage/myisam/mi_close.c:
  Bug#32082 : remove VOID macro
storage/myisam/mi_create.c:
  Bug#32082 : remove VOID macro
storage/myisam/mi_dbug.c:
  Bug#32082 : remove VOID macro
storage/myisam/mi_delete.c:
  Bug#32082 : remove VOID macro
storage/myisam/mi_delete_all.c:
  Bug#32082 : remove VOID macro
storage/myisam/mi_dynrec.c:
  Bug#32082 : remove VOID macro
storage/myisam/mi_info.c:
  Bug#32082 : remove VOID macro
storage/myisam/mi_locking.c:
  Bug#32082 : remove VOID macro
storage/myisam/mi_log.c:
  Bug#32082 : remove VOID macro
storage/myisam/mi_open.c:
  Bug#32082 : remove VOID macro
storage/myisam/mi_packrec.c:
  Bug#32082 : remove VOID macro
storage/myisam/mi_panic.c:
  Bug#32082 : remove VOID macro
storage/myisam/mi_rsame.c:
  Bug#32082 : remove VOID macro
storage/myisam/mi_statrec.c:
  Bug#32082 : remove VOID macro
storage/myisam/mi_test1.c:
  Bug#32082 : remove VOID macro
storage/myisam/mi_test2.c:
  Bug#32082 : remove VOID macro
storage/myisam/mi_test3.c:
  Bug#32082 : remove VOID macro
storage/myisam/mi_update.c:
  Bug#32082 : remove VOID macro
storage/myisam/mi_write.c:
  Bug#32082 : remove VOID macro
storage/myisam/myisamchk.c:
  Bug#32082 : remove VOID macro
storage/myisam/myisamlog.c:
  Bug#32082 : remove VOID macro
storage/myisam/myisampack.c:
  Bug#32082 : remove VOID macro
storage/myisam/sort.c:
  Bug#32082 : remove VOID macro
storage/myisammrg/myrg_close.c:
  Bug#32082 : remove VOID macro
storage/myisammrg/myrg_create.c:
  Bug#32082 : remove VOID macro
storage/myisammrg/myrg_open.c:
  Bug#32082 : remove VOID macro
strings/str_test.c:
  Bug#32082 : remove VOID macro
tests/thread_test.c:
  Bug#32082 : remove VOID macro
2009-11-24 16:54:59 +03:00
Alexander Nozdrin
a708ba6524 Manual merge from mysql-next-mr. 2009-11-02 14:10:04 +03:00
Alexander Nozdrin
2dc132b209 Merge from mysql-next-mr. 2009-10-23 15:22:21 +04:00
Sergey Glukhov
96dbafaa8d Bug#35428 When selecting from INFORMATION_SCHEMA tables, incomplete metadata
backport to Betony
2009-10-23 14:19:54 +05:00
Konstantin Osipov
8ec23470f1 Backport of revno 2630.28.10, 2630.28.31, 2630.28.26, 2630.33.1,
2630.39.1, 2630.28.29, 2630.34.3, 2630.34.2, 2630.34.1, 2630.29.29,
2630.29.28, 2630.31.1, 2630.28.13, 2630.28.10, 2617.23.14 and
some other minor revisions.

This patch implements: 

WL#4264 "Backup: Stabilize Service Interface" -- all the
server prerequisites except si_objects.{h,cc} themselves (they can
be just copied over, when needed).

WL#4435: Support OUT-parameters in prepared statements.

(and all issues in the initial patches for these two
tasks, that were discovered in pushbuild and during testing).

Bug#39519: mysql_stmt_close() should flush all data
associated with the statement.

After execution of a prepared statement, send OUT parameters of the invoked
stored procedure, if any, to the client.

When using the binary protocol, send the parameters in an additional result
set over the wire.  When using the text protocol, assign out parameters to
the user variables from the CALL(@var1, @var2, ...) specification.

The following refactoring has been made:
  - Protocol::send_fields() was renamed to Protocol::send_result_set_metadata();
  - A new Protocol::send_result_set_row() was introduced to incapsulate
    common functionality for sending row data.
  - Signature of Protocol::prepare_for_send() was changed: this operation
    does not need a list of items, the number of items is fully sufficient.

The following backward incompatible changes have been made:
  - CLIENT_MULTI_RESULTS is now enabled by default in the client;
  - CLIENT_PS_MULTI_RESUTLS is now enabled by default in the client.

include/mysql.h:
  Add a new flag to MYSQL_METHODS::flush_use_result
  function pointer. This flag determines if all results
  should be flushed or only the first one:
      
  - if flush_all_results is TRUE, then cli_flush_use_result()
    will read/flush all pending results. I.e. it will read
    all packets while server status attribute indicates that
    there are more results. This is a new semantic, required
    to fix the bug.
              
  - if flush_all_results is FALSE, the old sematic
    is preserved -- i.e. cli_flush_use_result() reads data
    until first EOF-packet.
include/mysql.h.pp:
  Update the ABI with new calls (compatible changes).
include/mysql_com.h:
  Add CLIENT_PS_OUT_PARAMS -- a client capability indicating that the client supportsю
libmysql/libmysql.c:
  Add mysql_stmt_next_result() -- analogue of mysql_next_result() for binary protocol.
  Fix a minor bug in alloc_fields() -- not all members were copied over,
  and some only shallow-copied (catalog).
  Flush all results in mysql_stmt_close() (Bug#39519).
libmysqld/lib_sql.cc:
  Rename send_fields() -> send_result_set_metadata().
  Refactoring: change prepare_for_send() so that it accepts only 
  what it really needs -- a number of elements in the list.
mysql-test/r/ps.result:
  Update results: WL#4435.
mysql-test/t/ps.test:
  WL#4435: A test case for an SQL-part of the problem.
sql-common/client.c:
  Bug#39519.
  Implement new functionality in cli_flush_use_result():
  if flush_all_delete is TRUE, then it should read/flush
  all pending results.
sql/Makefile.am:
  Add a new header sql_prepare.h to the list
  of build headers.
sql/events.cc:
  Rename: Protocol::send_fields() -> 
  Protocol::send_result_set_metadata().
sql/handler.cc:
  Rename: Protocol::send_fields() -> 
  Protocol::send_result_set_metadata().
sql/mysql_priv.h:
  Move sql_prepare.cc-specific declarations to a new
  header - sql_prepare.h.
sql/procedure.h:
  Rename: Protocol::send_fields() -> 
  Protocol::send_result_set_metadata().
sql/protocol.cc:
  Move the logic responsible for sending of one result
  set row to the Protocol class. Define a template
  for end-of-statement action. 
  Refactoring: change prepare_for_send() so that it accepts 
  only what it really needs -- a number of elements in the list.
  Rename send_fields() to send_result_set_metadata().
sql/protocol.h:
  Update with new declarations (WL#4435).
  Rename send_fields() -> send_result_set_metadata().
  prepare_for_send() only needs the number of columns to send,
  and doesn't use the item list - update signature to require
  only what's needed.
  Add a new protocol type -- Protocol_local.
sql/repl_failsafe.cc:
  Rename: Protocol::send_fields() -> 
  Protocol::send_result_set_metadata().
sql/slave.cc:
  Rename: Protocol::send_fields() -> 
  Protocol::send_result_set_metadata().
sql/sql_acl.cc:
  Rename: Protocol::send_fields() -> 
  Protocol::send_result_set_metadata().
sql/sql_base.cc:
  Include sql_prepare.h (for Reprepare_observer).
sql/sql_cache.cc:
  Extend the query cache flags block to be able
  to store a numeric id for the result format,
  not just a flag binary/non-binary.
sql/sql_class.cc:
  Update to use the rename of Protocol::send_fields()
  to Protocol::send_result_set_metadata().
  Use Protocol::send_one_result_set_row().
sql/sql_class.h:
  Move the declaration of Reprepare_observer to the 
  new header - sql_prepare.h.
  Update to the new signature of class Protocol::send_fields().
sql/sql_connect.cc:
  Use a protocol template method instead of
  raw NET layer API at the end of a statement.
sql/sql_cursor.cc:
  Rename: Protocol::send_fields() -> 
  Protocol::send_result_set_metadata().
sql/sql_error.cc:
  Rename: Protocol::send_fields() -> 
  Protocol::send_result_set_metadata().
sql/sql_handler.cc:
  Rename: Protocol::send_fields() -> 
  Protocol::send_result_set_metadata().
  Use new method Protocol::send_one_result_set_row().
sql/sql_help.cc:
  Rename: Protocol::send_fields() -> 
  Protocol::send_result_set_metadata().
sql/sql_lex.cc:
  Initialize multi_statements variable.
  Add a handy constant for empty lex
  string.
sql/sql_lex.h:
  Add a separate member for a standalone
  parsing option - multi-statements support.
sql/sql_list.cc:
  sql_list.h is a standalone header now, 
  no need to include mysql_priv.h.
sql/sql_list.h:
  Make sql_list.h a stand-alone header.
sql/sql_parse.cc:
  Include sql_prepare.h for prepared
  statements- related declarations.
  Use a new Protocol template method to end
  each statement (send OK, EOF or ERROR to
  the client).
sql/sql_prepare.cc:
  Implement Execute Direct API (WL#4264), 
  currently unused. It will be used by the service
  interface (Backup).
  Use a new header - sql_prepare.h.
  Add support for OUT parameters in the 
  binary and text protocol (prepared statements 
  only).
sql/sql_prepare.h:
  Add a new header to contain (for now)
  all prepared statement- external
  related declarations.
sql/sql_profile.cc:
  Rename: Protocol::send_fields() -> 
  Protocol::send_result_set_metadata().
sql/sql_repl.cc:
  Rename: Protocol::send_fields() -> 
  Protocol::send_result_set_metadata().
sql/sql_select.cc:
  Rename: Protocol::send_fields() -> 
  Protocol::send_result_set_metadata().
sql/sql_show.cc:
  Rename: Protocol::send_fields() -> 
  Protocol::send_result_set_metadata().
sql/sql_string.h:
  Add a way to convert a String to LEX_STRING.
sql/sql_table.cc:
  Rename: Protocol::send_fields() -> 
  Protocol::send_result_set_metadata().
sql/sql_update.cc:
  Remove an extraneous my_error(). The error
  is already reported in update_non_unique_table_error().
sql/sql_yacc.yy:
  Support for multi-statements is an independent
  property of parsing, not derived from 
  the protocol type.
tests/mysql_client_test.c:
  Add tests for WL#4435 (binary protocol).
2009-10-22 00:02:06 +04:00
Konstantin Osipov
9b41c7532d Backport of:
----------------------------------------------------------
revno: 2617.22.5
committer: Konstantin Osipov <kostja@sun.com>
branch nick: mysql-6.0-runtime
timestamp: Tue 2009-01-27 05:08:48 +0300
message:
  Remove non-prefixed use of HASH.
  Always use my_hash_init(), my_hash_inited(), my_hash_search(),
  my_hash_element(), my_hash_delete(), my_hash_free() rather
  than non-prefixed counterparts (hash_init(), etc).
  Remove the backward-compatible defines.
2009-10-14 20:37:38 +04:00
Staale Smedseng
d6ca0cbb23 Merge from 5.0 2009-09-17 17:25:52 +02:00
Staale Smedseng
e5888b16af Bug #43414 Parenthesis (and other) warnings compiling MySQL
with gcc 4.3.2
      
This is the fifth patch cleaning up more GCC warnings about
variables used before initialized using the new macro
UNINIT_VAR().
2009-09-17 17:10:30 +02:00
Kristofer Pettersson
fae95a4933 Bug#45781 infinite hang/crash in "opening tables" after handler tries to open merge
table

The MERGE table storage engine does not support the HA_CAN_SQL_HANDLE feature
and any attempt to open the merge table will fail with ER_ILLEGAL_HA.

After an error occurred the tables that was opened must be closed again
or they will be left in an inconsistent state. However, the assumption
made in the code for closing and register handler tables was that only
one table will be opened, and this is not true for MERGE tables which
will cause multiple tables to open.

The next time a SELECT operation was issued on the merge table it
caused the system to freeze.

This patch fixes this issue by making sure that all tables which
are opened also are closed in the event of an error.


mysql-test/r/merge.result:
  Added test case for bug 45781
mysql-test/t/merge.test:
  Added test case for bug 45781
sql/sql_handler.cc:
  * mysql_ha_open() was never ment to open more than one table. If we encounter more tables, we should
    close all tables related to the current substatement and raise an exception.
2009-07-16 01:23:57 +02:00
Sergey Glukhov
bf2e29d374 5.0-bugteam->5.1-bugteam merge 2009-04-17 13:46:27 +05:00