summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2018-04-04 08:24:57 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2018-04-04 08:24:57 +0300
commita5da1c64f8d96278c8e4408458f7e8d4b6dea415 (patch)
treee852956c3d812eb546fb049bf745350bd47343ee
parent12ed50cc8d20cc09e302e5dad9ed6a4a6d4ca222 (diff)
parentbc2501453c3ab9a2cf3516bc3557de8665bc2776 (diff)
downloadmariadb-git-a5da1c64f8d96278c8e4408458f7e8d4b6dea415.tar.gz
Merge 10.2 into 10.3
-rw-r--r--CMakeLists.txt8
-rw-r--r--extra/mariabackup/backup_copy.cc4
-rw-r--r--extra/mariabackup/backup_mysql.cc102
-rw-r--r--extra/mariabackup/xtrabackup.cc102
-rw-r--r--extra/mariabackup/xtrabackup.h1
-rw-r--r--mysql-test/main/derived_cond_pushdown.result159
-rw-r--r--mysql-test/main/derived_cond_pushdown.test45
-rw-r--r--sql/table.cc9
-rw-r--r--storage/innobase/innodb.cmake6
-rw-r--r--storage/innobase/log/log0log.cc16
10 files changed, 409 insertions, 43 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0813cf2288f..94362c349f2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -248,12 +248,6 @@ MY_CHECK_AND_SET_COMPILER_FLAG(-ggdb3 DEBUG)
OPTION(ENABLED_LOCAL_INFILE
"If we should should enable LOAD DATA LOCAL by default" ${IF_WIN})
-OPTION(WITH_INNODB_DISALLOW_WRITES "InnoDB freeze writes patch from Google" ${WITH_WSREP})
-IF (WITH_INNODB_DISALLOW_WRITES)
- SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWITH_INNODB_DISALLOW_WRITES")
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWITH_INNODB_DISALLOW_WRITES")
-ENDIF()
-
# Set DBUG_OFF and other optional release-only flags for non-debug project types
FOREACH(BUILD_TYPE RELEASE RELWITHDEBINFO MINSIZEREL)
FOREACH(LANG C CXX)
@@ -267,7 +261,7 @@ ENDFOREACH()
# Add safemutex for debug configurations, except on Windows
# (safemutex has never worked on Windows)
-IF(NOT WIN32 AND NOT WITH_INNODB_MEMCACHED)
+IF(NOT WIN32)
FOREACH(LANG C CXX)
SET(CMAKE_${LANG}_FLAGS_DEBUG "${CMAKE_${LANG}_FLAGS_DEBUG} -DSAFE_MUTEX")
ENDFOREACH()
diff --git a/extra/mariabackup/backup_copy.cc b/extra/mariabackup/backup_copy.cc
index 1542e57c84c..a2677f778f4 100644
--- a/extra/mariabackup/backup_copy.cc
+++ b/extra/mariabackup/backup_copy.cc
@@ -1428,6 +1428,10 @@ void backup_release()
history_lock_time = time(NULL) - history_lock_time;
}
+ if (opt_lock_ddl_per_table) {
+ mdl_unlock_all();
+ }
+
if (opt_safe_slave_backup && sql_thread_started) {
msg("Starting slave SQL thread\n");
xb_mysql_query(mysql_connection,
diff --git a/extra/mariabackup/backup_mysql.cc b/extra/mariabackup/backup_mysql.cc
index 0549b0c5e9c..59569fc625d 100644
--- a/extra/mariabackup/backup_mysql.cc
+++ b/extra/mariabackup/backup_mysql.cc
@@ -868,6 +868,76 @@ stop_query_killer()
os_event_wait_time(kill_query_thread_stopped, 60000);
}
+
+/*
+Killing connections that wait for MDL lock.
+If lock-ddl-per-table is used, there can be some DDL statements
+
+FLUSH TABLES would hang infinitely, if DDL statements are waiting for
+MDL lock, which mariabackup currently holds. Therefore we start killing
+those statements from a dedicated thread, until FLUSH TABLES WITH READ LOCK
+succeeds.
+*/
+
+static os_event_t mdl_killer_stop_event;
+static os_event_t mdl_killer_finished_event;
+
+static
+os_thread_ret_t
+DECLARE_THREAD(kill_mdl_waiters_thread(void *))
+{
+ MYSQL *mysql;
+ if ((mysql = xb_mysql_connect()) == NULL) {
+ msg("Error: kill mdl waiters thread failed to connect\n");
+ goto stop_thread;
+ }
+
+ for(;;){
+ if (os_event_wait_time(mdl_killer_stop_event, 1000) == 0)
+ break;
+
+ MYSQL_RES *result = xb_mysql_query(mysql,
+ "SELECT ID, COMMAND FROM INFORMATION_SCHEMA.PROCESSLIST "
+ " WHERE State='Waiting for table metadata lock'",
+ true, true);
+ while (MYSQL_ROW row = mysql_fetch_row(result))
+ {
+ char query[64];
+ msg_ts("Killing MDL waiting query '%s' on connection '%s'\n",
+ row[1], row[0]);
+ snprintf(query, sizeof(query), "KILL QUERY %s", row[0]);
+ xb_mysql_query(mysql, query, true);
+ }
+ }
+
+ mysql_close(mysql);
+
+stop_thread:
+ msg_ts("Kill mdl waiters thread stopped\n");
+ os_event_set(mdl_killer_finished_event);
+ os_thread_exit();
+ return os_thread_ret_t(0);
+}
+
+
+static void start_mdl_waiters_killer()
+{
+ mdl_killer_stop_event = os_event_create(0);
+ mdl_killer_finished_event = os_event_create(0);
+ os_thread_create(kill_mdl_waiters_thread, 0, 0);
+}
+
+
+/* Tell MDL killer to stop and finish for its completion*/
+static void stop_mdl_waiters_killer()
+{
+ os_event_set(mdl_killer_stop_event);
+ os_event_wait(mdl_killer_finished_event);
+
+ os_event_destroy(mdl_killer_stop_event);
+ os_event_destroy(mdl_killer_finished_event);
+}
+
/*********************************************************************//**
Function acquires either a backup tables lock, if supported
by the server, or a global read lock (FLUSH TABLES WITH READ LOCK)
@@ -890,6 +960,10 @@ lock_tables(MYSQL *connection)
return(true);
}
+ if (opt_lock_ddl_per_table) {
+ start_mdl_waiters_killer();
+ }
+
if (!opt_lock_wait_timeout && !opt_kill_long_queries_timeout) {
/* We do first a FLUSH TABLES. If a long update is running, the
@@ -930,6 +1004,10 @@ lock_tables(MYSQL *connection)
xb_mysql_query(connection, "FLUSH TABLES WITH READ LOCK", false);
+ if (opt_lock_ddl_per_table) {
+ stop_mdl_waiters_killer();
+ }
+
if (opt_kill_long_queries_timeout) {
stop_query_killer();
}
@@ -1647,25 +1725,6 @@ mdl_lock_init()
}
}
-#ifndef DBUG_OFF
-/* Test that table is really locked, if lock_ddl_per_table is set.
- The test is executed in DBUG_EXECUTE_IF block inside mdl_lock_table().
-*/
-static void check_mdl_lock_works(const char *table_name)
-{
- MYSQL *test_con= xb_mysql_connect();
- char *query;
- xb_a(asprintf(&query,
- "SET STATEMENT max_statement_time=1 FOR ALTER TABLE %s FORCE",
- table_name));
- int err = mysql_query(test_con, query);
- DBUG_ASSERT(err);
- int err_no = mysql_errno(test_con);
- DBUG_ASSERT(err_no == ER_STATEMENT_TIMEOUT);
- mysql_close(test_con);
- free(query);
-}
-#endif
void
mdl_lock_table(ulint space_id)
{
@@ -1681,13 +1740,10 @@ mdl_lock_table(ulint space_id)
while (MYSQL_ROW row = mysql_fetch_row(mysql_result)) {
std::string full_table_name = ut_get_name(0,row[0]);
std::ostringstream lock_query;
- lock_query << "SELECT * FROM " << full_table_name << " LIMIT 0";
+ lock_query << "SELECT 1 FROM " << full_table_name << " LIMIT 0";
msg_ts("Locking MDL for %s\n", full_table_name.c_str());
xb_mysql_query(mdl_con, lock_query.str().c_str(), false, false);
-
- DBUG_EXECUTE_IF("check_mdl_lock_works",
- check_mdl_lock_works(full_table_name.c_str()););
}
pthread_mutex_unlock(&mdl_lock_con_mutex);
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index a75d5ab820f..274bf050886 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -433,6 +433,91 @@ datafiles_iter_free(datafiles_iter_t *it)
free(it);
}
+#ifndef DBUG_OFF
+struct dbug_thread_param_t
+{
+ MYSQL *con;
+ const char *query;
+ int expect_err;
+ int expect_errno;
+ os_event_t done_event;
+};
+
+
+/* Thread procedure used in dbug_start_query_thread. */
+extern "C"
+os_thread_ret_t
+DECLARE_THREAD(dbug_execute_in_new_connection)(void *arg)
+{
+ mysql_thread_init();
+ dbug_thread_param_t *par= (dbug_thread_param_t *)arg;
+ int err = mysql_query(par->con, par->query);
+ int err_no = mysql_errno(par->con);
+ DBUG_ASSERT(par->expect_err == err);
+ if (err && par->expect_errno)
+ DBUG_ASSERT(err_no == par->expect_errno);
+ mysql_close(par->con);
+ mysql_thread_end();
+ os_event_t done = par->done_event;
+ delete par;
+ os_event_set(done);
+ os_thread_exit();
+ return os_thread_ret_t(0);
+}
+
+/*
+Execute query from a new connection, in own thread.
+
+@param query - query to be executed
+@param wait_state - if not NULL, wait until query from new connection
+ reaches this state (value of column State in I_S.PROCESSLIST)
+@param expected_err - if 0, query is supposed to finish successfully,
+ otherwise query should return error.
+@param expected_errno - if not 0, and query finished with error,
+ expected mysql_errno()
+*/
+static os_event_t dbug_start_query_thread(
+ const char *query,
+ const char *wait_state,
+ int expected_err,
+ int expected_errno)
+
+{
+ dbug_thread_param_t *par = new dbug_thread_param_t;
+ par->query = query;
+ par->expect_err = expected_err;
+ par->expect_errno = expected_errno;
+ par->done_event = os_event_create(0);
+ par->con = xb_mysql_connect();
+ os_thread_create(dbug_execute_in_new_connection, par, 0);
+
+ if (!wait_state)
+ return par->done_event;
+
+ char q[256];
+ snprintf(q, sizeof(q),
+ "SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST where ID=%lu"
+ " AND Command='Query' AND State='%s'",
+ mysql_thread_id(par->con), wait_state);
+ for (;;) {
+ MYSQL_RES *result = xb_mysql_query(mysql_connection,q, true, true);
+ if (mysql_fetch_row(result)) {
+ goto end;
+ }
+ msg_ts("Waiting for query '%s' on connection %lu to "
+ " reach state '%s'", query, mysql_thread_id(par->con),
+ wait_state);
+ my_sleep(1000);
+ }
+end:
+ msg_ts("query '%s' on connection %lu reached state '%s'", query,
+ mysql_thread_id(par->con), wait_state);
+ return par->done_event;
+}
+
+os_event_t dbug_alter_thread_done;
+#endif
+
void mdl_lock_all()
{
mdl_lock_init();
@@ -448,6 +533,11 @@ void mdl_lock_all()
mdl_lock_table(node->space->id);
}
datafiles_iter_free(it);
+
+ DBUG_EXECUTE_IF("check_mdl_lock_works",
+ dbug_alter_thread_done =
+ dbug_start_query_thread("ALTER TABLE test.t ADD COLUMN mdl_lock_column int",
+ "Waiting for table metadata lock",1, ER_QUERY_INTERRUPTED););
}
/** Check if the space id belongs to the table which name should
@@ -2460,7 +2550,6 @@ xtrabackup_copy_logfile(copy_logfile copy)
recv_sys->parse_start_lsn = log_copy_scanned_lsn;
recv_sys->scanned_lsn = log_copy_scanned_lsn;
- recv_sys->recovered_lsn = log_copy_scanned_lsn;
start_lsn = ut_uint64_align_down(log_copy_scanned_lsn,
OS_FILE_LOG_BLOCK_SIZE);
@@ -3984,6 +4073,8 @@ reread_log_header:
/* copy log file by current position */
log_copy_scanned_lsn = checkpoint_lsn_start;
+ recv_sys->recovered_lsn = log_copy_scanned_lsn;
+
if (xtrabackup_copy_logfile(COPY_FIRST))
goto fail;
@@ -4070,6 +4161,11 @@ reread_log_header:
backup_release();
+ DBUG_EXECUTE_IF("check_mdl_lock_works",
+ os_event_wait(dbug_alter_thread_done);
+ os_event_destroy(dbug_alter_thread_done);
+ );
+
if (ok) {
backup_finish();
}
@@ -4079,10 +4175,6 @@ reread_log_header:
goto fail;
}
- if (opt_lock_ddl_per_table) {
- mdl_unlock_all();
- }
-
xtrabackup_destroy_datasinks();
msg("mariabackup: Redo log (from LSN " LSN_PF " to " LSN_PF
diff --git a/extra/mariabackup/xtrabackup.h b/extra/mariabackup/xtrabackup.h
index 8eabf8f0e7e..c77485cb4de 100644
--- a/extra/mariabackup/xtrabackup.h
+++ b/extra/mariabackup/xtrabackup.h
@@ -110,6 +110,7 @@ extern my_bool opt_noversioncheck;
extern my_bool opt_no_backup_locks;
extern my_bool opt_decompress;
extern my_bool opt_remove_original;
+extern my_bool opt_lock_ddl_per_table;
extern char *opt_incremental_history_name;
extern char *opt_incremental_history_uuid;
diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result
index dd5abde1548..5edd91faf16 100644
--- a/mysql-test/main/derived_cond_pushdown.result
+++ b/mysql-test/main/derived_cond_pushdown.result
@@ -12604,6 +12604,165 @@ EXPLAIN
DROP TABLE t1,t2;
SET sql_mode = DEFAULT;
#
+# MDEV-15579: incorrect removal of sub-formulas to be pushed
+# into WHERE of materialized derived with GROUP BY
+#
+CREATE TABLE t1 (a INT, b INT, c INT, d INT);
+CREATE TABLE t2 (x INT, y INT, z INT);
+INSERT INTO t1 VALUES (1,1,66,1), (1,1,56,2), (3,2,42,3);
+INSERT INTO t2 VALUES (1,1,66), (1,12,32);
+SELECT *
+FROM t2,
+(
+SELECT a, b, max(c) AS max_c
+FROM t1
+GROUP BY a
+HAVING max_c > 37
+) AS v1
+WHERE (v1.a=1) AND (v1.b=v1.a) AND
+(v1.a=t2.x) AND (v1.max_c>30);
+x y z a b max_c
+1 1 66 1 1 66
+1 12 32 1 1 66
+EXPLAIN SELECT *
+FROM t2,
+(
+SELECT a, b, max(c) AS max_c
+FROM t1
+GROUP BY a
+HAVING max_c > 37
+) AS v1
+WHERE (v1.a=1) AND (v1.b=v1.a) AND
+(v1.a=t2.x) AND (v1.max_c>30);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+2 DERIVED t1 ALL NULL NULL NULL NULL 3 Using where
+EXPLAIN FORMAT=JSON SELECT *
+FROM t2,
+(
+SELECT a, b, max(c) AS max_c
+FROM t1
+GROUP BY a
+HAVING max_c > 37
+) AS v1
+WHERE (v1.a=1) AND (v1.b=v1.a) AND
+(v1.a=t2.x) AND (v1.max_c>30);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "t2.x = 1"
+ },
+ "block-nl-join": {
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100,
+ "attached_condition": "v1.a = 1 and v1.b = 1 and v1.max_c > 30"
+ },
+ "buffer_type": "flat",
+ "buffer_size": "256Kb",
+ "join_type": "BNL",
+ "materialized": {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "max_c > 37 and max_c > 30 and t1.b = 1",
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100,
+ "attached_condition": "t1.a = 1"
+ }
+ }
+ }
+ }
+ }
+}
+SELECT *
+FROM t2,
+(
+SELECT a, b, d, max(c) AS max_c
+FROM t1
+GROUP BY a,d
+HAVING max_c > 37
+) AS v1
+WHERE (v1.a=1) AND (v1.b=v1.a) AND (v1.b=v1.d) AND
+(v1.a=t2.x) AND (v1.max_c>30);
+x y z a b d max_c
+1 1 66 1 1 1 66
+1 12 32 1 1 1 66
+EXPLAIN SELECT *
+FROM t2,
+(
+SELECT a, b, d, max(c) AS max_c
+FROM t1
+GROUP BY a,d
+HAVING max_c > 37
+) AS v1
+WHERE (v1.a=1) AND (v1.b=v1.a) AND (v1.b=v1.d) AND
+(v1.a=t2.x) AND (v1.max_c>30);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+2 DERIVED t1 ALL NULL NULL NULL NULL 3 Using where
+EXPLAIN FORMAT=JSON SELECT *
+FROM t2,
+(
+SELECT a, b, d, max(c) AS max_c
+FROM t1
+GROUP BY a,d
+HAVING max_c > 37
+) AS v1
+WHERE (v1.a=1) AND (v1.b=v1.a) AND (v1.b=v1.d) AND
+(v1.a=t2.x) AND (v1.max_c>30);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "t2.x = 1"
+ },
+ "block-nl-join": {
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100,
+ "attached_condition": "v1.a = 1 and v1.b = 1 and v1.d = 1 and v1.max_c > 30"
+ },
+ "buffer_type": "flat",
+ "buffer_size": "256Kb",
+ "join_type": "BNL",
+ "materialized": {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "max_c > 37 and max_c > 30 and t1.b = 1",
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100,
+ "attached_condition": "t1.a = 1 and t1.d = 1"
+ }
+ }
+ }
+ }
+ }
+}
+DROP TABLE t1,t2;
+#
# MDEV-10855: Pushdown into derived with window functions
#
set @save_optimizer_switch= @@optimizer_switch;
diff --git a/mysql-test/main/derived_cond_pushdown.test b/mysql-test/main/derived_cond_pushdown.test
index e728a9590a1..2188cc00533 100644
--- a/mysql-test/main/derived_cond_pushdown.test
+++ b/mysql-test/main/derived_cond_pushdown.test
@@ -2166,6 +2166,51 @@ DROP TABLE t1,t2;
SET sql_mode = DEFAULT;
--echo #
+--echo # MDEV-15579: incorrect removal of sub-formulas to be pushed
+--echo # into WHERE of materialized derived with GROUP BY
+--echo #
+
+CREATE TABLE t1 (a INT, b INT, c INT, d INT);
+CREATE TABLE t2 (x INT, y INT, z INT);
+
+INSERT INTO t1 VALUES (1,1,66,1), (1,1,56,2), (3,2,42,3);
+INSERT INTO t2 VALUES (1,1,66), (1,12,32);
+
+LET $query=
+SELECT *
+FROM t2,
+(
+ SELECT a, b, max(c) AS max_c
+ FROM t1
+ GROUP BY a
+ HAVING max_c > 37
+) AS v1
+WHERE (v1.a=1) AND (v1.b=v1.a) AND
+ (v1.a=t2.x) AND (v1.max_c>30);
+EVAL $query;
+EVAL EXPLAIN $query;
+EVAL EXPLAIN FORMAT=JSON $query;
+
+LET $query=
+SELECT *
+FROM t2,
+(
+ SELECT a, b, d, max(c) AS max_c
+ FROM t1
+ GROUP BY a,d
+ HAVING max_c > 37
+) AS v1
+WHERE (v1.a=1) AND (v1.b=v1.a) AND (v1.b=v1.d) AND
+ (v1.a=t2.x) AND (v1.max_c>30);
+EVAL $query;
+EVAL EXPLAIN $query;
+EVAL EXPLAIN FORMAT=JSON $query;
+
+DROP TABLE t1,t2;
+
+# Start of 10.3 tests
+
+--echo #
--echo # MDEV-10855: Pushdown into derived with window functions
--echo #
diff --git a/sql/table.cc b/sql/table.cc
index 4f90d429ce5..3696241fa1f 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -8451,6 +8451,7 @@ Item* TABLE_LIST::build_pushable_cond_for_table(THD *thd, Item *cond)
return 0;
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
Item *item;
+ bool is_fix_needed= false;
while ((item=li++))
{
if (item->get_extraction_flag() == NO_EXTRACTION_FL)
@@ -8464,8 +8465,16 @@ Item* TABLE_LIST::build_pushable_cond_for_table(THD *thd, Item *cond)
return 0;
if (!fix)
continue;
+
+ if (fix->type() == Item::COND_ITEM &&
+ ((Item_cond*) fix)->functype() == Item_func::COND_AND_FUNC)
+ is_fix_needed= true;
+
new_cond->argument_list()->push_back(fix, thd->mem_root);
}
+ if (is_fix_needed)
+ new_cond->fix_fields(thd, 0);
+
switch (new_cond->argument_list()->elements)
{
case 0:
diff --git a/storage/innobase/innodb.cmake b/storage/innobase/innodb.cmake
index 71c9cc8594b..c053924a948 100644
--- a/storage/innobase/innodb.cmake
+++ b/storage/innobase/innodb.cmake
@@ -219,6 +219,12 @@ ELSE()
ADD_DEFINITIONS(-DMUTEX_SYS)
ENDIF()
+OPTION(WITH_INNODB_DISALLOW_WRITES "InnoDB freeze writes patch from Google" ${WITH_WSREP})
+IF (WITH_INNODB_DISALLOW_WRITES)
+ ADD_DEFINITIONS(-DWITH_INNODB_DISALLOW_WRITES)
+ENDIF()
+
+
# Include directories under innobase
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/innobase/include
${CMAKE_SOURCE_DIR}/storage/innobase/handler)
diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index 7da66c04c18..1047e93153a 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -1085,17 +1085,17 @@ log_buffer_switch()
OS_FILE_LOG_BLOCK_SIZE);
if (log_sys->first_in_use) {
+ log_sys->first_in_use = false;
ut_ad(log_sys->buf == ut_align(log_sys->buf,
OS_FILE_LOG_BLOCK_SIZE));
log_sys->buf += log_sys->buf_size;
} else {
+ log_sys->first_in_use = true;
log_sys->buf -= log_sys->buf_size;
ut_ad(log_sys->buf == ut_align(log_sys->buf,
OS_FILE_LOG_BLOCK_SIZE));
}
- log_sys->first_in_use = !log_sys->first_in_use;
-
/* Copy the last block to new buf */
ut_memcpy(log_sys->buf,
old_buf + area_end - OS_FILE_LOG_BLOCK_SIZE,
@@ -1235,6 +1235,9 @@ loop:
log_group_set_fields(&log_sys->log, log_sys->write_lsn);
log_mutex_exit();
+ /* Erase the end of the last log block. */
+ memset(write_buf + end_offset, 0, ~end_offset & OS_FILE_LOG_BLOCK_SIZE);
+
/* Calculate pad_size if needed. */
pad_size = 0;
if (write_ahead_size > OS_FILE_LOG_BLOCK_SIZE) {
@@ -1251,12 +1254,9 @@ loop:
/* The first block in the unit was initialized
after the last writing.
Needs to be written padded data once. */
- pad_size = write_ahead_size - end_offset_in_unit;
-
- if (area_end + pad_size > log_sys->buf_size) {
- pad_size = log_sys->buf_size - area_end;
- }
-
+ pad_size = std::min(
+ ulint(write_ahead_size) - end_offset_in_unit,
+ log_sys->buf_size - area_end);
::memset(write_buf + area_end, 0, pad_size);
}
}