mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Merge branch '10.5' into 10.6
This commit is contained in:
178
sql/sql_class.cc
178
sql/sql_class.cc
@ -72,6 +72,7 @@
|
||||
#include "wsrep_trans_observer.h"
|
||||
#endif /* WITH_WSREP */
|
||||
#include "opt_trace.h"
|
||||
#include <mysql/psi/mysql_transaction.h>
|
||||
|
||||
#ifdef HAVE_SYS_SYSCALL_H
|
||||
#include <sys/syscall.h>
|
||||
@ -813,12 +814,14 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
|
||||
system_thread= NON_SYSTEM_THREAD;
|
||||
cleanup_done= free_connection_done= abort_on_warning= 0;
|
||||
peer_port= 0; // For SHOW PROCESSLIST
|
||||
transaction.m_pending_rows_event= 0;
|
||||
transaction.on= 1;
|
||||
wt_thd_lazy_init(&transaction.wt, &variables.wt_deadlock_search_depth_short,
|
||||
&variables.wt_timeout_short,
|
||||
&variables.wt_deadlock_search_depth_long,
|
||||
&variables.wt_timeout_long);
|
||||
transaction= &default_transaction;
|
||||
transaction->m_pending_rows_event= 0;
|
||||
transaction->on= 1;
|
||||
wt_thd_lazy_init(&transaction->wt,
|
||||
&variables.wt_deadlock_search_depth_short,
|
||||
&variables.wt_timeout_short,
|
||||
&variables.wt_deadlock_search_depth_long,
|
||||
&variables.wt_timeout_long);
|
||||
#ifdef SIGNAL_WITH_VIO_CLOSE
|
||||
active_vio = 0;
|
||||
#endif
|
||||
@ -1262,10 +1265,10 @@ void THD::init()
|
||||
if (variables.sql_mode & MODE_ANSI_QUOTES)
|
||||
server_status|= SERVER_STATUS_ANSI_QUOTES;
|
||||
|
||||
transaction.all.modified_non_trans_table=
|
||||
transaction.stmt.modified_non_trans_table= FALSE;
|
||||
transaction.all.m_unsafe_rollback_flags=
|
||||
transaction.stmt.m_unsafe_rollback_flags= 0;
|
||||
transaction->all.modified_non_trans_table=
|
||||
transaction->stmt.modified_non_trans_table= FALSE;
|
||||
transaction->all.m_unsafe_rollback_flags=
|
||||
transaction->stmt.m_unsafe_rollback_flags= 0;
|
||||
|
||||
open_options=ha_open_options;
|
||||
update_lock_default= (variables.low_priority_updates ?
|
||||
@ -1396,11 +1399,11 @@ void THD::init_for_queries()
|
||||
|
||||
reset_root_defaults(mem_root, variables.query_alloc_block_size,
|
||||
variables.query_prealloc_size);
|
||||
reset_root_defaults(&transaction.mem_root,
|
||||
reset_root_defaults(&transaction->mem_root,
|
||||
variables.trans_alloc_block_size,
|
||||
variables.trans_prealloc_size);
|
||||
DBUG_ASSERT(!transaction.xid_state.is_explicit_XA());
|
||||
DBUG_ASSERT(transaction.implicit_xid.is_null());
|
||||
DBUG_ASSERT(!transaction->xid_state.is_explicit_XA());
|
||||
DBUG_ASSERT(transaction->implicit_xid.is_null());
|
||||
}
|
||||
|
||||
|
||||
@ -1539,7 +1542,7 @@ void THD::cleanup(void)
|
||||
delete_dynamic(&user_var_events);
|
||||
close_temporary_tables();
|
||||
|
||||
if (transaction.xid_state.is_explicit_XA())
|
||||
if (transaction->xid_state.is_explicit_XA())
|
||||
trans_xa_detach(this);
|
||||
else
|
||||
trans_rollback(this);
|
||||
@ -1565,7 +1568,7 @@ void THD::cleanup(void)
|
||||
decrease_user_connections(user_connect);
|
||||
user_connect= 0; // Safety
|
||||
}
|
||||
wt_thd_destroy(&transaction.wt);
|
||||
wt_thd_destroy(&transaction->wt);
|
||||
|
||||
my_hash_free(&user_vars);
|
||||
my_hash_free(&sequences);
|
||||
@ -1697,7 +1700,7 @@ THD::~THD()
|
||||
#endif
|
||||
mdl_context.destroy();
|
||||
|
||||
free_root(&transaction.mem_root,MYF(0));
|
||||
transaction->free();
|
||||
mysql_cond_destroy(&COND_wakeup_ready);
|
||||
mysql_mutex_destroy(&LOCK_wakeup_ready);
|
||||
mysql_mutex_destroy(&LOCK_thd_data);
|
||||
@ -1736,7 +1739,9 @@ THD::~THD()
|
||||
/* trick to make happy memory accounting system */
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
session_tracker.sysvars.deinit();
|
||||
#ifdef USER_VAR_TRACKING
|
||||
session_tracker.user_variables.deinit();
|
||||
#endif // USER_VAR_TRACKING
|
||||
#endif //EMBEDDED_LIBRARY
|
||||
|
||||
if (status_var.local_memory_used != 0)
|
||||
@ -2587,7 +2592,8 @@ void THD::add_changed_table(TABLE *table)
|
||||
{
|
||||
DBUG_ENTER("THD::add_changed_table(table)");
|
||||
|
||||
DBUG_ASSERT(in_multi_stmt_transaction_mode() && table->file->has_transactions());
|
||||
DBUG_ASSERT(in_multi_stmt_transaction_mode() &&
|
||||
table->file->has_transactions());
|
||||
add_changed_table(table->s->table_cache_key.str,
|
||||
(long) table->s->table_cache_key.length);
|
||||
DBUG_VOID_RETURN;
|
||||
@ -2597,8 +2603,8 @@ void THD::add_changed_table(TABLE *table)
|
||||
void THD::add_changed_table(const char *key, size_t key_length)
|
||||
{
|
||||
DBUG_ENTER("THD::add_changed_table(key)");
|
||||
CHANGED_TABLE_LIST **prev_changed = &transaction.changed_tables;
|
||||
CHANGED_TABLE_LIST *curr = transaction.changed_tables;
|
||||
CHANGED_TABLE_LIST **prev_changed = &transaction->changed_tables;
|
||||
CHANGED_TABLE_LIST *curr = transaction->changed_tables;
|
||||
|
||||
for (; curr; prev_changed = &(curr->next), curr = curr->next)
|
||||
{
|
||||
@ -4712,7 +4718,8 @@ TABLE *open_purge_table(THD *thd, const char *db, size_t dblen,
|
||||
DBUG_ASSERT(thd->open_tables == NULL);
|
||||
DBUG_ASSERT(thd->locked_tables_mode < LTM_PRELOCKED);
|
||||
|
||||
Open_table_context ot_ctx(thd, 0);
|
||||
/* Purge already hold the MDL for the table */
|
||||
Open_table_context ot_ctx(thd, MYSQL_OPEN_HAS_MDL_LOCK);
|
||||
TABLE_LIST *tl= (TABLE_LIST*)thd->alloc(sizeof(TABLE_LIST));
|
||||
LEX_CSTRING db_name= {db, dblen };
|
||||
LEX_CSTRING table_name= { tb, tblen };
|
||||
@ -5050,7 +5057,7 @@ thd_rpl_deadlock_check(MYSQL_THD thd, MYSQL_THD other_thd)
|
||||
if (!thd)
|
||||
return 0;
|
||||
DEBUG_SYNC(thd, "thd_report_wait_for");
|
||||
thd->transaction.stmt.mark_trans_did_wait();
|
||||
thd->transaction->stmt.mark_trans_did_wait();
|
||||
if (!other_thd)
|
||||
return 0;
|
||||
binlog_report_wait_for(thd, other_thd);
|
||||
@ -5153,7 +5160,7 @@ thd_need_ordering_with(const MYSQL_THD thd, const MYSQL_THD other_thd)
|
||||
|
||||
extern "C" int thd_non_transactional_update(const MYSQL_THD thd)
|
||||
{
|
||||
return(thd->transaction.all.modified_non_trans_table);
|
||||
return(thd->transaction->all.modified_non_trans_table);
|
||||
}
|
||||
|
||||
extern "C" int thd_binlog_format(const MYSQL_THD thd)
|
||||
@ -5362,7 +5369,7 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
|
||||
backup->limit_found_rows= limit_found_rows;
|
||||
backup->cuted_fields= cuted_fields;
|
||||
backup->client_capabilities= client_capabilities;
|
||||
backup->savepoints= transaction.savepoints;
|
||||
backup->savepoints= transaction->savepoints;
|
||||
backup->first_successful_insert_id_in_prev_stmt=
|
||||
first_successful_insert_id_in_prev_stmt;
|
||||
backup->first_successful_insert_id_in_cur_stmt=
|
||||
@ -5384,7 +5391,7 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
|
||||
client_capabilities &= ~CLIENT_MULTI_RESULTS;
|
||||
in_sub_stmt|= new_state;
|
||||
cuted_fields= 0;
|
||||
transaction.savepoints= 0;
|
||||
transaction->savepoints= 0;
|
||||
first_successful_insert_id_in_cur_stmt= 0;
|
||||
reset_slow_query_state();
|
||||
}
|
||||
@ -5410,16 +5417,16 @@ void THD::restore_sub_statement_state(Sub_statement_state *backup)
|
||||
level. It is enough to release first savepoint set on this level since
|
||||
all later savepoints will be released automatically.
|
||||
*/
|
||||
if (transaction.savepoints)
|
||||
if (transaction->savepoints)
|
||||
{
|
||||
SAVEPOINT *sv;
|
||||
for (sv= transaction.savepoints; sv->prev; sv= sv->prev)
|
||||
for (sv= transaction->savepoints; sv->prev; sv= sv->prev)
|
||||
{}
|
||||
/* ha_release_savepoint() never returns error. */
|
||||
(void)ha_release_savepoint(this, sv);
|
||||
}
|
||||
count_cuted_fields= backup->count_cuted_fields;
|
||||
transaction.savepoints= backup->savepoints;
|
||||
transaction->savepoints= backup->savepoints;
|
||||
variables.option_bits= backup->option_bits;
|
||||
in_sub_stmt= backup->in_sub_stmt;
|
||||
enable_slow_log= backup->enable_slow_log;
|
||||
@ -5740,6 +5747,95 @@ void THD::mark_transaction_to_rollback(bool all)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Commit the whole transaction (both statment and all)
|
||||
|
||||
This is used mainly to commit an independent transaction,
|
||||
like reading system tables.
|
||||
|
||||
@return 0 0k
|
||||
@return <>0 error code. my_error() has been called()
|
||||
*/
|
||||
|
||||
int THD::commit_whole_transaction_and_close_tables()
|
||||
{
|
||||
int error, error2;
|
||||
DBUG_ENTER("THD::commit_whole_transaction_and_close_tables");
|
||||
|
||||
/*
|
||||
This can only happened if we failed to open any table in the
|
||||
new transaction
|
||||
*/
|
||||
DBUG_ASSERT(open_tables);
|
||||
|
||||
if (!open_tables) // Safety for production usage
|
||||
DBUG_RETURN(0);
|
||||
|
||||
/*
|
||||
Ensure table was locked (opened with open_and_lock_tables()). If not
|
||||
the THD can't be part of any transactions and doesn't have to call
|
||||
this function.
|
||||
*/
|
||||
DBUG_ASSERT(lock);
|
||||
|
||||
error= ha_commit_trans(this, FALSE);
|
||||
/* This will call external_lock to unlock all tables */
|
||||
if ((error2= mysql_unlock_tables(this, lock)))
|
||||
{
|
||||
my_error(ER_ERROR_DURING_COMMIT, MYF(0), error2);
|
||||
error= error2;
|
||||
}
|
||||
lock= 0;
|
||||
if ((error2= ha_commit_trans(this, TRUE)))
|
||||
error= error2;
|
||||
close_thread_tables(this);
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
/**
|
||||
Start a new independent transaction
|
||||
*/
|
||||
|
||||
start_new_trans::start_new_trans(THD *thd)
|
||||
{
|
||||
org_thd= thd;
|
||||
mdl_savepoint= thd->mdl_context.mdl_savepoint();
|
||||
memcpy(old_ha_data, thd->ha_data, sizeof(old_ha_data));
|
||||
thd->reset_n_backup_open_tables_state(&open_tables_state_backup);
|
||||
bzero(thd->ha_data, sizeof(thd->ha_data));
|
||||
old_transaction= thd->transaction;
|
||||
thd->transaction= &new_transaction;
|
||||
new_transaction.on= 1;
|
||||
in_sub_stmt= thd->in_sub_stmt;
|
||||
thd->in_sub_stmt= 0;
|
||||
server_status= thd->server_status;
|
||||
m_transaction_psi= thd->m_transaction_psi;
|
||||
thd->m_transaction_psi= 0;
|
||||
wsrep_on= thd->variables.wsrep_on;
|
||||
thd->variables.wsrep_on= 0;
|
||||
thd->server_status&= ~(SERVER_STATUS_IN_TRANS |
|
||||
SERVER_STATUS_IN_TRANS_READONLY);
|
||||
thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
|
||||
}
|
||||
|
||||
|
||||
void start_new_trans::restore_old_transaction()
|
||||
{
|
||||
org_thd->transaction= old_transaction;
|
||||
org_thd->restore_backup_open_tables_state(&open_tables_state_backup);
|
||||
ha_close_connection(org_thd);
|
||||
memcpy(org_thd->ha_data, old_ha_data, sizeof(old_ha_data));
|
||||
org_thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
|
||||
org_thd->in_sub_stmt= in_sub_stmt;
|
||||
org_thd->server_status= server_status;
|
||||
if (org_thd->m_transaction_psi)
|
||||
MYSQL_COMMIT_TRANSACTION(org_thd->m_transaction_psi);
|
||||
org_thd->m_transaction_psi= m_transaction_psi;
|
||||
org_thd->variables.wsrep_on= wsrep_on;
|
||||
org_thd= 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Decide on logging format to use for the statement and issue errors
|
||||
or warnings as needed. The decision depends on the following
|
||||
@ -5853,7 +5949,9 @@ int THD::decide_logging_format(TABLE_LIST *tables)
|
||||
binlog by filtering rules.
|
||||
*/
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP_CLIENT_NNULL(this) && wsrep_thd_is_local(this) &&
|
||||
if (WSREP_CLIENT_NNULL(this) &&
|
||||
wsrep_thd_is_local(this) &&
|
||||
wsrep_is_active(this) &&
|
||||
variables.wsrep_trx_fragment_size > 0)
|
||||
{
|
||||
if (!is_current_stmt_binlog_format_row())
|
||||
@ -5866,11 +5964,8 @@ int THD::decide_logging_format(TABLE_LIST *tables)
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
if ((WSREP_EMULATE_BINLOG_NNULL(this) ||
|
||||
(mysql_bin_log.is_open() &&
|
||||
(variables.option_bits & OPTION_BIN_LOG))) &&
|
||||
!(wsrep_binlog_format() == BINLOG_FORMAT_STMT &&
|
||||
!binlog_filter->db_ok(db.str)))
|
||||
if (WSREP_EMULATE_BINLOG_NNULL(this) ||
|
||||
binlog_table_should_be_logged(&db))
|
||||
{
|
||||
if (is_bulk_op())
|
||||
{
|
||||
@ -6394,6 +6489,21 @@ exit:;
|
||||
}
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
/**
|
||||
Check if we should log a table DDL to the binlog
|
||||
|
||||
@@return true yes
|
||||
@@return false no
|
||||
*/
|
||||
|
||||
bool THD::binlog_table_should_be_logged(const LEX_CSTRING *db)
|
||||
{
|
||||
return (mysql_bin_log.is_open() &&
|
||||
(variables.option_bits & OPTION_BIN_LOG) &&
|
||||
(wsrep_binlog_format() != BINLOG_FORMAT_STMT ||
|
||||
binlog_filter->db_ok(db->str)));
|
||||
}
|
||||
|
||||
/*
|
||||
Template member function for ensuring that there is an rows log
|
||||
event of the apropriate type before proceeding.
|
||||
@ -7270,7 +7380,7 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
|
||||
log event is written to the binary log, we pretend that no
|
||||
table maps were written.
|
||||
*/
|
||||
if(binlog_should_compress(query_len))
|
||||
if (binlog_should_compress(query_len))
|
||||
{
|
||||
Query_compressed_log_event qinfo(this, query_arg, query_len, is_trans, direct,
|
||||
suppress_use, errcode);
|
||||
|
Reference in New Issue
Block a user