Commit 6f4f8c5f authored by Nirbhay Choubey's avatar Nirbhay Choubey

MDEV-7374 : Losing connection to MySQL while running ALTER TABLE

In the special case of ALTER TABLE with >10K rows, wsrep commit
should skip if wsrep is not enabled. Added a test case.
parent 61f73d40
......@@ -1999,3 +1999,11 @@ t1 CREATE TABLE `t1` (
UNIQUE KEY `idx` (`i`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
#
# MDEV-7374 : Losing connection to MySQL while running ALTER TABLE
#
CREATE TABLE t1(i INT) ENGINE=INNODB;
INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8);
INSERT INTO t1 SELECT a.* FROM t1 a, t1 b, t1 c, t1 d, t1 e;
ALTER TABLE t1 MODIFY i FLOAT;
DROP TABLE t1;
......@@ -1687,3 +1687,13 @@ alter table t1 add unique index if not exists idx(i);
alter table t1 add unique index if not exists idx(i);
show create table t1;
DROP TABLE t1;
--echo #
--echo # MDEV-7374 : Losing connection to MySQL while running ALTER TABLE
--echo #
CREATE TABLE t1(i INT) ENGINE=INNODB;
INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8);
INSERT INTO t1 SELECT a.* FROM t1 a, t1 b, t1 c, t1 d, t1 e;
ALTER TABLE t1 MODIFY i FLOAT;
DROP TABLE t1;
......@@ -1167,7 +1167,7 @@ static int prepare_or_error(handlerton *ht, THD *thd, bool all)
/* avoid sending error, if we're going to replay the transaction */
#ifdef WITH_WSREP
if (ht == wsrep_hton &&
err != WSREP_TRX_SIZE_EXCEEDED &&
err != EMSGSIZE &&
thd->wsrep_conflict_state != MUST_REPLAY)
#endif
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
......
......@@ -9885,6 +9885,7 @@ maria_declare_plugin_end;
#ifdef WITH_WSREP
IO_CACHE * get_trans_log(THD * thd)
{
DBUG_ASSERT(binlog_hton->slot != HA_SLOT_UNDEF);
binlog_cache_mngr *cache_mngr = (binlog_cache_mngr*)
thd_get_ha_data(thd, binlog_hton);
if (cache_mngr)
......
......@@ -158,11 +158,14 @@ static int wsrep_prepare(handlerton *hton, THD *thd, bool all)
(thd->variables.wsrep_on && !wsrep_trans_cache_is_empty(thd)))
{
int res= wsrep_run_wsrep_commit(thd, hton, all);
if (res == WSREP_TRX_SIZE_EXCEEDED)
res= EMSGSIZE;
else
res= EDEADLK; // for a better error message
DBUG_RETURN (wsrep_run_wsrep_commit(thd, hton, all));
if (res != 0)
{
if (res == WSREP_TRX_SIZE_EXCEEDED)
res= EMSGSIZE;
else
res= EDEADLK; // for a better error message
}
DBUG_RETURN (res);
}
DBUG_RETURN(0);
}
......@@ -554,7 +557,6 @@ static int wsrep_hton_init(void *p)
wsrep_hton->rollback= wsrep_rollback;
wsrep_hton->prepare= wsrep_prepare;
wsrep_hton->flags= HTON_NOT_USER_SELECTABLE | HTON_HIDDEN; // todo: fix flags
wsrep_hton->slot= 0;
return 0;
}
......
......@@ -7640,19 +7640,21 @@ no_commit:
;
} else if (src_table == prebuilt->table) {
#ifdef WITH_WSREP
switch (wsrep_run_wsrep_commit(user_thd, 0, 1))
{
case WSREP_TRX_OK:
break;
case WSREP_TRX_SIZE_EXCEEDED:
case WSREP_TRX_CERT_FAIL:
case WSREP_TRX_ERROR:
DBUG_RETURN(1);
}
if (wsrep_on(user_thd)) {
switch (wsrep_run_wsrep_commit(user_thd, wsrep_hton, 1))
{
case WSREP_TRX_OK:
break;
case WSREP_TRX_SIZE_EXCEEDED:
case WSREP_TRX_CERT_FAIL:
case WSREP_TRX_ERROR:
DBUG_RETURN(1);
}
if (binlog_hton->commit(binlog_hton, user_thd, 1))
DBUG_RETURN(1);
wsrep_post_commit(user_thd, TRUE);
if (binlog_hton->commit(binlog_hton, user_thd, 1))
DBUG_RETURN(1);
wsrep_post_commit(user_thd, TRUE);
}
#endif /* WITH_WSREP */
/* Source table is not in InnoDB format:
no need to re-acquire locks on it. */
......@@ -7665,19 +7667,21 @@ no_commit:
prebuilt->sql_stat_start = TRUE;
} else {
#ifdef WITH_WSREP
switch (wsrep_run_wsrep_commit(user_thd, 0, 1))
{
case WSREP_TRX_OK:
break;
case WSREP_TRX_SIZE_EXCEEDED:
case WSREP_TRX_CERT_FAIL:
case WSREP_TRX_ERROR:
DBUG_RETURN(1);
}
if (wsrep_on(user_thd)) {
switch (wsrep_run_wsrep_commit(user_thd, wsrep_hton, 1))
{
case WSREP_TRX_OK:
break;
case WSREP_TRX_SIZE_EXCEEDED:
case WSREP_TRX_CERT_FAIL:
case WSREP_TRX_ERROR:
DBUG_RETURN(1);
}
if (binlog_hton->commit(binlog_hton, user_thd, 1))
DBUG_RETURN(1);
wsrep_post_commit(user_thd, TRUE);
if (binlog_hton->commit(binlog_hton, user_thd, 1))
DBUG_RETURN(1);
wsrep_post_commit(user_thd, TRUE);
}
#endif /* WITH_WSREP */
/* Ensure that there are no other table locks than
LOCK_IX and LOCK_AUTO_INC on the destination table. */
......
......@@ -8101,19 +8101,21 @@ no_commit:
;
} else if (src_table == prebuilt->table) {
#ifdef WITH_WSREP
switch (wsrep_run_wsrep_commit(user_thd, wsrep_hton, 1))
{
case WSREP_TRX_OK:
break;
case WSREP_TRX_SIZE_EXCEEDED:
case WSREP_TRX_CERT_FAIL:
case WSREP_TRX_ERROR:
DBUG_RETURN(1);
}
if (wsrep_on(user_thd)) {
switch (wsrep_run_wsrep_commit(user_thd, wsrep_hton, 1))
{
case WSREP_TRX_OK:
break;
case WSREP_TRX_SIZE_EXCEEDED:
case WSREP_TRX_CERT_FAIL:
case WSREP_TRX_ERROR:
DBUG_RETURN(1);
}
if (binlog_hton->commit(binlog_hton, user_thd, 1))
DBUG_RETURN(1);
wsrep_post_commit(user_thd, TRUE);
if (binlog_hton->commit(binlog_hton, user_thd, 1))
DBUG_RETURN(1);
wsrep_post_commit(user_thd, TRUE);
}
#endif /* WITH_WSREP */
/* Source table is not in InnoDB format:
no need to re-acquire locks on it. */
......@@ -8126,19 +8128,21 @@ no_commit:
prebuilt->sql_stat_start = TRUE;
} else {
#ifdef WITH_WSREP
switch (wsrep_run_wsrep_commit(user_thd, wsrep_hton, 1))
{
case WSREP_TRX_OK:
break;
case WSREP_TRX_SIZE_EXCEEDED:
case WSREP_TRX_CERT_FAIL:
case WSREP_TRX_ERROR:
DBUG_RETURN(1);
}
if (wsrep_on(user_thd)) {
switch (wsrep_run_wsrep_commit(user_thd, wsrep_hton, 1))
{
case WSREP_TRX_OK:
break;
case WSREP_TRX_SIZE_EXCEEDED:
case WSREP_TRX_CERT_FAIL:
case WSREP_TRX_ERROR:
DBUG_RETURN(1);
}
if (binlog_hton->commit(binlog_hton, user_thd, 1))
DBUG_RETURN(1);
wsrep_post_commit(user_thd, TRUE);
if (binlog_hton->commit(binlog_hton, user_thd, 1))
DBUG_RETURN(1);
wsrep_post_commit(user_thd, TRUE);
}
#endif /* WITH_WSREP */
/* Ensure that there are no other table locks than
LOCK_IX and LOCK_AUTO_INC on the destination table. */
......
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