diff options
author | Dmitry Lenev <dlenev@mysql.com> | 2010-05-25 16:35:01 +0400 |
---|---|---|
committer | Dmitry Lenev <dlenev@mysql.com> | 2010-05-25 16:35:01 +0400 |
commit | bee0f214fdbb214471b3d043b2b00b6b8f2c1edd (patch) | |
tree | 5ca3eccef7fd43ef9cca0e1b7c7d9d307f34add2 /sql/mdl.h | |
parent | 705b98dff714298a9b9e77cab364a05f439c3b7b (diff) | |
download | mariadb-git-bee0f214fdbb214471b3d043b2b00b6b8f2c1edd.tar.gz |
Pre-requisite patch for bug #51263 "Deadlock between
transactional SELECT and ALTER TABLE ... REBUILD PARTITION".
The goal of this patch is to decouple type of metadata
lock acquired for table by open_tables() from type of
table-level lock to be acquired on it.
To achieve this we change approach to how we determine what
type of metadata lock should be acquired on table to be open.
Now instead of inferring it at open_tables() time from flags
and type of table-level lock we rely on that type of metadata
lock is properly set at parsing time and is not changed
further.
sql/ha_ndbcluster.cc:
Now one needs to properly initialize table list element's
MDL_request object before calling mysql_rm_table_part2().
sql/lock.cc:
lock_table_names() no longer initializes table list elements'
MDL_request objects. Now proper initialization of these
requests is a responsibility of the caller.
sql/lock.h:
Removed MYSQL_OPEN_TAKE_UPGRADABLE_MDL flag which became
unnecessary. Thanks to the fact that we don't reset type of
requests for metadata locks between re-executions we now can
figure out that upgradable locks are requested by simply
looking at their type which were set in the parser. As result
this flag became redundant.
sql/mdl.h:
Added version of new operator which simplifies allocation of
MDL_request objects on a MEM_ROOT.
sql/sp_head.cc:
Added comment explaining why it is OK to infer type of
metadata lock to request from type of table-level lock
for prelocking.
Added enum_mdl_type argument to sp_add_to_query_tables()
to simplify its usage in trigger implementation.
sql/sp_head.h:
Added enum_mdl_type argument to sp_add_to_query_tables()
to simplify its usage in trigger implementation.
sql/sql_base.cc:
- open_table_get_mdl_lock():
Preserve type of MDL_request for table list element which
was set in the parser by creating MDL_request objects on
memory root if MYSQL_OPEN_FORCE_SHARED_MDL or
MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL flag were specified.
Thanks to this and to the fact that we no longer reset
type of requests for metadata locks between re-executions
we no longer need to acquire exclusive metadata lock on
table to be created in a special way. This lock is acquired
by code handling acquiring of upgradable locks.
Also changed signature/calling convention for this function
to simplify its usage.
- Accordingly special lock strategy for table list elements
which was used for such locks became unnecessary and was
removed. Other strategies were renamed.
- Since we no longer have guarantee that MDL_request object
which were not satisfied due to lock conflict belongs to
table list element Open_table_context class and its methods
were extended to remember pointer to MDL_request which has
caused problem at request_backoff_action() time and use it
in recover_from_failed_open(). Similar approach is used
for cases when problem from which we need to recover is
not related to MDL but to the table itself. In this case
we store pointer to the element of table list.
- Changed open_tables()/open_tables_check_upgradable_mdl()/
open_tables_acquire_upgradable_mdl() not to rely on
MYSQL_OPEN_TAKE_UPGRADABLE_MDL flag to understand when
upgradable metadata locks should be acquired and not to
infer type of MDL lock from type of table-level lock.
Instead we assume that type of MDL to be acquired was set
in the parser (we can do this as type of MDL_request is
no longer reset between re-executions).
sql/sql_class.h:
Since we no longer have guarantee that MDL_request object
which were not satisfied due to lock conflict belongs to
table list element Open_table_context class and its methods
were extended to remember pointer to MDL_request which has
caused problem at request_backoff_action() time and use it
in recover_from_failed_open(). Similar approach is used
for cases when problem from which we need to recover is
not related to MDL but to the table itself. In this case
we store pointer to the element of table list.
sql/sql_db.cc:
Now one needs to properly initialize table list element's
MDL_request object before calling mysql_rm_table_part2()
or mysql_rename_tables().
sql/sql_lex.cc:
st_select_lex/st_select_lex_node::add_table_to_list() method
now has argument which allows specify type of metadata lock
to be requested for table list element being added.
sql/sql_lex.h:
- st_select_lex/st_select_lex_node::add_table_to_list()
method now has argument which specifies type of metadata
lock to be requested for table list element being added.
This allows to explicitly set type of MDL lock to be
acquired for a DDL statement in parser. It is also more
future-proof than inferring type of MDL request from type
of table-level lock.
- Added Yacc_state::m_mdl_type member which specifies which
type of metadata lock should be requested for tables to be
added to table list by a grammar rule in cases when the same
rule is used in several statements requiring different kinds
of metadata locks.
sql/sql_parse.cc:
- st_select_lex::add_table_to_list() method now has argument
which specifies type of metadata lock to be requested for
table list element being added. This allows to explicitly
set type of MDL lock to be acquired for a DDL statement in
parser. It is also more future-proof than inferring type of
MDL request from type of table-level lock.
- EXCLUSIVE_DOWNGRADABLE_MDL lock strategy has a new name -
OTLS_DOWNGRADE_IF_EXISTS.
- Adjusted LOCK TABLES implementation to the fact that we no
longer infer type of metadata lock to be acquired from table
level lock and that type of MDL request is set at parsing.
And thus MYSQL_OPEN_TAKE_UPGRADABLE_MDL flag became
unnecessary.
sql/sql_prepare.cc:
TABLE_LIST's lock strategy SHARED_MDL was renamed to OTLS_NONE
as now it means that metadata lock should not be changed during
call to open_table() (if it has been already acquired) and is
also used for exclusive metadata lock.
sql/sql_show.cc:
st_select_lex::add_table_to_list() method now has argument
which specifies type of metadata lock to be requested for
table list element being added.
sql/sql_table.cc:
- Adjusted mysql_admin_table()'s code to the fact that
open_tables() no longer determines what kind of metadata
lock should be obtained basing on type of table-level
lock and flags. Instead type of metadata lock for table
to be open should be set before calling open_tables().
- Changed mysql_alter_table() code to the facts:
a) that now it is responsibility of caller to properly
initalize MDL_request in table list elements before calling
lock_table_names()
b) and that MYSQL_OPEN_TAKE_UPGRADABLE_MDL is no longer
necessary since type of metadata lock to be obtained
at open_tables() time is set during parsing.
- Changed code of mysql_recreate_table() to properly set
type of metadata and table-level lock to be obtained
by mysql_alter_table() which it calls.
sql/sql_trigger.cc:
Instead of relying on MYSQL_OPEN_TAKE_UPGRADABLE_MDL flag to
force open_tables() to take an upgradable lock we now specify
exact type of lock to be taken when constructing table list
element for table to be open for CREATE/DROP TRIGGER.
sql/sql_view.cc:
We no longer use TABLE_LIST::EXCLUSIVE_MDL strategy to force
open_tables() to take an exclusive metadata lock on view to
be created. Instead we rely on parser setting proper type of
metadata lock to request and open_tables() acquiring it.
This became possible thanks to the fact that we no longer
reset type of MDL_request between statement re-executions.
sql/sql_yacc.yy:
Instead of inferring type of MDL_request for table to be
open from type of table-level lock and flags passed to
open_tables() we now explicitly specify them at parsing.
This became possible thanks to the fact that we no longer
reset type of MDL_request between statement re-executions.
In future this should allow to decouple type of metadata
lock from type of table-level lock.
The only exception to this approach is statements implemented
through mysql_admin_table() which re-uses same table list
element several times with different types of table-level
and metadata locks.
We now also properly initialize MDL_request objects for table
list elements which are later passed to lock_table_names()
function.
sql/table.cc:
Do not reset type of MDL_request between statement
re-executions. This became unnecessesary as we no longer
change type of MDL_request residing in table list element.
In its turn this change allows to set type of MDL_request
only once - at parsing time.
sql/table.h:
Got rid of TABLE_LIST::EXCLUSIVE_MDL lock strategy.
Now we can specify that we need to acquire exclusive lock
on table to be processed by open_tables() through setting
an appropriate type of MDL_request at parsing time (this
became possible thanks to the fact that we no longer reset
types of MDL_request's belonging to table list elements
between statement re-execution).
Strategy SHARED_MDL was renamed to OTLS_NONE as now it
means that metadata lock should not be changed during call
to open_table() (if it has been already acquired) and is
also used for exclusive metadata lock.
Strategy EXCLUSIVE_DOWNGRADABLE_MDL was renamed to
OTLS_DOWNGRADE_IF_EXISTS.
Diffstat (limited to 'sql/mdl.h')
-rw-r--r-- | sql/mdl.h | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/sql/mdl.h b/sql/mdl.h index 2fb21a5aa18..2e296b73057 100644 --- a/sql/mdl.h +++ b/sql/mdl.h @@ -308,6 +308,10 @@ public: MDL_key key; public: + static void *operator new(size_t size, MEM_ROOT *mem_root) throw () + { return alloc_root(mem_root, size); } + static void operator delete(void *ptr, MEM_ROOT *mem_root) {} + void init(MDL_key::enum_mdl_namespace namespace_arg, const char *db_arg, const char *name_arg, enum_mdl_type mdl_type_arg); |