summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Nielsen <knielsen@knielsen-hq.org>2017-08-07 12:38:47 +0200
committerKristian Nielsen <knielsen@knielsen-hq.org>2017-08-07 12:38:47 +0200
commitc5aa11cbb9cba7807cdf77bb3e5223be2d7389de (patch)
tree53ddc37421656ca28b2eeef2839eeaf9c155f5ba
parent11948d75862941e2780e550cbc5411895e1cc1c7 (diff)
downloadmariadb-git-bb-10.2-knielsen.tar.gz
MDEV-11937: InnoDB flushes redo log too oftenbb-10.2-knielsen
Problem was introduced with the InnoDB 5.7 merge, the code related to avoiding extra fsync at the end of commit when binlog is enabled. The MariaDB method for this was removed, but the replacement MySQL method based on thd_get_durability_property() is not functional in MariaDB. This commit reverts the offending parts of the merge and adds a test case, to fix the problem for InnoDB. But other storage engines are likely to have a similar problem.
-rw-r--r--mysql-test/suite/binlog/r/binlog_innodb.result10
-rw-r--r--mysql-test/suite/binlog/t/binlog_innodb.test29
-rw-r--r--storage/innobase/handler/ha_innodb.cc16
-rw-r--r--storage/innobase/handler/ha_innodb.h5
-rw-r--r--storage/innobase/trx/trx0trx.cc20
5 files changed, 42 insertions, 38 deletions
diff --git a/mysql-test/suite/binlog/r/binlog_innodb.result b/mysql-test/suite/binlog/r/binlog_innodb.result
index 2896706d407..233dda00075 100644
--- a/mysql-test/suite/binlog/r/binlog_innodb.result
+++ b/mysql-test/suite/binlog/r/binlog_innodb.result
@@ -176,4 +176,14 @@ ERROR 23000: Duplicate entry '4' for key 'PRIMARY'
# There must be no UPDATE query event;
include/show_binlog_events.inc
drop table t1, t2;
+*** MDEV-11937: InnoDB flushes redo log too often ***
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
+SET @old_flush = @@GLOBAL.innodb_flush_log_at_trx_commit;
+SET GLOBAL innodb_flush_log_at_trx_commit=1;
+SELECT IF(@num_sync < 100*1.5, "OK",
+CONCAT("ERROR: More than 1 fsync per commit (saw ", @num_sync/100, ")")) AS status;
+status
+OK
+DROP TABLE t1;
+SET GLOBAL innodb_flush_log_at_trx_commit=@old_flush;
End of tests
diff --git a/mysql-test/suite/binlog/t/binlog_innodb.test b/mysql-test/suite/binlog/t/binlog_innodb.test
index 8191b72d5a9..153dcdd155a 100644
--- a/mysql-test/suite/binlog/t/binlog_innodb.test
+++ b/mysql-test/suite/binlog/t/binlog_innodb.test
@@ -172,4 +172,33 @@ source include/show_binlog_events.inc;
# cleanup bug#27716
drop table t1, t2;
+--echo *** MDEV-11937: InnoDB flushes redo log too often ***
+
+# Count number of log fsyncs reported by InnoDB per commit.
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
+
+SET @old_flush = @@GLOBAL.innodb_flush_log_at_trx_commit;
+SET GLOBAL innodb_flush_log_at_trx_commit=1;
+
+--let $syncs1 = query_get_value(SHOW STATUS LIKE 'Innodb_os_log_fsyncs', Value, 1)
+--let $ROWS = 100
+--disable_query_log
+let $count = $ROWS;
+while ($count) {
+ eval INSERT INTO t1 VALUES ($count);
+ dec $count;
+}
+--let $syncs2 = query_get_value(SHOW STATUS LIKE 'Innodb_os_log_fsyncs', Value, 1)
+eval SET @num_sync = $syncs2 - $syncs1;
+--enable_query_log
+
+# Allow a bit of slack, in case some background process or something
+# is introducing a few more syncs.
+eval SELECT IF(@num_sync < $ROWS*1.5, "OK",
+ CONCAT("ERROR: More than 1 fsync per commit (saw ", @num_sync/$ROWS, ")")) AS status;
+
+DROP TABLE t1;
+SET GLOBAL innodb_flush_log_at_trx_commit=@old_flush;
+
+
--echo End of tests
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 68b69e94681..28818ed7388 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -1689,18 +1689,6 @@ thd_is_replication_slave_thread(
}
/******************************************************************//**
-Gets information on the durability property requested by thread.
-Used when writing either a prepare or commit record to the log
-buffer. @return the durability property. */
-enum durability_properties
-thd_requested_durability(
-/*=====================*/
- const THD* thd) /*!< in: thread handle */
-{
- return(thd_get_durability_property(thd));
-}
-
-/******************************************************************//**
Returns true if transaction should be flagged as read-only.
@return true if the thd is marked as read-only */
bool
@@ -4839,10 +4827,6 @@ innobase_commit(
this one, to allow then to group commit with us. */
thd_wakeup_subsequent_commits(thd, 0);
- if (!read_only) {
- trx->flush_log_later = false;
- }
-
/* Now do a write + flush of logs. */
trx_commit_complete_for_mysql(trx);
diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
index 769d4ae2a59..8a781963cec 100644
--- a/storage/innobase/handler/ha_innodb.h
+++ b/storage/innobase/handler/ha_innodb.h
@@ -570,11 +570,6 @@ bool thd_binlog_filter_ok(const MYSQL_THD thd);
*/
bool thd_sqlcom_can_generate_row_events(const MYSQL_THD thd);
-/** Gets information on the durability property requested by a thread.
-@param thd Thread handle
-@return a durability property. */
-durability_properties thd_get_durability_property(const MYSQL_THD thd);
-
/** Is strict sql_mode set.
@param thd Thread object
@return True if sql_mode has strict mode (all or trans), false otherwise. */
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc
index 6655be72ba1..55bb2605d7e 100644
--- a/storage/innobase/trx/trx0trx.cc
+++ b/storage/innobase/trx/trx0trx.cc
@@ -1845,9 +1845,7 @@ trx_commit_in_memory(
} else if (trx->flush_log_later) {
/* Do nothing yet */
trx->must_flush_log_later = true;
- } else if (srv_flush_log_at_trx_commit == 0
- || thd_requested_durability(trx->mysql_thd)
- == HA_IGNORE_DURABILITY) {
+ } else if (srv_flush_log_at_trx_commit == 0) {
/* Do nothing */
} else {
trx_flush_log_if_needed(lsn, trx);
@@ -2261,8 +2259,7 @@ trx_commit_complete_for_mysql(
{
if (trx->id != 0
|| !trx->must_flush_log_later
- || thd_requested_durability(trx->mysql_thd)
- == HA_IGNORE_DURABILITY) {
+ || (srv_flush_log_at_trx_commit == 1 && trx->active_commit_ordered)) {
return;
}
@@ -2750,18 +2747,7 @@ trx_prepare(
trx_sys_mutex_exit();
/*--------------------------------------*/
- switch (thd_requested_durability(trx->mysql_thd)) {
- case HA_IGNORE_DURABILITY:
- /* We set the HA_IGNORE_DURABILITY during prepare phase of
- binlog group commit to not flush redo log for every transaction
- here. So that we can flush prepared records of transactions to
- redo log in a group right before writing them to binary log
- during flush stage of binlog group commit. */
- break;
- case HA_REGULAR_DURABILITY:
- if (lsn == 0) {
- break;
- }
+ if (lsn) {
/* Depending on the my.cnf options, we may now write the log
buffer to the log files, making the prepared state of the
transaction durable if the OS does not crash. We may also