diff options
author | Konstantin Osipov <kostja@sun.com> | 2009-11-30 22:03:37 +0300 |
---|---|---|
committer | Konstantin Osipov <kostja@sun.com> | 2009-11-30 22:03:37 +0300 |
commit | aeebede1954d12b80f4c4aea016460501bfc2f5a (patch) | |
tree | 9ae4570228ac52e0055a55b7ebb3e020f24d0497 /sql/lock.cc | |
parent | de1979d3d69e55e40037b62d3ce502a4ddd05910 (diff) | |
download | mariadb-git-aeebede1954d12b80f4c4aea016460501bfc2f5a.tar.gz |
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().
Diffstat (limited to 'sql/lock.cc')
-rw-r--r-- | sql/lock.cc | 64 |
1 files changed, 29 insertions, 35 deletions
diff --git a/sql/lock.cc b/sql/lock.cc index 0c8c3095844..38b2d22f91f 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -94,31 +94,6 @@ static int lock_external(THD *thd, TABLE **table,uint count); static int unlock_external(THD *thd, TABLE **table,uint count); static void print_lock_error(int error, const char *); -/* - Lock tables. - - SYNOPSIS - mysql_lock_tables() - thd The current thread. - tables An array of pointers to the tables to lock. - count The number of tables to lock. - flags Options: - MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK Ignore a global read lock - MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY Ignore SET GLOBAL READ_ONLY - MYSQL_LOCK_IGNORE_FLUSH Ignore a flush tables. - MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN Instead of reopening altered - or dropped tables by itself, - mysql_lock_tables() should - notify upper level and rely - on caller doing this. - need_reopen Out parameter, TRUE if some tables were altered - or deleted and should be reopened by caller. - - RETURN - A lock structure pointer on success. - NULL on error or if some tables should be reopen. -*/ - /* Map the return value of thr_lock to an error from errmsg.txt */ static int thr_lock_errno_to_mysql[]= { 0, 1, ER_LOCK_WAIT_TIMEOUT, ER_LOCK_DEADLOCK }; @@ -247,6 +222,28 @@ static void reset_lock_data_and_free(MYSQL_LOCK **mysql_lock) } +/** + Lock tables. + + @param thd The current thread. + @param tables An array of pointers to the tables to lock. + @param count The number of tables to lock. + @param flags Options: + MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK Ignore a global read lock + MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY Ignore SET GLOBAL READ_ONLY + MYSQL_LOCK_IGNORE_FLUSH Ignore a flush tables. + @param need_reopen Out parameter, TRUE if some tables were altered + or deleted and should be reopened by caller. + + @note Caller of this function should always be ready to handle request to + reopen table unless there are external invariants which guarantee + that such thing won't be needed (for example we are obtaining lock + on table on which we already have exclusive metadata lock). + + @retval A lock structure pointer on success. + @retval NULL on error or if some tables should be reopen. +*/ + MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, uint flags, bool *need_reopen) { @@ -330,7 +327,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, my_error(rc, MYF(0)); break; } - else if (rc == 1) /* aborted */ + else if (rc == 1) /* aborted or killed */ { thd->some_tables_deleted=1; // Try again sql_lock->lock_count= 0; // Locks are already freed @@ -339,8 +336,9 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, else if (!thd->some_tables_deleted || (flags & MYSQL_LOCK_IGNORE_FLUSH)) { /* - Thread was killed or lock aborted. Let upper level close all - used tables and retry or give error. + Success and nobody set thd->some_tables_deleted to force reopen + or we were called with MYSQL_LOCK_IGNORE_FLUSH so such attempts + should be ignored. */ break; } @@ -366,13 +364,9 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, */ reset_lock_data_and_free(&sql_lock); retry: - if (flags & MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN) - { - *need_reopen= TRUE; - break; - } - if (wait_for_tables(thd)) - break; // Couldn't open tables + /* Let upper level close all used tables and retry or give error. */ + *need_reopen= TRUE; + break; } thd_proc_info(thd, 0); if (thd->killed) |