mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
Merge branch '10.6' into mariadb-10.6.20
This commit is contained in:
commit
f2bb2ab58c
13 changed files with 223 additions and 84 deletions
2
VERSION
2
VERSION
|
@ -1,4 +1,4 @@
|
|||
MYSQL_VERSION_MAJOR=10
|
||||
MYSQL_VERSION_MINOR=6
|
||||
MYSQL_VERSION_PATCH=20
|
||||
MYSQL_VERSION_PATCH=21
|
||||
SERVER_MATURITY=stable
|
||||
|
|
|
@ -4340,3 +4340,16 @@ DROP TABLE t0;
|
|||
#
|
||||
# End of 10.5 tests
|
||||
#
|
||||
#
|
||||
# Start of 10.6 tests
|
||||
#
|
||||
#
|
||||
# MDEV-20944 Wrong result of LEAST() and ASAN heap-use-after-free in my_strnncollsp_simple / Item::temporal_precision on TIME()
|
||||
#
|
||||
SET NAMES latin1;
|
||||
SELECT LEAST( CAST( 0 AS CHAR ), OLD_PASSWORD( 1 ) );
|
||||
LEAST( CAST( 0 AS CHAR ), OLD_PASSWORD( 1 ) )
|
||||
0
|
||||
#
|
||||
# End of 10.6 tests
|
||||
#
|
||||
|
|
|
@ -1141,3 +1141,18 @@ DROP TABLE t0;
|
|||
--echo #
|
||||
--echo # End of 10.5 tests
|
||||
--echo #
|
||||
|
||||
--echo #
|
||||
--echo # Start of 10.6 tests
|
||||
--echo #
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-20944 Wrong result of LEAST() and ASAN heap-use-after-free in my_strnncollsp_simple / Item::temporal_precision on TIME()
|
||||
--echo #
|
||||
|
||||
SET NAMES latin1;
|
||||
SELECT LEAST( CAST( 0 AS CHAR ), OLD_PASSWORD( 1 ) );
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.6 tests
|
||||
--echo #
|
||||
|
|
|
@ -224,3 +224,8 @@ SELECT INTERVAL(1,ROW(1,2));
|
|||
ERROR 21000: Operand should contain 1 column(s)
|
||||
SELECT INTERVAL(ROW(1,2),1);
|
||||
ERROR 21000: Operand should contain 1 column(s)
|
||||
#
|
||||
# MDEV-29184 Assertion `0' in Item_row::illegal_method_call, Type_handler_row::Item_update_null_value, Item::update_null_value
|
||||
#
|
||||
SELECT INTERVAL(0, ROW(1,1), 1, 1, 1, 1, 1, 1, 1) AS f;
|
||||
ERROR 21000: Operand should contain 1 column(s)
|
||||
|
|
|
@ -147,3 +147,11 @@ SELECT INTERVAL(ROW(1,1),ROW(1,2));
|
|||
SELECT INTERVAL(1,ROW(1,2));
|
||||
--error ER_OPERAND_COLUMNS
|
||||
SELECT INTERVAL(ROW(1,2),1);
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-29184 Assertion `0' in Item_row::illegal_method_call, Type_handler_row::Item_update_null_value, Item::update_null_value
|
||||
--echo #
|
||||
|
||||
--error ER_OPERAND_COLUMNS
|
||||
SELECT INTERVAL(0, ROW(1,1), 1, 1, 1, 1, 1, 1, 1) AS f;
|
||||
|
|
42
mysql-test/suite/rpl/r/parallel_backup_xa_debug.result
Normal file
42
mysql-test/suite/rpl/r/parallel_backup_xa_debug.result
Normal file
|
@ -0,0 +1,42 @@
|
|||
include/master-slave.inc
|
||||
[connection master]
|
||||
connection master;
|
||||
CREATE TABLE t (a INT) ENGINE = innodb;
|
||||
connection slave;
|
||||
include/stop_slave.inc
|
||||
SET @old_parallel_threads= @@GLOBAL.slave_parallel_threads;
|
||||
SET @old_parallel_mode = @@GLOBAL.slave_parallel_mode;
|
||||
SET @@global.slave_parallel_threads= 2;
|
||||
SET @@global.slave_parallel_mode = 'optimistic';
|
||||
connection master;
|
||||
# MDEV-35110
|
||||
SET @@gtid_seq_no=100;
|
||||
insert into t set a=1;
|
||||
xa start 'x';
|
||||
insert into t set a=2;
|
||||
xa end 'x';
|
||||
xa prepare 'x';
|
||||
connection slave;
|
||||
SET @@global.debug_dbug="+d,hold_worker_on_schedule";
|
||||
start slave;
|
||||
connection slave1;
|
||||
backup stage start;
|
||||
backup stage block_commit;
|
||||
connection slave;
|
||||
SET debug_sync = 'now SIGNAL continue_worker';
|
||||
SET debug_sync = RESET;
|
||||
connection slave1;
|
||||
backup stage end;
|
||||
connection master;
|
||||
xa rollback 'x';
|
||||
connection slave;
|
||||
# Clean up.
|
||||
connection slave;
|
||||
include/stop_slave.inc
|
||||
SET @@global.debug_dbug="";
|
||||
SET @@global.slave_parallel_threads= @old_parallel_threads;
|
||||
SET @@global.slave_parallel_mode = @old_parallel_mode;
|
||||
include/start_slave.inc
|
||||
connection server_1;
|
||||
DROP TABLE t;
|
||||
include/rpl_end.inc
|
64
mysql-test/suite/rpl/t/parallel_backup_xa_debug.test
Normal file
64
mysql-test/suite/rpl/t/parallel_backup_xa_debug.test
Normal file
|
@ -0,0 +1,64 @@
|
|||
# Verify deadlock between XA-PREPARE and BACKUP on the optimistic slave
|
||||
--source include/have_debug.inc
|
||||
--source include/have_debug_sync.inc
|
||||
--source include/have_innodb.inc
|
||||
# The test is not format specific, MIXED is required to optimize testing time
|
||||
--source include/have_binlog_format_mixed.inc
|
||||
--source include/master-slave.inc
|
||||
|
||||
--connection master
|
||||
CREATE TABLE t (a INT) ENGINE = innodb;
|
||||
|
||||
--sync_slave_with_master
|
||||
--source include/stop_slave.inc
|
||||
SET @old_parallel_threads= @@GLOBAL.slave_parallel_threads;
|
||||
SET @old_parallel_mode = @@GLOBAL.slave_parallel_mode;
|
||||
SET @@global.slave_parallel_threads= 2;
|
||||
SET @@global.slave_parallel_mode = 'optimistic';
|
||||
|
||||
--connection master
|
||||
--echo # MDEV-35110
|
||||
SET @@gtid_seq_no=100;
|
||||
insert into t set a=1;
|
||||
xa start 'x';
|
||||
insert into t set a=2;
|
||||
xa end 'x';
|
||||
xa prepare 'x';
|
||||
|
||||
--connection slave
|
||||
SET @@global.debug_dbug="+d,hold_worker_on_schedule";
|
||||
start slave;
|
||||
--let $wait_condition= SELECT count(*) = 1 FROM information_schema.processlist WHERE state LIKE "Waiting for prior transaction to commit"
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--connection slave1
|
||||
backup stage start;
|
||||
--send backup stage block_commit
|
||||
|
||||
--connection slave
|
||||
--let $wait_condition= SELECT count(*) = 1 FROM information_schema.processlist WHERE state LIKE "Waiting for backup lock"
|
||||
SET debug_sync = 'now SIGNAL continue_worker';
|
||||
SET debug_sync = RESET;
|
||||
|
||||
--connection slave1
|
||||
reap;
|
||||
backup stage end;
|
||||
|
||||
--connection master
|
||||
xa rollback 'x';
|
||||
|
||||
--sync_slave_with_master
|
||||
|
||||
--echo # Clean up.
|
||||
--connection slave
|
||||
--source include/stop_slave.inc
|
||||
SET @@global.debug_dbug="";
|
||||
SET @@global.slave_parallel_threads= @old_parallel_threads;
|
||||
SET @@global.slave_parallel_mode = @old_parallel_mode;
|
||||
|
||||
--source include/start_slave.inc
|
||||
|
||||
--connection server_1
|
||||
DROP TABLE t;
|
||||
|
||||
--source include/rpl_end.inc
|
|
@ -1781,7 +1781,13 @@ int ha_commit_trans(THD *thd, bool all)
|
|||
DBUG_PRINT("info", ("is_real_trans: %d rw_trans: %d rw_ha_count: %d",
|
||||
is_real_trans, rw_trans, rw_ha_count));
|
||||
|
||||
if (rw_trans)
|
||||
/*
|
||||
backup_commit_lock may have already been set.
|
||||
This can happen in case of spider that does xa_commit() by
|
||||
calling ha_commit_trans() from spader_commit().
|
||||
*/
|
||||
|
||||
if (rw_trans && !thd->backup_commit_lock)
|
||||
{
|
||||
/*
|
||||
Acquire a metadata lock which will ensure that COMMIT is blocked
|
||||
|
@ -2052,8 +2058,8 @@ end:
|
|||
not needed.
|
||||
*/
|
||||
thd->mdl_context.release_lock(mdl_backup.ticket);
|
||||
thd->backup_commit_lock= 0;
|
||||
}
|
||||
thd->backup_commit_lock= 0;
|
||||
#ifdef WITH_WSREP
|
||||
if (wsrep_is_active(thd) && is_real_trans && !error &&
|
||||
(rw_ha_count == 0 || all) &&
|
||||
|
|
|
@ -1951,22 +1951,15 @@ bool Item_func_opt_neg::eq(const Item *item, bool binary_cmp) const
|
|||
}
|
||||
|
||||
|
||||
bool Item_func_interval::fix_fields(THD *thd, Item **ref)
|
||||
bool Item_func_interval::fix_length_and_dec()
|
||||
{
|
||||
if (Item_long_func::fix_fields(thd, ref))
|
||||
return true;
|
||||
for (uint i= 0 ; i < row->cols(); i++)
|
||||
uint rows= row->cols();
|
||||
|
||||
for (uint i= 0 ; i < rows; i++)
|
||||
{
|
||||
if (row->element_index(i)->check_cols(1))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Item_func_interval::fix_length_and_dec()
|
||||
{
|
||||
uint rows= row->cols();
|
||||
|
||||
use_decimal_comparison= ((row->element_index(0)->result_type() ==
|
||||
DECIMAL_RESULT) ||
|
||||
|
|
|
@ -1120,7 +1120,6 @@ public:
|
|||
Item_func_interval(THD *thd, Item_row *a):
|
||||
Item_long_func(thd, a), row(a), intervals(0)
|
||||
{ }
|
||||
bool fix_fields(THD *, Item **) override;
|
||||
longlong val_int() override;
|
||||
bool fix_length_and_dec() override;
|
||||
LEX_CSTRING func_name_cstring() const override
|
||||
|
|
|
@ -2987,13 +2987,15 @@ String *Item_func_min_max::val_str_native(String *str)
|
|||
res=args[i]->val_str(str);
|
||||
else
|
||||
{
|
||||
String *res2;
|
||||
res2= args[i]->val_str(res == str ? &tmp_value : str);
|
||||
String *res2= args[i]->val_str(&tmp_value);
|
||||
if (res2)
|
||||
{
|
||||
int cmp= sortcmp(res,res2,collation.collation);
|
||||
if ((cmp_sign < 0 ? cmp : -cmp) < 0)
|
||||
res=res2;
|
||||
{
|
||||
str->copy(*res2);
|
||||
res= str;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((null_value= args[i]->null_value))
|
||||
|
|
120
sql/xa.cc
120
sql/xa.cc
|
@ -507,6 +507,40 @@ bool trans_xa_end(THD *thd)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Get the BACKUP_COMMIT lock for the duration of the XA.
|
||||
|
||||
The metadata lock which will ensure that COMMIT is blocked
|
||||
by active FLUSH TABLES WITH READ LOCK (and vice versa COMMIT in
|
||||
progress blocks FTWRL) and also by MDL_BACKUP_WAIT_COMMIT.
|
||||
We allow FLUSHer to COMMIT; we assume FLUSHer knows what it does.
|
||||
|
||||
Note that the function sets thd->backup_lock on sucess. The caller needs
|
||||
to reset thd->backup_commit_lock before returning!
|
||||
*/
|
||||
|
||||
static bool trans_xa_get_backup_lock(THD *thd, MDL_request *mdl_request)
|
||||
{
|
||||
DBUG_ASSERT(thd->backup_commit_lock == 0);
|
||||
MDL_REQUEST_INIT(mdl_request, MDL_key::BACKUP, "", "", MDL_BACKUP_COMMIT,
|
||||
MDL_EXPLICIT);
|
||||
if (thd->mdl_context.acquire_lock(mdl_request,
|
||||
thd->variables.lock_wait_timeout))
|
||||
return 1;
|
||||
thd->backup_commit_lock= mdl_request;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void trans_xa_release_backup_lock(THD *thd)
|
||||
{
|
||||
if (thd->backup_commit_lock)
|
||||
{
|
||||
thd->mdl_context.release_lock(thd->backup_commit_lock->ticket);
|
||||
thd->backup_commit_lock= 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Put a XA transaction in the PREPARED state.
|
||||
|
||||
|
@ -529,22 +563,15 @@ bool trans_xa_prepare(THD *thd)
|
|||
my_error(ER_XAER_NOTA, MYF(0));
|
||||
else
|
||||
{
|
||||
/*
|
||||
Acquire metadata lock which will ensure that COMMIT is blocked
|
||||
by active FLUSH TABLES WITH READ LOCK (and vice versa COMMIT in
|
||||
progress blocks FTWRL).
|
||||
|
||||
We allow FLUSHer to COMMIT; we assume FLUSHer knows what it does.
|
||||
*/
|
||||
MDL_request mdl_request;
|
||||
MDL_REQUEST_INIT(&mdl_request, MDL_key::BACKUP, "", "", MDL_BACKUP_COMMIT,
|
||||
MDL_STATEMENT);
|
||||
if (thd->mdl_context.acquire_lock(&mdl_request,
|
||||
thd->variables.lock_wait_timeout) ||
|
||||
if (trans_xa_get_backup_lock(thd, &mdl_request) ||
|
||||
ha_prepare(thd))
|
||||
{
|
||||
if (!mdl_request.ticket)
|
||||
{
|
||||
/* Failed to get the backup lock */
|
||||
ha_rollback_trans(thd, TRUE);
|
||||
}
|
||||
thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
|
||||
thd->transaction->all.reset();
|
||||
thd->server_status&=
|
||||
|
@ -572,6 +599,7 @@ bool trans_xa_prepare(THD *thd)
|
|||
res= thd->variables.pseudo_slave_mode || thd->slave_thread ?
|
||||
slave_applier_reset_xa_trans(thd) : 0;
|
||||
}
|
||||
trans_xa_release_backup_lock(thd);
|
||||
}
|
||||
|
||||
DBUG_RETURN(res);
|
||||
|
@ -635,19 +663,8 @@ bool trans_xa_commit(THD *thd)
|
|||
res= 1;
|
||||
goto _end_external_xid;
|
||||
}
|
||||
|
||||
res= xa_trans_rolled_back(xs);
|
||||
/*
|
||||
Acquire metadata lock which will ensure that COMMIT is blocked
|
||||
by active FLUSH TABLES WITH READ LOCK (and vice versa COMMIT in
|
||||
progress blocks FTWRL).
|
||||
|
||||
We allow FLUSHer to COMMIT; we assume FLUSHer knows what it does.
|
||||
*/
|
||||
MDL_REQUEST_INIT(&mdl_request, MDL_key::BACKUP, "", "", MDL_BACKUP_COMMIT,
|
||||
MDL_EXPLICIT);
|
||||
if (thd->mdl_context.acquire_lock(&mdl_request,
|
||||
thd->variables.lock_wait_timeout))
|
||||
if (trans_xa_get_backup_lock(thd, &mdl_request))
|
||||
{
|
||||
/*
|
||||
We can't rollback an XA transaction on lock failure due to
|
||||
|
@ -659,14 +676,11 @@ bool trans_xa_commit(THD *thd)
|
|||
res= true;
|
||||
goto _end_external_xid;
|
||||
}
|
||||
else
|
||||
{
|
||||
thd->backup_commit_lock= &mdl_request;
|
||||
}
|
||||
DBUG_ASSERT(!xid_state.xid_cache_element);
|
||||
|
||||
xid_state.xid_cache_element= xs;
|
||||
ha_commit_or_rollback_by_xid(thd->lex->xid, !res);
|
||||
|
||||
if (!res && thd->is_error())
|
||||
{
|
||||
// hton completion error retains xs/xid in the cache,
|
||||
|
@ -682,11 +696,7 @@ bool trans_xa_commit(THD *thd)
|
|||
res= res || thd->is_error();
|
||||
if (!xid_deleted)
|
||||
xs->acquired_to_recovered();
|
||||
if (mdl_request.ticket)
|
||||
{
|
||||
thd->mdl_context.release_lock(mdl_request.ticket);
|
||||
thd->backup_commit_lock= 0;
|
||||
}
|
||||
trans_xa_release_backup_lock(thd);
|
||||
}
|
||||
else
|
||||
my_error(ER_XAER_NOTA, MYF(0));
|
||||
|
@ -709,7 +719,8 @@ bool trans_xa_commit(THD *thd)
|
|||
if ((res= MY_TEST(r)))
|
||||
my_error(r == 1 ? ER_XA_RBROLLBACK : ER_XAER_RMERR, MYF(0));
|
||||
}
|
||||
else if (thd->transaction->xid_state.xid_cache_element->xa_state == XA_PREPARED)
|
||||
else if (thd->transaction->xid_state.xid_cache_element->xa_state ==
|
||||
XA_PREPARED)
|
||||
{
|
||||
MDL_request mdl_request;
|
||||
if (thd->lex->xa_opt != XA_NONE)
|
||||
|
@ -718,18 +729,7 @@ bool trans_xa_commit(THD *thd)
|
|||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
Acquire metadata lock which will ensure that COMMIT is blocked
|
||||
by active FLUSH TABLES WITH READ LOCK (and vice versa COMMIT in
|
||||
progress blocks FTWRL).
|
||||
|
||||
We allow FLUSHer to COMMIT; we assume FLUSHer knows what it does.
|
||||
*/
|
||||
MDL_REQUEST_INIT(&mdl_request, MDL_key::BACKUP, "", "", MDL_BACKUP_COMMIT,
|
||||
MDL_TRANSACTION);
|
||||
|
||||
if (thd->mdl_context.acquire_lock(&mdl_request,
|
||||
thd->variables.lock_wait_timeout))
|
||||
if (trans_xa_get_backup_lock(thd, &mdl_request))
|
||||
{
|
||||
/*
|
||||
We can't rollback an XA transaction on lock failure due to
|
||||
|
@ -756,6 +756,7 @@ bool trans_xa_commit(THD *thd)
|
|||
}
|
||||
|
||||
thd->m_transaction_psi= NULL;
|
||||
trans_xa_release_backup_lock(thd);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -793,7 +794,8 @@ bool trans_xa_commit(THD *thd)
|
|||
bool trans_xa_rollback(THD *thd)
|
||||
{
|
||||
XID_STATE &xid_state= thd->transaction->xid_state;
|
||||
|
||||
MDL_request mdl_request;
|
||||
bool error;
|
||||
DBUG_ENTER("trans_xa_rollback");
|
||||
|
||||
if (!xid_state.is_explicit_XA() ||
|
||||
|
@ -814,7 +816,6 @@ bool trans_xa_rollback(THD *thd)
|
|||
{
|
||||
bool res;
|
||||
bool xid_deleted= false;
|
||||
MDL_request mdl_request;
|
||||
bool rw_trans= (xs->rm_error != ER_XA_RBROLLBACK);
|
||||
|
||||
if (rw_trans && thd->is_read_only_ctx())
|
||||
|
@ -824,10 +825,7 @@ bool trans_xa_rollback(THD *thd)
|
|||
goto _end_external_xid;
|
||||
}
|
||||
|
||||
MDL_REQUEST_INIT(&mdl_request, MDL_key::BACKUP, "", "", MDL_BACKUP_COMMIT,
|
||||
MDL_EXPLICIT);
|
||||
if (thd->mdl_context.acquire_lock(&mdl_request,
|
||||
thd->variables.lock_wait_timeout))
|
||||
if (trans_xa_get_backup_lock(thd, &mdl_request))
|
||||
{
|
||||
/*
|
||||
We can't rollback an XA transaction on lock failure due to
|
||||
|
@ -838,10 +836,6 @@ bool trans_xa_rollback(THD *thd)
|
|||
|
||||
goto _end_external_xid;
|
||||
}
|
||||
else
|
||||
{
|
||||
thd->backup_commit_lock= &mdl_request;
|
||||
}
|
||||
res= xa_trans_rolled_back(xs);
|
||||
DBUG_ASSERT(!xid_state.xid_cache_element);
|
||||
|
||||
|
@ -858,11 +852,7 @@ bool trans_xa_rollback(THD *thd)
|
|||
xid_state.xid_cache_element= 0;
|
||||
if (!xid_deleted)
|
||||
xs->acquired_to_recovered();
|
||||
if (mdl_request.ticket)
|
||||
{
|
||||
thd->mdl_context.release_lock(mdl_request.ticket);
|
||||
thd->backup_commit_lock= 0;
|
||||
}
|
||||
trans_xa_release_backup_lock(thd);
|
||||
}
|
||||
else
|
||||
my_error(ER_XAER_NOTA, MYF(0));
|
||||
|
@ -879,11 +869,7 @@ bool trans_xa_rollback(THD *thd)
|
|||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
MDL_request mdl_request;
|
||||
MDL_REQUEST_INIT(&mdl_request, MDL_key::BACKUP, "", "", MDL_BACKUP_COMMIT,
|
||||
MDL_STATEMENT);
|
||||
if (thd->mdl_context.acquire_lock(&mdl_request,
|
||||
thd->variables.lock_wait_timeout))
|
||||
if (trans_xa_get_backup_lock(thd, &mdl_request))
|
||||
{
|
||||
/*
|
||||
We can't rollback an XA transaction on lock failure due to
|
||||
|
@ -894,7 +880,9 @@ bool trans_xa_rollback(THD *thd)
|
|||
DBUG_RETURN(true);
|
||||
}
|
||||
|
||||
DBUG_RETURN(xa_trans_force_rollback(thd));
|
||||
error= xa_trans_force_rollback(thd);
|
||||
trans_xa_release_backup_lock(thd);
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -402,6 +402,10 @@ row_vers_impl_x_locked(
|
|||
const rec_t* clust_rec;
|
||||
dict_index_t* clust_index;
|
||||
|
||||
/* The function must not be invoked under lock_sys latch to prevert
|
||||
latching orded violation, i.e. page latch must be acquired before
|
||||
lock_sys latch */
|
||||
lock_sys.assert_unlocked();
|
||||
/* The current function can be called from lock_rec_unlock_unmodified()
|
||||
under lock_sys.wr_lock() */
|
||||
|
||||
|
|
Loading…
Reference in a new issue