From aa9db4c162e9fa7560abb1bf8012233f30980e04 Mon Sep 17 00:00:00 2001 From: Nirbhay Choubey Date: Sun, 29 Jan 2017 13:21:38 -0500 Subject: [PATCH] MDEV-11817: Altering a table with more rows than .. .. wsrep_max_ws_rows causes cluster to break when running Galera cluster in TOI mode Problem: While copying records to temporary table during ALTER TABLE, if there are more than wsrep_max_wsrep_rows records, the command fails. Fix: Since, the temporary table records are not placed into the binary log, wsrep_affected_rows must not be incremented. Added a test. --- .../galera/r/galera_var_max_ws_rows.result | 20 +++++++++++++++ .../galera/t/galera_var_max_ws_rows.test | 25 +++++++++++++++++-- sql/handler.cc | 15 ++++++++--- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/mysql-test/suite/galera/r/galera_var_max_ws_rows.result b/mysql-test/suite/galera/r/galera_var_max_ws_rows.result index 6e239c70a3e..a1deb16c5a6 100644 --- a/mysql-test/suite/galera/r/galera_var_max_ws_rows.result +++ b/mysql-test/suite/galera/r/galera_var_max_ws_rows.result @@ -113,3 +113,23 @@ INSERT INTO t1 (f2) VALUES (2); ERROR HY000: wsrep_max_ws_rows exceeded DROP TABLE t1; DROP TABLE ten; +# +# MDEV-11817: Altering a table with more rows than +# wsrep_max_ws_rows causes cluster to break when running +# Galera cluster in TOI mode +# +CREATE TABLE t1(c1 INT)ENGINE = INNODB; +SET GLOBAL wsrep_max_ws_rows= DEFAULT; +INSERT INTO t1 VALUES(1); +INSERT INTO t1 SELECT * FROM t1; +SET GLOBAL wsrep_max_ws_rows= 1; +ALTER TABLE t1 CHANGE COLUMN c1 c1 BIGINT; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT COUNT(*) FROM t1; +COUNT(*) +2 +DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/galera_var_max_ws_rows.test b/mysql-test/suite/galera/t/galera_var_max_ws_rows.test index 944238bf1aa..ab6a3390c06 100644 --- a/mysql-test/suite/galera/t/galera_var_max_ws_rows.test +++ b/mysql-test/suite/galera/t/galera_var_max_ws_rows.test @@ -146,10 +146,31 @@ INSERT INTO t1 (f2) VALUES (1); --error ER_ERROR_DURING_COMMIT INSERT INTO t1 (f2) VALUES (2); +DROP TABLE t1; +DROP TABLE ten; + +--echo # +--echo # MDEV-11817: Altering a table with more rows than +--echo # wsrep_max_ws_rows causes cluster to break when running +--echo # Galera cluster in TOI mode +--echo # +--connection node_1 +CREATE TABLE t1(c1 INT)ENGINE = INNODB; +SET GLOBAL wsrep_max_ws_rows= DEFAULT; +INSERT INTO t1 VALUES(1); +INSERT INTO t1 SELECT * FROM t1; +SET GLOBAL wsrep_max_ws_rows= 1; +ALTER TABLE t1 CHANGE COLUMN c1 c1 BIGINT; + +--connection node_2 +SHOW CREATE TABLE t1; +SELECT COUNT(*) FROM t1; +DROP TABLE t1; + +--connection node_1 --disable_query_log --eval SET GLOBAL wsrep_max_ws_rows = $wsrep_max_ws_rows_orig --enable_query_log -DROP TABLE t1; -DROP TABLE ten; +--source include/galera_end.inc diff --git a/sql/handler.cc b/sql/handler.cc index af06427ff19..cca77eece48 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -5726,6 +5726,8 @@ static int write_locked_table_maps(THD *thd) typedef bool Log_func(THD*, TABLE*, bool, const uchar*, const uchar*); +static int check_wsrep_max_ws_rows(); + static int binlog_log_row(TABLE* table, const uchar *before_record, const uchar *after_record, @@ -5765,6 +5767,13 @@ static int binlog_log_row(TABLE* table, bool const has_trans= thd->lex->sql_command == SQLCOM_CREATE_TABLE || table->file->has_transactions(); error= (*log_func)(thd, table, has_trans, before_record, after_record); + + /* + Now that the record has been logged, increment wsrep_affected_rows and + also check whether its within the allowable limits (wsrep_max_ws_rows). + */ + if (error == 0) + error= check_wsrep_max_ws_rows(); } } return error ? HA_ERR_RBR_LOGGING_FAILED : 0; @@ -5923,7 +5932,7 @@ int handler::ha_write_row(uchar *buf) DBUG_RETURN(error); /* purecov: inspected */ DEBUG_SYNC_C("ha_write_row_end"); - DBUG_RETURN(check_wsrep_max_ws_rows()); + DBUG_RETURN(0); } @@ -5954,7 +5963,7 @@ int handler::ha_update_row(const uchar *old_data, uchar *new_data) rows_changed++; if (unlikely(error= binlog_log_row(table, old_data, new_data, log_func))) return error; - return check_wsrep_max_ws_rows(); + return 0; } int handler::ha_delete_row(const uchar *buf) @@ -5981,7 +5990,7 @@ int handler::ha_delete_row(const uchar *buf) rows_changed++; if (unlikely(error= binlog_log_row(table, buf, 0, log_func))) return error; - return check_wsrep_max_ws_rows(); + return 0; }