summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2015-12-09 12:57:04 +0100
committerSergei Golubchik <serg@mariadb.org>2015-12-09 12:57:04 +0100
commit142b7256070a5fc54f2e841e4bafdd544318eef5 (patch)
tree70c5afec33298952dbbf9f8724b3450e03795fa6 /storage
parent1a72c6fefdb48642f66dc6f32d8bc7a4cc607437 (diff)
parent9457139e591aa7fb0459788acdbc260db53b0f22 (diff)
downloadmariadb-git-142b7256070a5fc54f2e841e4bafdd544318eef5.tar.gz
Merge branch 'merge/merge-xtradb-5.5' into 5.5
5.5.46-37.6
Diffstat (limited to 'storage')
-rw-r--r--storage/xtradb/CMakeLists.txt17
-rw-r--r--storage/xtradb/btr/btr0cur.c47
-rw-r--r--storage/xtradb/dict/dict0crea.c2
-rw-r--r--storage/xtradb/handler/ha_innodb.cc88
-rw-r--r--storage/xtradb/include/ha_prototypes.h10
-rw-r--r--storage/xtradb/include/os0file.h11
-rw-r--r--storage/xtradb/include/os0sync.h115
-rw-r--r--storage/xtradb/include/sync0sync.h9
-rw-r--r--storage/xtradb/include/sync0sync.ic9
-rw-r--r--storage/xtradb/include/univ.i4
-rw-r--r--storage/xtradb/lock/lock0lock.c10
-rw-r--r--storage/xtradb/log/log0online.c16
-rw-r--r--storage/xtradb/log/log0recv.c2
-rw-r--r--storage/xtradb/os/os0file.c17
-rw-r--r--storage/xtradb/row/row0ins.c5
-rw-r--r--storage/xtradb/trx/trx0trx.c6
16 files changed, 318 insertions, 50 deletions
diff --git a/storage/xtradb/CMakeLists.txt b/storage/xtradb/CMakeLists.txt
index 2f8e42427d0..fe86358a594 100644
--- a/storage/xtradb/CMakeLists.txt
+++ b/storage/xtradb/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -136,6 +136,18 @@ IF(NOT CMAKE_CROSSCOMPILING)
}"
HAVE_IB_GCC_ATOMIC_THREAD_FENCE
)
+ CHECK_C_SOURCE_RUNS(
+ "#include<stdint.h>
+ int main()
+ {
+ unsigned char c;
+
+ __atomic_test_and_set(&c, __ATOMIC_ACQUIRE);
+ __atomic_clear(&c, __ATOMIC_RELEASE);
+ return(0);
+ }"
+ HAVE_IB_GCC_ATOMIC_TEST_AND_SET
+ )
ENDIF()
IF(HAVE_IB_GCC_ATOMIC_BUILTINS)
@@ -145,6 +157,9 @@ ENDIF()
IF(HAVE_IB_GCC_ATOMIC_BUILTINS_64)
ADD_DEFINITIONS(-DHAVE_IB_GCC_ATOMIC_BUILTINS_64=1)
ENDIF()
+IF(HAVE_IB_GCC_ATOMIC_TEST_AND_SET)
+ ADD_DEFINITIONS(-DHAVE_IB_GCC_ATOMIC_TEST_AND_SET=1)
+ENDIF()
IF(HAVE_IB_GCC_SYNC_SYNCHRONISE)
ADD_DEFINITIONS(-DHAVE_IB_GCC_SYNC_SYNCHRONISE=1)
diff --git a/storage/xtradb/btr/btr0cur.c b/storage/xtradb/btr/btr0cur.c
index be12bf62abd..0ec9367b27c 100644
--- a/storage/xtradb/btr/btr0cur.c
+++ b/storage/xtradb/btr/btr0cur.c
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@@ -318,7 +318,12 @@ btr_cur_latch_leaves(
ut_a(page_is_comp(get_block->frame)
== page_is_comp(page));
- ut_a(btr_page_get_next(get_block->frame, mtr)
+
+ /* For fake_change mode we avoid a detailed validation
+ as it operate in tweaked format where-in validation
+ may fail. */
+ ut_a(sibling_mode == RW_NO_LATCH
+ || btr_page_get_next(get_block->frame, mtr)
== page_get_page_no(page));
}
#endif /* UNIV_BTR_DEBUG */
@@ -2228,6 +2233,7 @@ btr_cur_optimistic_update(
ulint max_size;
ulint new_rec_size;
ulint old_rec_size;
+ ulint max_ins_size = 0;
dtuple_t* new_entry;
roll_ptr_t roll_ptr;
trx_t* trx;
@@ -2339,6 +2345,11 @@ any_extern:
: (old_rec_size
+ page_get_max_insert_size_after_reorganize(page, 1));
+ if (!page_zip) {
+ max_ins_size = page_get_max_insert_size_after_reorganize(
+ page, 1);
+ }
+
if (!(((max_size >= BTR_CUR_PAGE_REORGANIZE_LIMIT)
&& (max_size >= new_rec_size))
|| (page_get_n_recs(page) <= 1))) {
@@ -2395,10 +2406,14 @@ any_extern:
rec = btr_cur_insert_if_possible(cursor, new_entry, 0/*n_ext*/, mtr);
ut_a(rec); /* <- We calculated above the insert would fit */
- if (page_zip && !dict_index_is_clust(index)
+ if (!dict_index_is_clust(index)
&& page_is_leaf(page)) {
/* Update the free bits in the insert buffer. */
- ibuf_update_free_bits_zip(block, mtr);
+ if (page_zip) {
+ ibuf_update_free_bits_zip(block, mtr);
+ } else {
+ ibuf_update_free_bits_low(block, max_ins_size, mtr);
+ }
}
/* Restore the old explicit lock state on the record */
@@ -2507,6 +2522,7 @@ btr_cur_pessimistic_update(
ulint n_reserved;
ulint n_ext;
ulint* offsets = NULL;
+ ulint max_ins_size = 0;
*big_rec = NULL;
@@ -2659,6 +2675,11 @@ make_external:
/* skip CHANGE, LOG */
err = DB_SUCCESS;
goto return_after_reservations;
+ }
+
+ if (!page_zip) {
+ max_ins_size = page_get_max_insert_size_after_reorganize(
+ page, 1);
}
/* Store state of explicit locks on rec on the page infimum record,
@@ -2706,10 +2727,15 @@ make_external:
big_rec_vec != NULL && (flags & BTR_KEEP_POS_FLAG),
mtr);
- if (page_zip && !dict_index_is_clust(index)
+ if (!dict_index_is_clust(index)
&& page_is_leaf(page)) {
/* Update the free bits in the insert buffer. */
- ibuf_update_free_bits_zip(block, mtr);
+ if (page_zip) {
+ ibuf_update_free_bits_zip(block, mtr);
+ } else {
+ ibuf_update_free_bits_low(block, max_ins_size,
+ mtr);
+ }
}
err = DB_SUCCESS;
@@ -4016,7 +4042,14 @@ btr_estimate_number_of_different_key_vals(
page = btr_cur_get_page(&cursor);
- SRV_CORRUPT_TABLE_CHECK(page, goto exit_loop;);
+ DBUG_EXECUTE_IF("ib_corrupt_page_while_stats_calc",
+ page = NULL;);
+
+ SRV_CORRUPT_TABLE_CHECK(page,
+ {
+ mtr_commit(&mtr);
+ goto exit_loop;
+ });
rec = page_rec_get_next(page_get_infimum_rec(page));
diff --git a/storage/xtradb/dict/dict0crea.c b/storage/xtradb/dict/dict0crea.c
index 4419287ad8b..4c1c4f1bd6b 100644
--- a/storage/xtradb/dict/dict0crea.c
+++ b/storage/xtradb/dict/dict0crea.c
@@ -1255,7 +1255,7 @@ dict_create_index_step(
>= DICT_TF_FORMAT_ZIP);
node->index = dict_index_get_if_in_cache_low(index_id);
- ut_a(err == DB_SUCCESS ? node->index != NULL : node->index == NULL);
+ ut_a((node->index == 0) == (err != DB_SUCCESS));
if (err != DB_SUCCESS) {
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 19aec80dbbd..c04a502902d 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -1035,6 +1035,19 @@ thd_supports_xa(
}
/******************************************************************//**
+Check the status of fake changes mode (innodb_fake_changes)
+@return true if fake change mode is enabled. */
+extern "C" UNIV_INTERN
+ibool
+thd_fake_changes(
+/*=============*/
+ void* thd) /*!< in: thread handle, or NULL to query
+ the global innodb_supports_xa */
+{
+ return(THDVAR((THD*) thd, fake_changes));
+}
+
+/******************************************************************//**
Returns the lock wait timeout for the current connection.
@return the lock wait timeout, in seconds */
extern "C" UNIV_INTERN
@@ -1800,7 +1813,15 @@ innobase_trx_init(
trx->check_unique_secondary = !thd_test_options(
thd, OPTION_RELAXED_UNIQUE_CHECKS);
- trx->fake_changes = THDVAR(thd, fake_changes);
+ /* Transaction on start caches the fake_changes state and uses it for
+ complete transaction lifetime.
+ There are some APIs that doesn't need an active transaction object
+ but transaction object are just use as a cache object/data carrier.
+ Before using transaction object for such APIs refresh the state of
+ fake_changes. */
+ if (trx->state == TRX_NOT_STARTED) {
+ trx->fake_changes = thd_fake_changes(thd);
+ }
#ifdef EXTENDED_SLOWLOG
if (thd_log_slow_verbosity(thd) & (1ULL << SLOG_V_INNODB)) {
@@ -3620,12 +3641,26 @@ innobase_commit(
/* No-op in XtraDB */
trx_search_latch_release_if_reserved(trx);
+ /* If fake-changes mode = ON then allow
+ SELECT (they are read-only) and
+ CREATE ... SELECT * from table (Well this doesn't open up DDL for InnoDB
+ as ha_innobase::create will return appropriate error if fake-change = ON
+ but if create is trying to use other SE and SELECT is executing on
+ InnoDB table then we allow SELECT to proceed.
+ Ideally, statement like this should be marked CREATE_SELECT like
+ INSERT_SELECT but unfortunately it doesn't). */
if (UNIV_UNLIKELY(trx->fake_changes
+ && (thd_sql_command(thd) != SQLCOM_SELECT
+ && thd_sql_command(thd) != SQLCOM_CREATE_TABLE)
&& (all || (!thd_test_options(thd,
OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))))) {
- innobase_rollback(hton, thd, all); /* rollback implicitly */
- thd->stmt_da->reset_diagnostics_area(); /* because debug assertion code complains, if something left */
+ /* rollback implicitly */
+ innobase_rollback(hton, thd, all);
+
+ /* because debug assertion code complains, if something left */
+ thd->stmt_da->reset_diagnostics_area();
+
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
}
/* Transaction is deregistered only in a commit or a rollback. If
@@ -12714,6 +12749,46 @@ innodb_change_buffering_update(
*static_cast<const char*const*>(save);
}
+#ifdef UNIV_DEBUG
+/*************************************************************//**
+Check if it is a valid value of innodb_track_changed_pages.
+Changed pages tracking is not working correctly without initialization
+procedure on server startup. The function allows to temporary
+disable tracking, but only if the feature was enabled on startup.
+This function is registered as a callback with MySQL.
+@return 0 for valid innodb_track_changed_pages */
+static
+int
+innodb_track_changed_pages_validate(
+ THD* thd, /*!< in: thread handle */
+ struct st_mysql_sys_var* var, /*!< in: pointer to system
+ variable */
+ void* save, /*!< out: immediate result
+ for update function */
+ struct st_mysql_value* value) /*!< in: incoming bool */
+{
+ static bool enabled_on_startup = false;
+ long long intbuf = 0;
+
+ if (value->val_int(value, &intbuf)) {
+ /* The value is NULL. That is invalid. */
+ return 1;
+ }
+
+ if (srv_track_changed_pages || enabled_on_startup) {
+ enabled_on_startup = true;
+ *reinterpret_cast<ulong*>(save)
+ = static_cast<ulong>(intbuf);
+ return 0;
+ }
+
+ if (intbuf == srv_track_changed_pages)
+ return 0;
+
+ return 1;
+}
+#endif
+
#ifndef DBUG_OFF
static char* srv_buffer_pool_evict;
@@ -13424,7 +13499,12 @@ provide a testcase sync facility */
static MYSQL_SYSVAR_BOOL(track_changed_pages, srv_track_changed_pages,
track_changed_pages_flags,
"Track the redo log for changed pages and output a changed page bitmap",
- NULL, NULL, FALSE);
+#ifdef UNIV_DEBUG
+ innodb_track_changed_pages_validate,
+#else
+ NULL,
+#endif
+ NULL, FALSE);
static MYSQL_SYSVAR_ULONGLONG(max_bitmap_file_size, srv_max_bitmap_file_size,
PLUGIN_VAR_RQCMDARG,
diff --git a/storage/xtradb/include/ha_prototypes.h b/storage/xtradb/include/ha_prototypes.h
index ad0abb88ff6..c127e63ecbc 100644
--- a/storage/xtradb/include/ha_prototypes.h
+++ b/storage/xtradb/include/ha_prototypes.h
@@ -276,6 +276,16 @@ thd_supports_xa(
the global innodb_supports_xa */
/******************************************************************//**
+Check the status of fake changes mode (innodb_fake_changes)
+@return true if fake change mode is enabled. */
+
+ibool
+thd_fake_changes(
+/*=============*/
+ void* thd); /*!< in: thread handle, or NULL to query
+ the global innodb_supports_xa */
+
+/******************************************************************//**
Returns the lock wait timeout for the current connection.
@return the lock wait timeout, in seconds */
diff --git a/storage/xtradb/include/os0file.h b/storage/xtradb/include/os0file.h
index a7b74c83f39..71da5ea6125 100644
--- a/storage/xtradb/include/os0file.h
+++ b/storage/xtradb/include/os0file.h
@@ -119,6 +119,10 @@ log. */
#define OS_FILE_READ_ONLY 333
#define OS_FILE_READ_WRITE 444
#define OS_FILE_READ_ALLOW_DELETE 555 /* for ibbackup */
+#define OS_FILE_READ_WRITE_CACHED 666 /* OS_FILE_READ_WRITE but never
+ O_DIRECT. Only for
+ os_file_create_simple_no_error_handling
+ currently. */
/* Options for file_create */
#define OS_FILE_AIO 61
@@ -505,9 +509,10 @@ os_file_create_simple_no_error_handling_func(
OS_FILE_CREATE if a new file is created
(if exists, error) */
ulint access_type,/*!< in: OS_FILE_READ_ONLY,
- OS_FILE_READ_WRITE, or
- OS_FILE_READ_ALLOW_DELETE; the last option is
- used by a backup program reading the file */
+ OS_FILE_READ_WRITE, OS_FILE_READ_ALLOW_DELETE
+ (used by a backup program reading the file), or
+ OS_FILE_READ_WRITE_CACHED (disable O_DIRECT if
+ it would be enabled otherwise). */
ibool* success);/*!< out: TRUE if succeed, FALSE if error */
/****************************************************************//**
Tries to disable OS caching on an opened file descriptor. */
diff --git a/storage/xtradb/include/os0sync.h b/storage/xtradb/include/os0sync.h
index d9f24079a8a..a60dcbd1e75 100644
--- a/storage/xtradb/include/os0sync.h
+++ b/storage/xtradb/include/os0sync.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@@ -37,6 +37,21 @@ Created 9/6/1995 Heikki Tuuri
#include "univ.i"
#include "ut0lst.h"
+#if defined __i386__ || defined __x86_64__ || defined _M_IX86 \
+ || defined _M_X64 || defined __WIN__
+
+#define IB_STRONG_MEMORY_MODEL
+#undef HAVE_IB_GCC_ATOMIC_TEST_AND_SET // Quick-and-dirty fix for bug 1519094
+
+#endif /* __i386__ || __x86_64__ || _M_IX86 || M_X64 || __WIN__ */
+
+#ifdef HAVE_WINDOWS_ATOMICS
+typedef LONG lock_word_t; /*!< On Windows, InterlockedExchange operates
+ on LONG variable */
+#else
+typedef byte lock_word_t;
+#endif
+
#ifdef __WIN__
/** Native event (slow)*/
typedef HANDLE os_native_event_t;
@@ -354,6 +369,62 @@ Returns the old value of *ptr, atomically sets *ptr to new_val */
# define os_atomic_test_and_set_byte_acquire(ptr, new_val) \
__sync_lock_test_and_set(ptr, (byte) new_val)
+# if defined(HAVE_IB_GCC_ATOMIC_TEST_AND_SET)
+
+/** Do an atomic test-and-set.
+@param[in,out] ptr Memory location to set to non-zero
+@return the previous value */
+static inline
+lock_word_t
+os_atomic_test_and_set(volatile lock_word_t* ptr)
+{
+ return(__atomic_test_and_set(ptr, __ATOMIC_ACQUIRE));
+}
+
+/** Do an atomic clear.
+@param[in,out] ptr Memory location to set to zero */
+static inline
+void
+os_atomic_clear(volatile lock_word_t* ptr)
+{
+ __atomic_clear(ptr, __ATOMIC_RELEASE);
+}
+
+# elif defined(IB_STRONG_MEMORY_MODEL)
+
+/** Do an atomic test and set.
+@param[in,out] ptr Memory location to set to non-zero
+@return the previous value */
+static inline
+lock_word_t
+os_atomic_test_and_set(volatile lock_word_t* ptr)
+{
+ return(__sync_lock_test_and_set(ptr, 1));
+}
+
+/** Do an atomic release.
+
+In theory __sync_lock_release should be used to release the lock.
+Unfortunately, it does not work properly alone. The workaround is
+that more conservative __sync_lock_test_and_set is used instead.
+
+Performance regression was observed at some conditions for Intel
+architecture. Disable release barrier on Intel architecture for now.
+@param[in,out] ptr Memory location to write to
+@return the previous value */
+static inline
+lock_word_t
+os_atomic_clear(volatile lock_word_t* ptr)
+{
+ return(__sync_lock_test_and_set(ptr, 0));
+}
+
+# else
+
+# error "Unsupported platform"
+
+# endif /* HAVE_IB_GCC_ATOMIC_TEST_AND_SET */
+
#elif defined(HAVE_IB_SOLARIS_ATOMICS)
# define HAVE_ATOMIC_BUILTINS
@@ -413,6 +484,26 @@ Returns the old value of *ptr, atomically sets *ptr to new_val */
# define os_atomic_test_and_set_byte_release(ptr, new_val) \
atomic_swap_uchar(ptr, new_val)
+/** Do an atomic xchg and set to non-zero.
+@param[in,out] ptr Memory location to set to non-zero
+@return the previous value */
+static inline
+lock_word_t
+os_atomic_test_and_set(volatile lock_word_t* ptr)
+{
+ return(atomic_swap_uchar(ptr, 1));
+}
+
+/** Do an atomic xchg and set to zero.
+@param[in,out] ptr Memory location to set to zero
+@return the previous value */
+static inline
+lock_word_t
+os_atomic_clear(volatile lock_word_t* ptr)
+{
+ return(atomic_swap_uchar(ptr, 0));
+}
+
#elif defined(HAVE_WINDOWS_ATOMICS)
# define HAVE_ATOMIC_BUILTINS
@@ -472,6 +563,28 @@ clobbered */
# define os_atomic_test_and_set_byte_release(ptr, new_val) \
((byte) InterlockedExchange(ptr, new_val))
+/** Do an atomic test and set.
+InterlockedExchange() operates on LONG, and the LONG will be clobbered
+@param[in,out] ptr Memory location to set to non-zero
+@return the previous value */
+static inline
+lock_word_t
+os_atomic_test_and_set(volatile lock_word_t* ptr)
+{
+ return(InterlockedExchange(ptr, 1));
+}
+
+/** Do an atomic release.
+InterlockedExchange() operates on LONG, and the LONG will be clobbered
+@param[in,out] ptr Memory location to set to zero
+@return the previous value */
+static inline
+lock_word_t
+os_atomic_clear(volatile lock_word_t* ptr)
+{
+ return(InterlockedExchange(ptr, 0));
+}
+
#else
# define IB_ATOMICS_STARTUP_MSG \
"Mutexes and rw_locks use InnoDB's own implementation"
diff --git a/storage/xtradb/include/sync0sync.h b/storage/xtradb/include/sync0sync.h
index 8509058ab1f..7568690770d 100644
--- a/storage/xtradb/include/sync0sync.h
+++ b/storage/xtradb/include/sync0sync.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@@ -45,13 +45,6 @@ Created 9/5/1995 Heikki Tuuri
extern my_bool timed_mutexes;
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
-#ifdef _WIN32
-typedef LONG lock_word_t; /*!< On Windows, InterlockedExchange operates
- on LONG variable */
-#else
-typedef byte lock_word_t;
-#endif
-
#if defined UNIV_PFS_MUTEX || defined UNIV_PFS_RWLOCK
/* There are mutexes/rwlocks that we want to exclude from
instrumentation even if their corresponding performance schema
diff --git a/storage/xtradb/include/sync0sync.ic b/storage/xtradb/include/sync0sync.ic
index fee97355c56..48039c854d9 100644
--- a/storage/xtradb/include/sync0sync.ic
+++ b/storage/xtradb/include/sync0sync.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@@ -80,7 +80,7 @@ mutex_test_and_set(
mutex_t* mutex) /*!< in: mutex */
{
#if defined(HAVE_ATOMIC_BUILTINS)
- return(os_atomic_test_and_set_byte_acquire(&mutex->lock_word, 1));
+ return(os_atomic_test_and_set(&mutex->lock_word));
#else
ibool ret;
@@ -108,10 +108,7 @@ mutex_reset_lock_word(
mutex_t* mutex) /*!< in: mutex */
{
#if defined(HAVE_ATOMIC_BUILTINS)
- /* In theory __sync_lock_release should be used to release the lock.
- Unfortunately, it does not work properly alone. The workaround is
- that more conservative __sync_lock_test_and_set is used instead. */
- os_atomic_test_and_set_byte_release(&mutex->lock_word, 0);
+ os_atomic_clear(&mutex->lock_word);
#else
mutex->lock_word = 0;
diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i
index 7c19ceb9397..6e130b1c936 100644
--- a/storage/xtradb/include/univ.i
+++ b/storage/xtradb/include/univ.i
@@ -64,10 +64,10 @@ component, i.e. we show M.N.P as M.N */
(INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR)
#ifndef PERCONA_INNODB_VERSION
-#define PERCONA_INNODB_VERSION 37.4
+#define PERCONA_INNODB_VERSION 37.6
#endif
-#define INNODB_VERSION_STR "5.5.45-MariaDB-" IB_TO_STR(PERCONA_INNODB_VERSION)
+#define INNODB_VERSION_STR "5.5.46-MariaDB-" IB_TO_STR(PERCONA_INNODB_VERSION)
#define REFMAN "http://dev.mysql.com/doc/refman/" \
IB_TO_STR(MYSQL_MAJOR_VERSION) "." \
diff --git a/storage/xtradb/lock/lock0lock.c b/storage/xtradb/lock/lock0lock.c
index 9d0151f40f8..4d7587af288 100644
--- a/storage/xtradb/lock/lock0lock.c
+++ b/storage/xtradb/lock/lock0lock.c
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -2467,16 +2467,16 @@ lock_rec_inherit_to_gap(
/* If srv_locks_unsafe_for_binlog is TRUE or session is using
READ COMMITTED isolation level, we do not want locks set
by an UPDATE or a DELETE to be inherited as gap type locks. But we
- DO want S-locks set by a consistency constraint to be inherited also
- then. */
+ DO want S-locks/X-locks (taken for replace) set by a consistency
+ constraint to be inherited also then. */
while (lock != NULL) {
if (!lock_rec_get_insert_intention(lock)
&& !((srv_locks_unsafe_for_binlog
|| lock->trx->isolation_level
<= TRX_ISO_READ_COMMITTED)
- && lock_get_mode(lock) == LOCK_X)) {
-
+ && lock_get_mode(lock) ==
+ (lock->trx->duplicates ? LOCK_S : LOCK_X))) {
lock_rec_add_to_queue(LOCK_REC | LOCK_GAP
| lock_get_mode(lock),
heir_block, heir_heap_no,
diff --git a/storage/xtradb/log/log0online.c b/storage/xtradb/log/log0online.c
index acb3bd58714..a8444199ea9 100644
--- a/storage/xtradb/log/log0online.c
+++ b/storage/xtradb/log/log0online.c
@@ -544,7 +544,7 @@ log_online_start_bitmap_file(void)
innodb_file_bmp_key,
log_bmp_sys->out.name,
OS_FILE_CREATE,
- OS_FILE_READ_WRITE,
+ OS_FILE_READ_WRITE_CACHED,
&success);
}
if (UNIV_UNLIKELY(!success)) {
@@ -704,7 +704,7 @@ log_online_read_init(void)
log_bmp_sys->out.file
= os_file_create_simple_no_error_handling
(innodb_file_bmp_key, log_bmp_sys->out.name, OS_FILE_OPEN,
- OS_FILE_READ_WRITE, &success);
+ OS_FILE_READ_WRITE_CACHED, &success);
if (!success) {
@@ -1494,10 +1494,20 @@ log_online_open_bitmap_file_read_only(
ibool success = FALSE;
ulint size_low;
ulint size_high;
+ size_t srv_data_home_len;
ut_ad(name[0] != '\0');
- ut_snprintf(bitmap_file->name, FN_REFLEN, "%s%s", srv_data_home, name);
+ srv_data_home_len = strlen(srv_data_home);
+ if (srv_data_home_len
+ && srv_data_home[srv_data_home_len-1]
+ != SRV_PATH_SEPARATOR) {
+ ut_snprintf(bitmap_file->name, FN_REFLEN, "%s%c%s",
+ srv_data_home, SRV_PATH_SEPARATOR, name);
+ } else {
+ ut_snprintf(bitmap_file->name, FN_REFLEN, "%s%s",
+ srv_data_home, name);
+ }
bitmap_file->file
= os_file_create_simple_no_error_handling(innodb_file_bmp_key,
bitmap_file->name,
diff --git a/storage/xtradb/log/log0recv.c b/storage/xtradb/log/log0recv.c
index 5ab5e4be29e..e465f9a60bc 100644
--- a/storage/xtradb/log/log0recv.c
+++ b/storage/xtradb/log/log0recv.c
@@ -1840,7 +1840,7 @@ loop:
goto loop;
}
- ut_ad(allow_ibuf == FALSE ? mutex_own(&log_sys->mutex) : !mutex_own(&log_sys->mutex));
+ ut_ad((allow_ibuf == 0) == (mutex_own(&log_sys->mutex) != 0));
if (!allow_ibuf) {
recv_no_ibuf_operations = TRUE;
diff --git a/storage/xtradb/os/os0file.c b/storage/xtradb/os/os0file.c
index 3cec27f5c97..8870f823db3 100644
--- a/storage/xtradb/os/os0file.c
+++ b/storage/xtradb/os/os0file.c
@@ -1319,9 +1319,10 @@ os_file_create_simple_no_error_handling_func(
OS_FILE_CREATE if a new file is created
(if exists, error) */
ulint access_type,/*!< in: OS_FILE_READ_ONLY,
- OS_FILE_READ_WRITE, or
- OS_FILE_READ_ALLOW_DELETE; the last option is
- used by a backup program reading the file */
+ OS_FILE_READ_WRITE, OS_FILE_READ_ALLOW_DELETE
+ (used by a backup program reading the file), or
+ OS_FILE_READ_WRITE_CACHED (disable O_DIRECT if
+ it would be enabled otherwise). */
ibool* success)/*!< out: TRUE if succeed, FALSE if error */
{
#ifdef __WIN__
@@ -1344,7 +1345,8 @@ os_file_create_simple_no_error_handling_func(
if (access_type == OS_FILE_READ_ONLY) {
access = GENERIC_READ;
- } else if (access_type == OS_FILE_READ_WRITE) {
+ } else if (access_type == OS_FILE_READ_WRITE
+ || access_type == OS_FILE_READ_WRITE_CACHED) {
access = GENERIC_READ | GENERIC_WRITE;
} else if (access_type == OS_FILE_READ_ALLOW_DELETE) {
access = GENERIC_READ;
@@ -1405,7 +1407,8 @@ os_file_create_simple_no_error_handling_func(
if (file == -1) {
*success = FALSE;
#ifdef USE_FILE_LOCK
- } else if (access_type == OS_FILE_READ_WRITE
+ } else if ((access_type == OS_FILE_READ_WRITE
+ || access_type == OS_FILE_READ_WRITE_CACHED)
&& os_file_lock(file, name)) {
*success = FALSE;
close(file);
@@ -1418,7 +1421,9 @@ os_file_create_simple_no_error_handling_func(
disable OS caching (O_DIRECT) here as we do in
os_file_create_func(), so we open the same file in the same
mode, see man page of open(2). */
- if (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
+ if ((srv_unix_file_flush_method == SRV_UNIX_O_DIRECT
+ || srv_unix_file_flush_method == SRV_UNIX_ALL_O_DIRECT)
+ && access_type != OS_FILE_READ_WRITE_CACHED) {
os_file_set_nocache(file, name, mode_str);
}
}
diff --git a/storage/xtradb/row/row0ins.c b/storage/xtradb/row/row0ins.c
index 97a4fb0767f..6de9a95a694 100644
--- a/storage/xtradb/row/row0ins.c
+++ b/storage/xtradb/row/row0ins.c
@@ -247,8 +247,9 @@ row_ins_sec_index_entry_by_modify(
rec = btr_cur_get_rec(cursor);
ut_ad(!dict_index_is_clust(cursor->index));
- ut_ad(rec_get_deleted_flag(rec,
- dict_table_is_comp(cursor->index->table)));
+ ut_ad(UNIV_UNLIKELY(thr_get_trx(thr)->fake_changes)
+ || rec_get_deleted_flag(rec,
+ dict_table_is_comp(cursor->index->table)));
/* We know that in the alphabetical ordering, entry and rec are
identified. But in their binary form there may be differences if
diff --git a/storage/xtradb/trx/trx0trx.c b/storage/xtradb/trx/trx0trx.c
index 11b0de49e10..17cb8374d5c 100644
--- a/storage/xtradb/trx/trx0trx.c
+++ b/storage/xtradb/trx/trx0trx.c
@@ -880,6 +880,12 @@ trx_start_low(
trx->no = IB_ULONGLONG_MAX;
+ /* Cache the state of fake_changes that transaction will use for
+ lifetime. Any change in session/global fake_changes configuration during
+ lifetime of transaction will not be honored by already started
+ transaction. */
+ trx->fake_changes = thd_fake_changes(trx->mysql_thd);
+
trx->rseg = rseg;
trx->state = TRX_ACTIVE;