diff options
author | Sergei Golubchik <serg@mariadb.org> | 2015-12-09 12:57:04 +0100 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2015-12-09 12:57:04 +0100 |
commit | 142b7256070a5fc54f2e841e4bafdd544318eef5 (patch) | |
tree | 70c5afec33298952dbbf9f8724b3450e03795fa6 | |
parent | 1a72c6fefdb48642f66dc6f32d8bc7a4cc607437 (diff) | |
parent | 9457139e591aa7fb0459788acdbc260db53b0f22 (diff) | |
download | mariadb-git-142b7256070a5fc54f2e841e4bafdd544318eef5.tar.gz |
Merge branch 'merge/merge-xtradb-5.5' into 5.5
5.5.46-37.6
-rw-r--r-- | storage/xtradb/CMakeLists.txt | 17 | ||||
-rw-r--r-- | storage/xtradb/btr/btr0cur.c | 47 | ||||
-rw-r--r-- | storage/xtradb/dict/dict0crea.c | 2 | ||||
-rw-r--r-- | storage/xtradb/handler/ha_innodb.cc | 88 | ||||
-rw-r--r-- | storage/xtradb/include/ha_prototypes.h | 10 | ||||
-rw-r--r-- | storage/xtradb/include/os0file.h | 11 | ||||
-rw-r--r-- | storage/xtradb/include/os0sync.h | 115 | ||||
-rw-r--r-- | storage/xtradb/include/sync0sync.h | 9 | ||||
-rw-r--r-- | storage/xtradb/include/sync0sync.ic | 9 | ||||
-rw-r--r-- | storage/xtradb/include/univ.i | 4 | ||||
-rw-r--r-- | storage/xtradb/lock/lock0lock.c | 10 | ||||
-rw-r--r-- | storage/xtradb/log/log0online.c | 16 | ||||
-rw-r--r-- | storage/xtradb/log/log0recv.c | 2 | ||||
-rw-r--r-- | storage/xtradb/os/os0file.c | 17 | ||||
-rw-r--r-- | storage/xtradb/row/row0ins.c | 5 | ||||
-rw-r--r-- | storage/xtradb/trx/trx0trx.c | 6 |
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; |