MDEV-34594 : Assertion `client_state.transaction().active()' failed in
int wsrep_thd_append_key(THD*, const wsrep_key*, int, Wsrep_service_key_type) CREATE TABLE [SELECT|REPLACE SELECT] is CTAS and idea was that we force ROW format. However, it was not correctly enforced and keys were appended before wsrep transaction was started. At THD::decide_logging_format we should force used stmt binlog format to ROW in CTAS case and produce a warning if used binlog format was not ROW. At ha_innodb::update_row we should not append keys similarly as in ha_innodb::write_row if sql_command is SQLCOM_CREATE_TABLE. Improved error logging on ::write_row, ::update_row and ::delete_row if wsrep key append fails. Signed-off-by: Julius Goryavsky <julius.goryavsky@mariadb.com>
This commit is contained in:
parent
0e27351028
commit
cd8b8bb964
88
mysql-test/suite/galera/r/MDEV-34594.result
Normal file
88
mysql-test/suite/galera/r/MDEV-34594.result
Normal file
@ -0,0 +1,88 @@
|
||||
connection node_2;
|
||||
connection node_1;
|
||||
#
|
||||
# Case 1: test with binlog_format ROW
|
||||
#
|
||||
connection node_1;
|
||||
SET @@binlog_format=ROW;
|
||||
CREATE TABLE t1 (a INT UNIQUE) SELECT 1 AS a,2 AS b UNION SELECT 2 AS a,3 AS c;
|
||||
CREATE TABLE t2 (a INT UNIQUE) REPLACE SELECT 1 AS a,2 AS b UNION SELECT 1 AS a,3 AS c;
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
1 2
|
||||
2 3
|
||||
SELECT * FROM t2;
|
||||
a b
|
||||
1 3
|
||||
connection node_2;
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
1 2
|
||||
2 3
|
||||
SELECT * FROM t2;
|
||||
a b
|
||||
1 3
|
||||
DROP TABLE t1,t2;
|
||||
#
|
||||
# Case 2: test with binlog_format MIXED
|
||||
#
|
||||
connection node_1;
|
||||
SET @@binlog_format=MIXED;
|
||||
Warnings:
|
||||
Warning 1105 MariaDB Galera and flashback do not support binlog format: MIXED
|
||||
CREATE TABLE t1 (a INT UNIQUE) SELECT 1 AS a,2 AS b UNION SELECT 2 AS a,3 AS c;
|
||||
Warnings:
|
||||
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
|
||||
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
|
||||
CREATE TABLE t2 (a INT UNIQUE) REPLACE SELECT 1 AS a,2 AS b UNION SELECT 1 AS a,3 AS c;
|
||||
Warnings:
|
||||
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
|
||||
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
1 2
|
||||
2 3
|
||||
SELECT * FROM t2;
|
||||
a b
|
||||
1 3
|
||||
connection node_2;
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
1 2
|
||||
2 3
|
||||
SELECT * FROM t2;
|
||||
a b
|
||||
1 3
|
||||
DROP TABLE t1,t2;
|
||||
#
|
||||
# Case 3: test with binlog_format STATEMENT
|
||||
#
|
||||
connection node_1;
|
||||
SET @@binlog_format=STATEMENT;
|
||||
Warnings:
|
||||
Warning 1105 MariaDB Galera and flashback do not support binlog format: STATEMENT
|
||||
CREATE TABLE t1 (a INT UNIQUE) SELECT 1 AS a,2 AS b UNION SELECT 2 AS a,3 AS c;
|
||||
Warnings:
|
||||
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
|
||||
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
|
||||
CREATE TABLE t2 (a INT UNIQUE) REPLACE SELECT 1 AS a,2 AS b UNION SELECT 1 AS a,3 AS c;
|
||||
Warnings:
|
||||
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
|
||||
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
1 2
|
||||
2 3
|
||||
SELECT * FROM t2;
|
||||
a b
|
||||
1 3
|
||||
connection node_2;
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
1 2
|
||||
2 3
|
||||
SELECT * FROM t2;
|
||||
a b
|
||||
1 3
|
||||
DROP TABLE t1,t2;
|
||||
connection node_1;
|
68
mysql-test/suite/galera/t/MDEV-34594.test
Normal file
68
mysql-test/suite/galera/t/MDEV-34594.test
Normal file
@ -0,0 +1,68 @@
|
||||
--source include/galera_cluster.inc
|
||||
--source include/log_bin.inc
|
||||
|
||||
--echo #
|
||||
--echo # Case 1: test with binlog_format ROW
|
||||
--echo #
|
||||
--connection node_1
|
||||
SET @@binlog_format=ROW;
|
||||
CREATE TABLE t1 (a INT UNIQUE) SELECT 1 AS a,2 AS b UNION SELECT 2 AS a,3 AS c;
|
||||
#
|
||||
# Note that this has two rows (1,2) and (1,3) where (1,3) contains duplicate key
|
||||
# but we requested REPLACE --> ::update_row() is called to update (1,2) --> (1,3)
|
||||
#
|
||||
CREATE TABLE t2 (a INT UNIQUE) REPLACE SELECT 1 AS a,2 AS b UNION SELECT 1 AS a,3 AS c;
|
||||
SELECT * FROM t1;
|
||||
SELECT * FROM t2;
|
||||
|
||||
--connection node_2
|
||||
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'
|
||||
--source include/wait_condition.inc
|
||||
|
||||
SELECT * FROM t1;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
--echo #
|
||||
--echo # Case 2: test with binlog_format MIXED
|
||||
--echo #
|
||||
--connection node_1
|
||||
--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'
|
||||
--source include/wait_condition.inc
|
||||
SET @@binlog_format=MIXED;
|
||||
CREATE TABLE t1 (a INT UNIQUE) SELECT 1 AS a,2 AS b UNION SELECT 2 AS a,3 AS c;
|
||||
CREATE TABLE t2 (a INT UNIQUE) REPLACE SELECT 1 AS a,2 AS b UNION SELECT 1 AS a,3 AS c;
|
||||
SELECT * FROM t1;
|
||||
SELECT * FROM t2;
|
||||
|
||||
--connection node_2
|
||||
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'
|
||||
--source include/wait_condition.inc
|
||||
|
||||
SELECT * FROM t1;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
--echo #
|
||||
--echo # Case 3: test with binlog_format STATEMENT
|
||||
--echo #
|
||||
--connection node_1
|
||||
--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'
|
||||
--source include/wait_condition.inc
|
||||
SET @@binlog_format=STATEMENT;
|
||||
CREATE TABLE t1 (a INT UNIQUE) SELECT 1 AS a,2 AS b UNION SELECT 2 AS a,3 AS c;
|
||||
CREATE TABLE t2 (a INT UNIQUE) REPLACE SELECT 1 AS a,2 AS b UNION SELECT 1 AS a,3 AS c;
|
||||
SELECT * FROM t1;
|
||||
SELECT * FROM t2;
|
||||
|
||||
--connection node_2
|
||||
--let $wait_condition = SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2' OR TABLE_NAME = 't1'
|
||||
--source include/wait_condition.inc
|
||||
|
||||
SELECT * FROM t1;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
--connection node_1
|
||||
--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'
|
||||
--source include/wait_condition.inc
|
@ -16,6 +16,9 @@ SHOW VARIABLES LIKE 'binlog_format';
|
||||
Variable_name Value
|
||||
binlog_format STATEMENT
|
||||
CREATE TABLE IF NOT EXISTS test.t1 AS SELECT * FROM information_schema.routines WHERE 1 = 0;
|
||||
Warnings:
|
||||
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
|
||||
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
|
||||
SET binlog_format=MIXED;
|
||||
Warnings:
|
||||
Warning 1105 MariaDB Galera and flashback do not support binlog format: MIXED
|
||||
@ -26,9 +29,14 @@ SHOW VARIABLES LIKE 'binlog_format';
|
||||
Variable_name Value
|
||||
binlog_format MIXED
|
||||
CREATE TABLE IF NOT EXISTS test.t2 AS SELECT * FROM information_schema.routines WHERE 1 = 0;
|
||||
Warnings:
|
||||
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
|
||||
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
|
||||
SET binlog_format=ROW;
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
|
||||
Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW
|
||||
SHOW VARIABLES LIKE 'binlog_format';
|
||||
Variable_name Value
|
||||
binlog_format ROW
|
||||
|
@ -6372,6 +6372,24 @@ int THD::decide_logging_format(TABLE_LIST *tables)
|
||||
}
|
||||
set_current_stmt_binlog_format_row();
|
||||
}
|
||||
|
||||
/* If user has requested binlog_format STMT OR MIXED
|
||||
in CREATE TABLE [SELECT|REPLACE] we will fall back
|
||||
to ROW.
|
||||
|
||||
Note that we can't use local binlog_format variable
|
||||
here because wsrep_binlog_format sets it to ROW.
|
||||
*/
|
||||
if (wsrep_ctas && variables.binlog_format != BINLOG_FORMAT_ROW)
|
||||
{
|
||||
push_warning_printf(this, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_UNKNOWN_ERROR,
|
||||
"Galera does not support binlog_format = %s "
|
||||
"in CREATE TABLE [SELECT|REPLACE] forcing ROW",
|
||||
binlog_format == BINLOG_FORMAT_STMT ?
|
||||
"STMT" : "MIXED");
|
||||
set_current_stmt_binlog_format_row();
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
if (WSREP_EMULATE_BINLOG_NNULL(this) ||
|
||||
|
@ -7858,7 +7858,10 @@ set_max_autoinc:
|
||||
if (wsrep_append_keys(m_user_thd, WSREP_SERVICE_KEY_EXCLUSIVE,
|
||||
record,
|
||||
NULL)) {
|
||||
DBUG_PRINT("wsrep", ("row key failed"));
|
||||
WSREP_DEBUG("::write_rows::wsrep_append_keys failed THD %ld for %s.%s",
|
||||
thd_get_thread_id(m_user_thd),
|
||||
table->s->db.str,
|
||||
table->s->table_name.str);
|
||||
error_result = HA_ERR_INTERNAL_ERROR;
|
||||
goto func_exit;
|
||||
}
|
||||
@ -8558,16 +8561,20 @@ func_exit:
|
||||
#ifdef WITH_WSREP
|
||||
if (error == DB_SUCCESS && trx->is_wsrep()
|
||||
&& wsrep_thd_is_local(m_user_thd)
|
||||
&& !wsrep_thd_ignore_table(m_user_thd)) {
|
||||
DBUG_PRINT("wsrep", ("update row key"));
|
||||
&& !wsrep_thd_ignore_table(m_user_thd)
|
||||
&& (thd_sql_command(m_user_thd) != SQLCOM_CREATE_TABLE)
|
||||
&& (thd_sql_command(m_user_thd) != SQLCOM_LOAD ||
|
||||
thd_binlog_format(m_user_thd) == BINLOG_FORMAT_ROW)) {
|
||||
|
||||
if (wsrep_append_keys(m_user_thd,
|
||||
wsrep_protocol_version >= 4
|
||||
? WSREP_SERVICE_KEY_UPDATE
|
||||
: WSREP_SERVICE_KEY_EXCLUSIVE,
|
||||
old_row, new_row)){
|
||||
WSREP_DEBUG("WSREP: UPDATE_ROW_KEY FAILED");
|
||||
DBUG_PRINT("wsrep", ("row key failed"));
|
||||
old_row, new_row)) {
|
||||
WSREP_DEBUG("::update_rows::wsrep_append_keys failed THD %ld for %s.%s",
|
||||
thd_get_thread_id(m_user_thd),
|
||||
table->s->db.str,
|
||||
table->s->table_name.str);
|
||||
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
|
||||
}
|
||||
}
|
||||
@ -8620,7 +8627,10 @@ ha_innobase::delete_row(
|
||||
if (wsrep_append_keys(m_user_thd, WSREP_SERVICE_KEY_EXCLUSIVE,
|
||||
record,
|
||||
NULL)) {
|
||||
DBUG_PRINT("wsrep", ("delete fail"));
|
||||
WSREP_DEBUG("::delete_rows::wsrep_append_keys failed THD %ld for %s.%s",
|
||||
thd_get_thread_id(m_user_thd),
|
||||
table->s->db.str,
|
||||
table->s->table_name.str);
|
||||
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user