A follow up patch for the fix for Bug#51263 "Deadlock between
transactional SELECT and ALTER TABLE ... REBUILD PARTITION". Move declarations of sql_base.cc classes to sql_base.h (previously declared in sql_class.h). Became possible after a header file split.
This commit is contained in:
parent
08589ba9c9
commit
8b0c705c39
@ -16,11 +16,11 @@
|
|||||||
|
|
||||||
/* Basic functions needed by many modules */
|
/* Basic functions needed by many modules */
|
||||||
|
|
||||||
|
#include "sql_base.h" // setup_table_map
|
||||||
#include "my_global.h" /* NO_EMBEDDED_ACCESS_CHECKS */
|
#include "my_global.h" /* NO_EMBEDDED_ACCESS_CHECKS */
|
||||||
#include "sql_priv.h"
|
#include "sql_priv.h"
|
||||||
#include "unireg.h"
|
#include "unireg.h"
|
||||||
#include "debug_sync.h"
|
#include "debug_sync.h"
|
||||||
#include "sql_base.h" // setup_table_map
|
|
||||||
#include "lock.h" // broadcast_refresh, mysql_lock_remove,
|
#include "lock.h" // broadcast_refresh, mysql_lock_remove,
|
||||||
// mysql_unlock_tables,
|
// mysql_unlock_tables,
|
||||||
// mysql_lock_have_duplicate
|
// mysql_lock_have_duplicate
|
||||||
|
164
sql/sql_base.h
164
sql/sql_base.h
@ -322,6 +322,7 @@ inline TABLE_LIST *find_table_in_local_list(TABLE_LIST *table,
|
|||||||
db_name, table_name);
|
db_name, table_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool setup_fields_with_no_wrap(THD *thd, Item **ref_pointer_array,
|
inline bool setup_fields_with_no_wrap(THD *thd, Item **ref_pointer_array,
|
||||||
List<Item> &item,
|
List<Item> &item,
|
||||||
enum_mark_columns mark_used_columns,
|
enum_mark_columns mark_used_columns,
|
||||||
@ -336,6 +337,89 @@ inline bool setup_fields_with_no_wrap(THD *thd, Item **ref_pointer_array,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
An abstract class for a strategy specifying how the prelocking
|
||||||
|
algorithm should extend the prelocking set while processing
|
||||||
|
already existing elements in the set.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Prelocking_strategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Prelocking_strategy() { }
|
||||||
|
|
||||||
|
virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx,
|
||||||
|
Sroutine_hash_entry *rt, sp_head *sp,
|
||||||
|
bool *need_prelocking) = 0;
|
||||||
|
virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
|
||||||
|
TABLE_LIST *table_list, bool *need_prelocking) = 0;
|
||||||
|
virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx,
|
||||||
|
TABLE_LIST *table_list, bool *need_prelocking)= 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
A Strategy for prelocking algorithm suitable for DML statements.
|
||||||
|
|
||||||
|
Ensures that all tables used by all statement's SF/SP/triggers and
|
||||||
|
required for foreign key checks are prelocked and SF/SPs used are
|
||||||
|
cached.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class DML_prelocking_strategy : public Prelocking_strategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx,
|
||||||
|
Sroutine_hash_entry *rt, sp_head *sp,
|
||||||
|
bool *need_prelocking);
|
||||||
|
virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
|
||||||
|
TABLE_LIST *table_list, bool *need_prelocking);
|
||||||
|
virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx,
|
||||||
|
TABLE_LIST *table_list, bool *need_prelocking);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
A strategy for prelocking algorithm to be used for LOCK TABLES
|
||||||
|
statement.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Lock_tables_prelocking_strategy : public DML_prelocking_strategy
|
||||||
|
{
|
||||||
|
virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
|
||||||
|
TABLE_LIST *table_list, bool *need_prelocking);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Strategy for prelocking algorithm to be used for ALTER TABLE statements.
|
||||||
|
|
||||||
|
Unlike DML or LOCK TABLES strategy, it doesn't
|
||||||
|
prelock triggers, views or stored routines, since they are not
|
||||||
|
used during ALTER.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Alter_table_prelocking_strategy : public Prelocking_strategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
Alter_table_prelocking_strategy(Alter_info *alter_info)
|
||||||
|
: m_alter_info(alter_info)
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx,
|
||||||
|
Sroutine_hash_entry *rt, sp_head *sp,
|
||||||
|
bool *need_prelocking);
|
||||||
|
virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
|
||||||
|
TABLE_LIST *table_list, bool *need_prelocking);
|
||||||
|
virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx,
|
||||||
|
TABLE_LIST *table_list, bool *need_prelocking);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Alter_info *m_alter_info;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
open_tables(THD *thd, TABLE_LIST **tables, uint *counter, uint flags)
|
open_tables(THD *thd, TABLE_LIST **tables, uint *counter, uint flags)
|
||||||
{
|
{
|
||||||
@ -355,4 +439,84 @@ inline bool open_and_lock_tables(THD *thd, TABLE_LIST *tables,
|
|||||||
&prelocking_strategy);
|
&prelocking_strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
A context of open_tables() function, used to recover
|
||||||
|
from a failed open_table() or open_routine() attempt.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Open_table_context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum enum_open_table_action
|
||||||
|
{
|
||||||
|
OT_NO_ACTION= 0,
|
||||||
|
OT_WAIT_MDL_LOCK,
|
||||||
|
OT_WAIT_TDC,
|
||||||
|
OT_DISCOVER,
|
||||||
|
OT_REPAIR
|
||||||
|
};
|
||||||
|
Open_table_context(THD *thd, ulong timeout);
|
||||||
|
|
||||||
|
bool recover_from_failed_open(THD *thd);
|
||||||
|
bool request_backoff_action(enum_open_table_action action_arg,
|
||||||
|
MDL_request *mdl_request, TABLE_LIST *table);
|
||||||
|
|
||||||
|
void add_request(MDL_request *request)
|
||||||
|
{ m_mdl_requests.push_front(request); }
|
||||||
|
|
||||||
|
bool can_recover_from_failed_open() const
|
||||||
|
{ return m_action != OT_NO_ACTION; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
When doing a back-off, we close all tables acquired by this
|
||||||
|
statement. Return an MDL savepoint taken at the beginning of
|
||||||
|
the statement, so that we can rollback to it before waiting on
|
||||||
|
locks.
|
||||||
|
*/
|
||||||
|
MDL_ticket *start_of_statement_svp() const
|
||||||
|
{
|
||||||
|
return m_start_of_statement_svp;
|
||||||
|
}
|
||||||
|
|
||||||
|
MDL_request *get_global_mdl_request(THD *thd);
|
||||||
|
|
||||||
|
inline ulong get_timeout() const
|
||||||
|
{
|
||||||
|
return m_timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/** List of requests for all locks taken so far. Used for waiting on locks. */
|
||||||
|
MDL_request_list m_mdl_requests;
|
||||||
|
/** Back off action. */
|
||||||
|
enum enum_open_table_action m_action;
|
||||||
|
/** For OT_WAIT_MDL_LOCK action, the request for which we should wait. */
|
||||||
|
MDL_request *m_failed_mdl_request;
|
||||||
|
/**
|
||||||
|
For OT_DISCOVER and OT_REPAIR actions, the table list element for
|
||||||
|
the table which definition should be re-discovered or which
|
||||||
|
should be repaired.
|
||||||
|
*/
|
||||||
|
TABLE_LIST *m_failed_table;
|
||||||
|
MDL_ticket *m_start_of_statement_svp;
|
||||||
|
/**
|
||||||
|
Whether we had any locks when this context was created.
|
||||||
|
If we did, they are from the previous statement of a transaction,
|
||||||
|
and we can't safely do back-off (and release them).
|
||||||
|
*/
|
||||||
|
bool m_has_locks;
|
||||||
|
/**
|
||||||
|
Request object for global intention exclusive lock which is acquired during
|
||||||
|
opening tables for statements which take upgradable shared metadata locks.
|
||||||
|
*/
|
||||||
|
MDL_request *m_global_mdl_request;
|
||||||
|
/**
|
||||||
|
Lock timeout in seconds. Initialized to LONG_TIMEOUT when opening system
|
||||||
|
tables or to the "lock_wait_timeout" system variable for regular tables.
|
||||||
|
*/
|
||||||
|
uint m_timeout;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* SQL_BASE_INCLUDED */
|
#endif /* SQL_BASE_INCLUDED */
|
||||||
|
164
sql/sql_class.h
164
sql/sql_class.h
@ -1226,170 +1226,6 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
An abstract class for a strategy specifying how the prelocking
|
|
||||||
algorithm should extend the prelocking set while processing
|
|
||||||
already existing elements in the set.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Prelocking_strategy
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~Prelocking_strategy() { }
|
|
||||||
|
|
||||||
virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx,
|
|
||||||
Sroutine_hash_entry *rt, sp_head *sp,
|
|
||||||
bool *need_prelocking) = 0;
|
|
||||||
virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
|
|
||||||
TABLE_LIST *table_list, bool *need_prelocking) = 0;
|
|
||||||
virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx,
|
|
||||||
TABLE_LIST *table_list, bool *need_prelocking)= 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
A Strategy for prelocking algorithm suitable for DML statements.
|
|
||||||
|
|
||||||
Ensures that all tables used by all statement's SF/SP/triggers and
|
|
||||||
required for foreign key checks are prelocked and SF/SPs used are
|
|
||||||
cached.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class DML_prelocking_strategy : public Prelocking_strategy
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx,
|
|
||||||
Sroutine_hash_entry *rt, sp_head *sp,
|
|
||||||
bool *need_prelocking);
|
|
||||||
virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
|
|
||||||
TABLE_LIST *table_list, bool *need_prelocking);
|
|
||||||
virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx,
|
|
||||||
TABLE_LIST *table_list, bool *need_prelocking);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
A strategy for prelocking algorithm to be used for LOCK TABLES
|
|
||||||
statement.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Lock_tables_prelocking_strategy : public DML_prelocking_strategy
|
|
||||||
{
|
|
||||||
virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
|
|
||||||
TABLE_LIST *table_list, bool *need_prelocking);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Strategy for prelocking algorithm to be used for ALTER TABLE statements.
|
|
||||||
|
|
||||||
Unlike DML or LOCK TABLES strategy, it doesn't
|
|
||||||
prelock triggers, views or stored routines, since they are not
|
|
||||||
used during ALTER.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Alter_table_prelocking_strategy : public Prelocking_strategy
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
Alter_table_prelocking_strategy(Alter_info *alter_info)
|
|
||||||
: m_alter_info(alter_info)
|
|
||||||
{}
|
|
||||||
|
|
||||||
virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx,
|
|
||||||
Sroutine_hash_entry *rt, sp_head *sp,
|
|
||||||
bool *need_prelocking);
|
|
||||||
virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
|
|
||||||
TABLE_LIST *table_list, bool *need_prelocking);
|
|
||||||
virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx,
|
|
||||||
TABLE_LIST *table_list, bool *need_prelocking);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Alter_info *m_alter_info;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
A context of open_tables() function, used to recover
|
|
||||||
from a failed open_table() or open_routine() attempt.
|
|
||||||
|
|
||||||
Implemented in sql_base.cc.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Open_table_context
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum enum_open_table_action
|
|
||||||
{
|
|
||||||
OT_NO_ACTION= 0,
|
|
||||||
OT_WAIT_MDL_LOCK,
|
|
||||||
OT_WAIT_TDC,
|
|
||||||
OT_DISCOVER,
|
|
||||||
OT_REPAIR
|
|
||||||
};
|
|
||||||
Open_table_context(THD *thd, ulong timeout);
|
|
||||||
|
|
||||||
bool recover_from_failed_open(THD *thd);
|
|
||||||
bool request_backoff_action(enum_open_table_action action_arg,
|
|
||||||
MDL_request *mdl_request, TABLE_LIST *table);
|
|
||||||
|
|
||||||
void add_request(MDL_request *request)
|
|
||||||
{ m_mdl_requests.push_front(request); }
|
|
||||||
|
|
||||||
bool can_recover_from_failed_open() const
|
|
||||||
{ return m_action != OT_NO_ACTION; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
When doing a back-off, we close all tables acquired by this
|
|
||||||
statement. Return an MDL savepoint taken at the beginning of
|
|
||||||
the statement, so that we can rollback to it before waiting on
|
|
||||||
locks.
|
|
||||||
*/
|
|
||||||
MDL_ticket *start_of_statement_svp() const
|
|
||||||
{
|
|
||||||
return m_start_of_statement_svp;
|
|
||||||
}
|
|
||||||
|
|
||||||
MDL_request *get_global_mdl_request(THD *thd);
|
|
||||||
|
|
||||||
inline ulong get_timeout() const
|
|
||||||
{
|
|
||||||
return m_timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
/** List of requests for all locks taken so far. Used for waiting on locks. */
|
|
||||||
MDL_request_list m_mdl_requests;
|
|
||||||
/** Back off action. */
|
|
||||||
enum enum_open_table_action m_action;
|
|
||||||
/** For OT_WAIT_MDL_LOCK action, the request for which we should wait. */
|
|
||||||
MDL_request *m_failed_mdl_request;
|
|
||||||
/**
|
|
||||||
For OT_DISCOVER and OT_REPAIR actions, the table list element for
|
|
||||||
the table which definition should be re-discovered or which
|
|
||||||
should be repaired.
|
|
||||||
*/
|
|
||||||
TABLE_LIST *m_failed_table;
|
|
||||||
MDL_ticket *m_start_of_statement_svp;
|
|
||||||
/**
|
|
||||||
Whether we had any locks when this context was created.
|
|
||||||
If we did, they are from the previous statement of a transaction,
|
|
||||||
and we can't safely do back-off (and release them).
|
|
||||||
*/
|
|
||||||
bool m_has_locks;
|
|
||||||
/**
|
|
||||||
Request object for global intention exclusive lock which is acquired during
|
|
||||||
opening tables for statements which take upgradable shared metadata locks.
|
|
||||||
*/
|
|
||||||
MDL_request *m_global_mdl_request;
|
|
||||||
/**
|
|
||||||
Lock timeout in seconds. Initialized to LONG_TIMEOUT when opening system
|
|
||||||
tables or to the "lock_wait_timeout" system variable for regular tables.
|
|
||||||
*/
|
|
||||||
uint m_timeout;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Tables that were locked with LOCK TABLES statement.
|
Tables that were locked with LOCK TABLES statement.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user