summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/main/backup_lock.result14
-rw-r--r--mysql-test/main/backup_lock.test13
-rw-r--r--sql/handler.cc41
-rw-r--r--sql/handler.h1
-rw-r--r--sql/sql_parse.cc69
-rw-r--r--storage/maria/ha_maria.cc7
6 files changed, 122 insertions, 23 deletions
diff --git a/mysql-test/main/backup_lock.result b/mysql-test/main/backup_lock.result
index 95b2f520d90..8a179578e79 100644
--- a/mysql-test/main/backup_lock.result
+++ b/mysql-test/main/backup_lock.result
@@ -192,8 +192,10 @@ BACKUP STAGE END;
SET GLOBAL lock_wait_timeout=0;
CREATE TABLE t_permanent_innodb (col1 INT) ENGINE = InnoDB;
CREATE TABLE t_permanent_myisam (col1 INT) ENGINE = MyISAM;
+CREATE TABLE t_permanent_aria (col1 INT) ENGINE = Aria transactional=1;
INSERT INTO t_permanent_innodb SET col1 = 1;
INSERT INTO t_permanent_myisam SET col1 = 1;
+INSERT INTO t_permanent_aria SET col1 = 1;
CREATE TABLE t_con1_innodb (col1 INT) ENGINE = InnoDB;
CREATE TABLE t_con1_myisam (col1 INT) ENGINE = MyISAM;
connect con1,localhost,root,,;
@@ -207,13 +209,23 @@ connection con1;
UPDATE t_permanent_innodb SET col1 = 8;
UPDATE t_permanent_myisam SET col1 = 8;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+UPDATE t_permanent_aria SET col1 = 8;
DROP TABLE t_con1_innodb;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
DROP TABLE t_con1_myisam;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
connection default;
BACKUP STAGE END;
-DROP TABLE t_permanent_myisam, t_permanent_innodb;
+select * from t_permanent_innodb;
+col1
+1
+select * from t_permanent_myisam;
+col1
+1
+select * from t_permanent_aria;
+col1
+8
+DROP TABLE t_permanent_myisam, t_permanent_innodb, t_permanent_aria;
DROP TABLE t_con1_innodb, t_con1_myisam;
disconnect con1;
set global lock_wait_timeout=default;
diff --git a/mysql-test/main/backup_lock.test b/mysql-test/main/backup_lock.test
index d6db7a6364e..65c11432bb5 100644
--- a/mysql-test/main/backup_lock.test
+++ b/mysql-test/main/backup_lock.test
@@ -251,9 +251,11 @@ BACKUP STAGE END;
SET GLOBAL lock_wait_timeout=0;
CREATE TABLE t_permanent_innodb (col1 INT) ENGINE = InnoDB;
CREATE TABLE t_permanent_myisam (col1 INT) ENGINE = MyISAM;
+CREATE TABLE t_permanent_aria (col1 INT) ENGINE = Aria transactional=1;
INSERT INTO t_permanent_innodb SET col1 = 1;
-
INSERT INTO t_permanent_myisam SET col1 = 1;
+INSERT INTO t_permanent_aria SET col1 = 1;
+
CREATE TABLE t_con1_innodb (col1 INT) ENGINE = InnoDB;
CREATE TABLE t_con1_myisam (col1 INT) ENGINE = MyISAM;
@@ -270,6 +272,8 @@ BACKUP STAGE BLOCK_COMMIT;
UPDATE t_permanent_innodb SET col1 = 8;
--error ER_LOCK_WAIT_TIMEOUT
UPDATE t_permanent_myisam SET col1 = 8;
+UPDATE t_permanent_aria SET col1 = 8;
+
--error ER_LOCK_WAIT_TIMEOUT
DROP TABLE t_con1_innodb;
@@ -278,7 +282,12 @@ DROP TABLE t_con1_myisam;
--connection default
BACKUP STAGE END;
-DROP TABLE t_permanent_myisam, t_permanent_innodb;
+
+select * from t_permanent_innodb;
+select * from t_permanent_myisam;
+select * from t_permanent_aria;
+
+DROP TABLE t_permanent_myisam, t_permanent_innodb, t_permanent_aria;
DROP TABLE t_con1_innodb, t_con1_myisam;
--disconnect con1
set global lock_wait_timeout=default;
diff --git a/sql/handler.cc b/sql/handler.cc
index ffb89b30d92..9e648815beb 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1531,16 +1531,6 @@ int ha_commit_trans(THD *thd, bool all)
DBUG_RETURN(2);
}
-#ifdef WITH_ARIA_STORAGE_ENGINE
- if ((error= ha_maria::implicit_commit(thd, TRUE)))
- {
- my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
- ha_rollback_trans(thd, all);
- DBUG_RETURN(1);
- }
-
-#endif
-
if (!ha_info)
{
/*
@@ -1556,6 +1546,16 @@ int ha_commit_trans(THD *thd, bool all)
if (wsrep_is_active(thd) && is_real_trans && !error)
wsrep_commit_empty(thd, all);
#endif /* WITH_WSREP */
+
+#if defined(WITH_ARIA_STORAGE_ENGINE)
+ /* This is needed to ensure that repair commits properly */
+ if ((error= ha_maria::implicit_commit(thd, TRUE)))
+ {
+ my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
+ ha_rollback_trans(thd, all);
+ DBUG_RETURN(1);
+ }
+#endif
DBUG_RETURN(0);
}
@@ -1570,10 +1570,16 @@ int ha_commit_trans(THD *thd, bool all)
bool rw_trans= is_real_trans &&
(rw_ha_count > (thd->is_current_stmt_binlog_disabled()?0U:1U));
MDL_request mdl_request;
+ mdl_request.ticket= 0;
DBUG_PRINT("info", ("is_real_trans: %d rw_trans: %d rw_ha_count: %d",
is_real_trans, rw_trans, rw_ha_count));
- if (rw_trans)
+ /*
+ We need to test maria_hton because of plugin_innodb.test that changes
+ the plugin table to innodb and thus plugin_load will call
+ mysql_close_tables() which calls trans_commit_trans() with maria_hton = 0
+ */
+ if (rw_trans || (likely(maria_hton) && thd_get_ha_data(thd, maria_hton)))
{
/*
Acquire a metadata lock which will ensure that COMMIT is blocked
@@ -1587,8 +1593,8 @@ int ha_commit_trans(THD *thd, bool all)
MDL_EXPLICIT);
if (!WSREP(thd) &&
- thd->mdl_context.acquire_lock(&mdl_request,
- thd->variables.lock_wait_timeout))
+ thd->mdl_context.acquire_lock(&mdl_request,
+ thd->variables.lock_wait_timeout))
{
ha_rollback_trans(thd, all);
DBUG_RETURN(1);
@@ -1596,6 +1602,13 @@ int ha_commit_trans(THD *thd, bool all)
DEBUG_SYNC(thd, "ha_commit_trans_after_acquire_commit_lock");
}
+#if defined(WITH_ARIA_STORAGE_ENGINE)
+ if ((error= ha_maria::implicit_commit(thd, TRUE)))
+ {
+ my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
+ goto err;
+ }
+#endif
if (rw_trans &&
opt_readonly &&
@@ -1797,7 +1810,7 @@ err:
thd->rgi_slave->is_parallel_exec);
}
end:
- if (rw_trans && mdl_request.ticket)
+ if (mdl_request.ticket)
{
/*
We do not always immediately release transactional locks
diff --git a/sql/handler.h b/sql/handler.h
index 0eff7bd930d..e4903172c33 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -70,6 +70,7 @@ class Column_definition;
#define HA_ADMIN_NEEDS_UPGRADE -10
#define HA_ADMIN_NEEDS_ALTER -11
#define HA_ADMIN_NEEDS_CHECK -12
+#define HA_ADMIN_COMMIT_ERROR -13
/**
Return values for check_if_supported_inplace_alter().
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 4e81eb42d63..5922584c8c1 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1508,6 +1508,67 @@ uint maria_multi_check(THD *thd, char *packet, size_t packet_length)
}
+#if defined(WITH_ARIA_STORAGE_ENGINE)
+class Silence_all_errors : public Internal_error_handler
+{
+ char m_message[MYSQL_ERRMSG_SIZE];
+ int error;
+public:
+ Silence_all_errors():error(0) {}
+ virtual ~Silence_all_errors() {}
+
+ virtual bool handle_condition(THD *thd,
+ uint sql_errno,
+ const char* sql_state,
+ Sql_condition::enum_warning_level *level,
+ const char* msg,
+ Sql_condition ** cond_hdl)
+ {
+ error= sql_errno;
+ *cond_hdl= NULL;
+ strmake_buf(m_message, msg);
+ return true; // Error handled
+ }
+};
+#endif
+
+/*
+ Do an implict commit into the Aria storage engine
+*/
+
+static inline my_bool aria_implicit_commit(THD *thd)
+{
+#if defined(WITH_ARIA_STORAGE_ENGINE)
+ if (thd_get_ha_data(thd, maria_hton))
+ {
+ MDL_request mdl_request;
+ bool locked;
+ int res;
+ Silence_all_errors error_handler;
+ DBUG_ASSERT(maria_hton);
+
+ MDL_REQUEST_INIT(&mdl_request, MDL_key::BACKUP, "", "", MDL_BACKUP_COMMIT,
+ MDL_EXPLICIT);
+ /*
+ We have to ignore any errors from acquire_lock and continue even if we
+ don't get the lock as Aria can't roll back!
+ This function is also called in some cases when the message is already
+ sent to the user, so we can't even send a warning.
+ */
+ thd->push_internal_handler(& error_handler);
+ locked= !thd->mdl_context.acquire_lock(&mdl_request,
+ thd->variables.lock_wait_timeout);
+ thd->pop_internal_handler();
+ res= ha_maria::implicit_commit(thd, FALSE);
+ if (locked)
+ thd->mdl_context.release_lock(mdl_request.ticket);
+ return res;
+ }
+#endif
+ return 0;
+}
+
+
/**
Perform one connection-level (COM_XXXX) command.
@@ -1860,9 +1921,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
*/
char *beginning_of_next_stmt= (char*) parser_state.m_lip.found_semicolon;
-#ifdef WITH_ARIA_STORAGE_ENGINE
- ha_maria::implicit_commit(thd, FALSE);
-#endif
+ aria_implicit_commit(thd);
/* Finalize server status flags after executing a statement. */
thd->update_server_status();
@@ -5990,9 +6049,7 @@ finish:
trans_commit_stmt(thd);
thd->get_stmt_da()->set_overwrite_status(false);
}
-#ifdef WITH_ARIA_STORAGE_ENGINE
- ha_maria::implicit_commit(thd, FALSE);
-#endif
+ aria_implicit_commit(thd);
}
/* Free tables. Set stage 'closing tables' */
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 84f74fb272e..f55cef922c9 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -1477,6 +1477,13 @@ int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt)
}
break;
}
+ /*
+ Commit is needed in the case of tables are locked to ensure that repair
+ is registered in the recovery log
+ */
+ if (implicit_commit(thd, TRUE))
+ error= HA_ADMIN_COMMIT_ERROR;
+
if (!error && start_records != file->state->records &&
!(check_opt->flags & T_VERY_SILENT))
{