diff --git a/CMakeLists.txt b/CMakeLists.txt index 61f0fec9a3f..b5fb26880a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ -# Copyright (C) 2006 MySQL AB -# +# Copyright (C) 2009 Oracle/Innobase Oy +# # 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 Foundation; version 2 of the License. @@ -11,87 +11,121 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") -SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") -ADD_DEFINITIONS(-D_WIN32 -D_LIB) +# This is the CMakeLists for InnoDB Plugin -# Bug 19424 - InnoDB: Possibly a memory overrun of the buffer being freed (64-bit Visual C) -# Removing Win64 compiler optimizations for all innodb/mem/* files. -IF(CMAKE_GENERATOR MATCHES "Visual Studio" AND CMAKE_SIZEOF_VOID_P MATCHES 8) - SET_SOURCE_FILES_PROPERTIES(${CMAKE_SOURCE_DIR}/storage/innobase/mem/mem0mem.c - ${CMAKE_SOURCE_DIR}/storage/innobase/mem/mem0pool.c - PROPERTIES COMPILE_FLAGS -Od) -ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio" AND CMAKE_SIZEOF_VOID_P MATCHES 8) +# The dynamic plugin requires CMake 2.6.0 or later. Otherwise, the /DELAYLOAD +# property will not be set +CMAKE_MINIMUM_REQUIRED(VERSION 2.6 FATAL_ERROR) -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib - ${CMAKE_SOURCE_DIR}/storage/innobase/include - ${CMAKE_SOURCE_DIR}/storage/innobase/handler - ${CMAKE_SOURCE_DIR}/sql - ${CMAKE_SOURCE_DIR}/regex - ${CMAKE_SOURCE_DIR}/extra/yassl/include) +# When PROJECT is defined, a separate .sln file will be generated. +# PROJECT (INNODB_PLUGIN) -SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c - buf/buf0buddy.c buf/buf0buf.c buf/buf0flu.c buf/buf0lru.c buf/buf0rea.c - data/data0data.c data/data0type.c - dict/dict0boot.c dict/dict0crea.c dict/dict0dict.c dict/dict0load.c dict/dict0mem.c - dyn/dyn0dyn.c - eval/eval0eval.c eval/eval0proc.c - fil/fil0fil.c - fsp/fsp0fsp.c - fut/fut0fut.c fut/fut0lst.c - ha/ha0ha.c ha/hash0hash.c ha/ha0storage.c - ibuf/ibuf0ibuf.c - pars/lexyy.c pars/pars0grm.c pars/pars0opt.c pars/pars0pars.c pars/pars0sym.c - lock/lock0lock.c lock/lock0iter.c - log/log0log.c log/log0recv.c - mach/mach0data.c - mem/mem0mem.c mem/mem0pool.c - mtr/mtr0log.c mtr/mtr0mtr.c - os/os0file.c os/os0proc.c os/os0sync.c os/os0thread.c - page/page0cur.c page/page0page.c page/page0zip.c - que/que0que.c - handler/ha_innodb.cc handler/handler0alter.cc handler/i_s.cc handler/mysql_addons.cc - read/read0read.c - rem/rem0cmp.c rem/rem0rec.c - row/row0ext.c row/row0ins.c row/row0merge.c row/row0mysql.c - row/row0purge.c row/row0row.c row/row0sel.c row/row0uins.c - row/row0umod.c row/row0undo.c row/row0upd.c row/row0vers.c - srv/srv0que.c srv/srv0srv.c srv/srv0start.c - sync/sync0arr.c sync/sync0rw.c sync/sync0sync.c - thr/thr0loc.c - trx/trx0i_s.c trx/trx0purge.c trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c - trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c - usr/usr0sess.c - ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c ut/ut0list.c ut/ut0wqueue.c) +MESSAGE(STATUS "Enter InnoDB ...") +MESSAGE(STATUS "INNODB_DYNAMIC_PLUGIN: " ${INNODB_DYNAMIC_PLUGIN}) + +# Print out CMake info +MESSAGE(STATUS "CMAKE_GENERATOR: " ${CMAKE_GENERATOR}) +MESSAGE(STATUS "CMAKE_SOURCE_DIR: " ${CMAKE_SOURCE_DIR}) + +# Print out system information +MESSAGE(STATUS "CMAKE_SYSTEM: " ${CMAKE_SYSTEM}) +MESSAGE(STATUS "CMAKE_SYSTEM_PROCESSOR: " ${CMAKE_SYSTEM_PROCESSOR}) +MESSAGE(STATUS "UNIX: " ${UNIX}) +MESSAGE(STATUS "WIN32: " ${WIN32}) + +IF (CMAKE_SIZEOF_VOID_P MATCHES 8) + SET(WIN64 TRUE) +ENDIF (CMAKE_SIZEOF_VOID_P MATCHES 8) + +MESSAGE(STATUS "WIN64: " ${WIN64}) +MESSAGE(STATUS "MSVC: " ${MSVC}) + +# Check type sizes +include(CheckTypeSize) + +# Currently, the checked results are not used. +CHECK_TYPE_SIZE(int SIZEOF_INT) +CHECK_TYPE_SIZE(long SIZEOF_LONG) +CHECK_TYPE_SIZE(void* SIZEOF_VOID_P) + +# Include directories under innobase +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/innobase/include + ${CMAKE_SOURCE_DIR}/storage/innobase/handler) + +# Include directories under mysql +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/sql + ${CMAKE_SOURCE_DIR}/regex + ${CMAKE_SOURCE_DIR}/zlib + ${CMAKE_SOURCE_DIR}/extra/yassl/include) + +# Removing compiler optimizations for innodb/mem/* files on 64-bit Windows +# due to 64-bit compiler error, See MySQL Bug #19424, #36366, #34297 +IF(MSVC AND $(WIN64)) + SET_SOURCE_FILES_PROPERTIES(mem/mem0mem.c mem/mem0pool.c + PROPERTIES COMPILE_FLAGS -Od) +ENDIF(MSVC AND $(WIN64)) + +SET(INNODB_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c + buf/buf0buddy.c buf/buf0buf.c buf/buf0flu.c buf/buf0lru.c buf/buf0rea.c + data/data0data.c data/data0type.c + dict/dict0boot.c dict/dict0crea.c dict/dict0dict.c dict/dict0load.c dict/dict0mem.c + dyn/dyn0dyn.c + eval/eval0eval.c eval/eval0proc.c + fil/fil0fil.c + fsp/fsp0fsp.c + fut/fut0fut.c fut/fut0lst.c + ha/ha0ha.c ha/hash0hash.c ha/ha0storage.c + ibuf/ibuf0ibuf.c + pars/lexyy.c pars/pars0grm.c pars/pars0opt.c pars/pars0pars.c pars/pars0sym.c + lock/lock0lock.c lock/lock0iter.c + log/log0log.c log/log0recv.c + mach/mach0data.c + mem/mem0mem.c mem/mem0pool.c + mtr/mtr0log.c mtr/mtr0mtr.c + os/os0file.c os/os0proc.c os/os0sync.c os/os0thread.c + page/page0cur.c page/page0page.c page/page0zip.c + que/que0que.c + handler/ha_innodb.cc handler/handler0alter.cc handler/i_s.cc handler/mysql_addons.cc + read/read0read.c + rem/rem0cmp.c rem/rem0rec.c + row/row0ext.c row/row0ins.c row/row0merge.c row/row0mysql.c row/row0purge.c row/row0row.c + row/row0sel.c row/row0uins.c row/row0umod.c row/row0undo.c row/row0upd.c row/row0vers.c + srv/srv0que.c srv/srv0srv.c srv/srv0start.c + sync/sync0arr.c sync/sync0rw.c sync/sync0sync.c + thr/thr0loc.c + trx/trx0i_s.c trx/trx0purge.c trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c + trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c + usr/usr0sess.c + ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c + ut/ut0list.c ut/ut0wqueue.c) IF(NOT SOURCE_SUBLIBS) - ADD_LIBRARY(innobase ${INNOBASE_SOURCES}) - ADD_DEPENDENCIES(innobase GenError) - SET_TARGET_PROPERTIES(innobase PROPERTIES COMPILE_FLAGS "-DMYSQL_SERVER") + # INNODB_RW_LOCKS_USE_ATOMICS may be defined only if HAVE_WINDOWS_ATOMICS is defined. + # Windows Interlocked functions require Windows 2000 or newer operating system + ADD_DEFINITIONS(-D_WIN32 -DHAVE_WINDOWS_ATOMICS -DINNODB_RW_LOCKS_USE_ATOMICS) + ADD_LIBRARY(innobase STATIC ${INNODB_SOURCES}) + # Require mysqld_error.h, which is built as part of the GenError + ADD_DEPENDENCIES(innobase GenError) + # only set MYSQL_SERVER for the builtin engine, not the plugin + SET_TARGET_PROPERTIES(innobase PROPERTIES COMPILE_FLAGS "-DMYSQL_SERVER") - IF(INNODB_DYNAMIC_PLUGIN) - # The dynamic plugin requires CMake 2.6.0 or later. Otherwise, the /DELAYLOAD property - # will not be set - CMAKE_MINIMUM_REQUIRED(VERSION 2.6.0 FATAL_ERROR) - ADD_LIBRARY(ha_innodb SHARED ${INNOBASE_SOURCES} ha_innodb.def handler/win_delay_loader.cc) - ADD_DEPENDENCIES(ha_innodb GenError mysqld) - # If build type is not specified as Release, default to Debug - # This is a workaround to a problem in CMake 2.6, which does not - # set the path of mysqld.lib correctly - IF(CMAKE_BUILD_TYPE MATCHES Release) - SET(CMAKE_BUILD_TYPE "Release") - ELSE(CMAKE_BUILD_TYPE MATCHES Release) - SET(CMAKE_BUILD_TYPE "Debug") - ENDIF(CMAKE_BUILD_TYPE MATCHES Release) - TARGET_LINK_LIBRARIES(ha_innodb strings zlib) - TARGET_LINK_LIBRARIES(ha_innodb ${CMAKE_SOURCE_DIR}/sql/${CMAKE_BUILD_TYPE}/mysqld.lib) - SET_TARGET_PROPERTIES(ha_innodb PROPERTIES OUTPUT_NAME ha_innodb) - SET_TARGET_PROPERTIES(ha_innodb PROPERTIES LINK_FLAGS "/MAP /MAPINFO:EXPORTS") - SET_TARGET_PROPERTIES(ha_innodb PROPERTIES LINK_FLAGS "/ENTRY:\"_DllMainCRTStartup@12\"") - SET_TARGET_PROPERTIES(ha_innodb PROPERTIES COMPILE_FLAGS "-DMYSQL_DYNAMIC_PLUGIN") - SET_TARGET_PROPERTIES(ha_innodb PROPERTIES LINK_FLAGS "/DELAYLOAD:mysqld.exe") - ENDIF(INNODB_DYNAMIC_PLUGIN) + # Dynamic plugin ha_innodb.dll + IF(INNODB_DYNAMIC_PLUGIN) + ADD_LIBRARY(ha_innodb SHARED ${INNODB_SOURCES} ha_innodb.def handler/win_delay_loader.cc) + # Require mysqld_error.h, which is built as part of the GenError + # Also require mysqld.lib, which is built as part of the mysqld + ADD_DEPENDENCIES(ha_innodb GenError mysqld) + TARGET_LINK_LIBRARIES(ha_innodb ${CMAKE_SOURCE_DIR}/sql/\$\(OutDir\)/mysqld.lib) + SET_TARGET_PROPERTIES(ha_innodb PROPERTIES OUTPUT_NAME ha_innodb) + SET_TARGET_PROPERTIES(ha_innodb PROPERTIES LINK_FLAGS "/MAP /MAPINFO:EXPORTS") + SET_TARGET_PROPERTIES(ha_innodb PROPERTIES LINK_FLAGS "/ENTRY:\"_DllMainCRTStartup@12\"") + SET_TARGET_PROPERTIES(ha_innodb PROPERTIES COMPILE_FLAGS "-DMYSQL_DYNAMIC_PLUGIN") + SET_TARGET_PROPERTIES(ha_innodb PROPERTIES LINK_FLAGS "/DELAYLOAD:mysqld.exe") + ENDIF(INNODB_DYNAMIC_PLUGIN) ENDIF(NOT SOURCE_SUBLIBS) + +MESSAGE(STATUS "Exit InnoDB ...") diff --git a/ChangeLog b/ChangeLog index 594f2f38916..2531eb6e51d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,114 @@ +2009-05-19 The InnoDB Team + + * btr/btr0btr.c, btr/btr0cur.c, lock/lock0lock.c, + include/page0page.ic, include/lock0lock.h, include/dict0dict.h, + include/page0page.h, include/dict0dict.ic, ibuf/ibuf0ibuf.c, + page/page0zip.c, page/page0page.c: + Write updates of PAGE_MAX_TRX_ID to the redo log and add debug + assertions for checking that PAGE_MAX_TRX_ID is valid on leaf + pages of secondary indexes and the insert buffer B-tree. This bug + could cause failures in secondary index lookups in consistent + reads right after crash recovery. + +2009-05-18 The InnoDB Team + + * btr/btr0cur.c: + Correctly estimate the space needed on the compressed page when + performing an update by delete-and-insert. + +2009-05-14 The InnoDB Team + + * handler/ha_innodb.cc, include/srv0srv.h, + mysql-test/innodb_bug42101-nonzero-master.opt, + mysql-test/innodb_bug42101-nonzero.result, + mysql-test/innodb_bug42101-nonzero.test, + mysql-test/innodb_bug42101.result, mysql-test/innodb_bug42101.test, + srv/srv0srv.c: + Fix Bug#42101 Race condition in innodb_commit_concurrency + +2009-05-13 The InnoDB Team + + * dict/dict0dict.c: + Fix Bug#44320 InnoDB: missing DB_ROLL_PTR in Table Monitor COLUMNS + output + +2009-04-23 The InnoDB Team + + * row/row0mysql.c: + When scanning indexes, report in the error log any error codes + returned by the search function. These error codes will still be + ignored in CHECK TABLE. + +2009-04-23 The InnoDB Team + + * include/trx0types.h: + Define the logical type names trx_id_t, roll_ptr_t, and undo_no_t + and use them in place of dulint everywhere. + +2009-04-18 The InnoDB Team + + * handler/ha_innodb.cc, include/pars0pars.h: + Fix Bug#29125 Windows Server X64: so many compiler warnings + +2009-04-16 The InnoDB Team + + * include/univ.i: + Define REFMAN as the base URL of the MySQL Reference Manual and + use the macro in all diagnostic output. + +2009-04-16 The InnoDB Team + + * CMakeLists.txt, include/os0sync.h, include/sync0sync.h, + include/sync0sync.ic, include/univ.i, srv/srv0start.c, + sync/sync0sync.c: + Use the Windows Interlocked functions for atomic memory + access. + +2009-04-15 The InnoDB Team + + * mysql-test/innodb.result, mysql-test/innodb.test: + Fix Bug#43309 Test main.innodb can't be run twice + +2009-04-14 The InnoDB Team + + * CMakeLists.txt, handler/win_delay_loader.cc, + win-plugin/win-plugin.diff: + Remove statically linked libraries from MySQL (zlib and strings). + +2009-04-11 The InnoDB Team + + * CMakeLists.txt, win-plugin/README, win-plugin/win-plugin.diff: + Rewrite CMakeLists.txt. + +2009-04-07 The InnoDB Team + + * include/os0sync.h, include/sync0rw.ic, include/sync0sync.h, + include/sync0sync.ic, include/univ.i, plug.in, srv/srv0srv.c, + srv/srv0start.c, sync/sync0arr.c, sync/sync0sync.c: + Enable atomics on Solaris (using the libc functions as defined in + atomic.h) if GCC atomic builtins are not present. + +2009-04-07 The InnoDB Team + + * btr/btr0btr.c, dict/dict0dict.c, ibuf/ibuf0ibuf.c, + include/data0data.h, include/data0data.ic, include/data0type.h, + include/data0type.ic, include/dict0dict.h, include/dict0dict.ic, + include/rem0rec.ic, mysql-test/innodb.result, mysql-test/innodb.test, + pars/pars0pars.c, rem/rem0rec.c, row/row0upd.c: + Fix Bug#44032 In ROW_FORMAT=REDUNDANT, update UTF-8 CHAR + to/from NULL is not in-place + +2009-04-07 The InnoDB Team + + * page/page0cur.c: + Fix Bug#43660 SHOW INDEXES/ANALYZE does NOT update cardinality for + indexes of InnoDB table + 2009-04-06 The InnoDB Team * handler/ha_innodb.cc: Make the parameter innodb_change_buffering settable by the - configuration file or mysqld command line options. Before this + configuration file or mysqld command line options. Before this fix, the initial value specified for this parameter was ignored. 2009-04-06 The InnoDB Team @@ -25,6 +131,14 @@ In consistent reads, refuse to use newly created indexes that may lack history. +2009-03-25 The InnoDB Team + + * buf/buf0buf.c, handler/ha_innodb.cc, include/buf0buf.h: + In SHOW ENGINE INNODB MUTEX do not show the status of block->mutex, + block->lock, block->lock->mutex (if applicable) and all mutexes and + rw-locks for which number of os-waits are zero because this can + be overwhelming particularly when the buffer pool is very large. + 2009-03-20 The InnoDB Team * buf/buf0buf.c, include/log0recv.h, log/log0recv.c: @@ -67,7 +181,7 @@ dict_ind_redundant and dict_ind_compact, which are initialized by dict_init(). -2008-03-11 The InnoDB Team +2009-03-11 The InnoDB Team InnoDB Plugin 1.0.3 released diff --git a/btr/btr0btr.c b/btr/btr0btr.c index d170232f24d..a537fbcefb5 100644 --- a/btr/btr0btr.c +++ b/btr/btr0btr.c @@ -664,8 +664,7 @@ btr_page_get_father_node_ptr( " to fix the\n" "InnoDB: corruption. If the crash happens at " "the database startup, see\n" - "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "forcing-recovery.html about\n" + "InnoDB: " REFMAN "forcing-recovery.html about\n" "InnoDB: forcing recovery. " "Then dump + drop + reimport.\n", stderr); @@ -1002,8 +1001,16 @@ btr_page_reorganize_low( page_copy_rec_list_end_no_locks(block, temp_block, page_get_infimum_rec(temp_page), index, mtr); - /* Copy max trx id to recreated page */ - page_set_max_trx_id(block, NULL, page_get_max_trx_id(temp_page)); + + if (dict_index_is_sec_or_ibuf(index) && page_is_leaf(page)) { + /* Copy max trx id to recreated page */ + trx_id_t max_trx_id = page_get_max_trx_id(temp_page); + page_set_max_trx_id(block, NULL, max_trx_id, mtr); + /* In crash recovery, dict_index_is_sec_or_ibuf() always + returns TRUE, even for clustered indexes. max_trx_id is + unused in clustered index pages. */ + ut_ad(!ut_dulint_is_zero(max_trx_id) || recovery); + } if (UNIV_LIKELY_NULL(page_zip) && UNIV_UNLIKELY @@ -2761,7 +2768,11 @@ btr_discard_only_page_on_level( buf_block_t* block, /* in: page which is the only on its level */ mtr_t* mtr) /* in: mtr */ { - ulint page_level = 0; + ulint page_level = 0; + trx_id_t max_trx_id; + + /* Save the PAGE_MAX_TRX_ID from the leaf page. */ + max_trx_id = page_get_max_trx_id(buf_block_get_frame(block)); while (buf_block_get_page_no(block) != dict_index_get_page(index)) { btr_cur_t cursor; @@ -2804,9 +2815,16 @@ btr_discard_only_page_on_level( btr_page_empty(block, buf_block_get_page_zip(block), index, 0, mtr); - /* We play it safe and reset the free bits for the root */ if (!dict_index_is_clust(index)) { + /* We play it safe and reset the free bits for the root */ ibuf_reset_free_bits(block); + + if (page_is_leaf(buf_block_get_frame(block))) { + ut_a(!ut_dulint_is_zero(max_trx_id)); + page_set_max_trx_id(block, + buf_block_get_page_zip(block), + max_trx_id, mtr); + } } } @@ -3181,7 +3199,7 @@ btr_index_rec_validate( for (i = 0; i < n; i++) { ulint fixed_size = dict_col_get_fixed_size( - dict_index_get_nth_col(index, i)); + dict_index_get_nth_col(index, i), page_is_comp(page)); rec_get_nth_field_offs(offsets, i, &len); @@ -3265,7 +3283,6 @@ static void btr_validate_report1( /*=================*/ - /* out: TRUE if ok */ dict_index_t* index, /* in: index */ ulint level, /* in: B-tree level */ const buf_block_t* block) /* in: index page */ @@ -3285,7 +3302,6 @@ static void btr_validate_report2( /*=================*/ - /* out: TRUE if ok */ const dict_index_t* index, /* in: index */ ulint level, /* in: B-tree level */ const buf_block_t* block1, /* in: first index page */ diff --git a/btr/btr0cur.c b/btr/btr0cur.c index 0f38d852031..4fc78e8d6a3 100644 --- a/btr/btr0cur.c +++ b/btr/btr0cur.c @@ -182,8 +182,6 @@ UNIV_INLINE void btr_rec_set_deleted_flag( /*=====================*/ - /* out: TRUE on success; - FALSE on page_zip overflow */ rec_t* rec, /* in/out: physical record */ page_zip_des_t* page_zip,/* in/out: compressed page (or NULL) */ ulint flag) /* in: nonzero if delete marked */ @@ -1082,6 +1080,7 @@ btr_cur_ins_lock_and_undo( btr_cur_t* cursor, /* in: cursor on page after which to insert */ const dtuple_t* entry, /* in: entry to insert */ que_thr_t* thr, /* in: query thread or NULL */ + mtr_t* mtr, /* in/out: mini-transaction */ ibool* inherit)/* out: TRUE if the inserted new record maybe should inherit LOCK_GAP type locks from the successor record */ @@ -1089,7 +1088,7 @@ btr_cur_ins_lock_and_undo( dict_index_t* index; ulint err; rec_t* rec; - dulint roll_ptr; + roll_ptr_t roll_ptr; /* Check if we have to wait for a lock: enqueue an explicit lock request if yes */ @@ -1099,7 +1098,7 @@ btr_cur_ins_lock_and_undo( err = lock_rec_insert_check_and_lock(flags, rec, btr_cur_get_block(cursor), - index, thr, inherit); + index, thr, mtr, inherit); if (err != DB_SUCCESS) { @@ -1313,7 +1312,8 @@ fail_err: } /* Check locks and write to the undo log, if specified */ - err = btr_cur_ins_lock_and_undo(flags, cursor, entry, thr, &inherit); + err = btr_cur_ins_lock_and_undo(flags, cursor, entry, + thr, mtr, &inherit); if (UNIV_UNLIKELY(err != DB_SUCCESS)) { @@ -1393,9 +1393,7 @@ fail_err: buf_block_get_page_no(block), max_size, rec_size + PAGE_DIR_SLOT_SIZE, index->type); #endif - if (leaf - && !dict_index_is_clust(index) - && !dict_index_is_ibuf(index)) { + if (leaf && !dict_index_is_clust(index)) { /* Update the free bits of the B-tree page in the insert buffer bitmap. */ @@ -1489,7 +1487,8 @@ btr_cur_pessimistic_insert( /* Retry with a pessimistic insert. Check locks and write to undo log, if specified */ - err = btr_cur_ins_lock_and_undo(flags, cursor, entry, thr, &dummy_inh); + err = btr_cur_ins_lock_and_undo(flags, cursor, entry, + thr, mtr, &dummy_inh); if (err != DB_SUCCESS) { @@ -1584,7 +1583,8 @@ btr_cur_upd_lock_and_undo( ulint cmpl_info,/* in: compiler info on secondary index updates */ que_thr_t* thr, /* in: query thread */ - dulint* roll_ptr)/* out: roll pointer */ + mtr_t* mtr, /* in/out: mini-transaction */ + roll_ptr_t* roll_ptr)/* out: roll pointer */ { dict_index_t* index; rec_t* rec; @@ -1600,7 +1600,7 @@ btr_cur_upd_lock_and_undo( record */ return(lock_sec_rec_modify_check_and_lock( flags, btr_cur_get_block(cursor), rec, - index, thr)); + index, thr, mtr)); } /* Check if we have to wait for a lock: enqueue an explicit lock @@ -1645,7 +1645,7 @@ btr_cur_update_in_place_log( dict_index_t* index, /* in: index where cursor positioned */ const upd_t* update, /* in: update vector */ trx_t* trx, /* in: transaction */ - dulint roll_ptr, /* in: roll ptr */ + roll_ptr_t roll_ptr, /* in: roll ptr */ mtr_t* mtr) /* in: mtr */ { byte* log_ptr; @@ -1696,15 +1696,15 @@ btr_cur_parse_update_in_place( page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */ dict_index_t* index) /* in: index corresponding to page */ { - ulint flags; - rec_t* rec; - upd_t* update; - ulint pos; - dulint trx_id; - dulint roll_ptr; - ulint rec_offset; - mem_heap_t* heap; - ulint* offsets; + ulint flags; + rec_t* rec; + upd_t* update; + ulint pos; + trx_id_t trx_id; + roll_ptr_t roll_ptr; + ulint rec_offset; + mem_heap_t* heap; + ulint* offsets; if (end_ptr < ptr + 1) { @@ -1774,6 +1774,8 @@ btr_cur_update_alloc_zip( buf_block_t* block, /* in/out: buffer page */ dict_index_t* index, /* in: the index corresponding to the block */ ulint length, /* in: size needed */ + ibool create, /* in: TRUE=delete-and-insert, + FALSE=update-in-place */ mtr_t* mtr) /* in: mini-transaction */ { ut_a(page_zip == buf_block_get_page_zip(block)); @@ -1781,7 +1783,7 @@ btr_cur_update_alloc_zip( ut_ad(!dict_index_is_ibuf(index)); if (page_zip_available(page_zip, dict_index_is_clust(index), - length, 0)) { + length, create)) { return(TRUE); } @@ -1808,7 +1810,7 @@ btr_cur_update_alloc_zip( the free space available on the page. */ if (!page_zip_available(page_zip, dict_index_is_clust(index), - length, 0)) { + length, create)) { /* Out of space: reset the free bits. */ if (!dict_index_is_clust(index) && page_is_leaf(buf_block_get_frame(block))) { @@ -1844,7 +1846,7 @@ btr_cur_update_in_place( page_zip_des_t* page_zip; ulint err; rec_t* rec; - dulint roll_ptr = ut_dulint_zero; + roll_ptr_t roll_ptr = ut_dulint_zero; trx_t* trx; ulint was_delete_marked; mem_heap_t* heap = NULL; @@ -1873,13 +1875,13 @@ btr_cur_update_in_place( /* Check that enough space is available on the compressed page. */ if (UNIV_LIKELY_NULL(page_zip) && !btr_cur_update_alloc_zip(page_zip, block, index, - rec_offs_size(offsets), mtr)) { + rec_offs_size(offsets), FALSE, mtr)) { return(DB_ZIP_OVERFLOW); } /* Do lock checking and undo logging */ err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info, - thr, &roll_ptr); + thr, mtr, &roll_ptr); if (UNIV_UNLIKELY(err != DB_SUCCESS)) { if (UNIV_LIKELY_NULL(heap)) { @@ -1981,7 +1983,7 @@ btr_cur_optimistic_update( ulint new_rec_size; ulint old_rec_size; dtuple_t* new_entry; - dulint roll_ptr; + roll_ptr_t roll_ptr; trx_t* trx; mem_heap_t* heap; ulint i; @@ -2057,7 +2059,7 @@ any_extern: if (UNIV_LIKELY_NULL(page_zip) && !btr_cur_update_alloc_zip(page_zip, block, index, - new_rec_size, mtr)) { + new_rec_size, TRUE, mtr)) { err = DB_ZIP_OVERFLOW; goto err_exit; } @@ -2096,8 +2098,8 @@ any_extern: } /* Do lock checking and undo logging */ - err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info, thr, - &roll_ptr); + err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info, + thr, mtr, &roll_ptr); if (err != DB_SUCCESS) { err_exit: mem_heap_free(heap); @@ -2237,7 +2239,7 @@ btr_cur_pessimistic_update( dtuple_t* new_entry; ulint err; ulint optim_err; - dulint roll_ptr; + roll_ptr_t roll_ptr; trx_t* trx; ibool was_first; ulint n_extents = 0; @@ -2276,7 +2278,7 @@ btr_cur_pessimistic_update( /* Do lock checking and undo logging */ err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info, - thr, &roll_ptr); + thr, mtr, &roll_ptr); if (err != DB_SUCCESS) { return(err); @@ -2451,6 +2453,19 @@ make_external: ut_a(err == DB_SUCCESS); ut_a(dummy_big_rec == NULL); + if (dict_index_is_sec_or_ibuf(index)) { + /* Update PAGE_MAX_TRX_ID in the index page header. + It was not updated by btr_cur_pessimistic_insert() + because of BTR_NO_LOCKING_FLAG. */ + buf_block_t* rec_block; + + rec_block = btr_cur_get_block(cursor); + + page_update_max_trx_id(rec_block, + buf_block_get_page_zip(rec_block), + trx->id, mtr); + } + if (!rec_get_deleted_flag(rec, rec_offs_comp(offsets))) { /* The new inserted record owns its possible externally stored fields */ @@ -2509,7 +2524,7 @@ btr_cur_del_mark_set_clust_rec_log( dict_index_t* index, /* in: index of the record */ ibool val, /* in: value to set */ trx_t* trx, /* in: deleting transaction */ - dulint roll_ptr,/* in: roll ptr to the undo log record */ + roll_ptr_t roll_ptr,/* in: roll ptr to the undo log record */ mtr_t* mtr) /* in: mtr */ { byte* log_ptr; @@ -2558,13 +2573,13 @@ btr_cur_parse_del_mark_set_clust_rec( page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */ dict_index_t* index) /* in: index corresponding to page */ { - ulint flags; - ulint val; - ulint pos; - dulint trx_id; - dulint roll_ptr; - ulint offset; - rec_t* rec; + ulint flags; + ulint val; + ulint pos; + trx_id_t trx_id; + roll_ptr_t roll_ptr; + ulint offset; + rec_t* rec; ut_ad(!page || !!page_is_comp(page) == dict_table_is_comp(index->table)); @@ -2644,7 +2659,7 @@ btr_cur_del_mark_set_clust_rec( { dict_index_t* index; buf_block_t* block; - dulint roll_ptr; + roll_ptr_t roll_ptr; ulint err; rec_t* rec; page_zip_des_t* page_zip; @@ -2826,7 +2841,7 @@ btr_cur_del_mark_set_sec_rec( err = lock_sec_rec_modify_check_and_lock(flags, btr_cur_get_block(cursor), - rec, cursor->index, thr); + rec, cursor->index, thr, mtr); if (err != DB_SUCCESS) { return(err); diff --git a/buf/buf0buf.c b/buf/buf0buf.c index 8ee1ead7fbc..a29b982a783 100644 --- a/buf/buf0buf.c +++ b/buf/buf0buf.c @@ -372,8 +372,7 @@ buf_page_is_corrupted( "you may have copied the InnoDB\n" "InnoDB: tablespace but not the InnoDB " "log files. See\n" - "InnoDB: http://dev.mysql.com/doc/refman/" - "5.1/en/forcing-recovery.html\n" + "InnoDB: " REFMAN "forcing-recovery.html\n" "InnoDB: for more information.\n", (ulong) mach_read_from_4(read_buf + FIL_PAGE_OFFSET), @@ -1173,7 +1172,6 @@ static void buf_pool_shrink( /*============*/ - /* out: TRUE if shrunk */ ulint chunk_size) /* in: number of pages to remove */ { buf_chunk_t* chunks; @@ -3243,9 +3241,8 @@ corrupt: " You can use CHECK\n" "InnoDB: TABLE to scan your" " table for corruption.\n" - "InnoDB: See also" - " http://dev.mysql.com/doc/refman/5.1/en/" - "forcing-recovery.html\n" + "InnoDB: See also " + REFMAN "forcing-recovery.html\n" "InnoDB: about forcing recovery.\n", stderr); if (srv_force_recovery < SRV_FORCE_IGNORE_CORRUPT) { @@ -3371,6 +3368,7 @@ UNIV_INTERN ibool buf_validate(void) /*==============*/ + /* out: TRUE */ { buf_page_t* b; buf_chunk_t* chunk; @@ -3707,6 +3705,7 @@ UNIV_INTERN ulint buf_get_latched_pages_number(void) /*==============================*/ + /* out: number of latched pages */ { buf_chunk_t* chunk; buf_page_t* b; @@ -3795,6 +3794,7 @@ UNIV_INTERN ulint buf_get_n_pending_ios(void) /*=======================*/ + /* out: number of pending I/O operations */ { return(buf_pool->n_pend_reads + buf_pool->n_flush[BUF_FLUSH_LRU] @@ -3809,6 +3809,7 @@ UNIV_INTERN ulint buf_get_modified_ratio_pct(void) /*============================*/ + /* out: modified page percentage ratio */ { ulint ratio; @@ -3923,11 +3924,12 @@ buf_refresh_io_stats(void) } /************************************************************************* -Checks that all file pages in the buffer are in a replaceable state. */ +Asserts that all file pages in the buffer are in a replaceable state. */ UNIV_INTERN ibool buf_all_freed(void) /*===============*/ + /* out: TRUE */ { buf_chunk_t* chunk; ulint i; @@ -3988,6 +3990,7 @@ UNIV_INTERN ulint buf_get_free_list_len(void) /*=======================*/ + /* out: length of the free list */ { ulint len; diff --git a/buf/buf0lru.c b/buf/buf0lru.c index d6371ba348b..26fdf9d51bc 100644 --- a/buf/buf0lru.c +++ b/buf/buf0lru.c @@ -1874,6 +1874,7 @@ UNIV_INTERN ibool buf_LRU_validate(void) /*==================*/ + /* out: TRUE */ { buf_page_t* bpage; buf_block_t* block; diff --git a/dict/dict0dict.c b/dict/dict0dict.c index e95a666269d..434b4e04ead 100644 --- a/dict/dict0dict.c +++ b/dict/dict0dict.c @@ -29,9 +29,9 @@ Created 1/8/1996 Heikki Tuuri #endif /* dummy index for ROW_FORMAT=REDUNDANT supremum and infimum records */ -dict_index_t* dict_ind_redundant; +UNIV_INTERN dict_index_t* dict_ind_redundant; /* dummy index for ROW_FORMAT=COMPACT supremum and infimum records */ -dict_index_t* dict_ind_compact; +UNIV_INTERN dict_index_t* dict_ind_compact; #ifndef UNIV_HOTBACKUP #include "buf0buf.h" @@ -650,8 +650,7 @@ dict_table_get( /* out: table, NULL if does not exist */ const char* table_name, /* in: table name */ - ibool inc_mysql_count) - /* in: whether to increment the open + ibool inc_mysql_count)/* in: whether to increment the open handle count on the table */ { dict_table_t* table; @@ -1252,7 +1251,8 @@ dict_index_too_big_for_undo( ulint max_size = dict_col_get_max_size(col); ulint fixed_size - = dict_col_get_fixed_size(col); + = dict_col_get_fixed_size(col, + dict_table_is_comp(table)); if (fixed_size) { /* Fixed-size columns are stored locally. */ @@ -1382,7 +1382,7 @@ dict_index_too_big_for_tree( case in rec_get_converted_size_comp() for REC_STATUS_ORDINARY records. */ - field_max_size = dict_col_get_fixed_size(col); + field_max_size = dict_col_get_fixed_size(col, comp); if (field_max_size) { /* dict_index_add_col() should guarantee this */ ut_ad(!field->prefix_len @@ -1542,7 +1542,7 @@ too_big: if (field->prefix_len /* prefix index */ && !col->ord_part /* not yet ordering column */ - && !dict_col_get_fixed_size(col) /* variable-length */ + && !dict_col_get_fixed_size(col, TRUE) /* variable-length */ && dict_col_get_max_size(col) > BTR_EXTERN_FIELD_REF_SIZE * 2 /* long enough */) { @@ -1737,7 +1737,8 @@ dict_index_add_col( field = dict_index_get_nth_field(index, index->n_def - 1); field->col = col; - field->fixed_len = (unsigned int) dict_col_get_fixed_size(col); + field->fixed_len = (unsigned int) dict_col_get_fixed_size( + col, dict_table_is_comp(table)); if (prefix_len && field->fixed_len > prefix_len) { field->fixed_len = (unsigned int) prefix_len; @@ -1934,7 +1935,8 @@ dict_index_build_internal_clust( for (i = 0; i < trx_id_pos; i++) { fixed_size = dict_col_get_fixed_size( - dict_index_get_nth_col(new_index, i)); + dict_index_get_nth_col(new_index, i), + dict_table_is_comp(table)); if (fixed_size == 0) { new_index->trx_id_offset = 0; @@ -2447,8 +2449,7 @@ dict_foreign_error_report( fputs("The index in the foreign key in table is ", file); ut_print_name(file, NULL, FALSE, fk->foreign_index->name); fputs("\n" - "See http://dev.mysql.com/doc/refman/5.1/en/" - "innodb-foreign-key-constraints.html\n" + "See " REFMAN "innodb-foreign-key-constraints.html\n" "for correct foreign key definition.\n", file); } @@ -3368,8 +3369,7 @@ col_loop1: ut_print_name(ef, NULL, TRUE, name); fprintf(ef, " where the columns appear\n" "as the first columns. Constraint:\n%s\n" - "See http://dev.mysql.com/doc/refman/5.1/en/" - "innodb-foreign-key-constraints.html\n" + "See " REFMAN "innodb-foreign-key-constraints.html\n" "for correct foreign key definition.\n", start_of_latest_foreign); mutex_exit(&dict_foreign_err_mutex); @@ -3649,7 +3649,7 @@ try_find_index: " and such columns in old tables\n" "cannot be referenced by such columns" " in new tables.\n" - "See http://dev.mysql.com/doc/refman/5.1/en/" + "See " REFMAN "innodb-foreign-key-constraints.html\n" "for correct foreign key definition.\n", start_of_latest_foreign); @@ -4070,14 +4070,15 @@ dict_index_calc_min_rec_len( { ulint sum = 0; ulint i; + ulint comp = dict_table_is_comp(index->table); - if (dict_table_is_comp(index->table)) { + if (comp) { ulint nullable = 0; sum = REC_N_NEW_EXTRA_BYTES; for (i = 0; i < dict_index_get_n_fields(index); i++) { const dict_col_t* col = dict_index_get_nth_col(index, i); - ulint size = dict_col_get_fixed_size(col); + ulint size = dict_col_get_fixed_size(col, comp); sum += size; if (!size) { size = col->len; @@ -4096,7 +4097,7 @@ dict_index_calc_min_rec_len( for (i = 0; i < dict_index_get_n_fields(index); i++) { sum += dict_col_get_fixed_size( - dict_index_get_nth_col(index, i)); + dict_index_get_nth_col(index, i), comp); } if (sum > 127) { @@ -4132,8 +4133,7 @@ dict_update_statistics_low( " InnoDB: cannot calculate statistics for table %s\n" "InnoDB: because the .ibd file is missing. For help," " please refer to\n" - "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "innodb-troubleshooting.html\n", + "InnoDB: " REFMAN "innodb-troubleshooting.html\n", table->name); return; @@ -4255,7 +4255,7 @@ UNIV_INTERN void dict_table_print_by_name( /*=====================*/ - const char* name) + const char* name) /* in: table name */ { dict_table_t* table; @@ -4298,7 +4298,7 @@ dict_table_print_low( (ulong) UT_LIST_GET_LEN(table->indexes), (ulong) table->stat_n_rows); - for (i = 0; i + 1 < (ulint) table->n_cols; i++) { + for (i = 0; i < (ulint) table->n_cols; i++) { dict_col_print_low(table, dict_table_get_nth_col(table, i)); fputs("; ", stderr); } diff --git a/fil/fil0fil.c b/fil/fil0fil.c index f00f2e154ef..b7a291bb07e 100644 --- a/fil/fil0fil.c +++ b/fil/fil0fil.c @@ -185,8 +185,7 @@ struct fil_space_struct { tablespace whose size we do not know yet; last incomplete megabytes in data files may be ignored if space == 0 */ - ulint flags; /* in: compressed page size - and file format, or 0 */ + ulint flags; /* compressed page size and file format, or 0 */ ulint n_reserved_extents; /* number of reserved free extents for ongoing operations like B-tree page split */ @@ -1625,8 +1624,8 @@ fil_write_lsn_and_arch_no_to_file( ulint sum_of_sizes, /* in: combined size of previous files in space, in database pages */ ib_uint64_t lsn, /* in: lsn to write */ - ulint arch_log_no /* in: archived log number to write */ - __attribute__((unused))) + ulint arch_log_no __attribute__((unused))) + /* in: archived log number to write */ { byte* buf1; byte* buf; @@ -1870,6 +1869,8 @@ fil_op_write_log( MLOG_FILE_DELETE, or MLOG_FILE_RENAME */ ulint space_id, /* in: space id */ + ulint log_flags, /* in: redo log flags (stored + in the page number field) */ ulint flags, /* in: compressed page size and file format if type==MLOG_FILE_CREATE2, or 0 */ @@ -1893,8 +1894,8 @@ fil_op_write_log( return; } - log_ptr = mlog_write_initial_log_record_for_file_op(type, space_id, 0, - log_ptr, mtr); + log_ptr = mlog_write_initial_log_record_for_file_op( + type, space_id, log_flags, log_ptr, mtr); if (type == MLOG_FILE_CREATE2) { mach_write_to_4(log_ptr, flags); log_ptr += 4; @@ -1947,9 +1948,11 @@ fil_op_log_parse_or_replay( not fir completely between ptr and end_ptr */ byte* end_ptr, /* in: buffer end */ ulint type, /* in: the type of this log record */ - ulint space_id) /* in: the space id of the tablespace in + ulint space_id, /* in: the space id of the tablespace in question, or 0 if the log record should only be parsed but not replayed */ + ulint log_flags) /* in: redo log flags + (stored in the page number parameter) */ { ulint name_len; ulint new_name_len; @@ -2069,6 +2072,8 @@ fil_op_log_parse_or_replay( } else if (fil_get_space_id_for_table(name) != ULINT_UNDEFINED) { /* Do nothing */ + } else if (log_flags & MLOG_FILE_FLAG_TEMP) { + /* Temporary table, do nothing */ } else { /* Create the database directory for name, if it does not exist yet */ @@ -2232,7 +2237,7 @@ try_again: to write any log record */ mtr_start(&mtr); - fil_op_write_log(MLOG_FILE_DELETE, id, 0, path, NULL, &mtr); + fil_op_write_log(MLOG_FILE_DELETE, id, 0, 0, path, NULL, &mtr); mtr_commit(&mtr); #endif mem_free(path); @@ -2503,7 +2508,7 @@ retry: mtr_start(&mtr); - fil_op_write_log(MLOG_FILE_RENAME, id, 0, old_name, new_name, + fil_op_write_log(MLOG_FILE_RENAME, id, 0, 0, old_name, new_name, &mtr); mtr_commit(&mtr); } @@ -2707,7 +2712,9 @@ error_exit2: fil_op_write_log(flags ? MLOG_FILE_CREATE2 : MLOG_FILE_CREATE, - *space_id, flags, + *space_id, + is_temp ? MLOG_FILE_FLAG_TEMP : 0, + flags, tablename, NULL, &mtr); mtr_commit(&mtr); @@ -2945,8 +2952,7 @@ fil_open_single_table_tablespace( " a temporary table #sql...,\n" "InnoDB: and MySQL removed the .ibd file for this.\n" "InnoDB: Please refer to\n" - "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "innodb-troubleshooting.html\n" + "InnoDB: " REFMAN "innodb-troubleshooting.html\n" "InnoDB: for how to resolve the issue.\n", stderr); mem_free(filepath); @@ -2988,8 +2994,7 @@ fil_open_single_table_tablespace( "InnoDB: commands DISCARD TABLESPACE and" " IMPORT TABLESPACE?\n" "InnoDB: Please refer to\n" - "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "innodb-troubleshooting.html\n" + "InnoDB: " REFMAN "innodb-troubleshooting.html\n" "InnoDB: for how to resolve the issue.\n", (ulong) space_id, (ulong) space_flags, (ulong) id, (ulong) flags); @@ -3672,8 +3677,7 @@ fil_space_for_table_exists_in_mem( } error_exit: fputs("InnoDB: Please refer to\n" - "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "innodb-troubleshooting.html\n" + "InnoDB: " REFMAN "innodb-troubleshooting.html\n" "InnoDB: for how to resolve the issue.\n", stderr); mem_free(path); @@ -4685,17 +4689,25 @@ fil_addr_is_null( } /************************************************************************ -Accessor functions for a file page */ +Get the predecessor of a file page. */ UNIV_INTERN ulint -fil_page_get_prev(const byte* page) +fil_page_get_prev( +/*==============*/ + /* out: FIL_PAGE_PREV */ + const byte* page) /* in: file page */ { return(mach_read_from_4(page + FIL_PAGE_PREV)); } +/************************************************************************ +Get the successor of a file page. */ UNIV_INTERN ulint -fil_page_get_next(const byte* page) +fil_page_get_next( +/*==============*/ + /* out: FIL_PAGE_NEXT */ + const byte* page) /* in: file page */ { return(mach_read_from_4(page + FIL_PAGE_NEXT)); } @@ -4706,7 +4718,7 @@ UNIV_INTERN void fil_page_set_type( /*==============*/ - byte* page, /* in: file page */ + byte* page, /* in/out: file page */ ulint type) /* in: type */ { ut_ad(page); diff --git a/fsp/fsp0fsp.c b/fsp/fsp0fsp.c index 883b47b6a88..7d72f33d2b7 100644 --- a/fsp/fsp0fsp.c +++ b/fsp/fsp0fsp.c @@ -3240,8 +3240,7 @@ fseg_free_page_low( "InnoDB: database!\n", (ulong) page); crash: fputs("InnoDB: Please refer to\n" - "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "forcing-recovery.html\n" + "InnoDB: " REFMAN "forcing-recovery.html\n" "InnoDB: about forcing recovery.\n", stderr); ut_error; } diff --git a/handler/ha_innodb.cc b/handler/ha_innodb.cc index a9d0533bf66..1c3f09a1ee4 100644 --- a/handler/ha_innodb.cc +++ b/handler/ha_innodb.cc @@ -112,13 +112,7 @@ undefined. Map it to NULL. */ # define EQ_CURRENT_THD(thd) ((thd) == current_thd) #endif /* MYSQL_DYNAMIC_PLUGIN && __WIN__ */ -#ifdef MYSQL_DYNAMIC_PLUGIN -/* These must be weak global variables in the dynamic plugin. */ -struct handlerton* innodb_hton_ptr; -#else /* MYSQL_DYNAMIC_PLUGIN */ -/* This must be a global variable in the statically linked InnoDB. */ -struct handlerton* innodb_hton_ptr = NULL; -#endif /* MYSQL_DYNAMIC_PLUGIN */ +static struct handlerton* innodb_hton_ptr; static const long AUTOINC_OLD_STYLE_LOCKING = 0; static const long AUTOINC_NEW_STYLE_LOCKING = 1; @@ -129,6 +123,7 @@ static long innobase_mirrored_log_groups, innobase_log_files_in_group, innobase_additional_mem_pool_size, innobase_file_io_threads, innobase_force_recovery, innobase_open_files, innobase_autoinc_lock_mode; +static ulong innobase_commit_concurrency = 0; static long long innobase_buffer_pool_size, innobase_log_file_size; @@ -246,6 +241,39 @@ innobase_alter_table_flags( static const char innobase_hton_name[]= "InnoDB"; +/***************************************************************** +Check for a valid value of innobase_commit_concurrency. */ +static +int +innobase_commit_concurrency_validate( +/*=================================*/ + /* out: 0 for valid + innodb_commit_concurrency */ + 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 string */ +{ + long long intbuf; + ulong commit_concurrency; + + DBUG_ENTER("innobase_commit_concurrency_validate"); + + if (value->val_int(value, &intbuf)) { + /* The value is NULL. That is invalid. */ + DBUG_RETURN(1); + } + + *reinterpret_cast<ulong*>(save) = commit_concurrency + = static_cast<ulong>(intbuf); + + /* Allow the value to be updated, as long as it remains zero + or nonzero. */ + DBUG_RETURN(!(!commit_concurrency == !innobase_commit_concurrency)); +} + static MYSQL_THDVAR_BOOL(support_xa, PLUGIN_VAR_OPCMDARG, "Enable InnoDB support for the XA two-phase commit", /* check_func */ NULL, /* update_func */ NULL, @@ -356,7 +384,6 @@ static void innobase_drop_database( /*===================*/ - /* out: error number */ handlerton* hton, /* in: handlerton of Innodb */ char* path); /* in: database path; inside InnoDB the name of the last directory in the path is used as @@ -1089,19 +1116,22 @@ innobase_mysql_tmpfile(void) #endif /* defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN) */ /************************************************************************* -Wrapper around MySQL's copy_and_convert function, see it for -documentation. */ +Wrapper around MySQL's copy_and_convert function. */ extern "C" UNIV_INTERN ulint innobase_convert_string( /*====================*/ - void* to, - ulint to_length, - CHARSET_INFO* to_cs, - const void* from, - ulint from_length, - CHARSET_INFO* from_cs, - uint* errors) + /* out: number of bytes copied + to 'to' */ + void* to, /* out: converted string */ + ulint to_length, /* in: number of bytes reserved + for the converted string */ + CHARSET_INFO* to_cs, /* in: character set to convert to */ + const void* from, /* in: string to convert */ + ulint from_length, /* in: number of bytes to convert */ + CHARSET_INFO* from_cs, /* in: character set to convert from */ + uint* errors) /* out: number of errors encountered + during the conversion */ { return(copy_and_convert((char*)to, (uint32) to_length, to_cs, (const char*)from, (uint32) from_length, from_cs, @@ -2181,9 +2211,12 @@ error: Closes an InnoDB database. */ static int -innobase_end(handlerton *hton, ha_panic_function type) -/*==============*/ - /* out: TRUE if error */ +innobase_end( +/*=========*/ + /* out: TRUE if error */ + handlerton* hton, /* in/out: InnoDB handlerton */ + ha_panic_function type __attribute__((unused))) + /* in: ha_panic() parameter */ { int err= 0; @@ -2222,9 +2255,10 @@ Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes the logs, and the name of this function should be innobase_checkpoint. */ static bool -innobase_flush_logs(handlerton *hton) -/*=====================*/ +innobase_flush_logs( +/*================*/ /* out: TRUE if error */ + handlerton* hton) /* in/out: InnoDB handlerton */ { bool result = 0; @@ -2374,11 +2408,11 @@ innobase_commit( Note, the position is current because of prepare_commit_mutex */ retry: - if (srv_commit_concurrency > 0) { + if (innobase_commit_concurrency > 0) { pthread_mutex_lock(&commit_cond_m); commit_threads++; - if (commit_threads > srv_commit_concurrency) { + if (commit_threads > innobase_commit_concurrency) { commit_threads--; pthread_cond_wait(&commit_cond, &commit_cond_m); @@ -2400,7 +2434,7 @@ retry: innobase_commit_low(trx); trx->flush_log_later = FALSE; - if (srv_commit_concurrency > 0) { + if (innobase_commit_concurrency > 0) { pthread_mutex_lock(&commit_cond_m); commit_threads--; pthread_cond_signal(&commit_cond); @@ -2735,6 +2769,8 @@ Get the table flags to use for the statement. */ UNIV_INTERN handler::Table_flags ha_innobase::table_flags() const +/*============================*/ + /* out: table flags */ { /* Need to use tx_isolation here since table flags is (also) called before prebuilt is inited. */ @@ -2751,6 +2787,8 @@ static const char* ha_innobase_exts[] = { NullS }; +/******************************************************************** +Returns the table type (storage engine name). */ UNIV_INTERN const char* ha_innobase::table_type() const @@ -2760,15 +2798,20 @@ ha_innobase::table_type() const return(innobase_hton_name); } +/******************************************************************** +Returns the index type. */ UNIV_INTERN const char* -ha_innobase::index_type(uint) -/*=========================*/ +ha_innobase::index_type( +/*====================*/ + uint) /* out: index type */ { return("BTREE"); } +/******************************************************************** +Returns the table file name extension. */ UNIV_INTERN const char** ha_innobase::bas_ext() const @@ -2778,24 +2821,40 @@ ha_innobase::bas_ext() const return(ha_innobase_exts); } +/******************************************************************** +Returns the operations supported for indexes. */ UNIV_INTERN ulong -ha_innobase::index_flags(uint, uint, bool) const +ha_innobase::index_flags( +/*=====================*/ + /* out: flags of supported operations */ + uint, + uint, + bool) +const { return(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_READ_RANGE | HA_KEYREAD_ONLY); } +/******************************************************************** +Returns the maximum number of keys. */ UNIV_INTERN uint ha_innobase::max_supported_keys() const +/*===================================*/ + /* out: MAX_KEY */ { return(MAX_KEY); } +/******************************************************************** +Returns the maximum key length. */ UNIV_INTERN uint ha_innobase::max_supported_key_length() const +/*=========================================*/ + /* out: maximum supported key length, in bytes */ { /* An InnoDB page must store >= 2 keys; a secondary key record must also contain the primary key value: max key length is @@ -2805,23 +2864,32 @@ ha_innobase::max_supported_key_length() const return(3500); } +/******************************************************************** +Returns the key map of keys that are usable for scanning. */ UNIV_INTERN const key_map* ha_innobase::keys_to_use_for_scanning() + /* out: key_map_full */ { return(&key_map_full); } +/******************************************************************** +Determines if table caching is supported. */ UNIV_INTERN uint8 ha_innobase::table_cache_type() + /* out: HA_CACHE_TBL_ASKTRANSACT */ { return(HA_CACHE_TBL_ASKTRANSACT); } +/******************************************************************** +Determines if the primary key is clustered index. */ UNIV_INTERN bool ha_innobase::primary_key_is_clustered() + /* out: true */ { return(true); } @@ -2879,6 +2947,7 @@ UNIV_INTERN ulint ha_innobase::innobase_initialize_autoinc() /*======================================*/ + /* out: DB_SUCCESS or error code */ { dict_index_t* index; ulonglong auto_inc; @@ -3003,7 +3072,7 @@ retry: "or, the table contains indexes that this " "version of the engine\n" "doesn't support.\n" - "See http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n" + "See " REFMAN "innodb-troubleshooting.html\n" "how you can resolve the problem.\n", norm_name); free_share(share); @@ -3019,7 +3088,7 @@ retry: "Have you deleted the .ibd file from the " "database directory under\nthe MySQL datadir, " "or have you used DISCARD TABLESPACE?\n" - "See http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n" + "See " REFMAN "innodb-troubleshooting.html\n" "how you can resolve the problem.\n", norm_name); free_share(share); @@ -4745,6 +4814,7 @@ UNIV_INTERN int ha_innobase::index_end(void) /*========================*/ + /* out: 0 */ { int error = 0; DBUG_ENTER("index_end"); @@ -4797,7 +4867,6 @@ convert_search_mode_to_innobase( case HA_READ_MBR_WITHIN: case HA_READ_MBR_DISJOINT: case HA_READ_MBR_EQUAL: - my_error(ER_TABLE_CANT_HANDLE_SPKEYS, MYF(0)); return(PAGE_CUR_UNSUPP); /* do not use "default:" in order to produce a gcc warning: enumeration value '...' not handled in switch @@ -5089,8 +5158,8 @@ ha_innobase::change_active_index( /************************************************************************** Positions an index cursor to the index specified in keynr. Fetches the -row if any. */ -/* ??? This is only used to read whole keys ??? */ +row if any. +??? This is only used to read whole keys ??? */ UNIV_INTERN int ha_innobase::index_read_idx( @@ -6423,8 +6492,7 @@ static void innobase_drop_database( /*===================*/ - /* out: error number */ - handlerton *hton, /* in: handlerton of Innodb */ + handlerton *hton, /* in: handlerton of Innodb */ char* path) /* in: database path; inside InnoDB the name of the last directory in the path is used as the database name: for example, in 'mysql/data/test' @@ -6690,7 +6758,7 @@ ha_innobase::records_in_range( mode2); } else { - n_rows = 0; + n_rows = HA_POS_ERROR; } mem_heap_free(heap); @@ -7010,8 +7078,8 @@ ha_innobase::info( ".frm file. Have you mixed up " ".frm files from different " "installations? See " -"http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n", - + REFMAN + "innodb-troubleshooting.html\n", ib_table->name); break; } @@ -7023,7 +7091,7 @@ ha_innobase::info( "Index %s of %s has %lu columns unique inside InnoDB, but MySQL is asking " "statistics for %lu columns. Have you mixed up .frm files from different " "installations? " -"See http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n", +"See " REFMAN "innodb-troubleshooting.html\n", index->name, ib_table->name, (unsigned long) @@ -7404,7 +7472,7 @@ ha_innobase::get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list) f_key_info.referenced_key_name = thd_make_lex_string( thd, f_key_info.referenced_key_name, foreign->referenced_index->name, - strlen(foreign->referenced_index->name), 1); + (uint) strlen(foreign->referenced_index->name), 1); } else f_key_info.referenced_key_name= 0; @@ -7428,6 +7496,7 @@ UNIV_INTERN bool ha_innobase::can_switch_engines(void) /*=================================*/ + /* out: TRUE if can switch engines */ { bool can_switch; @@ -7861,8 +7930,8 @@ ha_innobase::transactional_table_lock( "InnoDB: Have you deleted the .ibd file" " from the database directory under\n" "InnoDB: the MySQL datadir?" - "InnoDB: See" - " http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n" + "InnoDB: See " REFMAN + "innodb-troubleshooting.html\n" "InnoDB: how you can resolve the problem.\n", prebuilt->table->name); DBUG_RETURN(HA_ERR_CRASHED); @@ -7926,15 +7995,13 @@ ha_innobase::transactional_table_lock( /**************************************************************************** Here we export InnoDB status variables to MySQL. */ static -int -innodb_export_status() -/*==================*/ +void +innodb_export_status(void) +/*======================*/ { if (innodb_inited) { srv_export_innodb_status(); } - - return(0); } /**************************************************************************** @@ -8017,7 +8084,7 @@ innodb_show_status( bool result = FALSE; - if (stat_print(thd, innobase_hton_name, strlen(innobase_hton_name), + if (stat_print(thd, innobase_hton_name, (uint) strlen(innobase_hton_name), STRING_WITH_LEN(""), str, flen)) { result= TRUE; } @@ -8048,7 +8115,7 @@ innodb_mutex_show_status( ulint rw_lock_count_os_yield= 0; ulonglong rw_lock_wait_time= 0; #endif /* UNIV_DEBUG */ - uint hton_name_len= strlen(innobase_hton_name), buf1len, buf2len; + uint hton_name_len= (uint) strlen(innobase_hton_name), buf1len, buf2len; DBUG_ENTER("innodb_mutex_show_status"); DBUG_ASSERT(hton == innodb_hton_ptr); @@ -8096,9 +8163,9 @@ innodb_mutex_show_status( rw_lock_wait_time += mutex->lspent_time; } #else /* UNIV_DEBUG */ - buf1len= my_snprintf(buf1, sizeof(buf1), "%s:%lu", + buf1len= (uint) my_snprintf(buf1, sizeof(buf1), "%s:%lu", mutex->cfile_name, (ulong) mutex->cline); - buf2len= my_snprintf(buf2, sizeof(buf2), "os_waits=%lu", + buf2len= (uint) my_snprintf(buf2, sizeof(buf2), "os_waits=%lu", mutex->count_os_wait); if (stat_print(thd, innobase_hton_name, @@ -8616,11 +8683,16 @@ ha_innobase::get_auto_increment( dict_table_autoinc_unlock(prebuilt->table); } -/* See comment in handler.h */ +/*********************************************************************** +Reset the auto-increment counter to the given value, i.e. the next row +inserted will get the given value. This is called e.g. after TRUNCATE +is emulated by doing a 'DELETE FROM t'. HA_ERR_WRONG_COMMAND is +returned by storage engines that don't support this operation. */ UNIV_INTERN int ha_innobase::reset_auto_increment( /*==============================*/ + /* out: 0 or error code */ ulonglong value) /* in: new value for table autoinc */ { DBUG_ENTER("ha_innobase::reset_auto_increment"); @@ -8656,7 +8728,7 @@ ha_innobase::get_error_message(int error, String *buf) { trx_t* trx = check_trx_exists(ha_thd()); - buf->copy(trx->detailed_error, strlen(trx->detailed_error), + buf->copy(trx->detailed_error, (uint) strlen(trx->detailed_error), system_charset_info); return(FALSE); @@ -9604,10 +9676,10 @@ static MYSQL_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size, "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.", NULL, NULL, 8*1024*1024L, 5*1024*1024L, LONGLONG_MAX, 1024*1024L); -static MYSQL_SYSVAR_ULONG(commit_concurrency, srv_commit_concurrency, +static MYSQL_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency, PLUGIN_VAR_RQCMDARG, "Helps in performance tuning in heavily concurrent environments.", - NULL, NULL, 0, 0, 1000, 0); + innobase_commit_concurrency_validate, NULL, 0, 0, 1000, 0); static MYSQL_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter, PLUGIN_VAR_RQCMDARG, diff --git a/handler/win_delay_loader.cc b/handler/win_delay_loader.cc index 8997e36d604..4a2d8f9b58c 100644 --- a/handler/win_delay_loader.cc +++ b/handler/win_delay_loader.cc @@ -90,14 +90,19 @@ absolute address (VA). This is due to the pointers in the delay descriptor (ImgDelayDescr in delayimp.h) have been changed from VAs to RVAs to work on both 32- and 64-bit platforms. */ template <class X> -X PFromRva(RVA rva) { +X PFromRva( +/*=======*/ + /* out: absolute virtual address */ + RVA rva) /* in: relative virtual address */ +{ return X(PBYTE(&__ImageBase) + rva); } /*********************************************************************** Convert to the old format for convenience. The structure as well as its element names follow the definition of ImgDelayDescr in delayimp.h. */ -struct InternalImgDelayDescr { +struct InternalImgDelayDescr +{ DWORD grAttrs; /* attributes */ LPCSTR szName; /* pointer to dll name */ HMODULE* phmod; /* address of module handle */ @@ -138,8 +143,7 @@ in the server: _db_return_ _db_dump_ -The plugin will get those function pointers during the initialization. -*/ +The plugin will get those function pointers during the initialization. */ typedef void (__cdecl* pfn_db_enter_)( const char* _func_, const char* _file_, @@ -352,7 +356,7 @@ wdl_load_mapfile( chain_header = map_cell; map_cell->symbol = strdup(func_name); - map_cell->value = (ulint) strtoull(tmp_buf, NULL, 0) + map_cell->value = (ulint) _strtoui64(tmp_buf, NULL, 0) - load_addr; map_fold = ut_fold_string(map_cell->symbol); diff --git a/ibuf/ibuf0ibuf.c b/ibuf/ibuf0ibuf.c index 0cf1b341130..6560dafe3ed 100644 --- a/ibuf/ibuf0ibuf.c +++ b/ibuf/ibuf0ibuf.c @@ -1534,8 +1534,10 @@ ibuf_rec_get_size( const rec_t* rec, /* in: ibuf record */ const byte* types, /* in: fields */ ulint n_fields, /* in: number of fields */ - ibool pre_4_1) /* in: TRUE=pre-4.1 format, + ibool pre_4_1, /* in: TRUE=pre-4.1 format, FALSE=newer */ + ulint comp) /* in: 0=ROW_FORMAT=REDUNDANT, + nonzero=ROW_FORMAT=COMPACT */ { ulint i; ulint field_offset; @@ -1561,11 +1563,11 @@ ibuf_rec_get_size( } else if (pre_4_1) { dtype_read_for_order_and_null_size(&dtype, types); - size += dtype_get_sql_null_size(&dtype); + size += dtype_get_sql_null_size(&dtype, comp); } else { dtype_new_read_for_order_and_null_size(&dtype, types); - size += dtype_get_sql_null_size(&dtype); + size += dtype_get_sql_null_size(&dtype, comp); } types += types_offset; @@ -1592,36 +1594,34 @@ ibuf_rec_get_volume( ulint n_fields; ulint data_size; ibool pre_4_1; + ulint comp; ut_ad(ibuf_inside()); ut_ad(rec_get_n_fields_old(ibuf_rec) > 2); data = rec_get_nth_field_old(ibuf_rec, 1, &len); + pre_4_1 = (len > 1); - if (len > 1) { + if (pre_4_1) { /* < 4.1.x format record */ ut_a(trx_doublewrite_must_reset_space_ids); ut_a(!trx_sys_multiple_tablespace_format); - pre_4_1 = TRUE; - n_fields = rec_get_n_fields_old(ibuf_rec) - 2; types = rec_get_nth_field_old(ibuf_rec, 1, &len); ut_ad(len == n_fields * DATA_ORDER_NULL_TYPE_BUF_SIZE); + comp = 0; } else { /* >= 4.1.x format record */ ibuf_op_t op; - ibool comp; ulint info_len; ut_a(trx_sys_multiple_tablespace_format); ut_a(*data == 0); - pre_4_1 = FALSE; - types = rec_get_nth_field_old(ibuf_rec, 3, &len); ibuf_rec_get_info(ibuf_rec, &op, &comp, &info_len, NULL); @@ -1655,7 +1655,7 @@ ibuf_rec_get_volume( n_fields = rec_get_n_fields_old(ibuf_rec) - 4; } - data_size = ibuf_rec_get_size(ibuf_rec, types, n_fields, pre_4_1); + data_size = ibuf_rec_get_size(ibuf_rec, types, n_fields, pre_4_1, comp); return(data_size + rec_get_converted_extra_size(data_size, n_fields, 0) + page_dir_calc_reserved_space(1)); @@ -2599,6 +2599,8 @@ ibuf_get_volume_buffered_hash( const rec_t* rec, /* in: ibuf record in post-4.1 format */ const byte* types, /* in: fields */ const byte* data, /* in: start of user record data */ + ulint comp, /* in: 0=ROW_FORMAT=REDUNDANT, + nonzero=ROW_FORMAT=COMPACT */ byte* hash, /* in/out: hash array */ ulint size) /* in: size of hash array, in bytes */ { @@ -2607,7 +2609,7 @@ ibuf_get_volume_buffered_hash( ulint bitmask; len = ibuf_rec_get_size(rec, types, rec_get_n_fields_old(rec) - 4, - FALSE); + FALSE, comp); fold = ut_fold_binary(data, len); hash += (fold / 8) % size; @@ -2668,7 +2670,7 @@ ibuf_get_volume_buffered_count( because deletes cannot be buffered if there are old-style inserts buffered for the page. */ - len = ibuf_rec_get_size(rec, types, n_fields, FALSE); + len = ibuf_rec_get_size(rec, types, n_fields, FALSE, 0); return(len + rec_get_converted_extra_size(len, n_fields, 0) @@ -2697,7 +2699,9 @@ ibuf_get_volume_buffered_count( See if this record has been already buffered. */ if (n_recs && ibuf_get_volume_buffered_hash( rec, types + IBUF_REC_INFO_SIZE, - types + len, hash, size)) { + types + len, + types[IBUF_REC_OFFSET_FLAGS] & IBUF_REC_COMPACT, + hash, size)) { (*n_recs)++; } @@ -3437,7 +3441,7 @@ bitmap_fail: if (err == DB_SUCCESS) { /* Update the page max trx id field */ page_update_max_trx_id(btr_cur_get_block(cursor), NULL, - thr_get_trx(thr)->id); + thr_get_trx(thr)->id, &mtr); } } else { ut_ad(mode == BTR_MODIFY_TREE); @@ -3457,7 +3461,7 @@ bitmap_fail: if (err == DB_SUCCESS) { /* Update the page max trx id field */ page_update_max_trx_id(btr_cur_get_block(cursor), NULL, - thr_get_trx(thr)->id); + thr_get_trx(thr)->id, &mtr); } ibuf_size_update(root, &mtr); @@ -4255,12 +4259,13 @@ loop: keep the latch to the rec page until the insertion is finished! */ dtuple_t* entry; - dulint max_trx_id; + trx_id_t max_trx_id; dict_index_t* dummy_index; ibuf_op_t op = ibuf_rec_get_op_type(rec); max_trx_id = page_get_max_trx_id(page_align(rec)); - page_update_max_trx_id(block, page_zip, max_trx_id); + page_update_max_trx_id(block, page_zip, max_trx_id, + &mtr); entry = ibuf_build_entry_from_ibuf_rec( rec, heap, &dummy_index); diff --git a/include/buf0buf.h b/include/buf0buf.h index bbe772777db..fb28b77b7a0 100644 --- a/include/buf0buf.h +++ b/include/buf0buf.h @@ -535,6 +535,7 @@ UNIV_INTERN ibool buf_validate(void); /*==============*/ + /* out: TRUE */ #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ #if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG /************************************************************************* @@ -571,6 +572,7 @@ UNIV_INTERN ulint buf_get_latched_pages_number(void); /*==============================*/ + /* out: number of latched pages */ #endif /* UNIV_DEBUG */ /************************************************************************* Returns the number of pending buf pool ios. */ @@ -578,6 +580,7 @@ UNIV_INTERN ulint buf_get_n_pending_ios(void); /*=======================*/ + /* out: number of pending I/O operations */ /************************************************************************* Prints info of the buffer i/o. */ UNIV_INTERN @@ -592,6 +595,7 @@ UNIV_INTERN ulint buf_get_modified_ratio_pct(void); /*============================*/ + /* out: modified page percentage ratio */ /************************************************************************** Refreshes the statistics used to print per-second averages. */ UNIV_INTERN @@ -599,11 +603,12 @@ void buf_refresh_io_stats(void); /*======================*/ /************************************************************************* -Checks that all file pages in the buffer are in a replaceable state. */ +Asserts that all file pages in the buffer are in a replaceable state. */ UNIV_INTERN ibool buf_all_freed(void); /*===============*/ + /* out: TRUE */ /************************************************************************* Checks that there currently are no pending i/o-operations for the buffer pool. */ @@ -1023,6 +1028,7 @@ UNIV_INTERN ulint buf_get_free_list_len(void); /*=======================*/ + /* out: length of the free list */ /******************************************************************** Stop watching if the marked page is read in. */ UNIV_INTERN diff --git a/include/buf0lru.h b/include/buf0lru.h index e73869580bd..79baa54923a 100644 --- a/include/buf0lru.h +++ b/include/buf0lru.h @@ -219,6 +219,7 @@ UNIV_INTERN ibool buf_LRU_validate(void); /*==================*/ + /* out: TRUE */ #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ #if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG /************************************************************************** diff --git a/include/data0data.h b/include/data0data.h index 1190a7ae45a..18e541e0eeb 100644 --- a/include/data0data.h +++ b/include/data0data.h @@ -277,7 +277,8 @@ ulint dtuple_get_data_size( /*=================*/ /* out: sum of data lens */ - const dtuple_t* tuple); /* in: typed data tuple */ + const dtuple_t* tuple, /* in: typed data tuple */ + ulint comp); /* in: nonzero=ROW_FORMAT=COMPACT */ /************************************************************************* Computes the number of externally stored fields in a data tuple. */ UNIV_INLINE diff --git a/include/data0data.ic b/include/data0data.ic index f11dbd9fce6..3308b0c5604 100644 --- a/include/data0data.ic +++ b/include/data0data.ic @@ -433,7 +433,8 @@ ulint dtuple_get_data_size( /*=================*/ /* out: sum of data lengths */ - const dtuple_t* tuple) /* in: typed data tuple */ + const dtuple_t* tuple, /* in: typed data tuple */ + ulint comp) /* in: nonzero=ROW_FORMAT=COMPACT */ { const dfield_t* field; ulint n_fields; @@ -452,7 +453,8 @@ dtuple_get_data_size( len = dfield_get_len(field); if (len == UNIV_SQL_NULL) { - len = dtype_get_sql_null_size(dfield_get_type(field)); + len = dtype_get_sql_null_size(dfield_get_type(field), + comp); } sum += len; diff --git a/include/data0type.h b/include/data0type.h index 27c809762d3..31e0d61ebc6 100644 --- a/include/data0type.h +++ b/include/data0type.h @@ -255,14 +255,16 @@ UNIV_INLINE ulint dtype_get_mtype( /*============*/ - const dtype_t* type); + /* out: SQL main data type */ + const dtype_t* type); /* in: data type */ /************************************************************************* Gets the precise data type. */ UNIV_INLINE ulint dtype_get_prtype( /*=============*/ - const dtype_t* type); + /* out: precise data type */ + const dtype_t* type); /* in: data type */ #ifndef UNIV_HOTBACKUP /************************************************************************* Compute the mbminlen and mbmaxlen members of a data type structure. */ @@ -310,7 +312,9 @@ UNIV_INLINE ulint dtype_get_len( /*==========*/ - const dtype_t* type); + /* out: fixed length of the type, in bytes, + or 0 if variable-length */ + const dtype_t* type); /* in: data type */ #ifndef UNIV_HOTBACKUP /************************************************************************* Gets the minimum length of a character, in bytes. */ @@ -352,7 +356,8 @@ dtype_get_fixed_size_low( ulint prtype, /* in: precise type */ ulint len, /* in: length */ ulint mbminlen, /* in: minimum length of a multibyte char */ - ulint mbmaxlen); /* in: maximum length of a multibyte char */ + ulint mbmaxlen, /* in: maximum length of a multibyte char */ + ulint comp); /* in: nonzero=ROW_FORMAT=COMPACT */ #ifndef UNIV_HOTBACKUP /*************************************************************************** Returns the minimum size of a data type. */ @@ -386,7 +391,8 @@ dtype_get_sql_null_size( /*====================*/ /* out: SQL null storage size in ROW_FORMAT=REDUNDANT */ - const dtype_t* type); /* in: type */ + const dtype_t* type, /* in: type */ + ulint comp); /* in: nonzero=ROW_FORMAT=COMPACT */ #ifndef UNIV_HOTBACKUP /************************************************************************** Reads to a type the stored information which determines its alphabetical diff --git a/include/data0type.ic b/include/data0type.ic index c1b4269bbec..dad2943d1bc 100644 --- a/include/data0type.ic +++ b/include/data0type.ic @@ -161,7 +161,8 @@ UNIV_INLINE ulint dtype_get_mtype( /*============*/ - const dtype_t* type) + /* out: SQL main data type */ + const dtype_t* type) /* in: data type */ { ut_ad(type); @@ -174,7 +175,8 @@ UNIV_INLINE ulint dtype_get_prtype( /*=============*/ - const dtype_t* type) + /* out: precise data type */ + const dtype_t* type) /* in: data type */ { ut_ad(type); @@ -187,7 +189,9 @@ UNIV_INLINE ulint dtype_get_len( /*==========*/ - const dtype_t* type) + /* out: fixed length of the type, in bytes, + or 0 if variable-length */ + const dtype_t* type) /* in: data type */ { ut_ad(type); @@ -398,7 +402,8 @@ dtype_get_fixed_size_low( ulint prtype, /* in: precise type */ ulint len, /* in: length */ ulint mbminlen, /* in: minimum length of a multibyte char */ - ulint mbmaxlen) /* in: maximum length of a multibyte char */ + ulint mbmaxlen, /* in: maximum length of a multibyte char */ + ulint comp) /* in: nonzero=ROW_FORMAT=COMPACT */ { switch (mtype) { case DATA_SYS: @@ -428,6 +433,8 @@ dtype_get_fixed_size_low( #ifndef UNIV_HOTBACKUP if (prtype & DATA_BINARY_TYPE) { return(len); + } else if (!comp) { + return(len); } else { /* We play it safe here and ask MySQL for mbminlen and mbmaxlen. Although @@ -581,13 +588,14 @@ dtype_get_sql_null_size( /*====================*/ /* out: SQL null storage size in ROW_FORMAT=REDUNDANT */ - const dtype_t* type) /* in: type */ + const dtype_t* type, /* in: type */ + ulint comp) /* in: nonzero=ROW_FORMAT=COMPACT */ { #ifndef UNIV_HOTBACKUP return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len, - type->mbminlen, type->mbmaxlen)); + type->mbminlen, type->mbmaxlen, comp)); #else /* !UNIV_HOTBACKUP */ return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len, - 0, 0)); + 0, 0, 0)); #endif /* !UNIV_HOTBACKUP */ } diff --git a/include/dict0dict.h b/include/dict0dict.h index 93ab3793665..7d1b7df9901 100644 --- a/include/dict0dict.h +++ b/include/dict0dict.h @@ -144,7 +144,8 @@ ulint dict_col_get_fixed_size( /*====================*/ /* out: fixed size, or 0 */ - const dict_col_t* col); /* in: column */ + const dict_col_t* col, /* in: column */ + ulint comp); /* in: nonzero=ROW_FORMAT=COMPACT */ /*************************************************************************** Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column. For fixed length types it is the fixed length of the type, otherwise 0. */ @@ -154,7 +155,8 @@ dict_col_get_sql_null_size( /*=======================*/ /* out: SQL null storage size in ROW_FORMAT=REDUNDANT */ - const dict_col_t* col); /* in: column */ + const dict_col_t* col, /* in: column */ + ulint comp); /* in: nonzero=ROW_FORMAT=COMPACT */ /************************************************************************* Gets the column number. */ @@ -162,7 +164,9 @@ UNIV_INLINE ulint dict_col_get_no( /*============*/ - const dict_col_t* col); + /* out: col->ind, table column + position (starting from 0) */ + const dict_col_t* col); /* in: column */ /************************************************************************* Gets the column position in the clustered index. */ UNIV_INLINE @@ -436,8 +440,8 @@ dict_foreign_find_equiv_index( foreign->foreign_index, or NULL */ dict_foreign_t* foreign);/* in: foreign key */ /************************************************************************** -Returns an index object by matching on the name and column names and if -more than index is found return the index with the higher id.*/ +Returns an index object by matching on the name and column names and +if more than one index matches return the index with the max id */ UNIV_INTERN dict_index_t* dict_table_get_index_by_max_id( @@ -480,7 +484,7 @@ UNIV_INTERN void dict_table_print_by_name( /*=====================*/ - const char* name); + const char* name); /* in: table name */ /************************************************************************** Outputs info on foreign keys of a table. */ UNIV_INTERN @@ -566,6 +570,16 @@ dict_index_is_ibuf( zero for other indexes */ const dict_index_t* index) /* in: index */ __attribute__((pure)); +/************************************************************************ +Check whether the index is a secondary index or the insert buffer tree. */ +UNIV_INLINE +ulint +dict_index_is_sec_or_ibuf( +/*======================*/ + /* out: nonzero for insert buffer, + zero for other indexes */ + const dict_index_t* index) /* in: index */ + __attribute__((pure)); /************************************************************************ Gets the number of user-defined columns in a table in the dictionary @@ -903,7 +917,9 @@ UNIV_INLINE const dict_col_t* dict_field_get_col( /*===============*/ - const dict_field_t* field); + /* out: field->col, + pointer to the table column */ + const dict_field_t* field); /* in: index field */ #ifndef UNIV_HOTBACKUP /************************************************************************** Returns an index object if it is found in the dictionary cache. diff --git a/include/dict0dict.ic b/include/dict0dict.ic index 982f0535fd0..51939642fac 100644 --- a/include/dict0dict.ic +++ b/include/dict0dict.ic @@ -104,10 +104,11 @@ ulint dict_col_get_fixed_size( /*====================*/ /* out: fixed size, or 0 */ - const dict_col_t* col) /* in: column */ + const dict_col_t* col, /* in: column */ + ulint comp) /* in: nonzero=ROW_FORMAT=COMPACT */ { return(dtype_get_fixed_size_low(col->mtype, col->prtype, col->len, - col->mbminlen, col->mbmaxlen)); + col->mbminlen, col->mbmaxlen, comp)); } /*************************************************************************** Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column. @@ -118,9 +119,10 @@ dict_col_get_sql_null_size( /*=======================*/ /* out: SQL null storage size in ROW_FORMAT=REDUNDANT */ - const dict_col_t* col) /* in: column */ + const dict_col_t* col, /* in: column */ + ulint comp) /* in: nonzero=ROW_FORMAT=COMPACT */ { - return(dict_col_get_fixed_size(col)); + return(dict_col_get_fixed_size(col, comp)); } /************************************************************************* @@ -129,7 +131,9 @@ UNIV_INLINE ulint dict_col_get_no( /*============*/ - const dict_col_t* col) + /* out: col->ind, table column + position (starting from 0) */ + const dict_col_t* col) /* in: column */ { ut_ad(col); @@ -243,6 +247,26 @@ dict_index_is_ibuf( return(UNIV_UNLIKELY(index->type & DICT_IBUF)); } +/************************************************************************ +Check whether the index is a secondary index or the insert buffer tree. */ +UNIV_INLINE +ulint +dict_index_is_sec_or_ibuf( +/*======================*/ + /* out: nonzero for insert buffer, + zero for other indexes */ + const dict_index_t* index) /* in: index */ +{ + ulint type; + + ut_ad(index); + ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); + + type = index->type; + + return(UNIV_LIKELY(!(type & DICT_CLUSTERED) || (type & DICT_IBUF))); +} + /************************************************************************ Gets the number of user-defined columns in a table in the dictionary cache. */ @@ -568,7 +592,9 @@ UNIV_INLINE const dict_col_t* dict_field_get_col( /*===============*/ - const dict_field_t* field) + /* out: field->col, + pointer to the table column */ + const dict_field_t* field) /* in: index field */ { ut_ad(field); diff --git a/include/dict0mem.h b/include/dict0mem.h index e6dea25da20..eaa9edea90a 100644 --- a/include/dict0mem.h +++ b/include/dict0mem.h @@ -402,7 +402,7 @@ struct dict_table_struct{ on the table: we cannot drop the table while there are foreign key checks running on it! */ - dulint query_cache_inv_trx_id; + trx_id_t query_cache_inv_trx_id; /* transactions whose trx id < than this number are not allowed to store to the MySQL query cache or retrieve from it; when a trx diff --git a/include/fil0fil.h b/include/fil0fil.h index 67fb3301d68..adc49afddaf 100644 --- a/include/fil0fil.h +++ b/include/fil0fil.h @@ -365,9 +365,11 @@ fil_op_log_parse_or_replay( not fir completely between ptr and end_ptr */ byte* end_ptr, /* in: buffer end */ ulint type, /* in: the type of this log record */ - ulint space_id); /* in: the space id of the tablespace in + ulint space_id, /* in: the space id of the tablespace in question, or 0 if the log record should only be parsed but not replayed */ + ulint log_flags); /* in: redo log flags + (stored in the page number parameter) */ /*********************************************************************** Deletes a single-table tablespace. The tablespace must be cached in the memory cache. */ @@ -682,19 +684,28 @@ fil_addr_is_null( /* out: TRUE if undefined */ fil_addr_t addr); /* in: address */ /************************************************************************ -Accessor functions for a file page */ +Get the predecessor of a file page. */ UNIV_INTERN ulint -fil_page_get_prev(const byte* page); +fil_page_get_prev( +/*==============*/ + /* out: FIL_PAGE_PREV */ + const byte* page); /* in: file page */ +/************************************************************************ +Get the successor of a file page. */ +UNIV_INTERN ulint -fil_page_get_next(const byte* page); +fil_page_get_next( +/*==============*/ + /* out: FIL_PAGE_NEXT */ + const byte* page); /* in: file page */ /************************************************************************* Sets the file page type. */ UNIV_INTERN void fil_page_set_type( /*==============*/ - byte* page, /* in: file page */ + byte* page, /* in/out: file page */ ulint type); /* in: type */ /************************************************************************* Gets the file page type. */ diff --git a/include/ha_prototypes.h b/include/ha_prototypes.h index ac5a640e662..12ba88daaec 100644 --- a/include/ha_prototypes.h +++ b/include/ha_prototypes.h @@ -26,19 +26,22 @@ Place, Suite 330, Boston, MA 02111-1307 USA InnoDB's C-code. */ /************************************************************************* -Wrapper around MySQL's copy_and_convert function, see it for -documentation. */ +Wrapper around MySQL's copy_and_convert function. */ UNIV_INTERN ulint innobase_convert_string( /*====================*/ - void* to, - ulint to_length, - CHARSET_INFO* to_cs, - const void* from, - ulint from_length, - CHARSET_INFO* from_cs, - uint* errors); + /* out: number of bytes copied + to 'to' */ + void* to, /* out: converted string */ + ulint to_length, /* in: number of bytes reserved + for the converted string */ + CHARSET_INFO* to_cs, /* in: character set to convert to */ + const void* from, /* in: string to convert */ + ulint from_length, /* in: number of bytes to convert */ + CHARSET_INFO* from_cs, /* in: character set to convert from */ + uint* errors); /* out: number of errors encountered + during the conversion */ /*********************************************************************** Formats the raw data in "data" (in InnoDB on-disk format) that is of diff --git a/include/lock0lock.h b/include/lock0lock.h index 2deeb804737..2de8708fdc9 100644 --- a/include/lock0lock.h +++ b/include/lock0lock.h @@ -28,6 +28,7 @@ Created 5/7/1996 Heikki Tuuri #include "univ.i" #include "buf0types.h" #include "trx0types.h" +#include "mtr0types.h" #include "rem0types.h" #include "dict0types.h" #include "que0types.h" @@ -288,10 +289,11 @@ lock_rec_insert_check_and_lock( DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, does nothing */ - rec_t* rec, /* in: record after which to insert */ + const rec_t* rec, /* in: record after which to insert */ buf_block_t* block, /* in/out: buffer block of rec */ dict_index_t* index, /* in: index */ que_thr_t* thr, /* in: query thread */ + mtr_t* mtr, /* in/out: mini-transaction */ ibool* inherit);/* out: set to TRUE if the new inserted record maybe should inherit LOCK_GAP type locks from the successor @@ -330,13 +332,14 @@ lock_sec_rec_modify_check_and_lock( ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, does nothing */ buf_block_t* block, /* in/out: buffer block of rec */ - rec_t* rec, /* in: record which should be + const rec_t* rec, /* in: record which should be modified; NOTE: as this is a secondary index, we always have to modify the clustered index record first: see the comment below */ dict_index_t* index, /* in: secondary index */ - que_thr_t* thr); /* in: query thread */ + que_thr_t* thr, /* in: query thread */ + mtr_t* mtr); /* in/out: mini-transaction */ /************************************************************************* Like the counterpart for a clustered index below, but now we read a secondary index record. */ @@ -617,7 +620,7 @@ ibool lock_check_trx_id_sanity( /*=====================*/ /* out: TRUE if ok */ - dulint trx_id, /* in: trx id */ + trx_id_t trx_id, /* in: trx id */ const rec_t* rec, /* in: user record */ dict_index_t* index, /* in: clustered index */ const ulint* offsets, /* in: rec_get_offsets(rec, index) */ diff --git a/include/lock0lock.ic b/include/lock0lock.ic index f978cc70678..56fea346eb3 100644 --- a/include/lock0lock.ic +++ b/include/lock0lock.ic @@ -79,7 +79,7 @@ lock_clust_rec_some_has_impl( dict_index_t* index, /* in: clustered index */ const ulint* offsets)/* in: rec_get_offsets(rec, index) */ { - dulint trx_id; + trx_id_t trx_id; ut_ad(mutex_own(&kernel_mutex)); ut_ad(dict_index_is_clust(index)); diff --git a/include/log0recv.h b/include/log0recv.h index 505e7aef918..adbbd7bdc62 100644 --- a/include/log0recv.h +++ b/include/log0recv.h @@ -77,6 +77,7 @@ UNIV_INLINE ibool recv_recovery_is_on(void); /*=====================*/ + /* out: recv_recovery_on */ #ifdef UNIV_LOG_ARCHIVE /*********************************************************************** Returns TRUE if recovery from backup is currently running. */ @@ -84,6 +85,7 @@ UNIV_INLINE ibool recv_recovery_from_backup_is_on(void); /*=================================*/ + /* out: recv_recovery_from_backup_on */ #endif /* UNIV_LOG_ARCHIVE */ /**************************************************************************** Applies the hashed log records to the page, if the page lsn is less than the diff --git a/include/log0recv.ic b/include/log0recv.ic index 4e6863b4730..2d570eab3db 100644 --- a/include/log0recv.ic +++ b/include/log0recv.ic @@ -30,6 +30,7 @@ UNIV_INLINE ibool recv_recovery_is_on(void) /*=====================*/ + /* out: recv_recovery_on */ { return(UNIV_UNLIKELY(recv_recovery_on)); } @@ -43,6 +44,7 @@ UNIV_INLINE ibool recv_recovery_from_backup_is_on(void) /*=================================*/ + /* out: recv_recovery_from_backup_on */ { return(recv_recovery_from_backup_on); } diff --git a/include/mem0mem.h b/include/mem0mem.h index f5e395cb1c1..10d574d446d 100644 --- a/include/mem0mem.h +++ b/include/mem0mem.h @@ -250,8 +250,7 @@ mem_free_func( /*==========*/ void* ptr, /* in, own: buffer to be freed */ const char* file_name, /* in: file name where created */ - ulint line /* in: line where created */ -); + ulint line); /* in: line where created */ /************************************************************************** Duplicates a NUL-terminated string. */ diff --git a/include/mem0mem.ic b/include/mem0mem.ic index 33fbdc4f139..03542d3d6f2 100644 --- a/include/mem0mem.ic +++ b/include/mem0mem.ic @@ -565,8 +565,7 @@ mem_free_func( /*==========*/ void* ptr, /* in, own: buffer to be freed */ const char* file_name, /* in: file name where created */ - ulint line /* in: line where created */ - ) + ulint line) /* in: line where created */ { mem_heap_t* heap; diff --git a/include/mtr0log.h b/include/mtr0log.h index bc7bde3541f..0bcb5bb80ea 100644 --- a/include/mtr0log.h +++ b/include/mtr0log.h @@ -237,8 +237,7 @@ mlog_parse_index( /* out: parsed record end, NULL if not a complete record */ byte* ptr, /* in: buffer */ - byte* end_ptr,/* in: buffer end */ - /* out: new value of log_ptr */ + const byte* end_ptr,/* in: buffer end */ ibool comp, /* in: TRUE=compact record format */ dict_index_t** index); /* out, own: dummy index */ diff --git a/include/mtr0mtr.h b/include/mtr0mtr.h index c92a89a3d83..3d98f957960 100644 --- a/include/mtr0mtr.h +++ b/include/mtr0mtr.h @@ -160,6 +160,12 @@ flag value must give the length also! */ #define MLOG_BIGGEST_TYPE ((byte)51) /* biggest value (used in asserts) */ +/* Flags for MLOG_FILE operations (stored in the page number +parameter, called log_flags in the functions). The page number +parameter was initially written as 0. */ +#define MLOG_FILE_FLAG_TEMP 1 /* identifies TEMPORARY TABLE in + MLOG_FILE_CREATE, MLOG_FILE_CREATE2 */ + /******************************************************************* Starts a mini-transaction and creates a mini-transaction handle and buffer in the memory buffer given by the caller. */ diff --git a/include/os0file.h b/include/os0file.h index 6623c58e9fe..1e7381d3afc 100644 --- a/include/os0file.h +++ b/include/os0file.h @@ -610,11 +610,14 @@ os_aio( ulint offset_high, /* in: most significant 32 bits of offset */ ulint n, /* in: number of bytes to read or write */ - fil_node_t* message1,/* in: messages for the aio handler (these - can be used to identify a completed aio - operation); if mode is OS_AIO_SYNC, these - are ignored */ - void* message2); + fil_node_t* message1,/* in: message for the aio handler + (can be used to identify a completed + aio operation); ignored if mode is + OS_AIO_SYNC */ + void* message2);/* in: message for the aio handler + (can be used to identify a completed + aio operation); ignored if mode is + OS_AIO_SYNC */ /**************************************************************************** Wakes up all async i/o threads so that they know to exit themselves in shutdown. */ diff --git a/include/os0proc.h b/include/os0proc.h index 19b0b112638..e4a353999fa 100644 --- a/include/os0proc.h +++ b/include/os0proc.h @@ -49,6 +49,7 @@ UNIV_INTERN ulint os_proc_get_number(void); /*====================*/ + /* out: process id as a number */ /******************************************************************** Allocates large pages memory. */ UNIV_INTERN diff --git a/include/os0sync.h b/include/os0sync.h index 7e058266762..771d8938c8b 100644 --- a/include/os0sync.h +++ b/include/os0sync.h @@ -285,21 +285,101 @@ os_fast_mutex_free( /*===============*/ os_fast_mutex_t* fast_mutex); /* in: mutex to free */ +/************************************************************** +Atomic compare-and-swap and increment for InnoDB. */ + #ifdef HAVE_GCC_ATOMIC_BUILTINS /************************************************************** -Atomic compare-and-swap for InnoDB. Currently requires GCC atomic builtins. Returns true if swapped, ptr is pointer to target, old_val is value to compare to, new_val is the value to swap in. */ -#define os_compare_and_swap(ptr, old_val, new_val) \ +# define os_compare_and_swap(ptr, old_val, new_val) \ __sync_bool_compare_and_swap(ptr, old_val, new_val) - +# define os_compare_and_swap_ulint(ptr, old_val, new_val) \ + os_compare_and_swap(ptr, old_val, new_val) +# define os_compare_and_swap_lint(ptr, old_val, new_val) \ + os_compare_and_swap(ptr, old_val, new_val) +# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \ + os_compare_and_swap(ptr, old_val, new_val) /************************************************************** -Atomic increment for InnoDB. Currently requires GCC atomic builtins. Returns the resulting value, ptr is pointer to target, amount is the amount of increment. */ -#define os_atomic_increment(ptr, amount) \ +# define os_atomic_increment(ptr, amount) \ __sync_add_and_fetch(ptr, amount) +# define os_atomic_increment_lint(ptr, amount) \ + os_atomic_increment(ptr, amount) +# define os_atomic_increment_ulint(ptr, amount) \ + os_atomic_increment(ptr, amount) +/************************************************************** +Returns the old value of *ptr, atomically sets *ptr to new_val */ +# define os_atomic_test_and_set_byte(ptr, new_val) \ + __sync_lock_test_and_set(ptr, new_val) +/* If not compiling with GCC or GCC doesn't support the atomic +intrinsics and running on Solaris >= 10 use Solaris atomics */ +#elif defined(HAVE_SOLARIS_ATOMICS) +#include <atomic.h> +/************************************************************** +Returns true if swapped, ptr is pointer to target, old_val is value to +compare to, new_val is the value to swap in. */ +# define os_compare_and_swap_ulint(ptr, old_val, new_val) \ + (atomic_cas_ulong(ptr, old_val, new_val) == old_val) +# define os_compare_and_swap_lint(ptr, old_val, new_val) \ + ((lint)atomic_cas_ulong((ulong_t*) ptr, old_val, new_val) == old_val) +# ifdef INNODB_RW_LOCKS_USE_ATOMICS +# if SIZEOF_PTHREAD_T == 4 +# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \ + ((pthread_t)atomic_cas_32(ptr, old_val, new_val) == old_val) +# elif SIZEOF_PTHREAD_T == 8 +# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \ + ((pthread_t)atomic_cas_64(ptr, old_val, new_val) == old_val) +# else +# error "SIZEOF_PTHREAD_T != 4 or 8" +# endif /* SIZEOF_PTHREAD_T CHECK */ +# endif /* INNODB_RW_LOCKS_USE_ATOMICS */ +/************************************************************** +Returns the resulting value, ptr is pointer to target, amount is the +amount of increment. */ +# define os_atomic_increment_lint(ptr, amount) \ + atomic_add_long_nv((ulong_t*) ptr, amount) +# define os_atomic_increment_ulint(ptr, amount) \ + atomic_add_long_nv(ptr, amount) +/************************************************************** +Returns the old value of *ptr, atomically sets *ptr to new_val */ +# define os_atomic_test_and_set_byte(ptr, new_val) \ + atomic_swap_uchar(ptr, new_val) +/* On Windows, use Windows atomics / interlocked */ +#elif defined(HAVE_WINDOWS_ATOMICS) +# ifdef _WIN64 +# define win_cmp_and_xchg InterlockedCompareExchange64 +# define win_xchg_and_add InterlockedExchangeAdd64 +# else /* _WIN64 */ +# define win_cmp_and_xchg InterlockedCompareExchange +# define win_xchg_and_add InterlockedExchangeAdd +# endif +/************************************************************** +Returns true if swapped, ptr is pointer to target, old_val is value to +compare to, new_val is the value to swap in. */ +# define os_compare_and_swap_ulint(ptr, old_val, new_val) \ + (win_cmp_and_xchg(ptr, new_val, old_val) == old_val) +# define os_compare_and_swap_lint(ptr, old_val, new_val) \ + (win_cmp_and_xchg(ptr, new_val, old_val) == old_val) +# ifdef INNODB_RW_LOCKS_USE_ATOMICS +# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \ + (InterlockedCompareExchange(ptr, new_val, old_val) == old_val) +# endif /* INNODB_RW_LOCKS_USE_ATOMICS */ +/************************************************************** +Returns the resulting value, ptr is pointer to target, amount is the +amount of increment. */ +# define os_atomic_increment_lint(ptr, amount) \ + (win_xchg_and_add(ptr, amount) + amount) +# define os_atomic_increment_ulint(ptr, amount) \ + ((ulint) (win_xchg_and_add(ptr, amount) + amount)) +/************************************************************** +Returns the old value of *ptr, atomically sets *ptr to new_val. +InterlockedExchange() operates on LONG, and the LONG will be +clobbered */ +# define os_atomic_test_and_set_byte(ptr, new_val) \ + ((byte) InterlockedExchange(ptr, new_val)) #endif /* HAVE_GCC_ATOMIC_BUILTINS */ #ifndef UNIV_NONINL diff --git a/include/os0thread.h b/include/os0thread.h index 863596bfa84..915b8ede99f 100644 --- a/include/os0thread.h +++ b/include/os0thread.h @@ -71,8 +71,8 @@ UNIV_INTERN ulint os_thread_pf( /*=========*/ - /* out: unsigned long int */ - os_thread_id_t a); /* in: thread or thread id */ + /* out: thread identifier as a number */ + os_thread_id_t a); /* in: OS thread identifier */ /******************************************************************** Creates a new thread of execution. The execution starts from the function given. The start function takes a void* parameter @@ -109,12 +109,14 @@ UNIV_INTERN os_thread_id_t os_thread_get_curr_id(void); /*========================*/ + /* out: current thread identifier */ /********************************************************************* Returns handle to the current thread. */ UNIV_INTERN os_thread_t os_thread_get_curr(void); /*====================*/ + /* out: current thread handle */ /********************************************************************* Advises the os to give up remainder of the thread's time slice. */ UNIV_INTERN @@ -150,6 +152,7 @@ UNIV_INTERN ulint os_thread_get_last_error(void); /*==========================*/ + /* out: last error on Windows, 0 otherwise */ #ifndef UNIV_NONINL #include "os0thread.ic" diff --git a/include/page0page.h b/include/page0page.h index 8a6844a0d47..c76cc89b128 100644 --- a/include/page0page.h +++ b/include/page0page.h @@ -66,8 +66,8 @@ typedef byte page_header_t; #define PAGE_N_RECS 16 /* number of user records on the page */ #define PAGE_MAX_TRX_ID 18 /* highest id of a trx which may have modified a record on the page; a dulint; defined only - in secondary indexes; specifically, not in an - ibuf tree; NOTE: this may be modified only + in secondary indexes and in the insert buffer + tree; NOTE: this may be modified only when the thread has an x-latch to the page, and ALSO an x-latch to btr_search_latch if there is a hash index to the page! */ @@ -177,7 +177,7 @@ page_offset( /***************************************************************** Returns the max trx id field value. */ UNIV_INLINE -dulint +trx_id_t page_get_max_trx_id( /*================*/ const page_t* page); /* in: page */ @@ -189,7 +189,8 @@ page_set_max_trx_id( /*================*/ buf_block_t* block, /* in/out: page */ page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */ - dulint trx_id);/* in: transaction id */ + trx_id_t trx_id, /* in: transaction id */ + mtr_t* mtr); /* in/out: mini-transaction, or NULL */ /***************************************************************** Sets the max trx id field value if trx_id is bigger than the previous value. */ @@ -200,7 +201,8 @@ page_update_max_trx_id( buf_block_t* block, /* in/out: page */ page_zip_des_t* page_zip,/* in/out: compressed page whose uncompressed part will be updated, or NULL */ - dulint trx_id);/* in: transaction id */ + trx_id_t trx_id, /* in: transaction id */ + mtr_t* mtr); /* in/out: mini-transaction */ /***************************************************************** Reads the given header field. */ UNIV_INLINE @@ -937,7 +939,7 @@ UNIV_INTERN void page_header_print( /*==============*/ - const page_t* page); + const page_t* page); /* in: index page */ /******************************************************************* This is used to print the contents of the page for debugging purposes. */ diff --git a/include/page0page.ic b/include/page0page.ic index 133861e9d69..10127dc90e0 100644 --- a/include/page0page.ic +++ b/include/page0page.ic @@ -23,6 +23,9 @@ Created 2/2/1994 Heikki Tuuri *******************************************************/ #include "mach0data.h" +#ifdef UNIV_DEBUG +# include "log0recv.h" +#endif /* !UNIV_DEBUG */ #ifndef UNIV_HOTBACKUP # include "rem0cmp.h" #endif /* !UNIV_HOTBACKUP */ @@ -59,7 +62,7 @@ page_offset( /***************************************************************** Returns the max trx id field value. */ UNIV_INLINE -dulint +trx_id_t page_get_max_trx_id( /*================*/ const page_t* page) /* in: page */ @@ -79,14 +82,24 @@ page_update_max_trx_id( buf_block_t* block, /* in/out: page */ page_zip_des_t* page_zip,/* in/out: compressed page whose uncompressed part will be updated, or NULL */ - dulint trx_id) /* in: transaction id */ + trx_id_t trx_id, /* in: transaction id */ + mtr_t* mtr) /* in/out: mini-transaction */ { ut_ad(block); + ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); + /* During crash recovery, this function may be called on + something else than a leaf page of a secondary index or the + insert buffer index tree (dict_index_is_sec_or_ibuf() returns + TRUE for the dummy indexes constructed during redo log + application). In that case, PAGE_MAX_TRX_ID is unused, + and trx_id is usually zero. */ + ut_ad(!ut_dulint_is_zero(trx_id) || recv_recovery_is_on()); + ut_ad(page_is_leaf(buf_block_get_frame(block))); if (ut_dulint_cmp(page_get_max_trx_id(buf_block_get_frame(block)), trx_id) < 0) { - page_set_max_trx_id(block, page_zip, trx_id); + page_set_max_trx_id(block, page_zip, trx_id, mtr); } } diff --git a/include/page0zip.h b/include/page0zip.h index f25a20fe678..50a9194c996 100644 --- a/include/page0zip.h +++ b/include/page0zip.h @@ -34,6 +34,7 @@ Created June 2005 by Marko Makela #include "page0types.h" #include "buf0types.h" #include "dict0types.h" +#include "trx0types.h" #include "mem0mem.h" /************************************************************************** @@ -286,8 +287,8 @@ page_zip_write_trx_id_and_roll_ptr( byte* rec, /* in/out: record */ const ulint* offsets,/* in: rec_get_offsets(rec, index) */ ulint trx_id_col,/* in: column number of TRX_ID in rec */ - dulint trx_id, /* in: transaction identifier */ - dulint roll_ptr)/* in: roll_ptr */ + trx_id_t trx_id, /* in: transaction identifier */ + roll_ptr_t roll_ptr)/* in: roll_ptr */ __attribute__((nonnull)); /************************************************************************** diff --git a/include/pars0pars.h b/include/pars0pars.h index e5693ee5575..35b6d88a785 100644 --- a/include/pars0pars.h +++ b/include/pars0pars.h @@ -368,12 +368,14 @@ UNIV_INTERN commit_node_t* pars_commit_statement(void); /*=======================*/ + /* out, own: commit node struct */ /************************************************************************* Parses a rollback statement. */ UNIV_INTERN roll_node_t* pars_rollback_statement(void); /*=========================*/ + /* out, own: rollback node struct */ /************************************************************************* Parses a column definition at a table creation. */ UNIV_INTERN @@ -700,7 +702,7 @@ struct for_node_struct{ definition */ que_node_t* loop_start_limit;/* initial value of loop variable */ que_node_t* loop_end_limit; /* end value of loop variable */ - int loop_end_value; /* evaluated value for the end value: + lint loop_end_value; /* evaluated value for the end value: it is calculated only when the loop is entered, and will not change within the loop */ diff --git a/include/que0que.h b/include/que0que.h index a534cb7e464..ee534d1b73a 100644 --- a/include/que0que.h +++ b/include/que0que.h @@ -410,7 +410,7 @@ struct que_fork_struct{ sym_tab_t* sym_tab; /* symbol table of the query, generated by the parser, or NULL if the graph was created 'by hand' */ - pars_info_t* info; /* in: info struct, or NULL */ + pars_info_t* info; /* info struct, or NULL */ /* The following cur_... fields are relevant only in a select graph */ ulint cur_end; /* QUE_CUR_NOT_DEFINED, QUE_CUR_START, diff --git a/include/read0read.h b/include/read0read.h index db9f86454e0..778d85382c4 100644 --- a/include/read0read.h +++ b/include/read0read.h @@ -41,9 +41,9 @@ read_view_t* read_view_open_now( /*===============*/ /* out, own: read view struct */ - dulint cr_trx_id, /* in: trx_id of creating - transaction, or (0, 0) used in - purge */ + trx_id_t cr_trx_id, /* in: trx_id of creating + transaction, or ut_dulint_zero + used in purge */ mem_heap_t* heap); /* in: memory heap from which allocated */ /************************************************************************* @@ -54,9 +54,9 @@ read_view_t* read_view_oldest_copy_or_open_new( /*==============================*/ /* out, own: read view struct */ - dulint cr_trx_id, /* in: trx_id of creating - transaction, or (0, 0) used in - purge */ + trx_id_t cr_trx_id, /* in: trx_id of creating + transaction, or ut_dulint_zero + used in purge */ mem_heap_t* heap); /* in: memory heap from which allocated */ /************************************************************************* @@ -80,16 +80,16 @@ UNIV_INLINE ibool read_view_sees_trx_id( /*==================*/ - /* out: TRUE if sees */ - read_view_t* view, /* in: read view */ - dulint trx_id);/* in: trx id */ + /* out: TRUE if sees */ + const read_view_t* view, /* in: read view */ + trx_id_t trx_id);/* in: trx id */ /************************************************************************* Prints a read view to stderr. */ UNIV_INTERN void read_view_print( /*============*/ - read_view_t* view); /* in: read view */ + const read_view_t* view); /* in: read view */ /************************************************************************* Create a consistent cursor view for mysql to be used in cursors. In this consistent read view modifications done by the creating transaction or future @@ -123,24 +123,29 @@ read_cursor_set_for_mysql( read should not see the modifications to the database. */ struct read_view_struct{ - ulint type; /* VIEW_NORMAL, VIEW_HIGH_GRANULARITY */ - dulint undo_no; /* (0, 0) or if type is VIEW_HIGH_GRANULARITY + ulint type; /* VIEW_NORMAL, VIEW_HIGH_GRANULARITY */ + undo_no_t undo_no;/* ut_dulint_zero or if type is + VIEW_HIGH_GRANULARITY transaction undo_no when this high-granularity consistent read view was created */ - dulint low_limit_no; /* The view does not need to see the undo + trx_id_t low_limit_no; + /* The view does not need to see the undo logs for transactions whose transaction number is strictly smaller (<) than this value: they can be removed in purge if not needed by other views */ - dulint low_limit_id; /* The read should not see any transaction + trx_id_t low_limit_id; + /* The read should not see any transaction with trx id >= this value. In other words, this is the "high water mark". */ - dulint up_limit_id; /* The read should see all trx ids which + trx_id_t up_limit_id; + /* The read should see all trx ids which are strictly smaller (<) than this value. In other words, this is the "low water mark". */ - ulint n_trx_ids; /* Number of cells in the trx_ids array */ - dulint* trx_ids; /* Additional trx ids which the read should + ulint n_trx_ids; + /* Number of cells in the trx_ids array */ + trx_id_t* trx_ids;/* Additional trx ids which the read should not see: typically, these are the active transactions at the time when the read is serialized, except the reading transaction @@ -148,8 +153,9 @@ struct read_view_struct{ descending order. These trx_ids should be between the "low" and "high" water marks, that is, up_limit_id and low_limit_id. */ - dulint creator_trx_id; /* trx id of creating transaction, or - (0, 0) used in purge */ + trx_id_t creator_trx_id; + /* trx id of creating transaction, or + ut_dulint_zero used in purge */ UT_LIST_NODE_T(read_view_t) view_list; /* List of read views in trx_sys */ }; diff --git a/include/read0read.ic b/include/read0read.ic index 9fc6af04e88..4fa3ec840d0 100644 --- a/include/read0read.ic +++ b/include/read0read.ic @@ -25,12 +25,12 @@ Created 2/16/1997 Heikki Tuuri /************************************************************************* Gets the nth trx id in a read view. */ UNIV_INLINE -dulint +trx_id_t read_view_get_nth_trx_id( /*=====================*/ - /* out: trx id */ - read_view_t* view, /* in: read view */ - ulint n) /* in: position */ + /* out: trx id */ + const read_view_t* view, /* in: read view */ + ulint n) /* in: position */ { ut_ad(n < view->n_trx_ids); @@ -45,7 +45,7 @@ read_view_set_nth_trx_id( /*=====================*/ read_view_t* view, /* in: read view */ ulint n, /* in: position */ - dulint trx_id) /* in: trx id to set */ + trx_id_t trx_id) /* in: trx id to set */ { ut_ad(n < view->n_trx_ids); @@ -58,9 +58,9 @@ UNIV_INLINE ibool read_view_sees_trx_id( /*==================*/ - /* out: TRUE if sees */ - read_view_t* view, /* in: read view */ - dulint trx_id) /* in: trx id */ + /* out: TRUE if sees */ + const read_view_t* view, /* in: read view */ + trx_id_t trx_id) /* in: trx id */ { ulint n_ids; int cmp; diff --git a/include/rem0rec.h b/include/rem0rec.h index 8e3176d36db..73f45fb7087 100644 --- a/include/rem0rec.h +++ b/include/rem0rec.h @@ -163,7 +163,6 @@ UNIV_INLINE void rec_set_n_owned_old( /*================*/ - /* out: TRUE on success */ rec_t* rec, /* in: old-style physical record */ ulint n_owned); /* in: the number of owned */ /********************************************************** diff --git a/include/rem0rec.ic b/include/rem0rec.ic index bbfb4dc4385..373f92440e4 100644 --- a/include/rem0rec.ic +++ b/include/rem0rec.ic @@ -540,7 +540,6 @@ UNIV_INLINE void rec_set_n_owned_old( /*================*/ - /* out: TRUE on success */ rec_t* rec, /* in: old-style physical record */ ulint n_owned) /* in: the number of owned */ { @@ -1577,7 +1576,7 @@ rec_get_converted_size( dtuple->n_fields, NULL)); } - data_size = dtuple_get_data_size(dtuple); + data_size = dtuple_get_data_size(dtuple, 0); extra_size = rec_get_converted_extra_size( data_size, dtuple_get_n_fields(dtuple), n_ext); diff --git a/include/row0ins.h b/include/row0ins.h index 6aa83bed0f6..135de22fe1d 100644 --- a/include/row0ins.h +++ b/include/row0ins.h @@ -125,7 +125,7 @@ struct ins_node_struct{ UT_LIST_BASE_NODE_T(dtuple_t) entry_list;/* list of entries, one for each index */ byte* row_id_buf;/* buffer for the row id sys field in row */ - dulint trx_id; /* trx id or the last trx which executed the + trx_id_t trx_id; /* trx id or the last trx which executed the node */ byte* trx_id_buf;/* buffer for the trx id sys field in row */ mem_heap_t* entry_sys_heap; diff --git a/include/row0merge.h b/include/row0merge.h index 31ef4cc9792..d25a2c152ea 100644 --- a/include/row0merge.h +++ b/include/row0merge.h @@ -148,10 +148,10 @@ dict_index_t* row_merge_create_index( /*===================*/ /* out: index, or NULL on error */ - trx_t* trx, /* in/out: trx (sets error_state) */ - dict_table_t* table, /* in: the index is on this table */ - const merge_index_def_t* /* in: the index definition */ - index_def); + trx_t* trx, /* in/out: trx (sets error_state) */ + dict_table_t* table, /* in: the index is on this table */ + const merge_index_def_t*index_def); + /* in: the index definition */ /************************************************************************* Check if a transaction can use an index. */ UNIV_INTERN diff --git a/include/row0mysql.h b/include/row0mysql.h index ae0b181d68f..63c169836df 100644 --- a/include/row0mysql.h +++ b/include/row0mysql.h @@ -174,9 +174,8 @@ UNIV_INTERN void row_update_prebuilt_trx( /*====================*/ - /* out: prebuilt dtuple */ - row_prebuilt_t* prebuilt, /* in: prebuilt struct in MySQL - handle */ + row_prebuilt_t* prebuilt, /* in/out: prebuilt struct + in MySQL handle */ trx_t* trx); /* in: transaction handle */ /************************************************************************* Unlocks AUTO_INC type locks that were possibly reserved by a trx. */ @@ -250,7 +249,9 @@ UNIV_INTERN ibool row_table_got_default_clust_index( /*==============================*/ - const dict_table_t* table); + /* out: TRUE if the clustered index + was generated automatically */ + const dict_table_t* table); /* in: table */ /************************************************************************* Calculates the key number used inside MySQL for an Innobase index. We have to take into account if we generated a default clustered index for the table */ @@ -258,7 +259,9 @@ UNIV_INTERN ulint row_get_mysql_key_number_for_index( /*===============================*/ - const dict_index_t* index); + /* out: the key number used + inside MySQL */ + const dict_index_t* index); /* in: index */ /************************************************************************* Does an update or delete of a row for MySQL. */ UNIV_INTERN diff --git a/include/row0purge.h b/include/row0purge.h index f848e049ff4..bee9d2231d7 100644 --- a/include/row0purge.h +++ b/include/row0purge.h @@ -82,11 +82,11 @@ struct purge_node_struct{ que_common_t common; /* node type: QUE_NODE_PURGE */ /*----------------------*/ /* Local storage for this graph node */ - dulint roll_ptr;/* roll pointer to undo log record */ + roll_ptr_t roll_ptr;/* roll pointer to undo log record */ trx_undo_rec_t* undo_rec;/* undo log record */ trx_undo_inf_t* reservation;/* reservation for the undo log record in the purge array */ - dulint undo_no;/* undo number of the record */ + undo_no_t undo_no;/* undo number of the record */ ulint rec_type;/* undo log record type: TRX_UNDO_INSERT_REC, ... */ btr_pcur_t pcur; /* persistent cursor used in searching the diff --git a/include/row0row.h b/include/row0row.h index 78da5da6c8f..c1058ef21a8 100644 --- a/include/row0row.h +++ b/include/row0row.h @@ -50,7 +50,7 @@ row_get_trx_id_offset( /************************************************************************* Reads the trx id field from a clustered index record. */ UNIV_INLINE -dulint +trx_id_t row_get_rec_trx_id( /*===============*/ /* out: value of the field */ @@ -60,7 +60,7 @@ row_get_rec_trx_id( /************************************************************************* Reads the roll pointer field from a clustered index record. */ UNIV_INLINE -dulint +roll_ptr_t row_get_rec_roll_ptr( /*=================*/ /* out: value of the field */ diff --git a/include/row0row.ic b/include/row0row.ic index 9947dd43257..d81eeac84d7 100644 --- a/include/row0row.ic +++ b/include/row0row.ic @@ -29,7 +29,7 @@ Created 4/20/1996 Heikki Tuuri /************************************************************************* Reads the trx id field from a clustered index record. */ UNIV_INLINE -dulint +trx_id_t row_get_rec_trx_id( /*===============*/ /* out: value of the field */ @@ -54,7 +54,7 @@ row_get_rec_trx_id( /************************************************************************* Reads the roll pointer field from a clustered index record. */ UNIV_INLINE -dulint +roll_ptr_t row_get_rec_roll_ptr( /*=================*/ /* out: value of the field */ diff --git a/include/row0sel.h b/include/row0sel.h index 2f8574d0691..4c839764410 100644 --- a/include/row0sel.h +++ b/include/row0sel.h @@ -67,8 +67,9 @@ UNIV_INLINE plan_t* sel_node_get_nth_plan( /*==================*/ - sel_node_t* node, - ulint i); + /* out: plan node */ + sel_node_t* node, /* in: select node */ + ulint i); /* in: get ith plan node */ /************************************************************************** Performs a select step. This is a high-level function used in SQL execution graphs. */ diff --git a/include/row0undo.h b/include/row0undo.h index a17cfb1babd..a7ac811854f 100644 --- a/include/row0undo.h +++ b/include/row0undo.h @@ -89,14 +89,14 @@ struct undo_node_struct{ que_common_t common; /* node type: QUE_NODE_UNDO */ ulint state; /* node execution state */ trx_t* trx; /* trx for which undo is done */ - dulint roll_ptr;/* roll pointer to undo log record */ + roll_ptr_t roll_ptr;/* roll pointer to undo log record */ trx_undo_rec_t* undo_rec;/* undo log record */ - dulint undo_no;/* undo number of the record */ + undo_no_t undo_no;/* undo number of the record */ ulint rec_type;/* undo log record type: TRX_UNDO_INSERT_REC, ... */ - dulint new_roll_ptr; /* roll ptr to restore to clustered index + roll_ptr_t new_roll_ptr; /* roll ptr to restore to clustered index record */ - dulint new_trx_id; /* trx id to restore to clustered index + trx_id_t new_trx_id; /* trx id to restore to clustered index record */ btr_pcur_t pcur; /* persistent cursor used in searching the clustered index record */ diff --git a/include/row0upd.h b/include/row0upd.h index 9bc18c2a17d..004a5c9b9ac 100644 --- a/include/row0upd.h +++ b/include/row0upd.h @@ -101,7 +101,7 @@ row_upd_write_sys_vals_to_log( /* out: new pointer to mlog */ dict_index_t* index, /* in: clustered index */ trx_t* trx, /* in: transaction */ - dulint roll_ptr,/* in: roll ptr of the undo log record */ + roll_ptr_t roll_ptr,/* in: roll ptr of the undo log record */ byte* log_ptr,/* pointer to a buffer of size > 20 opened in mlog */ mtr_t* mtr); /* in: mtr */ @@ -118,7 +118,7 @@ row_upd_rec_sys_fields( dict_index_t* index, /* in: clustered index */ const ulint* offsets,/* in: rec_get_offsets(rec, index) */ trx_t* trx, /* in: transaction */ - dulint roll_ptr);/* in: roll ptr of the undo log record */ + roll_ptr_t roll_ptr);/* in: roll ptr of the undo log record */ /************************************************************************* Sets the trx id or roll ptr field of a clustered index entry. */ UNIV_INTERN @@ -320,12 +320,12 @@ UNIV_INTERN byte* row_upd_parse_sys_vals( /*===================*/ - /* out: log data end or NULL */ - byte* ptr, /* in: buffer */ - byte* end_ptr,/* in: buffer end */ - ulint* pos, /* out: TRX_ID position in record */ - dulint* trx_id, /* out: trx id */ - dulint* roll_ptr);/* out: roll ptr */ + /* out: log data end or NULL */ + byte* ptr, /* in: buffer */ + byte* end_ptr,/* in: buffer end */ + ulint* pos, /* out: TRX_ID position in record */ + trx_id_t* trx_id, /* out: trx id */ + roll_ptr_t* roll_ptr);/* out: roll ptr */ /************************************************************************* Updates the trx id and roll ptr field in a clustered index record in database recovery. */ @@ -337,8 +337,8 @@ row_upd_rec_sys_fields_in_recovery( page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */ const ulint* offsets,/* in: array returned by rec_get_offsets() */ ulint pos, /* in: TRX_ID position in rec */ - dulint trx_id, /* in: transaction id */ - dulint roll_ptr);/* in: roll ptr of the undo log record */ + trx_id_t trx_id, /* in: transaction id */ + roll_ptr_t roll_ptr);/* in: roll ptr of the undo log record */ /************************************************************************* Parses the log data written by row_upd_index_write_log. */ UNIV_INTERN diff --git a/include/row0upd.ic b/include/row0upd.ic index 10c8077af8a..550a7f8efb2 100644 --- a/include/row0upd.ic +++ b/include/row0upd.ic @@ -152,7 +152,7 @@ row_upd_rec_sys_fields( dict_index_t* index, /* in: clustered index */ const ulint* offsets,/* in: rec_get_offsets(rec, index) */ trx_t* trx, /* in: transaction */ - dulint roll_ptr)/* in: roll ptr of the undo log record */ + roll_ptr_t roll_ptr)/* in: roll ptr of the undo log record */ { ut_ad(dict_index_is_clust(index)); ut_ad(rec_offs_validate(rec, index, offsets)); diff --git a/include/row0vers.h b/include/row0vers.h index 0feae77e8b5..cfe021581a0 100644 --- a/include/row0vers.h +++ b/include/row0vers.h @@ -55,10 +55,12 @@ UNIV_INTERN ibool row_vers_must_preserve_del_marked( /*==============================*/ - /* out: TRUE if earlier version should be preserved */ - dulint trx_id, /* in: transaction id in the version */ - mtr_t* mtr); /* in: mtr holding the latch on the clustered index - record; it will also hold the latch on purge_view */ + /* out: TRUE if earlier version should + be preserved */ + trx_id_t trx_id, /* in: transaction id in the version */ + mtr_t* mtr); /* in: mtr holding the latch on the + clustered index record; it will also + hold the latch on purge_view */ /********************************************************************* Finds out if a version of the record, where the version >= the current purge view, should have ientry as its secondary index entry. We check diff --git a/include/srv0srv.h b/include/srv0srv.h index c79fe72760c..247070b9572 100644 --- a/include/srv0srv.h +++ b/include/srv0srv.h @@ -144,7 +144,6 @@ extern ulint srv_max_dirty_pages_pct; extern ulint srv_force_recovery; extern ulong srv_thread_concurrency; -extern ulong srv_commit_concurrency; extern ulint srv_max_n_threads; @@ -376,6 +375,7 @@ UNIV_INTERN ulint srv_get_n_threads(void); /*===================*/ + /* out: sum of srv_n_threads[] */ /************************************************************************* Returns the calling thread type. */ @@ -523,7 +523,7 @@ Function to pass InnoDB status variables to MySQL */ UNIV_INTERN void srv_export_innodb_status(void); -/*=====================*/ +/*==========================*/ /* Thread slot in the thread table */ typedef struct srv_slot_struct srv_slot_t; diff --git a/include/sync0rw.h b/include/sync0rw.h index a32b628ee03..b49daf4e289 100644 --- a/include/sync0rw.h +++ b/include/sync0rw.h @@ -141,7 +141,8 @@ UNIV_INTERN ibool rw_lock_validate( /*=============*/ - rw_lock_t* lock); + /* out: TRUE */ + rw_lock_t* lock); /* in: rw-lock */ #endif /* UNIV_DEBUG */ /****************************************************************** NOTE! The following macros should be used in rw s-locking, not the @@ -209,28 +210,21 @@ UNIV_INLINE void rw_lock_s_unlock_func( /*==================*/ - rw_lock_t* lock /* in: rw-lock */ #ifdef UNIV_SYNC_DEBUG - ,ulint pass /* in: pass value; != 0, if the lock may have + ulint pass, /* in: pass value; != 0, if the lock may have been passed to another thread to unlock */ #endif - ); -/*********************************************************************** -Releases a shared mode lock. */ + rw_lock_t* lock); /* in/out: rw-lock */ #ifdef UNIV_SYNC_DEBUG -#define rw_lock_s_unlock(L) rw_lock_s_unlock_func(L, 0) +# define rw_lock_s_unlock_gen(L, P) rw_lock_s_unlock_func(P, L) #else -#define rw_lock_s_unlock(L) rw_lock_s_unlock_func(L) +# define rw_lock_s_unlock_gen(L, P) rw_lock_s_unlock_func(L) #endif /*********************************************************************** Releases a shared mode lock. */ +#define rw_lock_s_unlock(L) rw_lock_s_unlock_gen(L, 0) -#ifdef UNIV_SYNC_DEBUG -#define rw_lock_s_unlock_gen(L, P) rw_lock_s_unlock_func(L, P) -#else -#define rw_lock_s_unlock_gen(L, P) rw_lock_s_unlock_func(L) -#endif /****************************************************************** NOTE! The following macro should be used in rw x-locking, not the corresponding function. */ @@ -273,28 +267,21 @@ UNIV_INLINE void rw_lock_x_unlock_func( /*==================*/ - rw_lock_t* lock /* in: rw-lock */ #ifdef UNIV_SYNC_DEBUG - ,ulint pass /* in: pass value; != 0, if the lock may have + ulint pass, /* in: pass value; != 0, if the lock may have been passed to another thread to unlock */ #endif - ); -/*********************************************************************** -Releases an exclusive mode lock. */ + rw_lock_t* lock); /* in/out: rw-lock */ #ifdef UNIV_SYNC_DEBUG -#define rw_lock_x_unlock(L) rw_lock_x_unlock_func(L, 0) +# define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(P, L) #else -#define rw_lock_x_unlock(L) rw_lock_x_unlock_func(L) +# define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(L) #endif /*********************************************************************** Releases an exclusive mode lock. */ +#define rw_lock_x_unlock(L) rw_lock_x_unlock_gen(L, 0) -#ifdef UNIV_SYNC_DEBUG -#define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(L, P) -#else -#define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(L) -#endif /********************************************************************** Low-level function which locks an rw-lock in s-mode when we know that it is possible and none else is currently accessing the rw-lock structure. @@ -303,10 +290,9 @@ UNIV_INLINE void rw_lock_s_lock_direct( /*==================*/ - rw_lock_t* lock, /* in: pointer to rw-lock */ + rw_lock_t* lock, /* in/out: rw-lock */ const char* file_name, /* in: file name where requested */ - ulint line /* in: line where lock requested */ -); + ulint line); /* in: line where lock requested */ /********************************************************************** Low-level function which locks an rw-lock in x-mode when we know that it is not locked and none else is currently accessing the rw-lock structure. @@ -315,10 +301,9 @@ UNIV_INLINE void rw_lock_x_lock_direct( /*==================*/ - rw_lock_t* lock, /* in: pointer to rw-lock */ + rw_lock_t* lock, /* in/out: rw-lock */ const char* file_name, /* in: file name where requested */ - ulint line /* in: line where lock requested */ -); + ulint line); /* in: line where lock requested */ /********************************************************************** This function is used in the insert buffer to move the ownership of an x-latch on a buffer frame to the current thread. The x-latch was set by @@ -340,7 +325,7 @@ UNIV_INLINE void rw_lock_s_unlock_direct( /*====================*/ - rw_lock_t* lock); /* in: rw-lock */ + rw_lock_t* lock); /* in/out: rw-lock */ /********************************************************************** Releases an exclusive mode lock when we know there are no waiters, and none else will access the lock durint the time this function is executed. */ @@ -348,7 +333,7 @@ UNIV_INLINE void rw_lock_x_unlock_direct( /*====================*/ - rw_lock_t* lock); /* in: rw-lock */ + rw_lock_t* lock); /* in/out: rw-lock */ /********************************************************************** Returns the value of writer_count for the lock. Does not reserve the lock mutex, so the caller must be sure it is not changed during the call. */ @@ -356,25 +341,34 @@ UNIV_INLINE ulint rw_lock_get_x_lock_count( /*=====================*/ - /* out: value of writer_count */ - rw_lock_t* lock); /* in: rw-lock */ + /* out: value of writer_count */ + const rw_lock_t* lock); /* in: rw-lock */ /************************************************************************ -Accessor functions for rw lock. */ +Check if there are threads waiting for the rw-lock. */ UNIV_INLINE ulint rw_lock_get_waiters( /*================*/ - rw_lock_t* lock); + /* out: 1 if waiters, 0 otherwise */ + const rw_lock_t* lock); /* in: rw-lock */ +/********************************************************************** +Returns the write-status of the lock - this function made more sense +with the old rw_lock implementation. */ UNIV_INLINE ulint rw_lock_get_writer( /*===============*/ - rw_lock_t* lock); + /* out: RW_LOCK_NOT_LOCKED, + RW_LOCK_EX, RW_LOCK_WAIT_EX */ + const rw_lock_t* lock); /* in: rw-lock */ +/********************************************************************** +Returns the number of readers. */ UNIV_INLINE ulint rw_lock_get_reader_count( /*=====================*/ - rw_lock_t* lock); + /* out: number of readers */ + const rw_lock_t* lock); /* in: rw-lock */ /********************************************************************** Decrements lock_word the specified amount if it is greater than 0. This is used by both s_lock and x_lock operations. */ @@ -383,7 +377,7 @@ ibool rw_lock_lock_word_decr( /*===================*/ /* out: TRUE if decr occurs */ - rw_lock_t* lock, /* in: rw-lock */ + rw_lock_t* lock, /* in/out: rw-lock */ ulint amount); /* in: amount to decrement */ /********************************************************************** Increments lock_word the specified amount and returns new value. */ @@ -391,9 +385,10 @@ UNIV_INLINE lint rw_lock_lock_word_incr( /*===================*/ - /* out: TRUE if decr occurs */ - rw_lock_t* lock, - ulint amount); /* in: rw-lock */ + /* out: lock->lock_word after + increment */ + rw_lock_t* lock, /* in/out: rw-lock */ + ulint amount); /* in: amount to increment */ /********************************************************************** This function sets the lock->writer_thread and lock->recursive fields. For platforms where we are using atomic builtins instead of lock->mutex @@ -453,6 +448,7 @@ UNIV_INTERN ulint rw_lock_n_locked(void); /*==================*/ + /* out: number of locked rw-locks */ /*#####################################################################*/ diff --git a/include/sync0rw.ic b/include/sync0rw.ic index 9e7e4dc9bd8..4d0e0fec0c2 100644 --- a/include/sync0rw.ic +++ b/include/sync0rw.ic @@ -67,13 +67,13 @@ rw_lock_remove_debug_info( #endif /* UNIV_SYNC_DEBUG */ /************************************************************************ -Accessor functions for rw lock. */ +Check if there are threads waiting for the rw-lock. */ UNIV_INLINE ulint rw_lock_get_waiters( /*================*/ - /* out: 1 if waiters, 0 otherwise */ - rw_lock_t* lock) /* in: rw-lock */ + /* out: 1 if waiters, 0 otherwise */ + const rw_lock_t* lock) /* in: rw-lock */ { return(lock->waiters); } @@ -86,10 +86,10 @@ UNIV_INLINE void rw_lock_set_waiter_flag( /*====================*/ - rw_lock_t* lock) /* in: rw-lock */ + rw_lock_t* lock) /* in/out: rw-lock */ { #ifdef INNODB_RW_LOCKS_USE_ATOMICS - os_compare_and_swap(&lock->waiters, 0, 1); + os_compare_and_swap_ulint(&lock->waiters, 0, 1); #else /* INNODB_RW_LOCKS_USE_ATOMICS */ lock->waiters = 1; #endif /* INNODB_RW_LOCKS_USE_ATOMICS */ @@ -103,10 +103,10 @@ UNIV_INLINE void rw_lock_reset_waiter_flag( /*======================*/ - rw_lock_t* lock) /* in: rw-lock */ + rw_lock_t* lock) /* in/out: rw-lock */ { #ifdef INNODB_RW_LOCKS_USE_ATOMICS - os_compare_and_swap(&lock->waiters, 1, 0); + os_compare_and_swap_ulint(&lock->waiters, 1, 0); #else /* INNODB_RW_LOCKS_USE_ATOMICS */ lock->waiters = 0; #endif /* INNODB_RW_LOCKS_USE_ATOMICS */ @@ -119,10 +119,12 @@ UNIV_INLINE ulint rw_lock_get_writer( /*===============*/ - rw_lock_t* lock) + /* out: RW_LOCK_NOT_LOCKED, + RW_LOCK_EX, RW_LOCK_WAIT_EX */ + const rw_lock_t* lock) /* in: rw-lock */ { lint lock_word = lock->lock_word; - if(lock_word > 0) { + if (lock_word > 0) { /* return NOT_LOCKED in s-lock state, like the writer member of the old lock implementation. */ return(RW_LOCK_NOT_LOCKED); @@ -135,15 +137,16 @@ rw_lock_get_writer( } /********************************************************************** -Returns number of readers. */ +Returns the number of readers. */ UNIV_INLINE ulint rw_lock_get_reader_count( /*=====================*/ - rw_lock_t* lock) + /* out: number of readers */ + const rw_lock_t* lock) /* in: rw-lock */ { lint lock_word = lock->lock_word; - if(lock_word > 0) { + if (lock_word > 0) { /* s-locked, no x-waiters */ return(X_LOCK_DECR - lock_word); } else if (lock_word < 0 && lock_word > -X_LOCK_DECR) { @@ -171,12 +174,12 @@ UNIV_INLINE ulint rw_lock_get_x_lock_count( /*=====================*/ - /* out: value of writer_count */ - rw_lock_t* lock) /* in: rw-lock */ + /* out: value of writer_count */ + const rw_lock_t* lock) /* in: rw-lock */ { lint lock_copy = lock->lock_word; /* If there is a reader, lock_word is not divisible by X_LOCK_DECR */ - if(lock_copy > 0 || (-lock_copy) % X_LOCK_DECR != 0) { + if (lock_copy > 0 || (-lock_copy) % X_LOCK_DECR != 0) { return(0); } return(((-lock_copy) / X_LOCK_DECR) + 1); @@ -192,57 +195,47 @@ UNIV_INLINE ibool rw_lock_lock_word_decr( /*===================*/ - /* out: TRUE if decr occurs */ - rw_lock_t* lock, /* in: rw-lock */ - ulint amount) /* in: amount of decrement */ + /* out: TRUE if decr occurs */ + rw_lock_t* lock, /* in/out: rw-lock */ + ulint amount) /* in: amount to decrement */ { - #ifdef INNODB_RW_LOCKS_USE_ATOMICS - lint local_lock_word = lock->lock_word; while (local_lock_word > 0) { - if(os_compare_and_swap(&(lock->lock_word), - local_lock_word, - local_lock_word - amount)) { + if (os_compare_and_swap_lint(&lock->lock_word, + local_lock_word, + local_lock_word - amount)) { return(TRUE); } local_lock_word = lock->lock_word; } return(FALSE); - #else /* INNODB_RW_LOCKS_USE_ATOMICS */ - ibool success = FALSE; mutex_enter(&(lock->mutex)); - if(lock->lock_word > 0) { + if (lock->lock_word > 0) { lock->lock_word -= amount; success = TRUE; } mutex_exit(&(lock->mutex)); return(success); - #endif /* INNODB_RW_LOCKS_USE_ATOMICS */ } /********************************************************************** -Two different implementations for incrementing the lock_word of a rw_lock: -one for systems supporting atomic operations, one for others. -Returns the value of lock_word after increment. */ +Increments lock_word the specified amount and returns new value. */ UNIV_INLINE lint rw_lock_lock_word_incr( /*===================*/ - /* out: lock->lock_word after increment */ - rw_lock_t* lock, /* in: rw-lock */ - ulint amount) /* in: amount of increment */ + /* out: lock->lock_word after + increment */ + rw_lock_t* lock, /* in/out: rw-lock */ + ulint amount) /* in: amount of increment */ { - #ifdef INNODB_RW_LOCKS_USE_ATOMICS - - return(os_atomic_increment(&(lock->lock_word), amount)); - + return(os_atomic_increment_lint(&lock->lock_word, amount)); #else /* INNODB_RW_LOCKS_USE_ATOMICS */ - lint local_lock_word; mutex_enter(&(lock->mutex)); @@ -253,7 +246,6 @@ rw_lock_lock_word_incr( mutex_exit(&(lock->mutex)); return(local_lock_word); - #endif /* INNODB_RW_LOCKS_USE_ATOMICS */ } @@ -287,8 +279,8 @@ rw_lock_set_writer_id_and_recursion_flag( UNIV_MEM_VALID(&lock->writer_thread, sizeof lock->writer_thread); local_thread = lock->writer_thread; - success = os_compare_and_swap(&lock->writer_thread, - local_thread, curr_thread); + success = os_compare_and_swap_thread_id( + &lock->writer_thread, local_thread, curr_thread); ut_a(success); lock->recursive = recursive; @@ -342,7 +334,7 @@ UNIV_INLINE void rw_lock_s_lock_direct( /*==================*/ - rw_lock_t* lock, /* in: pointer to rw-lock */ + rw_lock_t* lock, /* in/out: rw-lock */ const char* file_name, /* in: file name where requested */ ulint line) /* in: line where lock requested */ { @@ -367,7 +359,7 @@ UNIV_INLINE void rw_lock_x_lock_direct( /*==================*/ - rw_lock_t* lock, /* in: pointer to rw-lock */ + rw_lock_t* lock, /* in/out: rw-lock */ const char* file_name, /* in: file name where requested */ ulint line) /* in: line where lock requested */ { @@ -448,7 +440,7 @@ rw_lock_x_lock_func_nowait( ibool success; #ifdef INNODB_RW_LOCKS_USE_ATOMICS - success = os_compare_and_swap(&(lock->lock_word), X_LOCK_DECR, 0); + success = os_compare_and_swap_lint(&lock->lock_word, X_LOCK_DECR, 0); #else success = FALSE; @@ -494,12 +486,11 @@ UNIV_INLINE void rw_lock_s_unlock_func( /*==================*/ - rw_lock_t* lock /* in: rw-lock */ #ifdef UNIV_SYNC_DEBUG - ,ulint pass /* in: pass value; != 0, if the lock may have + ulint pass, /* in: pass value; != 0, if the lock may have been passed to another thread to unlock */ #endif - ) + rw_lock_t* lock) /* in/out: rw-lock */ { ut_ad((lock->lock_word % X_LOCK_DECR) != 0); @@ -532,7 +523,7 @@ UNIV_INLINE void rw_lock_s_unlock_direct( /*====================*/ - rw_lock_t* lock) /* in: rw-lock */ + rw_lock_t* lock) /* in/out: rw-lock */ { ut_ad(lock->lock_word < X_LOCK_DECR); @@ -556,12 +547,11 @@ UNIV_INLINE void rw_lock_x_unlock_func( /*==================*/ - rw_lock_t* lock /* in: rw-lock */ #ifdef UNIV_SYNC_DEBUG - ,ulint pass /* in: pass value; != 0, if the lock may have + ulint pass, /* in: pass value; != 0, if the lock may have been passed to another thread to unlock */ #endif - ) + rw_lock_t* lock) /* in/out: rw-lock */ { ut_ad((lock->lock_word % X_LOCK_DECR) == 0); @@ -607,7 +597,7 @@ UNIV_INLINE void rw_lock_x_unlock_direct( /*====================*/ - rw_lock_t* lock) /* in: rw-lock */ + rw_lock_t* lock) /* in/out: rw-lock */ { /* Reset the exclusive lock if this thread no longer has an x-mode lock */ diff --git a/include/sync0sync.h b/include/sync0sync.h index bd9e26201e1..5f08d44b96d 100644 --- a/include/sync0sync.h +++ b/include/sync0sync.h @@ -42,6 +42,13 @@ Created 9/5/1995 Heikki Tuuri extern my_bool timed_mutexes; +#ifdef HAVE_WINDOWS_ATOMICS +typedef LONG lock_word_t; /* On Windows, InterlockedExchange operates + on LONG variable */ +#else +typedef byte lock_word_t; +#endif + /********************************************************************** Initializes the synchronization data structures. */ UNIV_INTERN @@ -153,6 +160,7 @@ void mutex_exit( /*=======*/ mutex_t* mutex); /* in: pointer to mutex */ +#ifdef UNIV_SYNC_DEBUG /********************************************************************** Returns TRUE if no mutex or rw-lock is currently locked. Works only in the debug version. */ @@ -160,6 +168,8 @@ UNIV_INTERN ibool sync_all_freed(void); /*================*/ + /* out: TRUE if no mutexes and rw-locks reserved */ +#endif /* UNIV_SYNC_DEBUG */ /*##################################################################### FUNCTION PROTOTYPES FOR DEBUGGING */ /*********************************************************************** @@ -183,7 +193,8 @@ UNIV_INTERN ibool mutex_validate( /*===========*/ - const mutex_t* mutex); + /* out: TRUE */ + const mutex_t* mutex); /* in: mutex */ /********************************************************************** Checks that the current thread owns the mutex. Works only in the debug version. */ @@ -253,12 +264,13 @@ UNIV_INTERN ulint mutex_n_reserved(void); /*==================*/ + /* out: number of reserved mutexes */ #endif /* UNIV_SYNC_DEBUG */ /********************************************************************** NOT to be used outside this module except in debugging! Gets the value of the lock word. */ UNIV_INLINE -byte +lock_word_t mutex_get_lock_word( /*================*/ const mutex_t* mutex); /* in: mutex */ @@ -484,15 +496,14 @@ implementation of a mutual exclusion semaphore. */ struct mutex_struct { os_event_t event; /* Used by sync0arr.c for the wait queue */ - byte lock_word; /* This byte is the target of the atomic - test-and-set instruction in Win32 and - x86 32/64 with GCC 4.1.0 or later version */ -#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER) -#elif defined(HAVE_GCC_ATOMIC_BUILTINS) -#else + volatile lock_word_t lock_word; /* lock_word is the target + of the atomic test-and-set instruction when + atomic operations are enabled. */ + +#if !defined(HAVE_ATOMIC_BUILTINS) os_fast_mutex_t - os_fast_mutex; /* In other systems we use this OS mutex - in place of lock_word */ + os_fast_mutex; /* We use this OS mutex in place of lock_word + when atomic operations are not enabled */ #endif ulint waiters; /* This ulint is set to 1 if there are (or may be) threads waiting in the global wait diff --git a/include/sync0sync.ic b/include/sync0sync.ic index c4b364fde5f..8a446a7e7ea 100644 --- a/include/sync0sync.ic +++ b/include/sync0sync.ic @@ -79,40 +79,8 @@ mutex_test_and_set( 1 */ mutex_t* mutex) /* in: mutex */ { -#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER) - byte res; - byte* lw; /* assembler code is used to ensure that - lock_word is loaded from memory */ - ut_ad(mutex); - ut_ad(sizeof(byte) == 1); - - lw = &(mutex->lock_word); - - __asm MOV ECX, lw - __asm MOV EDX, 1 - __asm XCHG DL, BYTE PTR [ECX] - __asm MOV res, DL - - /* The fence below would prevent this thread from - reading the data structure protected by the mutex - before the test-and-set operation is committed, but - the fence is apparently not needed: - - In a posting to comp.arch newsgroup (August 10, 1997) - Andy Glew said that in P6 a LOCKed instruction like - XCHG establishes a fence with respect to memory reads - and writes and thus an explicit fence is not - needed. In P5 he seemed to agree with a previous - newsgroup poster that LOCKed instructions serialize - all instruction execution, and, consequently, also - memory operations. This is confirmed in Intel Software - Dev. Manual, Vol. 3. */ - - /* mutex_fence(); */ - - return(res); -#elif defined(HAVE_GCC_ATOMIC_BUILTINS) - return __sync_lock_test_and_set(&(mutex->lock_word), 1); +#if defined(HAVE_ATOMIC_BUILTINS) + return(os_atomic_test_and_set_byte(&mutex->lock_word, 1)); #else ibool ret; @@ -139,21 +107,11 @@ mutex_reset_lock_word( /*==================*/ mutex_t* mutex) /* in: mutex */ { -#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER) - byte* lw; /* assembler code is used to ensure that - lock_word is loaded from memory */ - ut_ad(mutex); - - lw = &(mutex->lock_word); - - __asm MOV EDX, 0 - __asm MOV ECX, lw - __asm XCHG DL, BYTE PTR [ECX] -#elif defined(HAVE_GCC_ATOMIC_BUILTINS) +#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. */ - __sync_lock_test_and_set(&(mutex->lock_word), 0); + os_atomic_test_and_set_byte(&mutex->lock_word, 0); #else mutex->lock_word = 0; @@ -164,18 +122,14 @@ mutex_reset_lock_word( /********************************************************************** Gets the value of the lock word. */ UNIV_INLINE -byte +lock_word_t mutex_get_lock_word( /*================*/ const mutex_t* mutex) /* in: mutex */ { - const volatile byte* ptr; /* declared volatile to ensure that - lock_word is loaded from memory */ ut_ad(mutex); - ptr = &(mutex->lock_word); - - return(*ptr); + return(mutex->lock_word); } /********************************************************************** diff --git a/include/trx0purge.h b/include/trx0purge.h index 4921b860485..92342d51af7 100644 --- a/include/trx0purge.h +++ b/include/trx0purge.h @@ -58,10 +58,11 @@ UNIV_INTERN ibool trx_purge_update_undo_must_exist( /*=============================*/ - /* out: TRUE if is sure that it is preserved, also - if the function returns FALSE, it is possible that - the undo log still exists in the system */ - dulint trx_id);/* in: transaction id */ + /* out: TRUE if is sure that it is + preserved, also if the function + returns FALSE, it is possible that the + undo log still exists in the system */ + trx_id_t trx_id);/* in: transaction id */ /************************************************************************ Creates the global purge system control structure and inits the history mutex. */ @@ -91,7 +92,7 @@ trx_purge_fetch_next_rec( pointer to the dummy undo log record &trx_purge_dummy_rec if the whole undo log can skipped in purge; NULL if none left */ - dulint* roll_ptr,/* out: roll pointer to undo record */ + roll_ptr_t* roll_ptr,/* out: roll pointer to undo record */ trx_undo_inf_t** cell, /* out: storage cell for the record in the purge array */ mem_heap_t* heap); /* in: memory heap where copied */ @@ -144,10 +145,10 @@ struct trx_purge_struct{ /* The following two fields form the 'purge pointer' which advances during a purge, and which is used in history list truncation */ - dulint purge_trx_no; /* Purge has advanced past all + trx_id_t purge_trx_no; /* Purge has advanced past all transactions whose number is less than this */ - dulint purge_undo_no; /* Purge has advanced past all records + undo_no_t purge_undo_no; /* Purge has advanced past all records whose undo number is less than this */ /*-----------------------------*/ ibool next_stored; /* TRUE if the info of the next record diff --git a/include/trx0rec.h b/include/trx0rec.h index aa734a1680c..c2a2e4a4de2 100644 --- a/include/trx0rec.h +++ b/include/trx0rec.h @@ -51,42 +51,46 @@ UNIV_INLINE ulint trx_undo_rec_get_type( /*==================*/ - /* out: record type */ - trx_undo_rec_t* undo_rec); /* in: undo log record */ + /* out: record type */ + const trx_undo_rec_t* undo_rec); /* in: undo log record */ /************************************************************************** Reads from an undo log record the record compiler info. */ UNIV_INLINE ulint trx_undo_rec_get_cmpl_info( /*=======================*/ - /* out: compiler info */ - trx_undo_rec_t* undo_rec); /* in: undo log record */ + /* out: compiler info */ + const trx_undo_rec_t* undo_rec); /* in: undo log record */ /************************************************************************** Returns TRUE if an undo log record contains an extern storage field. */ UNIV_INLINE ibool trx_undo_rec_get_extern_storage( /*============================*/ - /* out: TRUE if extern */ - trx_undo_rec_t* undo_rec); /* in: undo log record */ + /* out: TRUE if extern */ + const trx_undo_rec_t* undo_rec); /* in: undo log record */ /************************************************************************** Reads the undo log record number. */ UNIV_INLINE -dulint +undo_no_t trx_undo_rec_get_undo_no( /*=====================*/ - /* out: undo no */ - trx_undo_rec_t* undo_rec); /* in: undo log record */ + /* out: undo no */ + const trx_undo_rec_t* undo_rec); /* in: undo log record */ /************************************************************************** - * Returns the start of the undo record data area. */ - +Returns the start of the undo record data area. */ UNIV_INLINE -byte* -trx_undo_rec_get_ptr( -/*==================*/ - /* out: compiler info */ - trx_undo_rec_t* undo_rec, /* in: undo log record */ - dulint undo_no); /* in: undo no read from node */ +ulint +trx_undo_rec_get_offset( +/*====================*/ + /* out: offset to the data area */ + undo_no_t undo_no) /* in: undo no read from node */ + __attribute__((const)); + +/************************************************************************** +Returns the start of the undo record data area. */ +#define trx_undo_rec_get_ptr(undo_rec, undo_no) \ + ((undo_rec) + trx_undo_rec_get_offset(undo_no)) /************************************************************************** Reads from an undo log record the general parameters. */ @@ -103,7 +107,7 @@ trx_undo_rec_get_pars( for update type records */ ibool* updated_extern, /* out: TRUE if we updated an externally stored fild */ - dulint* undo_no, /* out: undo log record number */ + undo_no_t* undo_no, /* out: undo log record number */ dulint* table_id); /* out: table id */ /*********************************************************************** Builds a row reference from an undo log record. */ @@ -141,14 +145,15 @@ UNIV_INTERN byte* trx_undo_update_rec_get_sys_cols( /*=============================*/ - /* out: remaining part of undo log - record after reading these values */ - byte* ptr, /* in: remaining part of undo log - record after reading general - parameters */ - dulint* trx_id, /* out: trx id */ - dulint* roll_ptr, /* out: roll ptr */ - ulint* info_bits); /* out: info bits state */ + /* out: remaining part of undo + log record after reading these + values */ + byte* ptr, /* in: remaining part of undo + log record after reading + general parameters */ + trx_id_t* trx_id, /* out: trx id */ + roll_ptr_t* roll_ptr, /* out: roll ptr */ + ulint* info_bits); /* out: info bits state */ /*********************************************************************** Builds an update vector based on a remaining part of an undo log record. */ UNIV_INTERN @@ -170,8 +175,8 @@ trx_undo_update_rec_get_update( TRX_UNDO_DEL_MARK_REC; in the last case, only trx id and roll ptr fields are added to the update vector */ - dulint trx_id, /* in: transaction id from this undorecord */ - dulint roll_ptr,/* in: roll pointer from this undo record */ + trx_id_t trx_id, /* in: transaction id from this undorecord */ + roll_ptr_t roll_ptr,/* in: roll pointer from this undo record */ ulint info_bits,/* in: info bits from this undo record */ trx_t* trx, /* in: transaction */ mem_heap_t* heap, /* in: memory heap from which the memory @@ -226,7 +231,7 @@ trx_undo_report_row_operation( const rec_t* rec, /* in: case of an update or delete marking, the record in the clustered index, otherwise NULL */ - dulint* roll_ptr); /* out: rollback pointer to the + roll_ptr_t* roll_ptr); /* out: rollback pointer to the inserted undo log record, ut_dulint_zero if BTR_NO_UNDO_LOG flag was specified */ @@ -238,7 +243,7 @@ trx_undo_rec_t* trx_undo_get_undo_rec_low( /*======================*/ /* out, own: copy of the record */ - dulint roll_ptr, /* in: roll pointer to record */ + roll_ptr_t roll_ptr, /* in: roll pointer to record */ mem_heap_t* heap); /* in: memory heap where copied */ /********************************************************************** Copies an undo record to heap. */ @@ -252,8 +257,8 @@ trx_undo_get_undo_rec( fetch the old version; NOTE: the caller must have latches on the clustered index page and purge_view */ - dulint roll_ptr, /* in: roll pointer to record */ - dulint trx_id, /* in: id of the trx that generated + roll_ptr_t roll_ptr, /* in: roll pointer to record */ + trx_id_t trx_id, /* in: id of the trx that generated the roll pointer: it points to an undo log of this transaction */ trx_undo_rec_t** undo_rec, /* out, own: copy of the record */ diff --git a/include/trx0rec.ic b/include/trx0rec.ic index 2cb3a8fa128..0d8c8dd6e28 100644 --- a/include/trx0rec.ic +++ b/include/trx0rec.ic @@ -29,8 +29,8 @@ UNIV_INLINE ulint trx_undo_rec_get_type( /*==================*/ - /* out: record type */ - trx_undo_rec_t* undo_rec) /* in: undo log record */ + /* out: record type */ + const trx_undo_rec_t* undo_rec) /* in: undo log record */ { return(mach_read_from_1(undo_rec + 2) & (TRX_UNDO_CMPL_INFO_MULT - 1)); } @@ -41,8 +41,8 @@ UNIV_INLINE ulint trx_undo_rec_get_cmpl_info( /*=======================*/ - /* out: compiler info */ - trx_undo_rec_t* undo_rec) /* in: undo log record */ + /* out: compiler info */ + const trx_undo_rec_t* undo_rec) /* in: undo log record */ { return(mach_read_from_1(undo_rec + 2) / TRX_UNDO_CMPL_INFO_MULT); } @@ -53,8 +53,8 @@ UNIV_INLINE ibool trx_undo_rec_get_extern_storage( /*============================*/ - /* out: TRUE if extern */ - trx_undo_rec_t* undo_rec) /* in: undo log record */ + /* out: TRUE if extern */ + const trx_undo_rec_t* undo_rec) /* in: undo log record */ { if (mach_read_from_1(undo_rec + 2) & TRX_UNDO_UPD_EXTERN) { @@ -67,13 +67,13 @@ trx_undo_rec_get_extern_storage( /************************************************************************** Reads the undo log record number. */ UNIV_INLINE -dulint +undo_no_t trx_undo_rec_get_undo_no( /*=====================*/ - /* out: undo no */ - trx_undo_rec_t* undo_rec) /* in: undo log record */ + /* out: undo no */ + const trx_undo_rec_t* undo_rec) /* in: undo log record */ { - byte* ptr; + const byte* ptr; ptr = undo_rec + 3; @@ -83,15 +83,13 @@ trx_undo_rec_get_undo_no( /************************************************************************** Returns the start of the undo record data area. */ UNIV_INLINE -byte* -trx_undo_rec_get_ptr( -/*=================*/ - /* out: compiler info */ - trx_undo_rec_t* undo_rec, /* in: undo log record */ - dulint undo_no) /* in: undo no read from node */ +ulint +trx_undo_rec_get_offset( +/*====================*/ + /* out: offset to the data area */ + undo_no_t undo_no) /* in: undo no read from node */ { - return (((byte*) undo_rec) + 3 - + mach_dulint_get_much_compressed_size(undo_no)); + return (3 + mach_dulint_get_much_compressed_size(undo_no)); } /*************************************************************************** @@ -105,14 +103,9 @@ trx_undo_rec_copy( mem_heap_t* heap) /* in: heap where copied */ { ulint len; - trx_undo_rec_t* rec_copy; len = mach_read_from_2(undo_rec) - ut_align_offset(undo_rec, UNIV_PAGE_SIZE); - rec_copy = mem_heap_alloc(heap, len); - - ut_memcpy(rec_copy, undo_rec, len); - - return(rec_copy); + return(mem_heap_dup(heap, undo_rec, len)); } #endif /* !UNIV_HOTBACKUP */ diff --git a/include/trx0roll.h b/include/trx0roll.h index 3318a5985d7..72e27e4c7b9 100644 --- a/include/trx0roll.h +++ b/include/trx0roll.h @@ -80,7 +80,7 @@ UNIV_INTERN void trx_roll_try_truncate( /*==================*/ - trx_t* trx); /* in: transaction */ + trx_t* trx); /* in/out: transaction */ /************************************************************************ Pops the topmost record when the two undo logs of a transaction are seen as a single stack of records ordered by their undo numbers. Inserts the @@ -95,8 +95,8 @@ trx_roll_pop_top_rec_of_trx( if none left, or if the undo number of the top record would be less than the limit */ trx_t* trx, /* in: transaction */ - dulint limit, /* in: least undo number we need */ - dulint* roll_ptr,/* out: roll pointer to undo record */ + undo_no_t limit, /* in: least undo number we need */ + roll_ptr_t* roll_ptr,/* out: roll pointer to undo record */ mem_heap_t* heap); /* in: memory heap where copied */ /************************************************************************ Reserves an undo log record for a query thread to undo. This should be @@ -106,17 +106,17 @@ UNIV_INTERN ibool trx_undo_rec_reserve( /*=================*/ - /* out: TRUE if succeeded */ - trx_t* trx, /* in: transaction */ - dulint undo_no);/* in: undo number of the record */ + /* out: TRUE if succeeded */ + trx_t* trx, /* in/out: transaction */ + undo_no_t undo_no);/* in: undo number of the record */ /*********************************************************************** Releases a reserved undo record. */ UNIV_INTERN void trx_undo_rec_release( /*=================*/ - trx_t* trx, /* in: transaction */ - dulint undo_no);/* in: undo number */ + trx_t* trx, /* in/out: transaction */ + undo_no_t undo_no);/* in: undo number */ /************************************************************************* Starts a rollback operation. */ UNIV_INTERN @@ -278,7 +278,7 @@ trx_roll_savepoint_free( /*********************************************************************** Frees savepoint structs starting from savep, if savep == NULL then free all savepoints. */ - +UNIV_INTERN void trx_roll_savepoints_free( /*=====================*/ @@ -289,10 +289,10 @@ trx_roll_savepoints_free( /* A cell in the array used during a rollback and a purge */ struct trx_undo_inf_struct{ - dulint trx_no; /* transaction number: not defined during + trx_id_t trx_no; /* transaction number: not defined during a rollback */ - dulint undo_no; /* undo number of an undo record */ - ibool in_use; /* TRUE if the cell is in use */ + undo_no_t undo_no;/* undo number of an undo record */ + ibool in_use; /* TRUE if the cell is in use */ }; /* During a rollback and a purge, undo numbers of undo records currently being diff --git a/include/trx0rseg.h b/include/trx0rseg.h index af3d05eaab8..327f577b104 100644 --- a/include/trx0rseg.h +++ b/include/trx0rseg.h @@ -148,7 +148,7 @@ struct trx_rseg_struct{ rseg mutex */ ulint space; /* space where the rollback segment is header is placed */ - ulint zip_size;/* in: compressed page size of space + ulint zip_size;/* compressed page size of space in bytes, or 0 for uncompressed spaces */ ulint page_no;/* page number of the rollback segment header */ @@ -174,7 +174,7 @@ struct trx_rseg_struct{ FIL_NULL if all list purged */ ulint last_offset; /* Byte offset of the last not yet purged log header */ - dulint last_trx_no; /* Transaction number of the last not + trx_id_t last_trx_no; /* Transaction number of the last not yet purged log */ ibool last_del_marks; /* TRUE if the last not yet purged log needs purging */ diff --git a/include/trx0sys.h b/include/trx0sys.h index c521f1c030c..e0a9d3ee0d6 100644 --- a/include/trx0sys.h +++ b/include/trx0sys.h @@ -84,7 +84,7 @@ UNIV_INTERN void trx_sys_doublewrite_init_or_restore_pages( /*======================================*/ - ibool restore_corrupt_pages); + ibool restore_corrupt_pages); /* in: TRUE=restore pages */ /******************************************************************** Marks the trx sys header when we have successfully upgraded to the >= 4.1.x multiple tablespace format. */ @@ -209,14 +209,14 @@ trx_sysf_rseg_set_page_no( /********************************************************************* Allocates a new transaction id. */ UNIV_INLINE -dulint +trx_id_t trx_sys_get_new_trx_id(void); /*========================*/ /* out: new, allocated trx id */ /********************************************************************* Allocates a new transaction number. */ UNIV_INLINE -dulint +trx_id_t trx_sys_get_new_trx_no(void); /*========================*/ /* out: new, allocated trx number */ @@ -229,15 +229,15 @@ UNIV_INLINE void trx_write_trx_id( /*=============*/ - byte* ptr, /* in: pointer to memory where written */ - dulint id); /* in: id */ + byte* ptr, /* in: pointer to memory where written */ + trx_id_t id); /* in: id */ #ifndef UNIV_HOTBACKUP /********************************************************************* Reads a trx id from an index page. In case that the id size changes in some future version, this function should be used instead of mach_read_... */ UNIV_INLINE -dulint +trx_id_t trx_read_trx_id( /*============*/ /* out: id */ @@ -248,15 +248,15 @@ UNIV_INLINE trx_t* trx_get_on_id( /*==========*/ - /* out: the trx handle or NULL if not found */ - dulint trx_id); /* in: trx id to search for */ + /* out: the trx handle or NULL if not found */ + trx_id_t trx_id);/* in: trx id to search for */ /******************************************************************** Returns the minumum trx id in trx list. This is the smallest id for which the trx can possibly be active. (But, you must look at the trx->conc_state to find out if the minimum trx id transaction itself is active, or already committed.) */ UNIV_INLINE -dulint +trx_id_t trx_list_get_min_trx_id(void); /*=========================*/ /* out: the minimum trx id, or trx_sys->max_trx_id @@ -267,8 +267,8 @@ UNIV_INLINE ibool trx_is_active( /*==========*/ - /* out: TRUE if active */ - dulint trx_id);/* in: trx id of the transaction */ + /* out: TRUE if active */ + trx_id_t trx_id);/* in: trx id of the transaction */ /******************************************************************** Checks that trx is in the trx list. */ UNIV_INTERN @@ -513,7 +513,7 @@ struct trx_doublewrite_struct{ /* The transaction system central memory data structure; protected by the kernel mutex */ struct trx_sys_struct{ - dulint max_trx_id; /* The smallest number not yet + trx_id_t max_trx_id; /* The smallest number not yet assigned as a transaction id or transaction number */ UT_LIST_BASE_NODE_T(trx_t) trx_list; diff --git a/include/trx0sys.ic b/include/trx0sys.ic index 760bd3ce68d..41e0c4a6b43 100644 --- a/include/trx0sys.ic +++ b/include/trx0sys.ic @@ -223,8 +223,8 @@ UNIV_INLINE void trx_write_trx_id( /*=============*/ - byte* ptr, /* in: pointer to memory where written */ - dulint id) /* in: id */ + byte* ptr, /* in: pointer to memory where written */ + trx_id_t id) /* in: id */ { #if DATA_TRX_ID_LEN != 6 # error "DATA_TRX_ID_LEN != 6" @@ -238,7 +238,7 @@ Reads a trx id from an index page. In case that the id size changes in some future version, this function should be used instead of mach_read_... */ UNIV_INLINE -dulint +trx_id_t trx_read_trx_id( /*============*/ /* out: id */ @@ -256,8 +256,8 @@ UNIV_INLINE trx_t* trx_get_on_id( /*==========*/ - /* out: the trx handle or NULL if not found */ - dulint trx_id) /* in: trx id to search for */ + /* out: the trx handle or NULL if not found */ + trx_id_t trx_id) /* in: trx id to search for */ { trx_t* trx; @@ -283,7 +283,7 @@ the trx can possibly be active. (But, you must look at the trx->conc_state to find out if the minimum trx id transaction itself is active, or already committed.) */ UNIV_INLINE -dulint +trx_id_t trx_list_get_min_trx_id(void) /*=========================*/ /* out: the minimum trx id, or trx_sys->max_trx_id @@ -309,8 +309,8 @@ UNIV_INLINE ibool trx_is_active( /*==========*/ - /* out: TRUE if active */ - dulint trx_id) /* in: trx id of the transaction */ + /* out: TRUE if active */ + trx_id_t trx_id) /* in: trx id of the transaction */ { trx_t* trx; @@ -344,12 +344,12 @@ trx_is_active( /********************************************************************* Allocates a new transaction id. */ UNIV_INLINE -dulint +trx_id_t trx_sys_get_new_trx_id(void) /*========================*/ /* out: new, allocated trx id */ { - dulint id; + trx_id_t id; ut_ad(mutex_own(&kernel_mutex)); @@ -376,7 +376,7 @@ trx_sys_get_new_trx_id(void) /********************************************************************* Allocates a new transaction number. */ UNIV_INLINE -dulint +trx_id_t trx_sys_get_new_trx_no(void) /*========================*/ /* out: new, allocated trx number */ diff --git a/include/trx0trx.h b/include/trx0trx.h index 7603ffef924..c45419539f1 100644 --- a/include/trx0trx.h +++ b/include/trx0trx.h @@ -530,15 +530,15 @@ struct trx_struct{ time_t start_time; /* time the trx object was created or the state last time became TRX_ACTIVE */ - dulint id; /* transaction id */ + trx_id_t id; /* transaction id */ XID xid; /* X/Open XA transaction identification to identify a transaction branch */ - dulint no; /* transaction serialization number == + trx_id_t no; /* transaction serialization number == max trx id when the transaction is moved to COMMITTED_IN_MEMORY state */ ib_uint64_t commit_lsn; /* lsn at the time of the commit */ - dulint table_id; /* Table to drop iff dict_operation + trx_id_t table_id; /* Table to drop iff dict_operation is TRUE, or ut_dulint_zero. */ /*------------------------------*/ void* mysql_thd; /* MySQL thread handle corresponding @@ -675,7 +675,7 @@ struct trx_struct{ accessed only when we know that there cannot be any activity in the undo logs! */ - dulint undo_no; /* next undo log record number to + undo_no_t undo_no; /* next undo log record number to assign; since the undo log is private for a transaction, this is a simple ascending sequence @@ -694,7 +694,7 @@ struct trx_struct{ NULL if no inserts performed yet */ trx_undo_t* update_undo; /* pointer to the update undo log, or NULL if no update performed yet */ - dulint roll_limit; /* least undo number to undo during + undo_no_t roll_limit; /* least undo number to undo during a rollback */ ulint pages_undone; /* number of undo log pages undone since the last undo log truncation */ diff --git a/include/trx0types.h b/include/trx0types.h index 896f4e8c0a2..d210766f360 100644 --- a/include/trx0types.h +++ b/include/trx0types.h @@ -59,10 +59,14 @@ enum trx_rb_ctx { in crash recovery */ }; +typedef dulint trx_id_t; +typedef dulint roll_ptr_t; +typedef dulint undo_no_t; + /* Transaction savepoint */ typedef struct trx_savept_struct trx_savept_t; struct trx_savept_struct{ - dulint least_undo_no; /* least undo number to undo */ + undo_no_t least_undo_no; /* least undo number to undo */ }; /* File objects */ diff --git a/include/trx0undo.h b/include/trx0undo.h index f6834bd7494..6f99f129247 100644 --- a/include/trx0undo.h +++ b/include/trx0undo.h @@ -34,9 +34,9 @@ Created 3/26/1996 Heikki Tuuri #ifndef UNIV_HOTBACKUP /*************************************************************************** -Builds a roll pointer dulint. */ +Builds a roll pointer. */ UNIV_INLINE -dulint +roll_ptr_t trx_undo_build_roll_ptr( /*====================*/ /* out: roll pointer */ @@ -45,24 +45,25 @@ trx_undo_build_roll_ptr( ulint page_no, /* in: page number */ ulint offset); /* in: offset of the undo entry within page */ /*************************************************************************** -Decodes a roll pointer dulint. */ +Decodes a roll pointer. */ UNIV_INLINE void trx_undo_decode_roll_ptr( /*=====================*/ - dulint roll_ptr, /* in: roll pointer */ - ibool* is_insert, /* out: TRUE if insert undo log */ - ulint* rseg_id, /* out: rollback segment id */ - ulint* page_no, /* out: page number */ - ulint* offset); /* out: offset of the undo entry within page */ + roll_ptr_t roll_ptr, /* in: roll pointer */ + ibool* is_insert, /* out: TRUE if insert undo log */ + ulint* rseg_id, /* out: rollback segment id */ + ulint* page_no, /* out: page number */ + ulint* offset); /* out: offset of the undo + entry within page */ /*************************************************************************** Returns TRUE if the roll pointer is of the insert type. */ UNIV_INLINE ibool trx_undo_roll_ptr_is_insert( /*========================*/ - /* out: TRUE if insert undo log */ - dulint roll_ptr); /* in: roll pointer */ + /* out: TRUE if insert undo log */ + roll_ptr_t roll_ptr); /* in: roll pointer */ #endif /* !UNIV_HOTBACKUP */ /********************************************************************* Writes a roll ptr to an index page. In case that the size changes in @@ -72,14 +73,15 @@ UNIV_INLINE void trx_write_roll_ptr( /*===============*/ - byte* ptr, /* in: pointer to memory where written */ - dulint roll_ptr); /* in: roll ptr */ + byte* ptr, /* in: pointer to memory where + written */ + roll_ptr_t roll_ptr); /* in: roll ptr */ /********************************************************************* Reads a roll ptr from an index page. In case that the roll ptr size changes in some future version, this function should be used instead of mach_read_... */ UNIV_INLINE -dulint +roll_ptr_t trx_read_roll_ptr( /*==============*/ /* out: roll ptr */ @@ -214,7 +216,7 @@ trx_undo_truncate_end( /*==================*/ trx_t* trx, /* in: transaction whose undo log it is */ trx_undo_t* undo, /* in: undo log */ - dulint limit); /* in: all undo records with undo number + undo_no_t limit); /* in: all undo records with undo number >= this value should be truncated */ /*************************************************************************** Truncates an undo log from the start. This function is used during a purge @@ -223,15 +225,17 @@ UNIV_INTERN void trx_undo_truncate_start( /*====================*/ - trx_rseg_t* rseg, /* in: rollback segment */ - ulint space, /* in: space id of the log */ - ulint hdr_page_no, /* in: header page number */ - ulint hdr_offset, /* in: header offset on the page */ - dulint limit); /* in: all undo pages with undo numbers < - this value should be truncated; NOTE that - the function only frees whole pages; the - header page is not freed, but emptied, if - all the records there are < limit */ + trx_rseg_t* rseg, /* in: rollback segment */ + ulint space, /* in: space id of the log */ + ulint hdr_page_no, /* in: header page number */ + ulint hdr_offset, /* in: header offset on the page */ + undo_no_t limit); /* in: all undo pages with + undo numbers < this value + should be truncated; NOTE that + the function only frees whole + pages; the header page is not + freed, but emptied, if all the + records there are < limit */ /************************************************************************ Initializes the undo log lists for a rollback segment memory copy. This function is only called when the database is started or a new @@ -374,7 +378,7 @@ struct trx_undo_struct{ necessary; also TRUE if the transaction has updated an externally stored field */ - dulint trx_id; /* id of the trx assigned to the undo + trx_id_t trx_id; /* id of the trx assigned to the undo log */ XID xid; /* X/Open XA transaction identification */ @@ -385,7 +389,7 @@ struct trx_undo_struct{ /*-----------------------------*/ ulint space; /* space id where the undo log placed */ - ulint zip_size; /* in: compressed page size of space + ulint zip_size; /* compressed page size of space in bytes, or 0 for uncompressed */ ulint hdr_page_no; /* page number of the header page in the undo log */ @@ -405,7 +409,7 @@ struct trx_undo_struct{ ulint top_offset; /* offset of the latest undo record, i.e., the topmost element in the undo log if we think of it as a stack */ - dulint top_undo_no; /* undo number of the latest record */ + undo_no_t top_undo_no; /* undo number of the latest record */ buf_block_t* guess_block; /* guess for the buffer block where the top page might reside */ /*-----------------------------*/ diff --git a/include/trx0undo.ic b/include/trx0undo.ic index d767716ba9a..3ae948931a2 100644 --- a/include/trx0undo.ic +++ b/include/trx0undo.ic @@ -27,9 +27,9 @@ Created 3/26/1996 Heikki Tuuri #ifndef UNIV_HOTBACKUP /*************************************************************************** -Builds a roll pointer dulint. */ +Builds a roll pointer. */ UNIV_INLINE -dulint +roll_ptr_t trx_undo_build_roll_ptr( /*====================*/ /* out: roll pointer */ @@ -51,16 +51,17 @@ trx_undo_build_roll_ptr( } /*************************************************************************** -Decodes a roll pointer dulint. */ +Decodes a roll pointer. */ UNIV_INLINE void trx_undo_decode_roll_ptr( /*=====================*/ - dulint roll_ptr, /* in: roll pointer */ - ibool* is_insert, /* out: TRUE if insert undo log */ - ulint* rseg_id, /* out: rollback segment id */ - ulint* page_no, /* out: page number */ - ulint* offset) /* out: offset of the undo entry within page */ + roll_ptr_t roll_ptr, /* in: roll pointer */ + ibool* is_insert, /* out: TRUE if insert undo log */ + ulint* rseg_id, /* out: rollback segment id */ + ulint* page_no, /* out: page number */ + ulint* offset) /* out: offset of the undo + entry within page */ { ulint low; ulint high; @@ -88,8 +89,8 @@ UNIV_INLINE ibool trx_undo_roll_ptr_is_insert( /*========================*/ - /* out: TRUE if insert undo log */ - dulint roll_ptr) /* in: roll pointer */ + /* out: TRUE if insert undo log */ + roll_ptr_t roll_ptr) /* in: roll pointer */ { ulint high; #if DATA_ROLL_PTR_LEN != 7 @@ -112,8 +113,9 @@ UNIV_INLINE void trx_write_roll_ptr( /*===============*/ - byte* ptr, /* in: pointer to memory where written */ - dulint roll_ptr) /* in: roll ptr */ + byte* ptr, /* in: pointer to memory where + written */ + roll_ptr_t roll_ptr) /* in: roll ptr */ { #if DATA_ROLL_PTR_LEN != 7 # error "DATA_ROLL_PTR_LEN != 7" @@ -126,7 +128,7 @@ Reads a roll ptr from an index page. In case that the roll ptr size changes in some future version, this function should be used instead of mach_read_... */ UNIV_INLINE -dulint +roll_ptr_t trx_read_roll_ptr( /*==============*/ /* out: roll ptr */ diff --git a/include/univ.i b/include/univ.i index eb0f24f082c..62ca52dd876 100644 --- a/include/univ.i +++ b/include/univ.i @@ -54,6 +54,8 @@ component, i.e. we show M.N.P as M.N */ INNODB_VERSION_MINOR, \ INNODB_VERSION_BUGFIX) +#define REFMAN "http://dev.mysql.com/doc/refman/5.1/en/" + #ifdef MYSQL_DYNAMIC_PLUGIN /* In the dynamic plugin, redefine some externally visible symbols in order not to conflict with the symbols of a builtin InnoDB. */ @@ -70,9 +72,10 @@ the virtual method table (vtable) in GCC 3. */ # include <windows.h> -# if !defined(WIN64) && !defined(_WIN64) -# define UNIV_CAN_USE_X86_ASSEMBLER -# endif +# if defined(HAVE_WINDOWS_ATOMICS) +/* If atomics are defined we use them in InnoDB mutex implementation */ +# define HAVE_ATOMIC_BUILTINS +# endif /* HAVE_WINDOWS_ATOMICS */ # ifdef _NT_ # define __NT__ @@ -106,17 +109,17 @@ if we are compiling on Windows. */ # include <sched.h> # endif -/* When compiling for Itanium IA64, undefine the flag below to prevent use -of the 32-bit x86 assembler in mutex operations. */ - -# if defined(__WIN__) && !defined(WIN64) && !defined(_WIN64) -# define UNIV_CAN_USE_X86_ASSEMBLER -# endif +# if defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_SOLARIS_ATOMICS) \ + || defined(HAVE_WINDOWS_ATOMICS) +/* If atomics are defined we use them in InnoDB mutex implementation */ +# define HAVE_ATOMIC_BUILTINS +# endif /* (HAVE_GCC_ATOMIC_BUILTINS) || (HAVE_SOLARIS_ATOMICS) + || (HAVE_WINDOWS_ATOMICS) */ /* For InnoDB rw_locks to work with atomics we need the thread_id to be no more than machine word wide. The following enables using atomics for InnoDB rw_locks where these conditions are met. */ -#ifdef HAVE_GCC_ATOMIC_BUILTINS +#ifdef HAVE_ATOMIC_BUILTINS /* if HAVE_ATOMIC_PTHREAD_T is defined at this point that means that the code from plug.in has defined it and we do not need to include ut0auxconf.h which would either define HAVE_ATOMIC_PTHREAD_T or will @@ -129,7 +132,7 @@ from Makefile.in->ut0auxconf.h */ # ifdef HAVE_ATOMIC_PTHREAD_T # define INNODB_RW_LOCKS_USE_ATOMICS # endif /* HAVE_ATOMIC_PTHREAD_T */ -#endif /* HAVE_GCC_ATOMIC_BUILTINS */ +#endif /* HAVE_ATOMIC_BUILTINS */ /* We only try to do explicit inlining of functions with gcc and Microsoft Visual C++ */ diff --git a/include/ut0byte.h b/include/ut0byte.h index 24aac1678b3..c0e6d4c24be 100644 --- a/include/ut0byte.h +++ b/include/ut0byte.h @@ -204,8 +204,12 @@ Tests if two dulints are equal. */ Sort function for dulint arrays. */ UNIV_INTERN void -ut_dulint_sort(dulint* arr, dulint* aux_arr, ulint low, ulint high); -/*===============================================================*/ +ut_dulint_sort( +/*===========*/ + dulint* arr, /* in/out: array to be sorted */ + dulint* aux_arr,/* in/out: auxiliary array (same size as arr) */ + ulint low, /* in: low bound of sort interval, inclusive */ + ulint high); /* in: high bound of sort interval, noninclusive */ #endif /* notdefined */ /************************************************************* diff --git a/include/ut0ut.h b/include/ut0ut.h index 06b5bbcb221..b3b3671ece9 100644 --- a/include/ut0ut.h +++ b/include/ut0ut.h @@ -165,6 +165,7 @@ UNIV_INTERN ib_time_t ut_time(void); /*=========*/ + /* out: system time */ /************************************************************** Returns system time. Upon successful completion, the value 0 is returned; otherwise the @@ -305,12 +306,14 @@ ut_copy_file( FILE* src); /* in: input file to be appended to output */ #endif /* !UNIV_HOTBACKUP */ -/************************************************************************** -snprintf(). */ - #ifdef __WIN__ +/************************************************************************** +A substitute for snprintf(3), formatted output conversion into +a limited buffer. */ +UNIV_INTERN int ut_snprintf( +/*========*/ /* out: number of characters that would have been printed if the size were unlimited, not including the terminating @@ -320,7 +323,7 @@ ut_snprintf( const char* fmt, /* in: format */ ...); /* in: format values */ #else -#define ut_snprintf snprintf +# define ut_snprintf snprintf #endif /* __WIN__ */ #ifndef UNIV_NONINL diff --git a/include/ut0vec.ic b/include/ut0vec.ic index b0e853717e3..cda1a825734 100644 --- a/include/ut0vec.ic +++ b/include/ut0vec.ic @@ -81,8 +81,9 @@ Test whether a vector is empty or not. */ UNIV_INLINE ibool ib_vector_is_empty( -/*===============*/ /* out: TRUE if empty else FALSE */ - const ib_vector_t* vec) /* in vector to test */ +/*===============*/ + /* out: TRUE if empty */ + const ib_vector_t* vec) /* in: vector */ { return(ib_vector_size(vec) == 0); } diff --git a/include/ut0wqueue.h b/include/ut0wqueue.h index 6bb80dad532..6ba36aec55e 100644 --- a/include/ut0wqueue.h +++ b/include/ut0wqueue.h @@ -64,6 +64,7 @@ Wait for a work item to appear in the queue. */ UNIV_INTERN void* ib_wqueue_wait( +/*===========*/ /* out: work item */ ib_wqueue_t* wq); /* in: work queue */ diff --git a/lock/lock0lock.c b/lock/lock0lock.c index 30591598d98..9ed32070b7b 100644 --- a/lock/lock0lock.c +++ b/lock/lock0lock.c @@ -452,7 +452,7 @@ ibool lock_check_trx_id_sanity( /*=====================*/ /* out: TRUE if ok */ - dulint trx_id, /* in: trx id */ + trx_id_t trx_id, /* in: trx id */ const rec_t* rec, /* in: user record */ dict_index_t* index, /* in: index */ const ulint* offsets, /* in: rec_get_offsets(rec, index) */ @@ -510,7 +510,7 @@ lock_clust_rec_cons_read_sees( const ulint* offsets,/* in: rec_get_offsets(rec, index) */ read_view_t* view) /* in: consistent read view */ { - dulint trx_id; + trx_id_t trx_id; ut_ad(dict_index_is_clust(index)); ut_ad(page_rec_is_user_rec(rec)); @@ -549,7 +549,7 @@ lock_sec_rec_cons_read_sees( by a read cursor */ const read_view_t* view) /* in: consistent read view */ { - dulint max_trx_id; + trx_id_t max_trx_id; ut_ad(page_rec_is_user_rec(rec)); @@ -563,6 +563,7 @@ lock_sec_rec_cons_read_sees( } max_trx_id = page_get_max_trx_id(page_align(rec)); + ut_ad(!ut_dulint_is_zero(max_trx_id)); return(ut_dulint_cmp(max_trx_id, view->up_limit_id) < 0); } @@ -4342,6 +4343,7 @@ static ulint lock_get_n_rec_locks(void) /*======================*/ + /* out: number of record locks */ { lock_t* lock; ulint n_locks = 0; @@ -4923,10 +4925,11 @@ lock_rec_insert_check_and_lock( DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, does nothing */ - rec_t* rec, /* in: record after which to insert */ + const rec_t* rec, /* in: record after which to insert */ buf_block_t* block, /* in/out: buffer block of rec */ dict_index_t* index, /* in: index */ que_thr_t* thr, /* in: query thread */ + mtr_t* mtr, /* in/out: mini-transaction */ ibool* inherit)/* out: set to TRUE if the new inserted record maybe should inherit LOCK_GAP type locks from the successor @@ -4946,7 +4949,7 @@ lock_rec_insert_check_and_lock( } trx = thr_get_trx(thr); - next_rec = page_rec_get_next(rec); + next_rec = page_rec_get_next((rec_t*) rec); next_rec_heap_no = page_rec_get_heap_no(next_rec); lock_mutex_enter_kernel(); @@ -4969,7 +4972,7 @@ lock_rec_insert_check_and_lock( /* Update the page max trx id field */ page_update_max_trx_id(block, buf_block_get_page_zip(block), - trx->id); + trx->id, mtr); } *inherit = FALSE; @@ -5008,7 +5011,7 @@ lock_rec_insert_check_and_lock( /* Update the page max trx id field */ page_update_max_trx_id(block, buf_block_get_page_zip(block), - trx->id); + trx->id, mtr); } #ifdef UNIV_DEBUG @@ -5144,13 +5147,14 @@ lock_sec_rec_modify_check_and_lock( ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, does nothing */ buf_block_t* block, /* in/out: buffer block of rec */ - rec_t* rec, /* in: record which should be + const rec_t* rec, /* in: record which should be modified; NOTE: as this is a secondary index, we always have to modify the clustered index record first: see the comment below */ dict_index_t* index, /* in: secondary index */ - que_thr_t* thr) /* in: query thread */ + que_thr_t* thr, /* in: query thread */ + mtr_t* mtr) /* in/out: mini-transaction */ { ulint err; ulint heap_no; @@ -5199,7 +5203,7 @@ lock_sec_rec_modify_check_and_lock( /* Update the page max trx id field */ page_update_max_trx_id(block, buf_block_get_page_zip(block), - thr_get_trx(thr)->id); + thr_get_trx(thr)->id, mtr); } return(err); diff --git a/log/log0log.c b/log/log0log.c index 63da4c9134f..b8146bde61b 100644 --- a/log/log0log.c +++ b/log/log0log.c @@ -177,6 +177,7 @@ static ib_uint64_t log_buf_pool_get_oldest_modification(void) /*======================================*/ + /* out: LSN of oldest modification */ { ib_uint64_t lsn; @@ -727,8 +728,7 @@ failure: " After an ERROR-FREE shutdown\n" "InnoDB: of mysqld you can adjust the size of" " ib_logfiles, as explained in\n" - "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "adding-and-removing.html\n" + "InnoDB: " REFMAN "adding-and-removing.html\n" "InnoDB: Cannot continue operation." " Calling exit(1).\n", (ulong)srv_thread_concurrency); diff --git a/log/log0recv.c b/log/log0recv.c index 6d3593e0ca7..db60ffb9961 100644 --- a/log/log0recv.c +++ b/log/log0recv.c @@ -612,8 +612,7 @@ not_consistent: "InnoDB: to create the InnoDB data files," " but log file creation failed.\n" "InnoDB: If that is the case, please refer to\n" - "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "error-creating-innodb.html\n"); + "InnoDB: " REFMAN "error-creating-innodb.html\n"); return(DB_ERROR); } @@ -1109,7 +1108,7 @@ recv_parse_or_apply_log_rec_body( case MLOG_FILE_RENAME: case MLOG_FILE_DELETE: case MLOG_FILE_CREATE2: - ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, 0); + ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, 0, 0); break; case MLOG_ZIP_WRITE_NODE_PTR: ut_ad(!page || page_type == FIL_PAGE_INDEX); @@ -2041,8 +2040,7 @@ recv_report_corrupt_log( "InnoDB: far enough in recovery! Please run CHECK TABLE\n" "InnoDB: on your InnoDB tables to check that they are ok!\n" "InnoDB: If mysqld crashes after this recovery, look at\n" - "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "forcing-recovery.html\n" + "InnoDB: " REFMAN "forcing-recovery.html\n" "InnoDB: about forcing recovery.\n", stderr); fflush(stderr); @@ -2160,7 +2158,8 @@ loop: point to the datadir we should use there */ if (NULL == fil_op_log_parse_or_replay( - body, end_ptr, type, space)) { + body, end_ptr, type, + space, page_no)) { fprintf(stderr, "InnoDB: Error: file op" " log record of type %lu" diff --git a/mtr/mtr0log.c b/mtr/mtr0log.c index d21a7cacd34..f75b52c5274 100644 --- a/mtr/mtr0log.c +++ b/mtr/mtr0log.c @@ -541,8 +541,7 @@ mlog_parse_index( /* out: parsed record end, NULL if not a complete record */ byte* ptr, /* in: buffer */ - byte* end_ptr,/* in: buffer end */ - /* out: new value of log_ptr */ + const byte* end_ptr,/* in: buffer end */ ibool comp, /* in: TRUE=compact record format */ dict_index_t** index) /* out, own: dummy index */ { diff --git a/mysql-test/innodb.result b/mysql-test/innodb.result index 385084fb457..e3c52fd7b6b 100644 --- a/mysql-test/innodb.result +++ b/mysql-test/innodb.result @@ -1736,36 +1736,36 @@ select count(*) from t1 where x = 18446744073709551601; count(*) 1 drop table t1; -show status like "Innodb_buffer_pool_pages_total"; -Variable_name Value -Innodb_buffer_pool_pages_total 511 -show status like "Innodb_page_size"; -Variable_name Value -Innodb_page_size 16384 -show status like "Innodb_rows_deleted"; -Variable_name Value -Innodb_rows_deleted 71 -show status like "Innodb_rows_inserted"; -Variable_name Value -Innodb_rows_inserted 1084 -show status like "Innodb_rows_updated"; -Variable_name Value -Innodb_rows_updated 885 -show status like "Innodb_row_lock_waits"; -Variable_name Value -Innodb_row_lock_waits 0 -show status like "Innodb_row_lock_current_waits"; -Variable_name Value -Innodb_row_lock_current_waits 0 -show status like "Innodb_row_lock_time"; -Variable_name Value -Innodb_row_lock_time 0 -show status like "Innodb_row_lock_time_max"; -Variable_name Value -Innodb_row_lock_time_max 0 -show status like "Innodb_row_lock_time_avg"; -Variable_name Value -Innodb_row_lock_time_avg 0 +SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_buffer_pool_pages_total'; +variable_value +511 +SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_page_size'; +variable_value +16384 +SELECT variable_value - @innodb_rows_deleted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_deleted'; +variable_value - @innodb_rows_deleted_orig +71 +SELECT variable_value - @innodb_rows_inserted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_inserted'; +variable_value - @innodb_rows_inserted_orig +1084 +SELECT variable_value - @innodb_rows_updated_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_updated'; +variable_value - @innodb_rows_updated_orig +885 +SELECT variable_value - @innodb_row_lock_waits_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_waits'; +variable_value - @innodb_row_lock_waits_orig +0 +SELECT variable_value - @innodb_row_lock_current_waits_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_current_waits'; +variable_value - @innodb_row_lock_current_waits_orig +0 +SELECT variable_value - @innodb_row_lock_time_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time'; +variable_value - @innodb_row_lock_time_orig +0 +SELECT variable_value - @innodb_row_lock_time_max_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time_max'; +variable_value - @innodb_row_lock_time_max_orig +0 +SELECT variable_value - @innodb_row_lock_time_avg_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time_avg'; +variable_value - @innodb_row_lock_time_avg_orig +0 show variables like "innodb_sync_spin_loops"; Variable_name Value innodb_sync_spin_loops 20 diff --git a/mysql-test/innodb.test b/mysql-test/innodb.test index 447abee21cd..0d8e164de34 100644 --- a/mysql-test/innodb.test +++ b/mysql-test/innodb.test @@ -6,22 +6,45 @@ # Use innodb_mysql.[test|result] files instead. # # # # If nevertheless you need to make some changes here, please, forward # -# your commit message To: dev@innodb.com Cc: dev-innodb@mysql.com # +# your commit message # +# To: innodb_dev_ww@oracle.com # +# Cc: dev-innodb@mysql.com # # (otherwise your changes may be erased). # # # ####################################################################### -- source include/have_innodb.inc -# -# Small basic test with ignore -# +# Save the original values of some variables in order to be able to +# estimate how much they have changed during the tests. Previously this +# test assumed that e.g. rows_deleted is 0 here and after deleting 23 +# rows it expected that rows_deleted will be 23. Now we do not make +# assumptions about the values of the variables at the beginning, e.g. +# rows_deleted should be 23 + "rows_deleted before the test". This allows +# the test to be run multiple times without restarting the mysqld server. +# See Bug#43309 Test main.innodb can't be run twice +-- disable_query_log +SET @innodb_thread_concurrency_orig = @@innodb_thread_concurrency; + +SET @innodb_rows_deleted_orig = (SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_deleted'); +SET @innodb_rows_inserted_orig = (SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_inserted'); +SET @innodb_rows_updated_orig = (SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_updated'); +SET @innodb_row_lock_waits_orig = (SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_waits'); +SET @innodb_row_lock_current_waits_orig = (SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_current_waits'); +SET @innodb_row_lock_time_orig = (SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time'); +SET @innodb_row_lock_time_max_orig = (SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time_max'); +SET @innodb_row_lock_time_avg_orig = (SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time_avg'); +-- enable_query_log --disable_warnings drop table if exists t1,t2,t3,t4; drop database if exists mysqltest; --enable_warnings +# +# Small basic test with ignore +# + create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) engine=innodb; insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David'), (2, 'Erik'), (3, 'Sasha'), (3, 'Jeremy'), (4, 'Matt'); @@ -1295,18 +1318,18 @@ drop table t1; # Test for testable InnoDB status variables. This test # uses previous ones(pages_created, rows_deleted, ...). --replace_result 512 511 -show status like "Innodb_buffer_pool_pages_total"; -show status like "Innodb_page_size"; -show status like "Innodb_rows_deleted"; -show status like "Innodb_rows_inserted"; -show status like "Innodb_rows_updated"; +SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_buffer_pool_pages_total'; +SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_page_size'; +SELECT variable_value - @innodb_rows_deleted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_deleted'; +SELECT variable_value - @innodb_rows_inserted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_inserted'; +SELECT variable_value - @innodb_rows_updated_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_updated'; # Test for row locks InnoDB status variables. -show status like "Innodb_row_lock_waits"; -show status like "Innodb_row_lock_current_waits"; -show status like "Innodb_row_lock_time"; -show status like "Innodb_row_lock_time_max"; -show status like "Innodb_row_lock_time_avg"; +SELECT variable_value - @innodb_row_lock_waits_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_waits'; +SELECT variable_value - @innodb_row_lock_current_waits_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_current_waits'; +SELECT variable_value - @innodb_row_lock_time_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time'; +SELECT variable_value - @innodb_row_lock_time_max_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time_max'; +SELECT variable_value - @innodb_row_lock_time_avg_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time_avg'; # Test for innodb_sync_spin_loops variable show variables like "innodb_sync_spin_loops"; @@ -2524,6 +2547,10 @@ DROP TABLE bug35537; DISCONNECT c1; CONNECTION default; +SET GLOBAL innodb_thread_concurrency = @innodb_thread_concurrency_orig; + +-- enable_query_log + ####################################################################### # # # Please, DO NOT TOUCH this file as well as the innodb.result file. # @@ -2532,7 +2559,9 @@ CONNECTION default; # Use innodb_mysql.[test|result] files instead. # # # # If nevertheless you need to make some changes here, please, forward # -# your commit message To: dev@innodb.com Cc: dev-innodb@mysql.com # +# your commit message # +# To: innodb_dev_ww@oracle.com # +# Cc: dev-innodb@mysql.com # # (otherwise your changes may be erased). # # # ####################################################################### diff --git a/mysql-test/innodb_bug42101-nonzero-master.opt b/mysql-test/innodb_bug42101-nonzero-master.opt new file mode 100644 index 00000000000..d71dbe17d5b --- /dev/null +++ b/mysql-test/innodb_bug42101-nonzero-master.opt @@ -0,0 +1 @@ +--innodb_commit_concurrency=1 diff --git a/mysql-test/innodb_bug42101-nonzero.result b/mysql-test/innodb_bug42101-nonzero.result new file mode 100644 index 00000000000..8a14296381c --- /dev/null +++ b/mysql-test/innodb_bug42101-nonzero.result @@ -0,0 +1,22 @@ +set global innodb_commit_concurrency=0; +ERROR HY000: Incorrect arguments to SET +select @@innodb_commit_concurrency; +@@innodb_commit_concurrency +1 +set global innodb_commit_concurrency=1; +select @@innodb_commit_concurrency; +@@innodb_commit_concurrency +1 +set global innodb_commit_concurrency=42; +select @@innodb_commit_concurrency; +@@innodb_commit_concurrency +42 +set global innodb_commit_concurrency=0; +ERROR HY000: Incorrect arguments to SET +select @@innodb_commit_concurrency; +@@innodb_commit_concurrency +42 +set global innodb_commit_concurrency=1; +select @@innodb_commit_concurrency; +@@innodb_commit_concurrency +1 diff --git a/mysql-test/innodb_bug42101-nonzero.test b/mysql-test/innodb_bug42101-nonzero.test new file mode 100644 index 00000000000..c691a234c51 --- /dev/null +++ b/mysql-test/innodb_bug42101-nonzero.test @@ -0,0 +1,19 @@ +# +# Bug#42101 Race condition in innodb_commit_concurrency +# http://bugs.mysql.com/42101 +# + +-- source include/have_innodb.inc + +--error ER_WRONG_ARGUMENTS +set global innodb_commit_concurrency=0; +select @@innodb_commit_concurrency; +set global innodb_commit_concurrency=1; +select @@innodb_commit_concurrency; +set global innodb_commit_concurrency=42; +select @@innodb_commit_concurrency; +--error ER_WRONG_ARGUMENTS +set global innodb_commit_concurrency=0; +select @@innodb_commit_concurrency; +set global innodb_commit_concurrency=1; +select @@innodb_commit_concurrency; diff --git a/mysql-test/innodb_bug42101.result b/mysql-test/innodb_bug42101.result new file mode 100644 index 00000000000..9a9c8e0ce9b --- /dev/null +++ b/mysql-test/innodb_bug42101.result @@ -0,0 +1,18 @@ +set global innodb_commit_concurrency=0; +select @@innodb_commit_concurrency; +@@innodb_commit_concurrency +0 +set global innodb_commit_concurrency=1; +ERROR HY000: Incorrect arguments to SET +select @@innodb_commit_concurrency; +@@innodb_commit_concurrency +0 +set global innodb_commit_concurrency=42; +ERROR HY000: Incorrect arguments to SET +select @@innodb_commit_concurrency; +@@innodb_commit_concurrency +0 +set global innodb_commit_concurrency=0; +select @@innodb_commit_concurrency; +@@innodb_commit_concurrency +0 diff --git a/mysql-test/innodb_bug42101.test b/mysql-test/innodb_bug42101.test new file mode 100644 index 00000000000..13d531ecde7 --- /dev/null +++ b/mysql-test/innodb_bug42101.test @@ -0,0 +1,17 @@ +# +# Bug#42101 Race condition in innodb_commit_concurrency +# http://bugs.mysql.com/42101 +# + +-- source include/have_innodb.inc + +set global innodb_commit_concurrency=0; +select @@innodb_commit_concurrency; +--error ER_WRONG_ARGUMENTS +set global innodb_commit_concurrency=1; +select @@innodb_commit_concurrency; +--error ER_WRONG_ARGUMENTS +set global innodb_commit_concurrency=42; +select @@innodb_commit_concurrency; +set global innodb_commit_concurrency=0; +select @@innodb_commit_concurrency; diff --git a/mysql-test/innodb_bug44032.result b/mysql-test/innodb_bug44032.result new file mode 100644 index 00000000000..da2a000b06e --- /dev/null +++ b/mysql-test/innodb_bug44032.result @@ -0,0 +1,7 @@ +CREATE TABLE bug44032(c CHAR(3) CHARACTER SET UTF8) ROW_FORMAT=REDUNDANT +ENGINE=InnoDB; +INSERT INTO bug44032 VALUES('abc'),(0xEFBCA4EFBCA4EFBCA4); +UPDATE bug44032 SET c='DDD' WHERE c=0xEFBCA4EFBCA4EFBCA4; +UPDATE bug44032 SET c=NULL WHERE c='DDD'; +UPDATE bug44032 SET c='DDD' WHERE c IS NULL; +DROP TABLE bug44032; diff --git a/mysql-test/innodb_bug44032.test b/mysql-test/innodb_bug44032.test new file mode 100644 index 00000000000..a963cb8b68f --- /dev/null +++ b/mysql-test/innodb_bug44032.test @@ -0,0 +1,13 @@ +# Bug44032 no update-in-place of UTF-8 columns in ROW_FORMAT=REDUNDANT +# (btr_cur_update_in_place not invoked when updating from/to NULL; +# the update is performed by delete and insert instead) + +-- source include/have_innodb.inc + +CREATE TABLE bug44032(c CHAR(3) CHARACTER SET UTF8) ROW_FORMAT=REDUNDANT +ENGINE=InnoDB; +INSERT INTO bug44032 VALUES('abc'),(0xEFBCA4EFBCA4EFBCA4); +UPDATE bug44032 SET c='DDD' WHERE c=0xEFBCA4EFBCA4EFBCA4; +UPDATE bug44032 SET c=NULL WHERE c='DDD'; +UPDATE bug44032 SET c='DDD' WHERE c IS NULL; +DROP TABLE bug44032; diff --git a/os/os0file.c b/os/os0file.c index 2786b0ed336..5c6e2cc5d6a 100644 --- a/os/os0file.c +++ b/os/os0file.c @@ -360,7 +360,7 @@ os_file_get_last_error( "InnoDB: Some operating system error numbers" " are described at\n" "InnoDB: " - "http://dev.mysql.com/doc/refman/5.1/en/" + REFMAN "operating-system-error-codes.html\n"); } } @@ -419,7 +419,7 @@ os_file_get_last_error( "InnoDB: Some operating system" " error numbers are described at\n" "InnoDB: " - "http://dev.mysql.com/doc/refman/5.1/en/" + REFMAN "operating-system-error-codes.html\n"); } } @@ -794,8 +794,7 @@ next_file: /* TODO: MySQL has apparently its own symlink implementation in Windows, dbname.sym can redirect a database directory: - http://dev.mysql.com/doc/refman/5.1/en/ - windows-symbolic-links.html */ + REFMAN "windows-symbolic-links.html" */ info->type = OS_FILE_TYPE_LINK; } else if (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { @@ -2573,8 +2572,7 @@ retry: "InnoDB: Some operating system error numbers" " are described at\n" "InnoDB: " - "http://dev.mysql.com/doc/refman/5.1/en/" - "operating-system-error-codes.html\n", + REFMAN "operating-system-error-codes.html\n", name, (ulong) offset_high, (ulong) offset, (ulong) GetLastError()); @@ -2645,8 +2643,7 @@ retry: "InnoDB: Some operating system error numbers" " are described at\n" "InnoDB: " - "http://dev.mysql.com/doc/refman/5.1/en/" - "operating-system-error-codes.html\n"); + REFMAN "operating-system-error-codes.html\n"); os_has_said_disk_full = TRUE; } @@ -2688,8 +2685,7 @@ retry: "InnoDB: Some operating system error numbers" " are described at\n" "InnoDB: " - "http://dev.mysql.com/doc/refman/5.1/en/" - "operating-system-error-codes.html\n"); + REFMAN "operating-system-error-codes.html\n"); os_has_said_disk_full = TRUE; } @@ -3773,11 +3769,14 @@ os_aio( ulint offset_high, /* in: most significant 32 bits of offset */ ulint n, /* in: number of bytes to read or write */ - fil_node_t* message1,/* in: messages for the aio handler (these - can be used to identify a completed aio - operation); if mode is OS_AIO_SYNC, these - are ignored */ - void* message2) + fil_node_t* message1,/* in: message for the aio handler + (can be used to identify a completed + aio operation); ignored if mode is + OS_AIO_SYNC */ + void* message2)/* in: message for the aio handler + (can be used to identify a completed + aio operation); ignored if mode is + OS_AIO_SYNC */ { os_aio_array_t* array; os_aio_slot_t* slot; diff --git a/os/os0proc.c b/os/os0proc.c index 8d4a71f8c4e..f5bc665a073 100644 --- a/os/os0proc.c +++ b/os/os0proc.c @@ -52,6 +52,7 @@ UNIV_INTERN ulint os_proc_get_number(void) /*====================*/ + /* out: process id as a number */ { #ifdef __WIN__ return((ulint)GetCurrentProcessId()); diff --git a/os/os0thread.c b/os/os0thread.c index 0da01a95048..67775b677d8 100644 --- a/os/os0thread.c +++ b/os/os0thread.c @@ -67,7 +67,8 @@ UNIV_INTERN ulint os_thread_pf( /*=========*/ - os_thread_id_t a) + /* out: thread identifier as a number */ + os_thread_id_t a) /* in: OS thread identifier */ { #ifdef UNIV_HPUX10 /* In HP-UX-10.20 a pthread_t is a struct of 3 fields: field1, field2, @@ -87,6 +88,7 @@ UNIV_INTERN os_thread_id_t os_thread_get_curr_id(void) /*=======================*/ + /* out: current thread identifier */ { #ifdef __WIN__ return(GetCurrentThreadId()); @@ -240,6 +242,7 @@ UNIV_INTERN os_thread_t os_thread_get_curr(void) /*====================*/ + /* out: current thread handle */ { #ifdef __WIN__ return(GetCurrentThread()); @@ -359,6 +362,7 @@ UNIV_INTERN ulint os_thread_get_last_error(void) /*==========================*/ + /* out: last error on Windows, 0 otherwise */ { #ifdef __WIN__ return(GetLastError()); diff --git a/page/page0cur.c b/page/page0cur.c index caf198ab3e7..11c130a35eb 100644 --- a/page/page0cur.c +++ b/page/page0cur.c @@ -30,16 +30,49 @@ Created 10/4/1994 Heikki Tuuri #include "page0zip.h" #include "mtr0log.h" #include "log0recv.h" +#include "ut0ut.h" #ifndef UNIV_HOTBACKUP #include "rem0cmp.h" -static ulint page_rnd = 976722341; - #ifdef PAGE_CUR_ADAPT # ifdef UNIV_SEARCH_PERF_STAT static ulint page_cur_short_succ = 0; # endif /* UNIV_SEARCH_PERF_STAT */ +/*********************************************************************** +This is a linear congruential generator PRNG. Returns a pseudo random +number between 0 and 2^64-1 inclusive. The formula and the constants +being used are: +X[n+1] = (a * X[n] + c) mod m +where: +X[0] = ut_time_us(NULL) +a = 1103515245 (3^5 * 5 * 7 * 129749) +c = 12345 (3 * 5 * 823) +m = 18446744073709551616 (2^64) +*/ +static +ib_uint64_t +page_cur_lcg_prng(void) +/*===================*/ + /* out: number between 0 and 2^64-1 */ +{ +#define LCG_a 1103515245 +#define LCG_c 12345 + static ib_uint64_t lcg_current = 0; + static ibool initialized = FALSE; + + if (!initialized) { + lcg_current = (ib_uint64_t) ut_time_us(NULL); + initialized = TRUE; + } + + /* no need to "% 2^64" explicitly because lcg_current is + 64 bit and this will be done anyway */ + lcg_current = LCG_a * lcg_current + LCG_c; + + return(lcg_current); +} + /******************************************************************** Tries a search shortcut based on the last insert. */ UNIV_INLINE @@ -524,9 +557,7 @@ page_cur_open_on_rnd_user_rec( return; } - page_rnd += 87584577; - - rnd = page_rnd % n_recs; + rnd = (ulint) (page_cur_lcg_prng() % n_recs); do { page_cur_move_to_next(cursor); @@ -1930,3 +1961,30 @@ page_cur_delete_rec( ut_a(!page_zip || page_zip_validate(page_zip, page)); #endif /* UNIV_ZIP_DEBUG */ } + +#ifdef UNIV_COMPILE_TEST_FUNCS + +/*********************************************************************** +Print the first n numbers, generated by page_cur_lcg_prng() to make sure +(visually) that it works properly. */ +void +test_page_cur_lcg_prng( +/*===================*/ + int n) /* in: print first n numbers */ +{ + int i; + unsigned long long rnd; + + for (i = 0; i < n; i++) { + rnd = page_cur_lcg_prng(); + printf("%llu\t%%2=%llu %%3=%llu %%5=%llu %%7=%llu %%11=%llu\n", + rnd, + rnd % 2, + rnd % 3, + rnd % 5, + rnd % 7, + rnd % 11); + } +} + +#endif /* UNIV_COMPILE_TEST_FUNCS */ diff --git a/page/page0page.c b/page/page0page.c index ea4e259bcb3..3217a44e065 100644 --- a/page/page0page.c +++ b/page/page0page.c @@ -209,7 +209,8 @@ page_set_max_trx_id( /*================*/ buf_block_t* block, /* in/out: page */ page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */ - dulint trx_id) /* in: transaction id */ + trx_id_t trx_id, /* in: transaction id */ + mtr_t* mtr) /* in/out: mini-transaction, or NULL */ { page_t* page = buf_block_get_frame(block); #ifndef UNIV_HOTBACKUP @@ -218,17 +219,24 @@ page_set_max_trx_id( if (is_hashed) { rw_lock_x_lock(&btr_search_latch); } + + ut_ad(!mtr || mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); #endif /* !UNIV_HOTBACKUP */ /* It is not necessary to write this change to the redo log, as during a database recovery we assume that the max trx id of every page is the maximum trx id assigned before the crash. */ - mach_write_to_8(page + (PAGE_HEADER + PAGE_MAX_TRX_ID), trx_id); if (UNIV_LIKELY_NULL(page_zip)) { + mach_write_to_8(page + (PAGE_HEADER + PAGE_MAX_TRX_ID), trx_id); page_zip_write_header(page_zip, page + (PAGE_HEADER + PAGE_MAX_TRX_ID), - 8, NULL); + 8, mtr); + } else if (mtr) { + mlog_write_dulint(page + (PAGE_HEADER + PAGE_MAX_TRX_ID), + trx_id, mtr); + } else { + mach_write_to_8(page + (PAGE_HEADER + PAGE_MAX_TRX_ID), trx_id); } #ifndef UNIV_HOTBACKUP @@ -447,7 +455,7 @@ page_create_low( page_header_set_field(page, NULL, PAGE_DIRECTION, PAGE_NO_DIRECTION); page_header_set_field(page, NULL, PAGE_N_DIRECTION, 0); page_header_set_field(page, NULL, PAGE_N_RECS, 0); - page_set_max_trx_id(block, NULL, ut_dulint_zero); + page_set_max_trx_id(block, NULL, ut_dulint_zero, NULL); memset(heap_top, 0, UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START - page_offset(heap_top)); @@ -692,8 +700,10 @@ page_copy_rec_list_end( lock_move_rec_list_end(new_block, block, rec); - page_update_max_trx_id(new_block, new_page_zip, - page_get_max_trx_id(page)); + if (dict_index_is_sec_or_ibuf(index) && page_is_leaf(page)) { + page_update_max_trx_id(new_block, new_page_zip, + page_get_max_trx_id(page), mtr); + } btr_search_move_or_delete_hash_entries(new_block, block, index); @@ -803,8 +813,12 @@ page_copy_rec_list_start( /* Update MAX_TRX_ID, the lock table, and possible hash index */ - page_update_max_trx_id(new_block, new_page_zip, - page_get_max_trx_id(page_align(rec))); + if (dict_index_is_sec_or_ibuf(index) + && page_is_leaf(page_align(rec))) { + page_update_max_trx_id(new_block, new_page_zip, + page_get_max_trx_id(page_align(rec)), + mtr); + } lock_move_rec_list_start(new_block, block, rec, ret); diff --git a/page/page0zip.c b/page/page0zip.c index 76783b9a039..ba590f37a33 100644 --- a/page/page0zip.c +++ b/page/page0zip.c @@ -273,6 +273,8 @@ page_zip_compress_write_log( byte* log_ptr; ulint trailer_size; + ut_ad(!dict_index_is_ibuf(index)); + log_ptr = mlog_open(mtr, 11 + 2 + 2); if (!log_ptr) { @@ -346,6 +348,7 @@ page_zip_get_n_prev_extern( ut_ad(page_is_comp(page)); ut_ad(dict_table_is_comp(index->table)); ut_ad(dict_index_is_clust(index)); + ut_ad(!dict_index_is_ibuf(index)); heap_no = rec_get_heap_no_new(rec); ut_ad(heap_no >= PAGE_HEAP_NO_USER_LOW); @@ -648,9 +651,9 @@ static void* page_zip_malloc( /*============*/ - void* opaque, - uInt items, - uInt size) + void* opaque, /* in/out: memory heap */ + uInt items, /* in: number of items to allocate */ + uInt size) /* in: size of an item in bytes */ { return(mem_heap_alloc(opaque, items * size)); } @@ -661,8 +664,8 @@ static void page_zip_free( /*==========*/ - void* opaque __attribute__((unused)), - void* address __attribute__((unused))) + void* opaque __attribute__((unused)), /* in: memory heap */ + void* address __attribute__((unused)))/* in: object to free */ { } @@ -1137,6 +1140,8 @@ page_zip_compress( ut_a(fil_page_get_type(page) == FIL_PAGE_INDEX); ut_ad(page_simple_validate_new((page_t*) page)); ut_ad(page_zip_simple_validate(page_zip)); + ut_ad(dict_table_is_comp(index->table)); + ut_ad(!dict_index_is_ibuf(index)); UNIV_MEM_ASSERT_RW(page, UNIV_PAGE_SIZE); @@ -3169,6 +3174,8 @@ page_zip_validate( #endif /* UNIV_ZIP_DEBUG */ #ifdef UNIV_DEBUG +/************************************************************************** +Assert that the compressed and decompressed page headers match. */ static ibool page_zip_header_cmp( @@ -3795,8 +3802,8 @@ page_zip_write_trx_id_and_roll_ptr( byte* rec, /* in/out: record */ const ulint* offsets,/* in: rec_get_offsets(rec, index) */ ulint trx_id_col,/* in: column number of TRX_ID in rec */ - dulint trx_id, /* in: transaction identifier */ - dulint roll_ptr)/* in: roll_ptr */ + trx_id_t trx_id, /* in: transaction identifier */ + roll_ptr_t roll_ptr)/* in: roll_ptr */ { byte* field; byte* storage; @@ -4369,6 +4376,7 @@ page_zip_reorganize( ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); ut_ad(page_is_comp(page)); + ut_ad(!dict_index_is_ibuf(index)); /* Note that page_zip_validate(page_zip, page) may fail here. */ UNIV_MEM_ASSERT_RW(page, UNIV_PAGE_SIZE); UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip)); @@ -4400,8 +4408,13 @@ page_zip_reorganize( page_copy_rec_list_end_no_locks(block, temp_block, page_get_infimum_rec(temp_page), index, mtr); - /* Copy max trx id to recreated page */ - page_set_max_trx_id(block, NULL, page_get_max_trx_id(temp_page)); + + if (!dict_index_is_clust(index) && page_is_leaf(temp_page)) { + /* Copy max trx id to recreated page */ + trx_id_t max_trx_id = page_get_max_trx_id(temp_page); + page_set_max_trx_id(block, NULL, max_trx_id, NULL); + ut_ad(!ut_dulint_is_zero(max_trx_id)); + } /* Restore logging. */ mtr_set_log_mode(mtr, log_mode); @@ -4446,6 +4459,7 @@ page_zip_copy_recs( { ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX)); ut_ad(mtr_memo_contains_page(mtr, (page_t*) src, MTR_MEMO_PAGE_X_FIX)); + ut_ad(!dict_index_is_ibuf(index)); #ifdef UNIV_ZIP_DEBUG /* The B-tree operations that call this function may set FIL_PAGE_PREV or PAGE_LEVEL, causing a temporary min_rec_flag @@ -4459,6 +4473,11 @@ page_zip_copy_recs( ut_a(dict_index_is_clust(index)); } + /* The PAGE_MAX_TRX_ID must be set on leaf pages of secondary + indexes. It does not matter on other pages. */ + ut_a(dict_index_is_clust(index) || !page_is_leaf(src) + || !ut_dulint_is_zero(page_get_max_trx_id(src))); + UNIV_MEM_ASSERT_W(page, UNIV_PAGE_SIZE); UNIV_MEM_ASSERT_W(page_zip->data, page_zip_get_size(page_zip)); UNIV_MEM_ASSERT_RW(src, UNIV_PAGE_SIZE); diff --git a/pars/pars0pars.c b/pars/pars0pars.c index 62ae3b3d09b..55272cc5c5e 100644 --- a/pars/pars0pars.c +++ b/pars/pars0pars.c @@ -945,7 +945,8 @@ pars_process_assign_list( if (!dict_col_get_fixed_size( dict_index_get_nth_col(clust_index, - upd_field->field_no))) { + upd_field->field_no), + dict_table_is_comp(node->table))) { changes_field_size = 0; } @@ -1554,6 +1555,7 @@ UNIV_INTERN commit_node_t* pars_commit_statement(void) /*=======================*/ + /* out, own: commit node struct */ { return(commit_node_create(pars_sym_tab_global->heap)); } @@ -1564,6 +1566,7 @@ UNIV_INTERN roll_node_t* pars_rollback_statement(void) /*=========================*/ + /* out, own: rollback node struct */ { return(roll_node_create(pars_sym_tab_global->heap)); } diff --git a/plug.in b/plug.in index 7852ffeed94..9677847ffa9 100644 --- a/plug.in +++ b/plug.in @@ -46,6 +46,16 @@ MYSQL_PLUGIN_ACTIONS(innobase, [ irix*|osf*|sysv5uw7*|openbsd*) CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";; *solaris*|*SunOS*) + # Begin Solaris atomic function checks + AC_CHECK_FUNCS(atomic_cas_ulong atomic_cas_32 \ + atomic_cas_64 atomic_add_long, + AC_DEFINE( + [HAVE_SOLARIS_ATOMICS], + [1], + [Define to 1 if Solaris supports \ + atomic functions.])) + ### End Solaris atomic function checks + CFLAGS="$CFLAGS -DUNIV_SOLARIS";; esac INNODB_DYNAMIC_CFLAGS="-DMYSQL_DYNAMIC_PLUGIN" @@ -63,12 +73,17 @@ MYSQL_PLUGIN_ACTIONS(innobase, [ AC_TRY_RUN( [ #include <pthread.h> + #include <string.h> int main(int argc, char** argv) { pthread_t x1; pthread_t x2; pthread_t x3; + memset(&x1, 0x0, sizeof(x1)); + memset(&x2, 0x0, sizeof(x2)); + memset(&x3, 0x0, sizeof(x3)); + __sync_bool_compare_and_swap(&x1, x2, x3); return(0); @@ -83,6 +98,39 @@ MYSQL_PLUGIN_ACTIONS(innobase, [ AC_MSG_RESULT(no) ] ) + + # Try using solaris atomics on SunOS if GCC atomics are not available + AC_CHECK_DECLS( + [HAVE_ATOMIC_PTHREAD_T], + [ + AC_MSG_NOTICE(no need to check pthread_t size) + ], + [ + AC_CHECK_DECLS( + [HAVE_SOLARIS_ATOMICS], + [ + AC_MSG_CHECKING(checking if pthread_t size is integral) + AC_TRY_RUN( + [ + #include <pthread.h> + int main() + { + pthread_t x = 0; + return(0); + } + ], + [ + AC_DEFINE([HAVE_ATOMIC_PTHREAD_T], [1], + [pthread_t can be used by solaris atomics]) + AC_MSG_RESULT(yes) + # size of pthread_t is needed for typed solaris atomics + AC_CHECK_SIZEOF([pthread_t], [], [#include <pthread.h>]) + ], + [ + AC_MSG_RESULT(no) + ]) + ]) + ]) ]) # vim: set ft=config: diff --git a/read/read0read.c b/read/read0read.c index e3e5ee5d623..2c74082ecac 100644 --- a/read/read0read.c +++ b/read/read0read.c @@ -151,7 +151,7 @@ read_view_create_low( view = mem_heap_alloc(heap, sizeof(read_view_t)); view->n_trx_ids = n; - view->trx_ids = mem_heap_alloc(heap, n * sizeof(dulint)); + view->trx_ids = mem_heap_alloc(heap, n * sizeof *view->trx_ids); return(view); } @@ -166,8 +166,9 @@ read_view_t* read_view_oldest_copy_or_open_new( /*==============================*/ /* out, own: read view struct */ - dulint cr_trx_id, /* in: trx_id of creating - transaction, or (0, 0) used in purge*/ + trx_id_t cr_trx_id, /* in: trx_id of creating + transaction, or ut_dulint_zero + used in purge */ mem_heap_t* heap) /* in: memory heap from which allocated */ { @@ -249,9 +250,9 @@ read_view_t* read_view_open_now( /*===============*/ /* out, own: read view struct */ - dulint cr_trx_id, /* in: trx_id of creating - transaction, or (0, 0) used in - purge */ + trx_id_t cr_trx_id, /* in: trx_id of creating + transaction, or ut_dulint_zero + used in purge */ mem_heap_t* heap) /* in: memory heap from which allocated */ { @@ -358,7 +359,7 @@ UNIV_INTERN void read_view_print( /*============*/ - read_view_t* view) /* in: read view */ + const read_view_t* view) /* in: read view */ { ulint n_ids; ulint i; diff --git a/rem/rem0rec.c b/rem/rem0rec.c index e0b95ab61de..d3669906eff 100644 --- a/rem/rem0rec.c +++ b/rem/rem0rec.c @@ -949,7 +949,7 @@ rec_convert_dtuple_to_rec_old( ut_ad(dtuple_check_typed(dtuple)); n_fields = dtuple_get_n_fields(dtuple); - data_size = dtuple_get_data_size(dtuple); + data_size = dtuple_get_data_size(dtuple, 0); ut_ad(n_fields > 0); @@ -982,7 +982,7 @@ rec_convert_dtuple_to_rec_old( if (dfield_is_null(field)) { len = dtype_get_sql_null_size( - dfield_get_type(field)); + dfield_get_type(field), 0); data_write_sql_null(rec + end_offset, len); end_offset += len; @@ -1010,7 +1010,7 @@ rec_convert_dtuple_to_rec_old( if (dfield_is_null(field)) { len = dtype_get_sql_null_size( - dfield_get_type(field)); + dfield_get_type(field), 0); data_write_sql_null(rec + end_offset, len); end_offset += len; diff --git a/row/row0merge.c b/row/row0merge.c index 0d3c9bfec0d..44e8a121525 100644 --- a/row/row0merge.c +++ b/row/row0merge.c @@ -2193,10 +2193,10 @@ dict_index_t* row_merge_create_index( /*===================*/ /* out: index, or NULL on error */ - trx_t* trx, /* in/out: trx (sets error_state) */ - dict_table_t* table, /* in: the index is on this table */ - const merge_index_def_t* /* in: the index definition */ - index_def) + trx_t* trx, /* in/out: trx (sets error_state) */ + dict_table_t* table, /* in: the index is on this table */ + const merge_index_def_t*index_def) + /* in: the index definition */ { dict_index_t* index; ulint err; diff --git a/row/row0mysql.c b/row/row0mysql.c index bfc6caa0f4f..594e1ca9a5a 100644 --- a/row/row0mysql.c +++ b/row/row0mysql.c @@ -30,6 +30,7 @@ Created 9/17/2000 Heikki Tuuri #endif #include "row0ins.h" +#include "row0merge.h" #include "row0sel.h" #include "row0upd.h" #include "row0row.h" @@ -561,8 +562,7 @@ handle_new_error: "InnoDB: If the mysqld server crashes" " after the startup or when\n" "InnoDB: you dump the tables, look at\n" - "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "forcing-recovery.html" + "InnoDB: " REFMAN "forcing-recovery.html" " for help.\n", stderr); break; default: @@ -735,9 +735,8 @@ UNIV_INTERN void row_update_prebuilt_trx( /*====================*/ - /* out: prebuilt dtuple */ - row_prebuilt_t* prebuilt, /* in: prebuilt struct in MySQL - handle */ + row_prebuilt_t* prebuilt, /* in/out: prebuilt struct + in MySQL handle */ trx_t* trx) /* in: transaction handle */ { if (trx->magic_n != TRX_MAGIC_N) { @@ -1061,8 +1060,7 @@ row_insert_for_mysql( "InnoDB: the MySQL datadir, or have you" " used DISCARD TABLESPACE?\n" "InnoDB: Look from\n" - "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "innodb-troubleshooting.html\n" + "InnoDB: " REFMAN "innodb-troubleshooting.html\n" "InnoDB: how you can resolve the problem.\n", prebuilt->table->name); return(DB_ERROR); @@ -1297,8 +1295,7 @@ row_update_for_mysql( "InnoDB: the MySQL datadir, or have you" " used DISCARD TABLESPACE?\n" "InnoDB: Look from\n" - "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "innodb-troubleshooting.html\n" + "InnoDB: " REFMAN "innodb-troubleshooting.html\n" "InnoDB: how you can resolve the problem.\n", prebuilt->table->name); return(DB_ERROR); @@ -1463,9 +1460,9 @@ row_unlock_for_mysql( if (prebuilt->new_rec_locks >= 1) { - rec_t* rec; + const rec_t* rec; dict_index_t* index; - dulint rec_trx_id; + trx_id_t rec_trx_id; mtr_t mtr; mtr_start(&mtr); @@ -1494,7 +1491,7 @@ row_unlock_for_mysql( /* If the record has been modified by this transaction, do not unlock it. */ - ut_a(index->type & DICT_CLUSTERED); + ut_a(dict_index_is_clust(index)); if (index->trx_id_offset) { rec_trx_id = trx_read_trx_id(rec @@ -1619,7 +1616,9 @@ UNIV_INTERN ibool row_table_got_default_clust_index( /*==============================*/ - const dict_table_t* table) + /* out: TRUE if the clustered index + was generated automatically */ + const dict_table_t* table) /* in: table */ { const dict_index_t* clust_index; @@ -1635,7 +1634,9 @@ UNIV_INTERN ulint row_get_mysql_key_number_for_index( /*===============================*/ - const dict_index_t* index) + /* out: the key number used + inside MySQL */ + const dict_index_t* index) /* in: index */ { const dict_index_t* ind; ulint i; @@ -1913,9 +1914,8 @@ err_exit: " and DROP TABLE will\n" "InnoDB: succeed.\n" "InnoDB: You can look for further help from\n" - "InnoDB: " - "http://dev.mysql.com/doc/refman/5.1/en/" - "innodb-troubleshooting.html\n", stderr); + "InnoDB: " REFMAN "innodb-troubleshooting.html\n", + stderr); /* We may also get err == DB_ERROR if the .ibd file for the table already exists */ @@ -3082,8 +3082,7 @@ row_drop_table_for_mysql( "InnoDB: MySQL database directory" " from another database?\n" "InnoDB: You can look for further help from\n" - "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "innodb-troubleshooting.html\n", + "InnoDB: " REFMAN "innodb-troubleshooting.html\n", stderr); goto funct_exit; } @@ -3661,8 +3660,7 @@ row_rename_table_for_mysql( "InnoDB: MySQL database directory" " from another database?\n" "InnoDB: You can look for further help from\n" - "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "innodb-troubleshooting.html\n", + "InnoDB: " REFMAN "innodb-troubleshooting.html\n", stderr); goto funct_exit; } else if (table->ibd_file_missing) { @@ -3674,8 +3672,7 @@ row_rename_table_for_mysql( fputs(" does not have an .ibd file" " in the database directory.\n" "InnoDB: You can look for further help from\n" - "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "innodb-troubleshooting.html\n", + "InnoDB: " REFMAN "innodb-troubleshooting.html\n", stderr); goto funct_exit; } else if (new_is_tmp) { @@ -3827,8 +3824,7 @@ end: "InnoDB: Have you deleted the .frm file" " and not used DROP TABLE?\n" "InnoDB: You can look for further help from\n" - "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "innodb-troubleshooting.html\n" + "InnoDB: " REFMAN "innodb-troubleshooting.html\n" "InnoDB: If table ", stderr); ut_print_name(stderr, trx, TRUE, new_name); fputs(" is a temporary table #sql..., then" @@ -3950,6 +3946,14 @@ row_scan_and_check_index( *n_rows = 0; + if (!row_merge_is_index_usable(prebuilt->trx, index)) { + /* A newly created index may lack some delete-marked + records that may exist in the read view of + prebuilt->trx. Thus, such indexes must not be + accessed by consistent read. */ + return(is_ok); + } + buf = mem_alloc(UNIV_PAGE_SIZE); heap = mem_heap_create(100); @@ -3957,6 +3961,8 @@ row_scan_and_check_index( in scanning the index entries */ prebuilt->index = index; + /* row_merge_is_index_usable() was already checked above. */ + prebuilt->index_usable = TRUE; prebuilt->sql_stat_start = TRUE; prebuilt->template_type = ROW_MYSQL_DUMMY_TEMPLATE; prebuilt->n_template = 0; @@ -3976,7 +3982,17 @@ loop: } cnt = 1000; } - if (ret != DB_SUCCESS) { + + switch (ret) { + case DB_SUCCESS: + break; + default: + ut_print_timestamp(stderr); + fputs(" InnoDB: Warning: CHECK TABLE on ", stderr); + dict_index_name_print(stderr, prebuilt->trx, index); + fprintf(stderr, " returned %lu\n", ret); + /* fall through (this error is ignored by CHECK TABLE) */ + case DB_END_OF_INDEX: func_exit: mem_free(buf); mem_heap_free(heap); @@ -4100,8 +4116,7 @@ row_check_table_for_mysql( "InnoDB: the MySQL datadir, or have you" " used DISCARD TABLESPACE?\n" "InnoDB: Look from\n" - "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "innodb-troubleshooting.html\n" + "InnoDB: " REFMAN "innodb-troubleshooting.html\n" "InnoDB: how you can resolve the problem.\n", table->name); return(DB_ERROR); diff --git a/row/row0purge.c b/row/row0purge.c index b1a17433fae..efdec5d1f7a 100644 --- a/row/row0purge.c +++ b/row/row0purge.c @@ -591,10 +591,10 @@ row_purge_parse_undo_rec( dict_index_t* clust_index; byte* ptr; trx_t* trx; - dulint undo_no; + undo_no_t undo_no; dulint table_id; - dulint trx_id; - dulint roll_ptr; + trx_id_t trx_id; + roll_ptr_t roll_ptr; ulint info_bits; ulint type; ulint cmpl_info; @@ -690,10 +690,10 @@ row_purge( purge_node_t* node, /* in: row purge node */ que_thr_t* thr) /* in: query thread */ { - dulint roll_ptr; - ibool purge_needed; - ibool updated_extern; - trx_t* trx; + roll_ptr_t roll_ptr; + ibool purge_needed; + ibool updated_extern; + trx_t* trx; ut_ad(node && thr); diff --git a/row/row0sel.c b/row/row0sel.c index 11958c5afe7..26371868418 100644 --- a/row/row0sel.c +++ b/row/row0sel.c @@ -3335,8 +3335,7 @@ row_search_for_mysql( "InnoDB: the MySQL datadir, or have you used" " DISCARD TABLESPACE?\n" "InnoDB: Look from\n" - "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "innodb-troubleshooting.html\n" + "InnoDB: " REFMAN "innodb-troubleshooting.html\n" "InnoDB: how you can resolve the problem.\n", prebuilt->table->name); diff --git a/row/row0uins.c b/row/row0uins.c index ce23e55bb5c..168ee71c844 100644 --- a/row/row0uins.c +++ b/row/row0uins.c @@ -251,7 +251,7 @@ row_undo_ins_parse_undo_rec( { dict_index_t* clust_index; byte* ptr; - dulint undo_no; + undo_no_t undo_no; dulint table_id; ulint type; ulint dummy; diff --git a/row/row0umod.c b/row/row0umod.c index 82139bd259f..048d00dc096 100644 --- a/row/row0umod.c +++ b/row/row0umod.c @@ -68,7 +68,7 @@ row_undo_mod_undo_also_prev_vers( /* out: TRUE if also previous modify or insert of this row should be undone */ undo_node_t* node, /* in: row undo node */ - dulint* undo_no)/* out: the undo number */ + undo_no_t* undo_no)/* out: the undo number */ { trx_undo_rec_t* undo_rec; trx_t* trx; @@ -223,7 +223,7 @@ row_undo_mod_clust( ulint err; ibool success; ibool more_vers; - dulint new_undo_no; + undo_no_t new_undo_no; ut_ad(node && thr); @@ -745,10 +745,10 @@ row_undo_mod_parse_undo_rec( { dict_index_t* clust_index; byte* ptr; - dulint undo_no; + undo_no_t undo_no; dulint table_id; - dulint trx_id; - dulint roll_ptr; + trx_id_t trx_id; + roll_ptr_t roll_ptr; ulint info_bits; ulint type; ulint cmpl_info; diff --git a/row/row0undo.c b/row/row0undo.c index d372f88e207..17e9d826134 100644 --- a/row/row0undo.c +++ b/row/row0undo.c @@ -236,10 +236,10 @@ row_undo( undo_node_t* node, /* in: row undo node */ que_thr_t* thr) /* in: query thread */ { - ulint err; - trx_t* trx; - dulint roll_ptr; - ibool locked_data_dict; + ulint err; + trx_t* trx; + roll_ptr_t roll_ptr; + ibool locked_data_dict; ut_ad(node && thr); diff --git a/row/row0upd.c b/row/row0upd.c index 80e47b37751..9bf4c8727e3 100644 --- a/row/row0upd.c +++ b/row/row0upd.c @@ -328,8 +328,8 @@ row_upd_rec_sys_fields_in_recovery( page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */ const ulint* offsets,/* in: array returned by rec_get_offsets() */ ulint pos, /* in: TRX_ID position in rec */ - dulint trx_id, /* in: transaction id */ - dulint roll_ptr)/* in: roll ptr of the undo log record */ + trx_id_t trx_id, /* in: transaction id */ + roll_ptr_t roll_ptr)/* in: roll ptr of the undo log record */ { ut_ad(rec_offs_validate(rec, NULL, offsets)); @@ -422,7 +422,8 @@ row_upd_changes_field_size_or_external( new_len = dict_col_get_sql_null_size( dict_index_get_nth_col(index, - upd_field->field_no)); + upd_field->field_no), + 0); } old_len = rec_offs_nth_size(offsets, upd_field->field_no); @@ -507,7 +508,7 @@ row_upd_write_sys_vals_to_log( /* out: new pointer to mlog */ dict_index_t* index, /* in: clustered index */ trx_t* trx, /* in: transaction */ - dulint roll_ptr,/* in: roll ptr of the undo log record */ + roll_ptr_t roll_ptr,/* in: roll ptr of the undo log record */ byte* log_ptr,/* pointer to a buffer of size > 20 opened in mlog */ mtr_t* mtr __attribute__((unused))) /* in: mtr */ @@ -534,12 +535,12 @@ UNIV_INTERN byte* row_upd_parse_sys_vals( /*===================*/ - /* out: log data end or NULL */ - byte* ptr, /* in: buffer */ - byte* end_ptr,/* in: buffer end */ - ulint* pos, /* out: TRX_ID position in record */ - dulint* trx_id, /* out: trx id */ - dulint* roll_ptr)/* out: roll ptr */ + /* out: log data end or NULL */ + byte* ptr, /* in: buffer */ + byte* end_ptr,/* in: buffer end */ + ulint* pos, /* out: TRX_ID position in record */ + trx_id_t* trx_id, /* out: trx id */ + roll_ptr_t* roll_ptr)/* out: roll ptr */ { ptr = mach_parse_compressed(ptr, end_ptr, pos); diff --git a/row/row0vers.c b/row/row0vers.c index 3abba6d6fb8..b7024fee82d 100644 --- a/row/row0vers.c +++ b/row/row0vers.c @@ -64,7 +64,7 @@ row_vers_impl_x_locked_off_kernel( rec_t* clust_rec; ulint* clust_offsets; rec_t* version; - dulint trx_id; + trx_id_t trx_id; mem_heap_t* heap; mem_heap_t* heap2; dtuple_t* row; @@ -157,7 +157,7 @@ row_vers_impl_x_locked_off_kernel( rec_t* prev_version; ulint vers_del; row_ext_t* ext; - dulint prev_trx_id; + trx_id_t prev_trx_id; mutex_exit(&kernel_mutex); @@ -305,10 +305,12 @@ UNIV_INTERN ibool row_vers_must_preserve_del_marked( /*==============================*/ - /* out: TRUE if earlier version should be preserved */ - dulint trx_id, /* in: transaction id in the version */ - mtr_t* mtr) /* in: mtr holding the latch on the clustered index - record; it will also hold the latch on purge_view */ + /* out: TRUE if earlier version should + be preserved */ + trx_id_t trx_id, /* in: transaction id in the version */ + mtr_t* mtr) /* in: mtr holding the latch on the + clustered index record; it will also + hold the latch on purge_view */ { #ifdef UNIV_SYNC_DEBUG ut_ad(!rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED)); @@ -499,7 +501,7 @@ row_vers_build_for_consistent_read( { const rec_t* version; rec_t* prev_version; - dulint trx_id; + trx_id_t trx_id; mem_heap_t* heap = NULL; byte* buf; ulint err; @@ -523,8 +525,8 @@ row_vers_build_for_consistent_read( for (;;) { mem_heap_t* heap2 = heap; trx_undo_rec_t* undo_rec; - dulint roll_ptr; - dulint undo_no; + roll_ptr_t roll_ptr; + undo_no_t undo_no; heap = mem_heap_create(1024); /* If we have high-granularity consistent read view and @@ -632,7 +634,7 @@ row_vers_build_for_semi_consistent_read( mem_heap_t* heap = NULL; byte* buf; ulint err; - dulint rec_trx_id = ut_dulint_zero; + trx_id_t rec_trx_id = ut_dulint_zero; ut_ad(dict_index_is_clust(index)); ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX) @@ -655,7 +657,7 @@ row_vers_build_for_semi_consistent_read( trx_t* version_trx; mem_heap_t* heap2; rec_t* prev_version; - dulint version_trx_id; + trx_id_t version_trx_id; version_trx_id = row_get_rec_trx_id(version, index, *offsets); if (rec == version) { diff --git a/srv/srv0srv.c b/srv/srv0srv.c index 005d135cb2d..934c1f25c7c 100644 --- a/srv/srv0srv.c +++ b/srv/srv0srv.c @@ -284,7 +284,6 @@ computer. Bigger computers need bigger values. Value 0 will disable the concurrency check. */ UNIV_INTERN ulong srv_thread_concurrency = 0; -UNIV_INTERN ulong srv_commit_concurrency = 0; /* this mutex protects srv_conc data structures */ UNIV_INTERN os_fast_mutex_t srv_conc_mutex; @@ -671,6 +670,7 @@ UNIV_INTERN ulint srv_get_n_threads(void) /*===================*/ + /* out: sum of srv_n_threads[] */ { ulint i; ulint n_threads = 0; @@ -1773,6 +1773,7 @@ Function to pass InnoDB status variables to MySQL */ UNIV_INTERN void srv_export_innodb_status(void) +/*==========================*/ { mutex_enter(&srv_innodb_monitor_mutex); @@ -1811,7 +1812,7 @@ srv_export_innodb_status(void) export_vars.innodb_buffer_pool_pages_misc = buf_pool->curr_size - UT_LIST_GET_LEN(buf_pool->LRU) - UT_LIST_GET_LEN(buf_pool->free); -#ifdef HAVE_GCC_ATOMIC_BUILTINS +#ifdef HAVE_ATOMIC_BUILTINS export_vars.innodb_have_atomic_builtins = 1; #else export_vars.innodb_have_atomic_builtins = 0; diff --git a/srv/srv0start.c b/srv/srv0start.c index ef1c53b9e2b..ae74c62f9b9 100644 --- a/srv/srv0start.c +++ b/srv/srv0start.c @@ -118,20 +118,9 @@ static char* srv_monitor_file_name; #define SRV_MAX_N_PENDING_SYNC_IOS 100 -/* Avoid warnings when using purify */ - -#ifdef HAVE_purify -static int inno_bcmp(register const char *s1, register const char *s2, - register uint len) -{ - while ((len-- != 0) && (*s1++ == *s2++)) - ; - - return(len + 1); -} -#define memcmp(A,B,C) inno_bcmp((A),(B),(C)) -#endif - +/************************************************************************* +Convert a numeric string that optionally ends in G or M, to a number +containing megabytes. */ static char* srv_parse_megabytes( @@ -444,7 +433,9 @@ static os_thread_ret_t io_handler_thread( /*==============*/ - void* arg) + /* out: OS_THREAD_DUMMY_RETURN */ + void* arg) /* in: pointer to the number of the segment in + the aio array */ { ulint segment; ulint i; @@ -1079,13 +1070,29 @@ innobase_start_or_create_for_mysql(void) } #ifdef HAVE_GCC_ATOMIC_BUILTINS -#ifdef INNODB_RW_LOCKS_USE_ATOMICS +# ifdef INNODB_RW_LOCKS_USE_ATOMICS fprintf(stderr, "InnoDB: Mutexes and rw_locks use GCC atomic builtins.\n"); -#else /* INNODB_RW_LOCKS_USE_ATOMICS */ +# else /* INNODB_RW_LOCKS_USE_ATOMICS */ fprintf(stderr, "InnoDB: Mutexes use GCC atomic builtins, rw_locks do not.\n"); -#endif /* INNODB_RW_LOCKS_USE_ATOMICS */ +# endif /* INNODB_RW_LOCKS_USE_ATOMICS */ +#elif defined(HAVE_SOLARIS_ATOMICS) +# ifdef INNODB_RW_LOCKS_USE_ATOMICS + fprintf(stderr, + "InnoDB: Mutexes and rw_locks use Solaris atomic functions.\n"); +# else + fprintf(stderr, + "InnoDB: Mutexes use Solaris atomic functions.\n"); +# endif /* INNODB_RW_LOCKS_USE_ATOMICS */ +#elif HAVE_WINDOWS_ATOMICS +# ifdef INNODB_RW_LOCKS_USE_ATOMICS + fprintf(stderr, + "InnoDB: Mutexes and rw_locks use Windows interlocked functions.\n"); +# else + fprintf(stderr, + "InnoDB: Mutexes use Windows interlocked functions.\n"); +# endif /* INNODB_RW_LOCKS_USE_ATOMICS */ #else /* HAVE_GCC_ATOMIC_BUILTINS */ fprintf(stderr, "InnoDB: Neither mutexes nor rw_locks use GCC atomic builtins.\n"); @@ -1851,8 +1858,7 @@ innobase_start_or_create_for_mysql(void) " to an earlier version of\n" "InnoDB: InnoDB! But if you absolutely need to" " downgrade, see\n" - "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "multiple-tablespaces.html\n" + "InnoDB: " REFMAN "multiple-tablespaces.html\n" "InnoDB: for instructions.\n"); } diff --git a/sync/sync0arr.c b/sync/sync0arr.c index dcf2744ac87..12c908101e9 100644 --- a/sync/sync0arr.c +++ b/sync/sync0arr.c @@ -856,8 +856,8 @@ sync_array_object_signalled( /*========================*/ sync_array_t* arr) /* in: wait array */ { -#ifdef HAVE_GCC_ATOMIC_BUILTINS - (void) os_atomic_increment(&arr->sg_count, 1); +#ifdef HAVE_ATOMIC_BUILTINS + (void) os_atomic_increment_ulint(&arr->sg_count, 1); #else sync_array_enter(arr); diff --git a/sync/sync0rw.c b/sync/sync0rw.c index 1f693c4d407..75875865493 100644 --- a/sync/sync0rw.c +++ b/sync/sync0rw.c @@ -194,6 +194,7 @@ static rw_lock_debug_t* rw_lock_debug_create(void) /*======================*/ + /* out, own: debug info struct */ { return((rw_lock_debug_t*) mem_alloc(sizeof(rw_lock_debug_t))); } @@ -329,7 +330,8 @@ UNIV_INTERN ibool rw_lock_validate( /*=============*/ - rw_lock_t* lock) + /* out: TRUE */ + rw_lock_t* lock) /* in: rw-lock */ { ut_a(lock); @@ -1010,6 +1012,7 @@ UNIV_INTERN ulint rw_lock_n_locked(void) /*==================*/ + /* out: number of locked rw-locks */ { rw_lock_t* lock; ulint count = 0; diff --git a/sync/sync0sync.c b/sync/sync0sync.c index 209d3a784be..aed4dbadd27 100644 --- a/sync/sync0sync.c +++ b/sync/sync0sync.c @@ -235,9 +235,7 @@ mutex_create_func( const char* cfile_name, /* in: file name where created */ ulint cline) /* in: file line where created */ { -#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER) - mutex_reset_lock_word(mutex); -#elif defined(HAVE_GCC_ATOMIC_BUILTINS) +#if defined(HAVE_ATOMIC_BUILTINS) mutex_reset_lock_word(mutex); #else os_fast_mutex_init(&(mutex->os_fast_mutex)); @@ -327,9 +325,7 @@ mutex_free( os_event_free(mutex->event); -#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER) -#elif defined(HAVE_GCC_ATOMIC_BUILTINS) -#else +#if !defined(HAVE_ATOMIC_BUILTINS) os_fast_mutex_free(&(mutex->os_fast_mutex)); #endif /* If we free the mutex protecting the mutex list (freeing is @@ -378,7 +374,8 @@ UNIV_INTERN ibool mutex_validate( /*===========*/ - const mutex_t* mutex) + /* out: TRUE */ + const mutex_t* mutex) /* in: mutex */ { ut_a(mutex); ut_a(mutex->magic_n == MUTEX_MAGIC_N); @@ -707,6 +704,7 @@ UNIV_INTERN ulint mutex_n_reserved(void) /*==================*/ + /* out: number of reserved mutexes */ { mutex_t* mutex; ulint count = 0; @@ -739,6 +737,7 @@ UNIV_INTERN ibool sync_all_freed(void) /*================*/ + /* out: TRUE if no mutexes and rw-locks reserved */ { return(mutex_n_reserved() + rw_lock_n_locked() == 0); } diff --git a/trx/trx0purge.c b/trx/trx0purge.c index 7a2a27a94ff..87c45172b34 100644 --- a/trx/trx0purge.c +++ b/trx/trx0purge.c @@ -56,10 +56,11 @@ UNIV_INTERN ibool trx_purge_update_undo_must_exist( /*=============================*/ - /* out: TRUE if is sure that it is preserved, also - if the function returns FALSE, it is possible that - the undo log still exists in the system */ - dulint trx_id) /* in: transaction id */ + /* out: TRUE if is sure that it is + preserved, also if the function + returns FALSE, it is possible that the + undo log still exists in the system */ + trx_id_t trx_id) /* in: transaction id */ { #ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED)); @@ -81,9 +82,9 @@ static trx_undo_inf_t* trx_purge_arr_store_info( /*=====================*/ - /* out: pointer to the storage cell */ - dulint trx_no, /* in: transaction number */ - dulint undo_no)/* in: undo number */ + /* out: pointer to the storage cell */ + trx_id_t trx_no, /* in: transaction number */ + undo_no_t undo_no)/* in: undo number */ { trx_undo_inf_t* cell; trx_undo_arr_t* arr; @@ -133,13 +134,13 @@ void trx_purge_arr_get_biggest( /*======================*/ trx_undo_arr_t* arr, /* in: purge array */ - dulint* trx_no, /* out: transaction number: ut_dulint_zero + trx_id_t* trx_no, /* out: transaction number: ut_dulint_zero if array is empty */ - dulint* undo_no)/* out: undo number */ + undo_no_t* undo_no)/* out: undo number */ { trx_undo_inf_t* cell; - dulint pair_trx_no; - dulint pair_undo_no; + trx_id_t pair_trx_no; + undo_no_t pair_undo_no; int trx_cmp; ulint n_used; ulint i; @@ -443,9 +444,9 @@ void trx_purge_truncate_rseg_history( /*============================*/ trx_rseg_t* rseg, /* in: rollback segment */ - dulint limit_trx_no, /* in: remove update undo logs whose + trx_id_t limit_trx_no, /* in: remove update undo logs whose trx number is < limit_trx_no */ - dulint limit_undo_no) /* in: if transaction number is equal + undo_no_t limit_undo_no) /* in: if transaction number is equal to limit_trx_no, truncate undo records with undo number < limit_undo_no */ { @@ -549,8 +550,8 @@ trx_purge_truncate_history(void) /*============================*/ { trx_rseg_t* rseg; - dulint limit_trx_no; - dulint limit_undo_no; + trx_id_t limit_trx_no; + undo_no_t limit_undo_no; ut_ad(mutex_own(&(purge_sys->mutex))); @@ -617,7 +618,7 @@ trx_purge_rseg_get_next_history_log( trx_ulogf_t* log_hdr; trx_usegf_t* seg_hdr; fil_addr_t prev_log_addr; - dulint trx_no; + trx_id_t trx_no; ibool del_marks; mtr_t mtr; @@ -718,7 +719,7 @@ trx_purge_choose_next_log(void) trx_undo_rec_t* rec; trx_rseg_t* rseg; trx_rseg_t* min_rseg; - dulint min_trx_no; + trx_id_t min_trx_no; ulint space = 0; /* remove warning (??? bug ???) */ ulint zip_size = 0; ulint page_no = 0; /* remove warning (??? bug ???) */ @@ -938,7 +939,7 @@ trx_purge_fetch_next_rec( pointer to the dummy undo log record &trx_purge_dummy_rec, if the whole undo log can skipped in purge; NULL if none left */ - dulint* roll_ptr,/* out: roll pointer to undo record */ + roll_ptr_t* roll_ptr,/* out: roll pointer to undo record */ trx_undo_inf_t** cell, /* out: storage cell for the record in the purge array */ mem_heap_t* heap) /* in: memory heap where copied */ diff --git a/trx/trx0rec.c b/trx/trx0rec.c index dfd1c7e2a67..c4d27ef8ae5 100644 --- a/trx/trx0rec.c +++ b/trx/trx0rec.c @@ -290,7 +290,7 @@ trx_undo_rec_get_pars( for update type records */ ibool* updated_extern, /* out: TRUE if we updated an externally stored fild */ - dulint* undo_no, /* out: undo log record number */ + undo_no_t* undo_no, /* out: undo log record number */ dulint* table_id) /* out: table id */ { byte* ptr; @@ -552,7 +552,7 @@ trx_undo_page_report_modify( ulint type_cmpl; byte* type_cmpl_ptr; ulint i; - dulint trx_id; + trx_id_t trx_id; ibool ignore_prefix = FALSE; byte ext_buf[REC_MAX_INDEX_COL_LEN + BTR_EXTERN_FIELD_REF_SIZE]; @@ -835,14 +835,14 @@ UNIV_INTERN byte* trx_undo_update_rec_get_sys_cols( /*=============================*/ - /* out: remaining part of undo log - record after reading these values */ - byte* ptr, /* in: remaining part of undo log - record after reading general - parameters */ - dulint* trx_id, /* out: trx id */ - dulint* roll_ptr, /* out: roll ptr */ - ulint* info_bits) /* out: info bits state */ + /* out: remaining part of undo log + record after reading these values */ + byte* ptr, /* in: remaining part of undo + log record after reading + general parameters */ + trx_id_t* trx_id, /* out: trx id */ + roll_ptr_t* roll_ptr, /* out: roll ptr */ + ulint* info_bits) /* out: info bits state */ { /* Read the state of the info bits */ *info_bits = mach_read_from_1(ptr); @@ -914,8 +914,8 @@ trx_undo_update_rec_get_update( TRX_UNDO_DEL_MARK_REC; in the last case, only trx id and roll ptr fields are added to the update vector */ - dulint trx_id, /* in: transaction id from this undo record */ - dulint roll_ptr,/* in: roll pointer from this undo record */ + trx_id_t trx_id, /* in: transaction id from this undo record */ + roll_ptr_t roll_ptr,/* in: roll pointer from this undo record */ ulint info_bits,/* in: info bits from this undo record */ trx_t* trx, /* in: transaction */ mem_heap_t* heap, /* in: memory heap from which the memory @@ -1167,7 +1167,7 @@ trx_undo_report_row_operation( const rec_t* rec, /* in: in case of an update or delete marking, the record in the clustered index, otherwise NULL */ - dulint* roll_ptr) /* out: rollback pointer to the + roll_ptr_t* roll_ptr) /* out: rollback pointer to the inserted undo log record, ut_dulint_zero if BTR_NO_UNDO_LOG flag was specified */ @@ -1337,7 +1337,7 @@ trx_undo_rec_t* trx_undo_get_undo_rec_low( /*======================*/ /* out, own: copy of the record */ - dulint roll_ptr, /* in: roll pointer to record */ + roll_ptr_t roll_ptr, /* in: roll pointer to record */ mem_heap_t* heap) /* in: memory heap where copied */ { trx_undo_rec_t* undo_rec; @@ -1377,8 +1377,8 @@ trx_undo_get_undo_rec( fetch the old version; NOTE: the caller must have latches on the clustered index page and purge_view */ - dulint roll_ptr, /* in: roll pointer to record */ - dulint trx_id, /* in: id of the trx that generated + roll_ptr_t roll_ptr, /* in: roll pointer to record */ + trx_id_t trx_id, /* in: id of the trx that generated the roll pointer: it points to an undo log of this transaction */ trx_undo_rec_t** undo_rec, /* out, own: copy of the record */ @@ -1432,13 +1432,13 @@ trx_undo_prev_version_build( { trx_undo_rec_t* undo_rec = NULL; dtuple_t* entry; - dulint rec_trx_id; + trx_id_t rec_trx_id; ulint type; - dulint undo_no; + undo_no_t undo_no; dulint table_id; - dulint trx_id; - dulint roll_ptr; - dulint old_roll_ptr; + trx_id_t trx_id; + roll_ptr_t roll_ptr; + roll_ptr_t old_roll_ptr; upd_t* update; byte* ptr; ulint info_bits; diff --git a/trx/trx0roll.c b/trx/trx0roll.c index cc2fab46eec..666ca431ee5 100644 --- a/trx/trx0roll.c +++ b/trx/trx0roll.c @@ -198,7 +198,7 @@ trx_roll_savepoint_free( /*********************************************************************** Frees savepoint structs starting from savep, if savep == NULL then free all savepoints. */ - +UNIV_INTERN void trx_roll_savepoints_free( /*=====================*/ @@ -614,6 +614,7 @@ UNIV_INTERN trx_undo_arr_t* trx_undo_arr_create(void) /*=====================*/ + /* out, own: undo number array */ { trx_undo_arr_t* arr; mem_heap_t* heap; @@ -657,10 +658,10 @@ static ibool trx_undo_arr_store_info( /*====================*/ - /* out: FALSE if the record already existed in the - array */ - trx_t* trx, /* in: transaction */ - dulint undo_no)/* in: undo number */ + /* out: FALSE if the record already + existed in the array */ + trx_t* trx, /* in: transaction */ + undo_no_t undo_no)/* in: undo number */ { trx_undo_inf_t* cell; trx_undo_inf_t* stored_here; @@ -720,7 +721,7 @@ void trx_undo_arr_remove_info( /*=====================*/ trx_undo_arr_t* arr, /* in: undo number array */ - dulint undo_no)/* in: undo number */ + undo_no_t undo_no)/* in: undo number */ { trx_undo_inf_t* cell; ulint n_used; @@ -750,7 +751,7 @@ trx_undo_arr_remove_info( /*********************************************************************** Gets the biggest undo number in an array. */ static -dulint +undo_no_t trx_undo_arr_get_biggest( /*=====================*/ /* out: biggest value, ut_dulint_zero if @@ -759,7 +760,7 @@ trx_undo_arr_get_biggest( { trx_undo_inf_t* cell; ulint n_used; - dulint biggest; + undo_no_t biggest; ulint n; ulint i; @@ -790,11 +791,11 @@ UNIV_INTERN void trx_roll_try_truncate( /*==================*/ - trx_t* trx) /* in: transaction */ + trx_t* trx) /* in/out: transaction */ { trx_undo_arr_t* arr; - dulint limit; - dulint biggest; + undo_no_t limit; + undo_no_t biggest; ut_ad(mutex_own(&(trx->undo_mutex))); ut_ad(mutex_own(&((trx->rseg)->mutex))); @@ -886,8 +887,8 @@ trx_roll_pop_top_rec_of_trx( if none left, or if the undo number of the top record would be less than the limit */ trx_t* trx, /* in: transaction */ - dulint limit, /* in: least undo number we need */ - dulint* roll_ptr,/* out: roll pointer to undo record */ + undo_no_t limit, /* in: least undo number we need */ + roll_ptr_t* roll_ptr,/* out: roll pointer to undo record */ mem_heap_t* heap) /* in: memory heap where copied */ { trx_undo_t* undo; @@ -895,7 +896,7 @@ trx_roll_pop_top_rec_of_trx( trx_undo_t* upd_undo; trx_undo_rec_t* undo_rec; trx_undo_rec_t* undo_rec_copy; - dulint undo_no; + undo_no_t undo_no; ibool is_insert; trx_rseg_t* rseg; ulint progress_pct; @@ -1013,9 +1014,9 @@ UNIV_INTERN ibool trx_undo_rec_reserve( /*=================*/ - /* out: TRUE if succeeded */ - trx_t* trx, /* in: transaction */ - dulint undo_no)/* in: undo number of the record */ + /* out: TRUE if succeeded */ + trx_t* trx, /* in/out: transaction */ + undo_no_t undo_no)/* in: undo number of the record */ { ibool ret; @@ -1034,8 +1035,8 @@ UNIV_INTERN void trx_undo_rec_release( /*=================*/ - trx_t* trx, /* in: transaction */ - dulint undo_no)/* in: undo number */ + trx_t* trx, /* in/out: transaction */ + undo_no_t undo_no)/* in: undo number */ { trx_undo_arr_t* arr; diff --git a/trx/trx0sys.c b/trx/trx0sys.c index 1c736b1ee8c..dfa896df537 100644 --- a/trx/trx0sys.c +++ b/trx/trx0sys.c @@ -403,7 +403,7 @@ UNIV_INTERN void trx_sys_doublewrite_init_or_restore_pages( /*======================================*/ - ibool restore_corrupt_pages) + ibool restore_corrupt_pages) /* in: TRUE=restore pages */ { byte* buf; byte* read_buf; diff --git a/trx/trx0undo.c b/trx/trx0undo.c index cdf70a8d3d0..62582cc02c0 100644 --- a/trx/trx0undo.c +++ b/trx/trx0undo.c @@ -115,7 +115,7 @@ trx_undo_mem_create( ulint id, /* in: slot index within rseg */ ulint type, /* in: type of the log: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */ - dulint trx_id, /* in: id of the trx for which the undo log + trx_id_t trx_id, /* in: id of the trx for which the undo log is created */ const XID* xid, /* in: X/Open XA transaction identification*/ ulint page_no,/* in: undo log header page number */ @@ -129,11 +129,12 @@ static ulint trx_undo_insert_header_reuse( /*=========================*/ - /* out: undo log header byte offset on page */ - page_t* undo_page, /* in: insert undo log segment header page, - x-latched */ - dulint trx_id, /* in: transaction id */ - mtr_t* mtr); /* in: mtr */ + /* out: undo log header byte + offset on page */ + page_t* undo_page, /* in/out: insert undo log segment + header page, x-latched */ + trx_id_t trx_id, /* in: transaction id */ + mtr_t* mtr); /* in: mtr */ /************************************************************************** If an update undo log can be discarded immediately, this function frees the space, resetting the page to the proper state for caching. */ @@ -514,9 +515,9 @@ UNIV_INLINE void trx_undo_header_create_log( /*=======================*/ - page_t* undo_page, /* in: undo log header page */ - dulint trx_id, /* in: transaction id */ - mtr_t* mtr) /* in: mtr */ + const page_t* undo_page, /* in: undo log header page */ + trx_id_t trx_id, /* in: transaction id */ + mtr_t* mtr) /* in: mtr */ { mlog_write_initial_log_record(undo_page, MLOG_UNDO_HDR_CREATE, mtr); @@ -534,13 +535,14 @@ static ulint trx_undo_header_create( /*===================*/ - /* out: header byte offset on page */ - page_t* undo_page, /* in: undo log segment header page, - x-latched; it is assumed that there are - TRX_UNDO_LOG_XA_HDR_SIZE bytes free space - on it */ - dulint trx_id, /* in: transaction id */ - mtr_t* mtr) /* in: mtr */ + /* out: header byte offset on page */ + page_t* undo_page, /* in/out: undo log segment + header page, x-latched; it is + assumed that there is + TRX_UNDO_LOG_XA_HDR_SIZE bytes + free space on it */ + trx_id_t trx_id, /* in: transaction id */ + mtr_t* mtr) /* in: mtr */ { trx_upagef_t* page_hdr; trx_usegf_t* seg_hdr; @@ -685,9 +687,9 @@ UNIV_INLINE void trx_undo_insert_header_reuse_log( /*=============================*/ - page_t* undo_page, /* in: undo log header page */ - dulint trx_id, /* in: transaction id */ - mtr_t* mtr) /* in: mtr */ + const page_t* undo_page, /* in: undo log header page */ + trx_id_t trx_id, /* in: transaction id */ + mtr_t* mtr) /* in: mtr */ { mlog_write_initial_log_record(undo_page, MLOG_UNDO_HDR_REUSE, mtr); @@ -710,7 +712,7 @@ trx_undo_parse_page_header( page_t* page, /* in: page or NULL */ mtr_t* mtr) /* in: mtr or NULL */ { - dulint trx_id; + trx_id_t trx_id; ptr = mach_dulint_parse_compressed(ptr, end_ptr, &trx_id); @@ -739,11 +741,12 @@ static ulint trx_undo_insert_header_reuse( /*=========================*/ - /* out: undo log header byte offset on page */ - page_t* undo_page, /* in: insert undo log segment header page, - x-latched */ - dulint trx_id, /* in: transaction id */ - mtr_t* mtr) /* in: mtr */ + /* out: undo log header byte + offset on page */ + page_t* undo_page, /* in/out: insert undo log segment + header page, x-latched */ + trx_id_t trx_id, /* in: transaction id */ + mtr_t* mtr) /* in: mtr */ { trx_upagef_t* page_hdr; trx_usegf_t* seg_hdr; @@ -1064,7 +1067,7 @@ trx_undo_truncate_end( /*==================*/ trx_t* trx, /* in: transaction whose undo log it is */ trx_undo_t* undo, /* in: undo log */ - dulint limit) /* in: all undo records with undo number + undo_no_t limit) /* in: all undo records with undo number >= this value should be truncated */ { page_t* undo_page; @@ -1137,15 +1140,17 @@ UNIV_INTERN void trx_undo_truncate_start( /*====================*/ - trx_rseg_t* rseg, /* in: rollback segment */ - ulint space, /* in: space id of the log */ - ulint hdr_page_no, /* in: header page number */ - ulint hdr_offset, /* in: header offset on the page */ - dulint limit) /* in: all undo pages with undo numbers < - this value should be truncated; NOTE that - the function only frees whole pages; the - header page is not freed, but emptied, if - all the records there are < limit */ + trx_rseg_t* rseg, /* in: rollback segment */ + ulint space, /* in: space id of the log */ + ulint hdr_page_no, /* in: header page number */ + ulint hdr_offset, /* in: header offset on the page */ + undo_no_t limit) /* in: all undo pages with + undo numbers < this value + should be truncated; NOTE that + the function only frees whole + pages; the header page is not + freed, but emptied, if all the + records there are < limit */ { page_t* undo_page; trx_undo_rec_t* rec; @@ -1270,7 +1275,7 @@ trx_undo_mem_create_at_db_start( trx_undo_t* undo; ulint type; ulint state; - dulint trx_id; + trx_id_t trx_id; ulint offset; fil_addr_t last_addr; page_t* last_page; @@ -1443,7 +1448,7 @@ trx_undo_mem_create( ulint id, /* in: slot index within rseg */ ulint type, /* in: type of the log: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */ - dulint trx_id, /* in: id of the trx for which the undo log + trx_id_t trx_id, /* in: id of the trx for which the undo log is created */ const XID* xid, /* in: X/Open transaction identification */ ulint page_no,/* in: undo log header page number */ @@ -1498,7 +1503,7 @@ void trx_undo_mem_init_for_reuse( /*========================*/ trx_undo_t* undo, /* in: undo log to init */ - dulint trx_id, /* in: id of the trx for which the undo log + trx_id_t trx_id, /* in: id of the trx for which the undo log is created */ const XID* xid, /* in: X/Open XA transaction identification*/ ulint offset) /* in: undo log header byte offset on page */ @@ -1557,7 +1562,7 @@ trx_undo_create( trx_rseg_t* rseg, /* in: rollback segment memory copy */ ulint type, /* in: type of the log: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */ - dulint trx_id, /* in: id of the trx for which the undo log + trx_id_t trx_id, /* in: id of the trx for which the undo log is created */ const XID* xid, /* in: X/Open transaction identification*/ trx_undo_t** undo, /* out: the new undo log object, undefined @@ -1627,7 +1632,7 @@ trx_undo_reuse_cached( trx_rseg_t* rseg, /* in: rollback segment memory object */ ulint type, /* in: type of the log: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */ - dulint trx_id, /* in: id of the trx for which the undo log + trx_id_t trx_id, /* in: id of the trx for which the undo log is used */ const XID* xid, /* in: X/Open XA transaction identification */ mtr_t* mtr) /* in: mtr */ diff --git a/ut/ut0auxconf.c b/ut/ut0auxconf.c deleted file mode 100644 index fd9433d16f6..00000000000 --- a/ut/ut0auxconf.c +++ /dev/null @@ -1,13 +0,0 @@ -#include <pthread.h> - -int -main(int argc, char** argv) -{ - pthread_t x1; - pthread_t x2; - pthread_t x3; - - __sync_bool_compare_and_swap(&x1, x2, x3); - - return(0); -} diff --git a/ut/ut0auxconf_atomic_pthread_t_gcc.c b/ut/ut0auxconf_atomic_pthread_t_gcc.c new file mode 100644 index 00000000000..30de5aa6f17 --- /dev/null +++ b/ut/ut0auxconf_atomic_pthread_t_gcc.c @@ -0,0 +1,43 @@ +/***************************************************************************** + +Copyright (c) 2009, Innobase Oy. 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 +Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +/***************************************************************************** +If this program compiles, then pthread_t objects can be used as arguments +to GCC atomic builtin functions. + +Created March 5, 2009 Vasil Dimov +*****************************************************************************/ + +#include <pthread.h> +#include <string.h> + +int +main(int argc, char** argv) +{ + pthread_t x1; + pthread_t x2; + pthread_t x3; + + memset(&x1, 0x0, sizeof(x1)); + memset(&x2, 0x0, sizeof(x2)); + memset(&x3, 0x0, sizeof(x3)); + + __sync_bool_compare_and_swap(&x1, x2, x3); + + return(0); +} diff --git a/ut/ut0auxconf_atomic_pthread_t_solaris.c b/ut/ut0auxconf_atomic_pthread_t_solaris.c new file mode 100644 index 00000000000..a18a537d1d4 --- /dev/null +++ b/ut/ut0auxconf_atomic_pthread_t_solaris.c @@ -0,0 +1,34 @@ +/***************************************************************************** + +Copyright (c) 2009, Innobase Oy. 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 +Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +/***************************************************************************** +If this program compiles, then pthread_t objects can be used as arguments +to Solaris libc atomic functions. + +Created April 18, 2009 Vasil Dimov +*****************************************************************************/ + +#include <pthread.h> + +int +main(int argc, char** argv) +{ + pthread_t x = 0; + + return(0); +} diff --git a/ut/ut0auxconf_have_solaris_atomics.c b/ut/ut0auxconf_have_solaris_atomics.c new file mode 100644 index 00000000000..7eb704edd4b --- /dev/null +++ b/ut/ut0auxconf_have_solaris_atomics.c @@ -0,0 +1,39 @@ +/***************************************************************************** + +Copyright (c) 2009, Innobase Oy. 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 +Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +/***************************************************************************** +If this program compiles, then Solaris libc atomic funcions are available. + +Created April 18, 2009 Vasil Dimov +*****************************************************************************/ +#include <atomic.h> + +int +main(int argc, char** argv) +{ + ulong_t ulong = 0; + uint32_t uint32 = 0; + uint64_t uint64 = 0; + + atomic_cas_ulong(&ulong, 0, 1); + atomic_cas_32(&uint32, 0, 1); + atomic_cas_64(&uint64, 0, 1); + atomic_add_long(&ulong, 0); + + return(0); +} diff --git a/ut/ut0auxconf_sizeof_pthread_t.c b/ut/ut0auxconf_sizeof_pthread_t.c new file mode 100644 index 00000000000..96add4526ef --- /dev/null +++ b/ut/ut0auxconf_sizeof_pthread_t.c @@ -0,0 +1,35 @@ +/***************************************************************************** + +Copyright (c) 2009, Innobase Oy. 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 +Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +/***************************************************************************** +This program should compile and when run, print a single line like: +#define SIZEOF_PTHREAD_T %d + +Created April 18, 2009 Vasil Dimov +*****************************************************************************/ + +#include <stdio.h> +#include <pthread.h> + +int +main(int argc, char** argv) +{ + printf("#define SIZEOF_PTHREAD_T %d\n", (int) sizeof(pthread_t)); + + return(0); +} diff --git a/ut/ut0byte.c b/ut/ut0byte.c index 5e11e37d0b6..d80ba932c38 100644 --- a/ut/ut0byte.c +++ b/ut/ut0byte.c @@ -41,8 +41,12 @@ UNIV_INTERN const dulint ut_dulint_max = {0xFFFFFFFFUL, 0xFFFFFFFFUL}; Sort function for dulint arrays. */ UNIV_INTERN void -ut_dulint_sort(dulint* arr, dulint* aux_arr, ulint low, ulint high) -/*===============================================================*/ +ut_dulint_sort( +/*===========*/ + dulint* arr, /* in/out: array to be sorted */ + dulint* aux_arr,/* in/out: auxiliary array (same size as arr) */ + ulint low, /* in: low bound of sort interval, inclusive */ + ulint high) /* in: high bound of sort interval, noninclusive */ { UT_SORT_FUNCTION_BODY(ut_dulint_sort, arr, aux_arr, low, high, ut_dulint_cmp); diff --git a/ut/ut0dbg.c b/ut/ut0dbg.c index 983ee5835e4..8fe9a9813f8 100644 --- a/ut/ut0dbg.c +++ b/ut/ut0dbg.c @@ -78,8 +78,7 @@ ut_dbg_assertion_failed( " or crashes, even\n" "InnoDB: immediately after the mysqld startup, there may be\n" "InnoDB: corruption in the InnoDB tablespace. Please refer to\n" - "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "forcing-recovery.html\n" + "InnoDB: " REFMAN "forcing-recovery.html\n" "InnoDB: about forcing recovery.\n", stderr); #if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT) ut_dbg_stop_threads = TRUE; diff --git a/ut/ut0ut.c b/ut/ut0ut.c index 016df3a0af5..ef5c06bea03 100644 --- a/ut/ut0ut.c +++ b/ut/ut0ut.c @@ -116,6 +116,7 @@ UNIV_INTERN ib_time_t ut_time(void) /*=========*/ + /* out: system time */ { return(time(NULL)); } @@ -551,13 +552,15 @@ ut_copy_file( } #endif /* !UNIV_HOTBACKUP */ -/************************************************************************** -snprintf(). */ - #ifdef __WIN__ -#include <stdarg.h> +# include <stdarg.h> +/************************************************************************** +A substitute for snprintf(3), formatted output conversion into +a limited buffer. */ +UNIV_INTERN int ut_snprintf( +/*========*/ /* out: number of characters that would have been printed if the size were unlimited, not including the terminating diff --git a/ut/ut0wqueue.c b/ut/ut0wqueue.c index a5c14ac8130..967f7fa9eeb 100644 --- a/ut/ut0wqueue.c +++ b/ut/ut0wqueue.c @@ -77,6 +77,7 @@ Wait for a work item to appear in the queue. */ UNIV_INTERN void* ib_wqueue_wait( +/*===========*/ /* out: work item */ ib_wqueue_t* wq) /* in: work queue */ { diff --git a/win-plugin/README b/win-plugin/README index 9182f2c555c..00f4e996a3f 100644 --- a/win-plugin/README +++ b/win-plugin/README @@ -13,9 +13,6 @@ When applying the patch, the following files will be modified: * CMakeLists.txt * sql/CMakeLists.txt * win/configure.js - * win/build-vs71.bat - * win/build-vs8.bat - * win/build-vs8_x64.bat Also, two new files will be added: diff --git a/win-plugin/win-plugin.diff b/win-plugin/win-plugin.diff index 6547217ea42..4b3354ac4de 100644 --- a/win-plugin/win-plugin.diff +++ b/win-plugin/win-plugin.diff @@ -33,11 +33,11 @@ diff -Nur sql/CMakeLists.txt.orig sql/CMakeLists.txt IF(EMBED_MANIFESTS) MYSQL_EMBED_MANIFEST("mysqld" "asInvoker") ENDIF(EMBED_MANIFESTS) - + diff -Nur sql/mysqld.def.orig sql/mysqld.def --- sql/mysqld.def.orig 1969-12-31 18:00:00 -06:00 -+++ sql/mysqld.def 2008-10-31 02:20:32 -05:00 -@@ -0,0 +1,98 @@ ++++ sql/mysqld.def 2009-04-09 02:20:32 -05:00 +@@ -0,0 +1,111 @@ +EXPORTS + ?use_hidden_primary_key@handler@@UAEXXZ + ?get_dynamic_partition_info@handler@@UAEXPAUPARTITION_INFO@@I@Z @@ -136,11 +136,24 @@ diff -Nur sql/mysqld.def.orig sql/mysqld.def + pthread_cond_destroy + localtime_r + my_strdup ++ deflate ++ deflateEnd ++ deflateReset ++ deflateInit2_ ++ inflateEnd ++ inflateInit_ ++ inflate ++ compressBound ++ inflateInit2_ ++ adler32 ++ longlong2str ++ strend ++ my_snprintf diff -Nur sql/mysqld_x64.def.orig sql/mysqld_x64.def --- sql/mysqld_x64.def.orig 1969-12-31 18:00:00 -06:00 -+++ sql/mysqld_x64.def 2008-10-31 02:22:04 -05:00 -@@ -0,0 +1,98 @@ ++++ sql/mysqld_x64.def 2009-04-09 02:22:04 -05:00 +@@ -0,0 +1,111 @@ +EXPORTS + ?use_hidden_primary_key@handler@@UEAAXXZ + ?get_dynamic_partition_info@handler@@UEAAXPEAUPARTITION_INFO@@I@Z @@ -239,6 +252,19 @@ diff -Nur sql/mysqld_x64.def.orig sql/mysqld_x64.def + pthread_cond_destroy + localtime_r + my_strdup ++ deflate ++ deflateEnd ++ deflateReset ++ deflateInit2_ ++ inflateEnd ++ inflateInit_ ++ inflate ++ compressBound ++ inflateInit2_ ++ adler32 ++ longlong2str ++ strend ++ my_snprintf diff -Nur win/configure.js.orig win/configure.js --- win/configure.js.orig 2008-09-26 21:18:37 -05:00 @@ -251,68 +277,3 @@ diff -Nur win/configure.js.orig win/configure.js configfile.WriteLine("SET (" + args.Item(i) + " TRUE)"); break; case "MYSQL_SERVER_SUFFIX": - -diff -Nur win/build-vs71.bat.orig win/build-vs71.bat ---- win/build-vs71.bat.orig 2008-08-20 10:21:59 -05:00 -+++ win/build-vs71.bat 2008-10-27 10:52:38 -05:00 -@@ -15,8 +15,10 @@ - REM along with this program; if not, write to the Free Software - REM Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -+REM CMAKE_BUILD_TYPE can be specified as Release or Debug -+ - if exist cmakecache.txt del cmakecache.txt - copy win\vs71cache.txt cmakecache.txt --cmake -G "Visual Studio 7 .NET 2003" -+cmake -G "Visual Studio 7 .NET 2003" -DCMAKE_BUILD_TYPE=%1 - copy cmakecache.txt win\vs71cache.txt - -diff -Nur win/build-vs8.bat.orig win/build-vs8.bat ---- win/build-vs8.bat.orig 2008-08-20 10:21:59 -05:00 -+++ win/build-vs8.bat 2008-10-27 10:52:31 -05:00 -@@ -15,7 +15,9 @@ - REM along with this program; if not, write to the Free Software - REM Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -+REM CMAKE_BUILD_TYPE can be specified as Release or Debug -+ - if exist cmakecache.txt del cmakecache.txt - copy win\vs8cache.txt cmakecache.txt --cmake -G "Visual Studio 8 2005" -+cmake -G "Visual Studio 8 2005" -DCMAKE_BUILD_TYPE=%1 - copy cmakecache.txt win\vs8cache.txt - -diff -Nur win/build-vs8_x64.bat.orig win/build-vs8_x64.bat ---- win/build-vs8_x64.bat.orig 2008-08-20 10:21:59 -05:00 -+++ win/build-vs8_x64.bat 2008-10-27 10:53:11 -05:00 -@@ -15,7 +15,9 @@ - REM along with this program; if not, write to the Free Software - REM Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -+REM CMAKE_BUILD_TYPE can be specified as Release or Debug -+ - if exist cmakecache.txt del cmakecache.txt - copy win\vs8cache.txt cmakecache.txt --cmake -G "Visual Studio 8 2005 Win64" -+cmake -G "Visual Studio 8 2005 Win64" -DCMAKE_BUILD_TYPE=%1 - copy cmakecache.txt win\vs8cache.txt - -diff -Nur old/build-vs9.bat new/build-vs9.bat ---- win/build-vs9.bat.orig 2008-11-17 14:07:18 -06:00 -+++ win/build-vs9.bat 2009-03-21 03:45:34 -05:00 -@@ -14,5 +14,5 @@ - REM You should have received a copy of the GNU General Public License - REM along with this program; if not, write to the Free Software - REM Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --cmake -G "Visual Studio 9 2008" -+cmake -G "Visual Studio 9 2008" -DCMAKE_BUILD_TYPE=%1 - -diff -Nur old/build-vs9_x64.bat new/build-vs9_x64.bat ---- win/build-vs9_x64.bat.orig 2008-11-17 14:07:18 -06:00 -+++ win/build-vs9_x64.bat 2009-03-21 03:45:42 -05:00 -@@ -14,5 +14,5 @@ - REM You should have received a copy of the GNU General Public License - REM along with this program; if not, write to the Free Software - REM Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --cmake -G "Visual Studio 9 2008 Win64" -+cmake -G "Visual Studio 9 2008 Win64" -DCMAKE_BUILD_TYPE=%1