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
|
Variable_name Value
|
||||||
binlog_format STATEMENT
|
binlog_format STATEMENT
|
||||||
CREATE TABLE IF NOT EXISTS test.t1 AS SELECT * FROM information_schema.routines WHERE 1 = 0;
|
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;
|
SET binlog_format=MIXED;
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1105 MariaDB Galera and flashback do not support binlog format: MIXED
|
Warning 1105 MariaDB Galera and flashback do not support binlog format: MIXED
|
||||||
@ -26,9 +29,14 @@ SHOW VARIABLES LIKE 'binlog_format';
|
|||||||
Variable_name Value
|
Variable_name Value
|
||||||
binlog_format MIXED
|
binlog_format MIXED
|
||||||
CREATE TABLE IF NOT EXISTS test.t2 AS SELECT * FROM information_schema.routines WHERE 1 = 0;
|
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;
|
SET binlog_format=ROW;
|
||||||
SHOW WARNINGS;
|
SHOW WARNINGS;
|
||||||
Level Code Message
|
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';
|
SHOW VARIABLES LIKE 'binlog_format';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
binlog_format ROW
|
binlog_format ROW
|
||||||
|
@ -6372,6 +6372,24 @@ int THD::decide_logging_format(TABLE_LIST *tables)
|
|||||||
}
|
}
|
||||||
set_current_stmt_binlog_format_row();
|
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 */
|
#endif /* WITH_WSREP */
|
||||||
|
|
||||||
if (WSREP_EMULATE_BINLOG_NNULL(this) ||
|
if (WSREP_EMULATE_BINLOG_NNULL(this) ||
|
||||||
|
@ -7858,7 +7858,10 @@ set_max_autoinc:
|
|||||||
if (wsrep_append_keys(m_user_thd, WSREP_SERVICE_KEY_EXCLUSIVE,
|
if (wsrep_append_keys(m_user_thd, WSREP_SERVICE_KEY_EXCLUSIVE,
|
||||||
record,
|
record,
|
||||||
NULL)) {
|
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;
|
error_result = HA_ERR_INTERNAL_ERROR;
|
||||||
goto func_exit;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
@ -8558,16 +8561,20 @@ func_exit:
|
|||||||
#ifdef WITH_WSREP
|
#ifdef WITH_WSREP
|
||||||
if (error == DB_SUCCESS && trx->is_wsrep()
|
if (error == DB_SUCCESS && trx->is_wsrep()
|
||||||
&& wsrep_thd_is_local(m_user_thd)
|
&& wsrep_thd_is_local(m_user_thd)
|
||||||
&& !wsrep_thd_ignore_table(m_user_thd)) {
|
&& !wsrep_thd_ignore_table(m_user_thd)
|
||||||
DBUG_PRINT("wsrep", ("update row key"));
|
&& (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,
|
if (wsrep_append_keys(m_user_thd,
|
||||||
wsrep_protocol_version >= 4
|
wsrep_protocol_version >= 4
|
||||||
? WSREP_SERVICE_KEY_UPDATE
|
? WSREP_SERVICE_KEY_UPDATE
|
||||||
: WSREP_SERVICE_KEY_EXCLUSIVE,
|
: WSREP_SERVICE_KEY_EXCLUSIVE,
|
||||||
old_row, new_row)){
|
old_row, new_row)) {
|
||||||
WSREP_DEBUG("WSREP: UPDATE_ROW_KEY FAILED");
|
WSREP_DEBUG("::update_rows::wsrep_append_keys failed THD %ld for %s.%s",
|
||||||
DBUG_PRINT("wsrep", ("row key failed"));
|
thd_get_thread_id(m_user_thd),
|
||||||
|
table->s->db.str,
|
||||||
|
table->s->table_name.str);
|
||||||
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
|
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,
|
if (wsrep_append_keys(m_user_thd, WSREP_SERVICE_KEY_EXCLUSIVE,
|
||||||
record,
|
record,
|
||||||
NULL)) {
|
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);
|
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user