Commit 6911e00a authored by Jan Lindström's avatar Jan Lindström Committed by Julius Goryavsky

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: default avatarJulius Goryavsky <julius.goryavsky@mariadb.com>
parent 8b51d344
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;
Timeout in wait_condition.inc for SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'
Id User Host db Command Time State Info Progress
1 system user NULL Sleep 31 wsrep applier committed NULL 0.000
2 system user NULL Sleep 36 wsrep aborter idle NULL 0.000
10 root localhost:46588 test Query 0 starting show full processlist 0.000
SELECT * FROM t1;
a b
1 2
2 3
SELECT * FROM t2;
a b
1 3
DROP TABLE t1,t2;
connection node_1;
--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'
--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'; ...@@ -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'; ...@@ -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) ...@@ -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 @@ ha_innobase::write_row( ...@@ -7858,7 +7858,10 @@ ha_innobase::write_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", ("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 @@ ha_innobase::update_row( ...@@ -8558,16 +8561,20 @@ ha_innobase::update_row(
#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( ...@@ -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);
} }
} }
......
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