Commit 1e1073b8 authored by Marko Mäkelä's avatar Marko Mäkelä

Merge 10.5 into 10.6

parents 9fe681c9 c6846757
set global aria_encrypt_tables = 1;
SET @aria_encrypt= @@aria_encrypt_tables;
SET global aria_encrypt_tables=1;
create table t1 (i int, key(i)) engine=aria;
insert into t1 values (1);
drop table t1;
......@@ -10,4 +11,17 @@ check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
drop table t1;
set global aria_encrypt_tables = 0;
#
# MDEV CHECK on encrypted Aria table complains about "Wrong LSN"
#
CREATE TABLE t1 (f DATE PRIMARY KEY) ENGINE=Aria;
INSERT INTO t1 (f) VALUES ('1995-01-01'),('2000-01-01');
DELETE FROM t1 WHERE f = '2000-01-01';
OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
CHECK TABLE t1 EXTENDED;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
set global aria_encrypt_tables=@aria_encrypt;
--source include/have_file_key_management_plugin.inc
--source include/have_sequence.inc
SET @aria_encrypt= @@aria_encrypt_tables;
SET global aria_encrypt_tables=1;
#
# MDEV-8022 Assertion `rc == 0' failed in ma_encrypt on dropping an encrypted Aria table
#
set global aria_encrypt_tables = 1;
create table t1 (i int, key(i)) engine=aria;
insert into t1 values (1);
drop table t1;
......@@ -24,7 +26,18 @@ alter table t1 enable keys;
check table t1;
drop table t1;
--echo #
--echo # MDEV CHECK on encrypted Aria table complains about "Wrong LSN"
--echo #
CREATE TABLE t1 (f DATE PRIMARY KEY) ENGINE=Aria;
INSERT INTO t1 (f) VALUES ('1995-01-01'),('2000-01-01');
DELETE FROM t1 WHERE f = '2000-01-01';
OPTIMIZE TABLE t1;
CHECK TABLE t1 EXTENDED;
DROP TABLE t1;
#
# Cleanup
#
set global aria_encrypt_tables = 0;
set global aria_encrypt_tables=@aria_encrypt;
connection node_2;
connection node_1;
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
LOCK TABLE t1 WRITE CONCURRENT;
connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
connection node_1a;
SET lock_wait_timeout= 1;
CREATE VIEW v1 AS SELECT * FROM t1;
connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1;
connection node_1b;
SET SESSION wsrep_sync_wait = 0;
connection node_1;
UNLOCK TABLES;
connection node_1a;
DROP VIEW v1;
DROP TABLE t1;
--source include/galera_cluster.inc
--source include/have_log_bin.inc
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
LOCK TABLE t1 WRITE CONCURRENT;
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
--connection node_1a
# TOI operations will ignore lock_wait_timeout
SET lock_wait_timeout= 1;
--send CREATE VIEW v1 AS SELECT * FROM t1
--connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1
--connection node_1b
SET SESSION wsrep_sync_wait = 0;
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE = 'Waiting for table level lock'
--source include/wait_condition.inc
--connection node_1
UNLOCK TABLES;
--connection node_1a
--reap
DROP VIEW v1;
DROP TABLE t1;
GCF-336 :
GCF-582 :
GCF-609 :
GCF-810A :
GCF-810B :
GCF-810C :
......
connection node_2;
connection node_1;
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB;
connection node_1;
SET SESSION wsrep_trx_fragment_size=1;
SET AUTOCOMMIT=OFF;
START TRANSACTION;
INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
connection node_2;
SET SESSION wsrep_trx_fragment_size=1;
SET AUTOCOMMIT=OFF;
START TRANSACTION;
INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19),(20);
INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19),(20);
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
ERROR 23000: Duplicate entry '11' for key 'PRIMARY'
INSERT INTO t1 VALUES (31),(32),(33);
SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log;
COUNT(*) = 0
0
connection node_1;
SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log;
COUNT(*) = 0
0
COMMIT;
connection node_2;
COMMIT;
SELECT * FROM t1;
f1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
31
32
33
connection node_1;
SELECT * FROM t1;
f1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
31
32
33
DROP TABLE t1;
......@@ -17,7 +17,7 @@ SET SESSION wsrep_trx_fragment_size=1;
SET AUTOCOMMIT=OFF;
START TRANSACTION;
INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19),(20);
--error ER_LOCK_DEADLOCK
--error ER_DUP_ENTRY
INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19),(20);
INSERT INTO t1 VALUES (31),(32),(33);
......@@ -27,4 +27,11 @@ SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log;
SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log;
COMMIT;
--connection node_2
COMMIT;
SELECT * FROM t1;
--connection node_1
SELECT * FROM t1;
DROP TABLE t1;
connection node_2;
connection node_1;
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 CHAR(10)) ENGINE=InnoDB;
connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
connection node_1;
SET SESSION wsrep_trx_fragment_size = 1;
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY);
CREATE TABLE t2 (f1 INTEGER PRIMARY KEY);
INSERT INTO t2 VALUES (1),(2),(3);
ALTER TABLE t2 DROP PRIMARY KEY;
INSERT INTO t2 VALUES (1);
SET SESSION wsrep_trx_fragment_size = 1;
START TRANSACTION;
INSERT INTO t1 SELECT * FROM t2;
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
SELECT * FROM t1;
f1
connection node_2;
SELECT * FROM t1;
f1
connection node_1;
DROP TABLE t1;
DROP TABLE t2;
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 CHAR(10)) ENGINE=InnoDB;
connection node_1;
SET SESSION wsrep_trx_fragment_size = 1;
START TRANSACTION;
INSERT INTO t1 VALUES (1, 'node1');
connection node_1a;
INSERT INTO t1 VALUES (5, 'node2');
connection node_1;
INSERT INTO t1 VALUES (5, 'node1');
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
ERROR 23000: Duplicate entry '5' for key 'PRIMARY'
SELECT * FROM t1;
f1 f2
1 node1
5 node2
SET SESSION wsrep_trx_fragment_size = 10000;
START TRANSACTION;
......@@ -24,6 +44,7 @@ INSERT INTO t1 VALUES(15, 'node2');
connection node_1;
SELECT * FROM t1;
f1 f2
1 node1
5 node2
10 node1
INSERT INTO t1 VALUES(15, 'node1');
......@@ -31,6 +52,7 @@ ERROR 23000: Duplicate entry '15' for key 'PRIMARY'
COMMIT;
SELECT * FROM t1;
f1 f2
1 node1
5 node2
10 node1
15 node2
......
......@@ -13,7 +13,7 @@ INSERT INTO t1 VALUES (REPEAT('e', 512));
INSERT INTO t1 VALUES (REPEAT('f', 512));
connection node_2;
connection node_1;
INSERT INTO t1 VALUES (REPEAT('c', 512));
INSERT INTO t1 VALUES (REPEAT('g', 1024)),(REPEAT('c', 512));
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
connection node_1;
SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log;
......
connection node_2;
connection node_1;
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY);
SET SESSION wsrep_trx_fragment_size=1;
START TRANSACTION;
INSERT INTO t1 VALUES (1);
SET SESSION wsrep_cluster_name = ' ';
ERROR HY000: Variable 'wsrep_cluster_name' is a GLOBAL variable and should be set with SET GLOBAL
INSERT INTO t1 VALUES (2);
COMMIT;
SELECT f1 AS expect_1_and_2 FROM t1;
expect_1_and_2
1
2
DROP TABLE t1;
--source include/galera_cluster.inc
--source include/have_innodb.inc
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 CHAR(10)) ENGINE=InnoDB;
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
#
# Test 1: statement rollback is not safe
# (some fragments were already replicated)
# Test 1: statement rollback is not safe.
# Statement has already replicated some fragments
#
--connection node_1
SET SESSION wsrep_trx_fragment_size = 1;
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY);
CREATE TABLE t2 (f1 INTEGER PRIMARY KEY);
INSERT INTO t2 VALUES (1),(2),(3);
ALTER TABLE t2 DROP PRIMARY KEY;
INSERT INTO t2 VALUES (1);
SET SESSION wsrep_trx_fragment_size = 1;
START TRANSACTION;
# The following INSERT .. SELECT inserts a duplicate key,
# ER_LOCK_DEADLOCK is the only possible outcome at this point.
# Notice that ER_DUP_ENTRY is NOT an option here because we were
# forced to rollback the whole transaction (not just the statement)
--error ER_LOCK_DEADLOCK
INSERT INTO t1 SELECT * FROM t2;
SELECT * FROM t1;
--connection node_2
SELECT * FROM t1;
--connection node_1
DROP TABLE t1;
DROP TABLE t2;
#
# Test 2: statement rollback is safe.
# Fragments were already replicated, not in the same statement
#
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 CHAR(10)) ENGINE=InnoDB;
--connection node_1
SET SESSION wsrep_trx_fragment_size = 1;
START TRANSACTION;
......@@ -19,20 +47,16 @@ INSERT INTO t1 VALUES (1, 'node1');
INSERT INTO t1 VALUES (5, 'node2');
--connection node_1
# If we try to INSERT a duplicate key, ER_LOCK_DEADLOCK is the only possible
# outcome at this point. Notice that ER_DUP_ENTRY is NOT an option here
# because we were forced to rollback the whole transaction (not just the
# statement)
--error ER_LOCK_DEADLOCK
# Only the statement is rolled back, expect ER_DUP_ENTRY
--error ER_DUP_ENTRY
INSERT INTO t1 VALUES (5, 'node1');
SELECT * FROM t1;
#
# Test 2: statement rollback is safe
# (no fragments have been replicated)
# Test 3: statement rollback is safe
# No fragments have been replicated
#
SET SESSION wsrep_trx_fragment_size = 10000;
START TRANSACTION;
......
......@@ -22,12 +22,13 @@ INSERT INTO t1 VALUES (REPEAT('f', 512));
--let $wait_condition = SELECT COUNT(*) > 0 FROM mysql.wsrep_streaming_log;
--connection node_1
# Deadlock error instead of dupkey since the transaction is SR and
# statement rollback is not safe.
# Deadlock error instead of dupkey since the transaction is SR,
# and the statement has already replicated a fragment (which
# makes statement rollback unsafe).
--error ER_LOCK_DEADLOCK
INSERT INTO t1 VALUES (REPEAT('c', 512));
INSERT INTO t1 VALUES (REPEAT('g', 1024)),(REPEAT('c', 512));
# Confirm that the wsrep_streaming_log table is now empty, as it was a full transaction rollback
# Confirm that the wsrep_schema table is now empty, as it was a full transaction rollback
--connection node_1
SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log;
......
#
# Statement with no side effects causes unnecessary full rollback
#
--source include/galera_cluster.inc
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY);
SET SESSION wsrep_trx_fragment_size=1;
START TRANSACTION;
INSERT INTO t1 VALUES (1);
# Let's cause some bogus error with a statement that
# does not cause any replication event.
# The following used to return error ER_LOCK_DEADLOCK
# and cause the entire transaction to be rolled back.
--error ER_GLOBAL_VARIABLE
SET SESSION wsrep_cluster_name = ' ';
INSERT INTO t1 VALUES (2);
COMMIT;
SELECT f1 AS expect_1_and_2 FROM t1;
DROP TABLE t1;
\ No newline at end of file
......@@ -2890,3 +2890,30 @@ SELECT COUNT(*) FROM t1;
COUNT(*)
16
DROP TABLE t1;
#
# MDEV-25630 Rollback of instant operation adds wrong
# column to secondary index
#
CREATE TABLE t1 (f1 INT, f2 INT, f3 INT, f4 INT,
PRIMARY KEY(f1, f4),
KEY(f2))ENGINE=InnoDB;
CREATE TABLE t2 (f1 INT, f2 INT, PRIMARY KEY(f1),
FOREIGN KEY fk (f2) REFERENCES t2(f1)
)ENGINE=InnoDB;
ALTER TABLE t1 ADD f5 INT;
SET FOREIGN_KEY_CHECKS=0;
ALTER TABLE t1 DROP COLUMN f3, ADD FOREIGN KEY fk (f1)
REFERENCES x(x);
ERROR HY000: Failed to add the foreign key constraint 'test/fk' to system tables
ALTER TABLE t1 DROP COLUMN f5;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`f1` int(11) NOT NULL,
`f2` int(11) DEFAULT NULL,
`f3` int(11) DEFAULT NULL,
`f4` int(11) NOT NULL,
PRIMARY KEY (`f1`,`f4`),
KEY `f2` (`f2`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
DROP TABLE t1, t2;
......@@ -929,3 +929,23 @@ INSERT INTO t1(a, b) SELECT '', '' FROM seq_1_to_16;
SELECT COUNT(*) FROM t1;
# Cleanup
DROP TABLE t1;
--echo #
--echo # MDEV-25630 Rollback of instant operation adds wrong
--echo # column to secondary index
--echo #
CREATE TABLE t1 (f1 INT, f2 INT, f3 INT, f4 INT,
PRIMARY KEY(f1, f4),
KEY(f2))ENGINE=InnoDB;
CREATE TABLE t2 (f1 INT, f2 INT, PRIMARY KEY(f1),
FOREIGN KEY fk (f2) REFERENCES t2(f1)
)ENGINE=InnoDB;
ALTER TABLE t1 ADD f5 INT;
SET FOREIGN_KEY_CHECKS=0;
--error ER_FK_FAIL_ADD_SYSTEM
ALTER TABLE t1 DROP COLUMN f3, ADD FOREIGN KEY fk (f1)
REFERENCES x(x);
ALTER TABLE t1 DROP COLUMN f5;
SHOW CREATE TABLE t1;
DROP TABLE t1, t2;
......@@ -166,10 +166,10 @@ wsrep_thread_count 2
# variables
SELECT COUNT(*) AS EXPECT_49 FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME LIKE "wsrep%";
EXPECT_49
49
52
SELECT COUNT(*) AS EXPECT_49 FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIKE "wsrep%";
EXPECT_49
49
51
SELECT VARIABLE_NAME FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME LIKE "wsrep%" ORDER BY VARIABLE_NAME;
VARIABLE_NAME
WSREP_AUTO_INCREMENT_CONTROL
......@@ -188,11 +188,13 @@ WSREP_DRUPAL_282555_WORKAROUND
WSREP_FORCED_BINLOG_FORMAT
WSREP_GTID_DOMAIN_ID
WSREP_GTID_MODE
WSREP_GTID_SEQ_NO
WSREP_IGNORE_APPLY_ERRORS
WSREP_LOAD_DATA_SPLITTING
WSREP_LOG_CONFLICTS
WSREP_MAX_WS_ROWS
WSREP_MAX_WS_SIZE
WSREP_MODE
WSREP_MYSQL_REPLICATION_BUNDLE
WSREP_NODE_ADDRESS
WSREP_NODE_INCOMING_ADDRESS
......@@ -218,6 +220,7 @@ WSREP_SST_DONOR_REJECTS_QUERIES
WSREP_SST_METHOD
WSREP_SST_RECEIVE_ADDRESS
WSREP_START_POSITION
WSREP_STRICT_DDL
WSREP_SYNC_WAIT
WSREP_TRX_FRAGMENT_SIZE
WSREP_TRX_FRAGMENT_UNIT
......@@ -244,6 +247,7 @@ WSREP_LOAD_DATA_SPLITTING
WSREP_LOG_CONFLICTS
WSREP_MAX_WS_ROWS
WSREP_MAX_WS_SIZE
WSREP_MODE
WSREP_MYSQL_REPLICATION_BUNDLE
WSREP_NODE_ADDRESS
WSREP_NODE_INCOMING_ADDRESS
......@@ -269,6 +273,7 @@ WSREP_SST_DONOR_REJECTS_QUERIES
WSREP_SST_METHOD
WSREP_SST_RECEIVE_ADDRESS
WSREP_START_POSITION
WSREP_STRICT_DDL
WSREP_SYNC_WAIT
WSREP_TRX_FRAGMENT_SIZE
WSREP_TRX_FRAGMENT_UNIT
......@@ -95,24 +95,6 @@ my_bool thr_lock_inited=0;
ulong locks_immediate = 0L, locks_waited = 0L;
enum thr_lock_type thr_upgraded_concurrent_insert_lock = TL_WRITE;
#ifdef WITH_WSREP
static wsrep_thd_is_brute_force_fun wsrep_thd_is_brute_force= NULL;
static wsrep_abort_thd_fun wsrep_abort_thd= NULL;
static my_bool wsrep_debug;
static my_bool wsrep_convert_LOCK_to_trx;
static wsrep_on_fun wsrep_on = NULL;
void wsrep_thr_lock_init(
wsrep_thd_is_brute_force_fun bf_fun, wsrep_abort_thd_fun abort_fun,
my_bool debug, my_bool convert_LOCK_to_trx, wsrep_on_fun on_fun
) {
wsrep_thd_is_brute_force = bf_fun;
wsrep_abort_thd = abort_fun;
wsrep_debug = debug;
wsrep_convert_LOCK_to_trx= convert_LOCK_to_trx;
wsrep_on = on_fun;
}
#endif
/* The following constants are only for debug output */
#define MAX_THREADS 1000
#define MAX_LOCKS 1000
......@@ -653,93 +635,6 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
DBUG_RETURN(result);
}
#ifdef WITH_WSREP
/*
* If brute force applier would need to wait for a thr lock,
* it needs to make sure that it will get the lock without (too much)
* delay.
* We identify here the owners of blocking locks and ask them to
* abort. We then put our lock request in the first place in the
* wait queue. When lock holders abort (one by one) the lock release
* algorithm should grant the lock to us. We rely on this and proceed
* to wait_for_locks().
* wsrep_break_locks() should be called in all the cases, where lock
* wait would happen.
*
* TODO: current implementation might not cover all possible lock wait
* situations. This needs an review still.
* TODO: lock release, might favor some other lock (instead our bf).
* This needs an condition to check for bf locks first.
* TODO: we still have a debug fprintf, this should be removed
*/
static my_bool
wsrep_break_lock(
THR_LOCK_DATA *data, struct st_lock_list *lock_queue1,
struct st_lock_list *wait_queue)
{
if (wsrep_on && wsrep_on(data->owner->mysql_thd) &&
wsrep_thd_is_brute_force &&
wsrep_thd_is_brute_force(data->owner->mysql_thd, TRUE))
{
THR_LOCK_DATA *holder;
/* if locking session conversion to transaction has been enabled,
we know that this conflicting lock must be read lock and furthermore,
lock holder is read-only. It is safe to wait for him.
*/
#ifdef TODO_WHEN_LOCK_TABLES_IS_A_TRANSACTION
if (wsrep_convert_LOCK_to_trx &&
(THD*)(data->owner->mysql_thd)->in_lock_tables)
{
if (wsrep_debug)
fprintf(stderr,"WSREP wsrep_break_lock read lock untouched\n");
return FALSE;
}
#endif
if (wsrep_debug)
fprintf(stderr,"WSREP wsrep_break_lock aborting locks\n");
/* aborting lock holder(s) here */
for (holder=(lock_queue1) ? lock_queue1->data : NULL;
holder;
holder=holder->next)
{
if (!wsrep_thd_is_brute_force(holder->owner->mysql_thd, TRUE))
{
wsrep_abort_thd(data->owner->mysql_thd,
holder->owner->mysql_thd, FALSE);
}
else
{
if (wsrep_debug)
fprintf(stderr,"WSREP wsrep_break_lock skipping BF lock conflict\n");
return FALSE;
}
}
/* Add our lock to the head of the wait queue */
if (*(wait_queue->last)==wait_queue->data)
{
wait_queue->last=&data->next;
assert(wait_queue->data==0);
}
else
{
assert(wait_queue->data!=0);
wait_queue->data->prev=&data->next;
}
data->next=wait_queue->data;
data->prev=&wait_queue->data;
wait_queue->data=data;
data->cond=get_cond();
statistic_increment(locks_immediate,&THR_LOCK_lock);
return TRUE;
}
return FALSE;
}
#endif
static enum enum_thr_lock_result
thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout)
{
......@@ -747,9 +642,6 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout)
enum enum_thr_lock_result result= THR_LOCK_SUCCESS;
struct st_lock_list *wait_queue;
enum thr_lock_type lock_type= data->type;
#ifdef WITH_WSREP
my_bool wsrep_lock_inserted= FALSE;
#endif
MYSQL_TABLE_WAIT_VARIABLES(locker, state) /* no ';' */
DBUG_ENTER("thr_lock");
......@@ -846,13 +738,6 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout)
lock but a high priority write waiting in the write_wait queue.
In the latter case we should yield the lock to the writer.
*/
#ifdef WITH_WSREP
if (wsrep_break_lock(data, &lock->write, &lock->read_wait))
{
wsrep_lock_inserted= TRUE;
}
#endif
wait_queue= &lock->read_wait;
}
else /* Request for WRITE lock */
......@@ -1000,20 +885,8 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout)
(ulong) lock->read.data->owner->thread_id,
data->type));
}
#ifdef WITH_WSREP
if (wsrep_break_lock(data, &lock->write, &lock->write_wait))
{
wsrep_lock_inserted= TRUE;
}
#endif
wait_queue= &lock->write_wait;
}
/* Can't get lock yet; Wait for it */
#ifdef WITH_WSREP
if (wsrep_lock_inserted && wsrep_on(data->owner->mysql_thd))
DBUG_RETURN(wait_for_lock(wait_queue, data, 1, lock_wait_timeout));
#endif
result= wait_for_lock(wait_queue, data, 0, lock_wait_timeout);
MYSQL_END_TABLE_LOCK_WAIT(locker);
DBUG_RETURN(result);
......
......@@ -11078,34 +11078,6 @@ void wsrep_thd_binlog_stmt_rollback(THD * thd)
DBUG_VOID_RETURN;
}
bool wsrep_stmt_rollback_is_safe(THD* thd)
{
bool ret(true);
DBUG_ENTER("wsrep_binlog_stmt_rollback_is_safe");
binlog_cache_mngr *cache_mngr=
(binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
if (binlog_hton && cache_mngr)
{
binlog_cache_data * trx_cache = &cache_mngr->trx_cache;
if (thd->wsrep_sr().fragments_certified() > 0 &&
(trx_cache->get_prev_position() == MY_OFF_T_UNDEF ||
trx_cache->get_prev_position() < thd->wsrep_sr().log_position()))
{
WSREP_DEBUG("statement rollback is not safe for streaming replication"
" pre-stmt_pos: %llu, frag repl pos: %zu\n"
"Thread: %llu, SQL: %s",
trx_cache->get_prev_position(),
thd->wsrep_sr().log_position(),
thd->thread_id, thd->query());
ret = false;
}
}
DBUG_RETURN(ret);
}
void wsrep_register_binlog_handler(THD *thd, bool trx)
{
DBUG_ENTER("register_binlog_handler");
......
/*
Copyright (c) 2000, 2016, Oracle and/or its affiliates.
Copyright (c) 2009, 2020, MariaDB Corporation.
Copyright (c) 2009, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -688,6 +688,7 @@ typedef struct system_variables
are based on the cluster size):
*/
ulong saved_auto_increment_increment, saved_auto_increment_offset;
ulong saved_lock_wait_timeout;
ulonglong wsrep_gtid_seq_no;
#endif /* WITH_WSREP */
uint eq_range_index_dive_limit;
......
......@@ -943,9 +943,6 @@ void wsrep_init_startup (bool sst_first)
{
if (wsrep_init()) unireg_abort(1);
wsrep_thr_lock_init(wsrep_thd_is_BF, wsrep_thd_bf_abort,
wsrep_debug, wsrep_convert_LOCK_to_trx, wsrep_on);
/*
Pre-initialize global_system_variables.table_plugin with a dummy engine
(placeholder) required during the initialization of wsrep threads (THDs).
......@@ -2754,6 +2751,13 @@ int wsrep_to_isolation_begin(THD *thd, const char *db_, const char *table_,
thd->variables.auto_increment_increment= 1;
}
/*
TOI operations will ignore provided lock_wait_timeout and restore it
after operation is done.
*/
thd->variables.saved_lock_wait_timeout= thd->variables.lock_wait_timeout;
thd->variables.lock_wait_timeout= LONG_TIMEOUT;
if (thd->variables.wsrep_on && wsrep_thd_is_local(thd))
{
switch (wsrep_OSU_method_get(thd)) {
......@@ -2789,6 +2793,9 @@ void wsrep_to_isolation_end(THD *thd)
{
DBUG_ASSERT(wsrep_thd_is_local_toi(thd) ||
wsrep_thd_is_in_rsu(thd));
thd->variables.lock_wait_timeout= thd->variables.saved_lock_wait_timeout;
if (wsrep_thd_is_local_toi(thd))
{
DBUG_ASSERT(wsrep_OSU_method_get(thd) == WSREP_OSU_TOI);
......
......@@ -404,8 +404,6 @@ int wsrep_to_buf_helper(
int wsrep_create_trigger_query(THD *thd, uchar** buf, size_t* buf_len);
int wsrep_create_event_query(THD *thd, uchar** buf, size_t* buf_len);
bool wsrep_stmt_rollback_is_safe(THD* thd);
void wsrep_init_sidno(const wsrep_uuid_t&);
bool wsrep_node_is_donor();
bool wsrep_node_is_synced();
......
......@@ -374,11 +374,14 @@ static inline int wsrep_before_rollback(THD* thd, bool all)
}
if (thd->wsrep_trx().is_streaming() &&
!wsrep_stmt_rollback_is_safe(thd))
(wsrep_fragments_certified_for_stmt(thd) > 0))
{
/* Non-safe statement rollback during SR multi statement
transasction. Self abort the transaction, the actual rollback
and error handling will be done in after statement phase. */
transaction. A statement rollback is considered unsafe, if
the same statement has already replicated one or more fragments.
Self abort the transaction, the actual rollback and error
handling will be done in after statement phase. */
WSREP_DEBUG("statement rollback is not safe for streaming replication");
wsrep_thd_self_abort(thd);
ret= 0;
}
......
......@@ -733,6 +733,13 @@ inline void dict_table_t::rollback_instant(
const ulint* col_map)
{
ut_d(dict_sys.assert_locked());
if (cols == old_cols) {
/* Alter fails before instant operation happens.
So there is no need to do rollback instant operation */
return;
}
dict_index_t* index = indexes.start;
/* index->is_instant() does not necessarily hold here, because
the table may have been emptied */
......
......@@ -179,7 +179,8 @@ int maria_close(register MARIA_HA *info)
mysql_rwlock_destroy(&share->keyinfo[i].root_lock);
}
}
DBUG_ASSERT(share->now_transactional == share->base.born_transactional);
DBUG_ASSERT(share->now_transactional == share->base.born_transactional ||
share->internal_table);
/*
We assign -1 because checkpoint does not need to flush (in case we
have concurrent checkpoint if no then we do not need it here also)
......
......@@ -187,9 +187,9 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share,
maria_delay_key_write)
share->delay_key_write=1;
if (!share->base.born_transactional) /* For transactional ones ... */
if (!share->now_transactional) /* If not transctional table */
{
/* ... force crash if no trn given */
/* Pagecache requires access to info->trn->rec_lsn */
_ma_set_tmp_trn_for_table(&info, &dummy_transaction_object);
info.state= &share->state.state; /* Change global values by default */
}
......@@ -282,7 +282,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags,
ulong *nulls_per_key_part;
my_off_t key_root[HA_MAX_POSSIBLE_KEY];
ulonglong max_key_file_length, max_data_file_length;
my_bool versioning= 1;
my_bool versioning= 1, born_transactional;
File data_file= -1, kfile= -1;
struct ms3_st *s3_client= 0;
S3_INFO *share_s3= 0;
......@@ -526,6 +526,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags,
file_version= (share->state.header.not_used == 0);
if (file_version == 0)
share->base.language= share->state.header.not_used;
born_transactional= share->base.born_transactional;
share->state.state_length=base_pos;
/* For newly opened tables we reset the error-has-been-printed flag */
......@@ -560,7 +561,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags,
We can ignore testing uuid if STATE_NOT_MOVABLE is not set, as in this
case the uuid will be set in _ma_mark_file_changed().
*/
if (share->base.born_transactional &&
if (born_transactional &&
((share->state.create_trid > trnman_get_max_trid() &&
!maria_in_recovery) ||
((share->state.changed & STATE_NOT_MOVABLE) &&
......@@ -601,7 +602,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags,
}
/* Ensure we have space in the key buffer for transaction id's */
if (share->base.born_transactional)
if (born_transactional)
share->base.max_key_length= ALIGN_SIZE(share->base.max_key_length +
MARIA_MAX_PACK_TRANSID_SIZE);
......@@ -700,7 +701,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags,
share->block_size= share->base.block_size; /* Convenience */
share->max_index_block_size= share->block_size - KEYPAGE_CHECKSUM_SIZE;
share->keypage_header= ((share->base.born_transactional ?
share->keypage_header= ((born_transactional ?
LSN_STORE_SIZE + TRANSID_SIZE :
0) + KEYPAGE_KEYID_SIZE + KEYPAGE_FLAG_SIZE +
KEYPAGE_USED_SIZE);
......@@ -723,7 +724,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags,
/* Calculate length to store a key + nod flag and transaction info */
keyinfo->max_store_length= (keyinfo->maxlength +
share->base.key_reflength);
if (share->base.born_transactional)
if (born_transactional)
keyinfo->max_store_length+= MARIA_INDEX_OVERHEAD_SIZE;
/* See ma_delete.cc::underflow() */
......@@ -862,9 +863,9 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags,
file for REPAIR. Don't do logging. This base information will not go
to disk.
*/
share->base.born_transactional= FALSE;
born_transactional= FALSE;
}
if (share->base.born_transactional)
if (born_transactional)
{
share->page_type= PAGECACHE_LSN_PAGE;
if (share->state.create_rename_lsn == LSN_NEEDS_NEW_STATE_LSNS)
......@@ -915,7 +916,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags,
}
else
share->page_type= PAGECACHE_PLAIN_PAGE;
share->now_transactional= share->base.born_transactional;
share->now_transactional= born_transactional;
/* Use pack_reclength as we don't want to modify base.pack_recklength */
if (share->state.header.org_data_file_type == DYNAMIC_RECORD)
......
......@@ -717,6 +717,10 @@ TRUNCATE TABLE ta_l;
connection master_1;
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
a b date_format(c, '%Y-%m-%d %H:%i:%s')
connection master_1;
create table t2345678911234567892123456789312345678941234567895123234234(id int) ENGINE=SPIDER
COMMENT='host "192.168.21.1", user "spider", password "password", database "test32738123123123"';
drop table t2345678911234567892123456789312345678941234567895123234234;
deinit
connection master_1;
......
......@@ -2677,6 +2677,11 @@ if ($USE_CHILD_GROUP2)
--connection master_1
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_l ORDER BY a;
--connection master_1
create table t2345678911234567892123456789312345678941234567895123234234(id int) ENGINE=SPIDER
COMMENT='host "192.168.21.1", user "spider", password "password", database "test32738123123123"';
drop table t2345678911234567892123456789312345678941234567895123234234;
--echo
--echo deinit
--disable_warnings
......@@ -2689,6 +2694,7 @@ if ($USE_CHILD_GROUP2)
--connection child2_2
DROP DATABASE IF EXISTS auto_test_remote2;
}
--disable_query_log
--disable_result_log
--source test_deinit.inc
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment