diff options
123 files changed, 2297 insertions, 2396 deletions
diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 4eab3d239d0..df9a60f35ad 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] -post_commit_to = "commits@lists.mysql.com" -post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-trunk-bugfixing" +post_commit_to = commits@lists.mysql.com, innodb_dev_ww@oracle.com +post_push_to = commits@lists.mysql.com, innodb_dev_ww@oracle.com +tree_name = "mysql-trunk-innodb" diff --git a/CMakeLists.txt b/CMakeLists.txt index e50e24d0fa5..fed3d61be8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -148,6 +148,9 @@ OPTION(ENABLED_PROFILING "Enable profiling" ON) OPTION(CYBOZU "" OFF) OPTION(BACKUP_TEST "" OFF) OPTION(WITHOUT_SERVER OFF) +IF(UNIX) + OPTION(WITH_VALGRIND "Valgrind instrumentation" OFF) +ENDIF() OPTION (WITH_UNIT_TESTS "Compile MySQL with unit tests" ON) MARK_AS_ADVANCED(CYBOZU BACKUP_TEST WITHOUT_SERVER DISABLE_SHARED) diff --git a/config.h.cmake b/config.h.cmake index 1b59c580503..c484edb65a5 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -308,7 +308,7 @@ #define USE_MB 1 #define USE_MB_IDENT 1 - +#cmakedefine HAVE_VALGRIND /* Types we may use */ #ifdef __APPLE__ diff --git a/configure.cmake b/configure.cmake index d032d7ed448..c2e1dc4647b 100644 --- a/configure.cmake +++ b/configure.cmake @@ -805,7 +805,7 @@ ENDIF(NOT HAVE_POSIX_SIGNALS) # Assume regular sprintf SET(SPRINTFS_RETURNS_INT 1) -IF(CMAKE_COMPILER_IS_GNUXX AND HAVE_CXXABI_H) +IF(CMAKE_COMPILER_IS_GNUCXX AND HAVE_CXXABI_H) CHECK_CXX_SOURCE_COMPILES(" #include <cxxabi.h> int main(int argc, char **argv) @@ -994,6 +994,14 @@ configuration. By default gcc built-in sync functions are used, if available and 'smp' configuration otherwise.") MARK_AS_ADVANCED(WITH_ATOMIC_LOCKS MY_ATOMIC_MODE_RWLOCK MY_ATOMIC_MODE_DUMMY) +IF(WITH_VALGRIND) + CHECK_INCLUDE_FILES("valgrind/memcheck.h;valgrind/valgrind.h" + HAVE_VALGRIND_HEADERS) + IF(HAVE_VALGRIND_HEADERS) + SET(HAVE_VALGRIND 1) + ENDIF() +ENDIF() + #-------------------------------------------------------------------- # Check for IPv6 support #-------------------------------------------------------------------- diff --git a/mysql-test/suite/innodb/r/innodb_bug52199.result b/mysql-test/suite/innodb/r/innodb_bug52199.result new file mode 100644 index 00000000000..7e8c1ee46e0 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug52199.result @@ -0,0 +1,5 @@ +CREATE TABLE bug52199 (a INT NOT NULL, +b CHAR(125) CHARACTER SET utf32 COLLATE utf32_bin NOT NULL +)ENGINE=InnoDB; +CREATE UNIQUE INDEX idx ON bug52199(a); +DROP TABLE bug52199; diff --git a/mysql-test/suite/innodb/r/innodb_bug54679.result b/mysql-test/suite/innodb/r/innodb_bug54679.result new file mode 100644 index 00000000000..948696fb31d --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug54679.result @@ -0,0 +1,88 @@ +SET GLOBAL innodb_file_format='Barracuda'; +SET GLOBAL innodb_file_per_table=ON; +SET innodb_strict_mode=ON; +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables +WHERE TABLE_NAME='bug54679'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug54679 Compressed row_format=COMPRESSED +ALTER TABLE bug54679 ADD COLUMN b INT; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables +WHERE TABLE_NAME='bug54679'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug54679 Compressed row_format=COMPRESSED +DROP TABLE bug54679; +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables +WHERE TABLE_NAME='bug54679'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug54679 Compact +ALTER TABLE bug54679 KEY_BLOCK_SIZE=1; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables +WHERE TABLE_NAME='bug54679'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug54679 Compressed KEY_BLOCK_SIZE=1 +ALTER TABLE bug54679 ROW_FORMAT=REDUNDANT; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +DROP TABLE bug54679; +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables +WHERE TABLE_NAME='bug54679'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug54679 Redundant row_format=REDUNDANT +ALTER TABLE bug54679 KEY_BLOCK_SIZE=2; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables +WHERE TABLE_NAME='bug54679'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug54679 Compressed row_format=REDUNDANT KEY_BLOCK_SIZE=2 +SET GLOBAL innodb_file_format=Antelope; +ALTER TABLE bug54679 KEY_BLOCK_SIZE=4; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE bug54679 ROW_FORMAT=DYNAMIC; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. +Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +DROP TABLE bug54679; +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +ERROR HY000: Can't create table 'test.bug54679' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. +Error 1005 Can't create table 'test.bug54679' (errno: 1478) +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB; +SET GLOBAL innodb_file_format=Barracuda; +SET GLOBAL innodb_file_per_table=OFF; +ALTER TABLE bug54679 KEY_BLOCK_SIZE=4; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE bug54679 ROW_FORMAT=DYNAMIC; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +DROP TABLE bug54679; +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +ERROR HY000: Can't create table 'test.bug54679' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. +Error 1005 Can't create table 'test.bug54679' (errno: 1478) +SET GLOBAL innodb_file_per_table=ON; +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +DROP TABLE bug54679; diff --git a/mysql-test/suite/innodb/r/innodb_information_schema.result b/mysql-test/suite/innodb/r/innodb_information_schema.result index 1737dab2ff0..13de084bc09 100644 --- a/mysql-test/suite/innodb/r/innodb_information_schema.result +++ b/mysql-test/suite/innodb/r/innodb_information_schema.result @@ -42,21 +42,7 @@ trx_isolation_level varchar(16) NO trx_unique_checks int(1) NO 0 trx_foreign_key_checks int(1) NO 0 trx_last_foreign_key_error varchar(256) YES NULL -trx_apative_hash_latched int(1) NO 0 -trx_adaptive_hash_timeout bigint(21) unsigned NO 0 -trx_operation_state varchar(64) YES NULL -trx_tables_in_use bigint(21) unsigned NO 0 -trx_tables_locked bigint(21) unsigned NO 0 -trx_lock_structs bigint(21) unsigned NO 0 -trx_lock_memory_bytes bigint(21) unsigned NO 0 -trx_rows_locked bigint(21) unsigned NO 0 -trx_rows_modified bigint(21) unsigned NO 0 -trx_concurrency_tickets bigint(21) unsigned NO 0 -trx_isolation_level varchar(16) NO -trx_unique_checks int(1) NO 0 -trx_foreign_key_checks int(1) NO 0 -trx_last_foreign_key_error varchar(256) YES NULL -trx_apative_hash_latched int(1) NO 0 +trx_adaptive_hash_latched int(1) NO 0 trx_adaptive_hash_timeout bigint(21) unsigned NO 0 trx_state trx_weight trx_tables_in_use trx_tables_locked trx_rows_locked trx_rows_modified trx_concurrency_tickets trx_isolation_level trx_unique_checks trx_foreign_key_checks RUNNING 4 0 0 7 1 0 REPEATABLE READ 1 1 diff --git a/mysql-test/suite/innodb/t/innodb_bug52199.test b/mysql-test/suite/innodb/t/innodb_bug52199.test new file mode 100644 index 00000000000..0fec64ba243 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug52199.test @@ -0,0 +1,7 @@ +-- source include/have_innodb.inc + +CREATE TABLE bug52199 (a INT NOT NULL, +b CHAR(125) CHARACTER SET utf32 COLLATE utf32_bin NOT NULL +)ENGINE=InnoDB; +CREATE UNIQUE INDEX idx ON bug52199(a); +DROP TABLE bug52199; diff --git a/mysql-test/suite/innodb/t/innodb_bug54679.test b/mysql-test/suite/innodb/t/innodb_bug54679.test new file mode 100644 index 00000000000..c5e308acb5e --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug54679.test @@ -0,0 +1,101 @@ +# Test Bug #54679 alter table causes compressed row_format to revert to compact + +--source include/have_innodb.inc + +let $file_format=`select @@innodb_file_format`; +let $file_format_max=`select @@innodb_file_format_max`; +let $file_per_table=`select @@innodb_file_per_table`; +SET GLOBAL innodb_file_format='Barracuda'; +SET GLOBAL innodb_file_per_table=ON; +SET innodb_strict_mode=ON; + +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables +WHERE TABLE_NAME='bug54679'; + +# The ROW_FORMAT of the table should be preserved when it is not specified +# in ALTER TABLE. +ALTER TABLE bug54679 ADD COLUMN b INT; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables +WHERE TABLE_NAME='bug54679'; + +DROP TABLE bug54679; + +# Check that the ROW_FORMAT conversion to/from COMPRESSED works. + +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables +WHERE TABLE_NAME='bug54679'; + +# KEY_BLOCK_SIZE implies COMPRESSED. +ALTER TABLE bug54679 KEY_BLOCK_SIZE=1; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables +WHERE TABLE_NAME='bug54679'; + +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE bug54679 ROW_FORMAT=REDUNDANT; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +DROP TABLE bug54679; +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables +WHERE TABLE_NAME='bug54679'; + +ALTER TABLE bug54679 KEY_BLOCK_SIZE=2; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables +WHERE TABLE_NAME='bug54679'; + +# This prevents other than REDUNDANT or COMPACT ROW_FORMAT for new tables. +SET GLOBAL innodb_file_format=Antelope; + +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE bug54679 KEY_BLOCK_SIZE=4; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE bug54679 ROW_FORMAT=DYNAMIC; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +DROP TABLE bug54679; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB; + +SET GLOBAL innodb_file_format=Barracuda; +# This will prevent ROW_FORMAT=COMPRESSED, because the system tablespace +# cannot be compressed. +SET GLOBAL innodb_file_per_table=OFF; + +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE bug54679 KEY_BLOCK_SIZE=4; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE bug54679 ROW_FORMAT=DYNAMIC; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +DROP TABLE bug54679; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +SET GLOBAL innodb_file_per_table=ON; +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +DROP TABLE bug54679; + +# restore original values, quietly so the test does not fail if those +# defaults are changed +-- disable_query_log +EVAL SET GLOBAL innodb_file_format=$file_format; +EVAL SET GLOBAL innodb_file_format_max=$file_format_max; +EVAL SET GLOBAL innodb_file_per_table=$file_per_table; +-- enable_query_log diff --git a/mysql-test/suite/rpl/t/rpl_sync-slave.opt b/mysql-test/suite/rpl/t/rpl_sync-slave.opt index 7d6147ed59a..fba451a5b3e 100644 --- a/mysql-test/suite/rpl/t/rpl_sync-slave.opt +++ b/mysql-test/suite/rpl/t/rpl_sync-slave.opt @@ -1 +1 @@ ---sync-relay-log-info=1 --relay-log-recovery=1 --innodb_file_format_check='ON' --default-storage-engine=MyISAM --innodb-file-per-table=0 +--sync-relay-log-info=1 --relay-log-recovery=1 --innodb_file_format_check=1 --default-storage-engine=MyISAM --innodb-file-per-table=0 diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index b6399dcc478..218dbad2df0 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -40,6 +40,12 @@ IF(UNIX) ENDIF() ENDIF() +# Enable InnoDB's UNIV_DEBUG if MySQL's WITH_DEBUG[_FULL] is defined +# enable when this bug is resolved: +# Bug#54861 Additional connections not handled properly in mtr --embedded +#IF(WITH_DEBUG OR WITH_DEBUG_FULL) +# ADD_DEFINITIONS("-DUNIV_DEBUG") +#ENDIF() IF(NOT MSVC) # either define HAVE_IB_GCC_ATOMIC_BUILTINS or not @@ -182,11 +188,7 @@ IF(SIZEOF_PTHREAD_T) ENDIF() IF(MSVC) - # Windows atomics do not perform well. Disable Windows atomics by default. - # See bug#52102 for details. - - #ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DINNODB_RW_LOCKS_USE_ATOMICS -DHAVE_IB_PAUSE_INSTRUCTION) - ADD_DEFINITIONS(-DHAVE_IB_PAUSE_INSTRUCTION) + ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DHAVE_IB_PAUSE_INSTRUCTION) ENDIF() diff --git a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c index 05dd094b6df..f8638af2e71 100644 --- a/storage/innobase/btr/btr0btr.c +++ b/storage/innobase/btr/btr0btr.c @@ -737,7 +737,7 @@ btr_create( ulint space, /*!< in: space where created */ ulint zip_size,/*!< in: compressed page size in bytes or 0 for uncompressed pages */ - dulint index_id,/*!< in: index id */ + index_id_t index_id,/*!< in: index id */ dict_index_t* index, /*!< in: index */ mtr_t* mtr) /*!< in: mini-transaction handle */ { @@ -1020,7 +1020,7 @@ btr_page_reorganize_low( /* 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); + ut_ad(max_trx_id != 0 || recovery); } if (UNIV_LIKELY_NULL(page_zip) @@ -2883,7 +2883,7 @@ btr_discard_only_page_on_level( ibuf_reset_free_bits(block); if (page_is_leaf(buf_block_get_frame(block))) { - ut_a(!ut_dulint_is_zero(max_trx_id)); + ut_a(max_trx_id); page_set_max_trx_id(block, buf_block_get_page_zip(block), max_trx_id, mtr); diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c index 31e1a2d4b12..537d5f51184 100644 --- a/storage/innobase/btr/btr0cur.c +++ b/storage/innobase/btr/btr0cur.c @@ -660,7 +660,7 @@ retry_page_get: buf_block_dbg_add_level(block, SYNC_TREE_NODE); } - ut_ad(0 == ut_dulint_cmp(index->id, btr_page_get_index_id(page))); + ut_ad(index->id == btr_page_get_index_id(page)); if (UNIV_UNLIKELY(height == ULINT_UNDEFINED)) { /* We are in the root node */ @@ -854,8 +854,7 @@ btr_cur_open_at_index_side_func( RW_NO_LATCH, NULL, BUF_GET, file, line, mtr); page = buf_block_get_frame(block); - ut_ad(0 == ut_dulint_cmp(index->id, - btr_page_get_index_id(page))); + ut_ad(index->id == btr_page_get_index_id(page)); block->check_index_page_at_flush = TRUE; @@ -975,8 +974,7 @@ btr_cur_open_at_rnd_pos_func( RW_NO_LATCH, NULL, BUF_GET, file, line, mtr); page = buf_block_get_frame(block); - ut_ad(0 == ut_dulint_cmp(index->id, - btr_page_get_index_id(page))); + ut_ad(index->id == btr_page_get_index_id(page)); if (height == ULINT_UNDEFINED) { /* We are in the root node */ @@ -1135,7 +1133,7 @@ btr_cur_trx_report( const char* op) /*!< in: operation */ { fprintf(stderr, "Trx with id " TRX_ID_FMT " going to ", - TRX_ID_PREP_PRINTF(trx->id)); + (ullint) trx->id); fputs(op, stderr); dict_index_name_print(stderr, trx, index); putc('\n', stderr); @@ -1826,7 +1824,7 @@ btr_cur_update_in_place( page_zip_des_t* page_zip; ulint err; rec_t* rec; - roll_ptr_t roll_ptr = ut_dulint_zero; + roll_ptr_t roll_ptr = 0; trx_t* trx; ulint was_delete_marked; mem_heap_t* heap = NULL; @@ -4936,7 +4934,7 @@ btr_copy_externally_stored_field( /*******************************************************************//** Copies an externally stored field of a record to mem heap. -@return the field copied to heap */ +@return the field copied to heap, or NULL if the field is incomplete */ UNIV_INTERN byte* btr_rec_copy_externally_stored_field( @@ -4966,6 +4964,18 @@ btr_rec_copy_externally_stored_field( data = rec_get_nth_field(rec, offsets, no, &local_len); + ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE); + + if (UNIV_UNLIKELY + (!memcmp(data + local_len - BTR_EXTERN_FIELD_REF_SIZE, + field_ref_zero, BTR_EXTERN_FIELD_REF_SIZE))) { + /* The externally stored field was not written yet. + This record should only be seen by + recv_recovery_rollback_active() or any + TRX_ISO_READ_UNCOMMITTED transactions. */ + return(NULL); + } + return(btr_copy_externally_stored_field(len, data, zip_size, local_len, heap)); } diff --git a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c index 98a321bdb80..06cc48c7c60 100644 --- a/storage/innobase/btr/btr0sea.c +++ b/storage/innobase/btr/btr0sea.c @@ -46,6 +46,7 @@ Created 2/17/1996 Heikki Tuuri /** Flag: has the search system been enabled? Protected by btr_search_latch and btr_search_enabled_mutex. */ UNIV_INTERN char btr_search_enabled = TRUE; +UNIV_INTERN ibool btr_search_fully_disabled = FALSE; /** Mutex protecting btr_search_enabled */ static mutex_t btr_search_enabled_mutex; @@ -213,12 +214,19 @@ btr_search_disable(void) mutex_enter(&btr_search_enabled_mutex); rw_lock_x_lock(&btr_search_latch); + /* Disable access to hash index, also tell ha_insert_for_fold() + stop adding new nodes to hash index, but still allow updating + existing nodes */ btr_search_enabled = FALSE; /* Clear all block->is_hashed flags and remove all entries from btr_search_sys->hash_index. */ buf_pool_drop_hash_index(); + /* hash index has been cleaned up, disallow any operation to + the hash index */ + btr_search_fully_disabled = TRUE; + /* btr_search_enabled_mutex should guarantee this. */ ut_ad(!btr_search_enabled); @@ -237,6 +245,7 @@ btr_search_enable(void) rw_lock_x_lock(&btr_search_latch); btr_search_enabled = TRUE; + btr_search_fully_disabled = FALSE; rw_lock_x_unlock(&btr_search_latch); mutex_exit(&btr_search_enabled_mutex); @@ -523,9 +532,9 @@ btr_search_update_hash_ref( buf_block_t* block, /*!< in: buffer block where cursor positioned */ btr_cur_t* cursor) /*!< in: cursor */ { - ulint fold; - rec_t* rec; - dulint index_id; + ulint fold; + rec_t* rec; + index_id_t index_id; ut_ad(cursor->flag == BTR_CUR_HASH_FAIL); #ifdef UNIV_SYNC_DEBUG @@ -830,7 +839,7 @@ btr_search_guess_on_hash( buf_block_t* block; rec_t* rec; ulint fold; - dulint index_id; + index_id_t index_id; #ifdef notdefined btr_cur_t cursor2; btr_pcur_t pcur; @@ -922,8 +931,7 @@ btr_search_guess_on_hash( is positioned on. We cannot look at the next of the previous record to determine if our guess for the cursor position is right. */ - if (UNIV_EXPECT - (ut_dulint_cmp(index_id, btr_page_get_index_id(block->frame)), 0) + if (UNIV_UNLIKELY(index_id != btr_page_get_index_id(block->frame)) || !btr_search_check_guess(cursor, has_search_latch, tuple, mode, mtr)) { @@ -1028,7 +1036,7 @@ btr_search_drop_page_hash_index( const rec_t* rec; ulint fold; ulint prev_fold; - dulint index_id; + index_id_t index_id; ulint n_cached; ulint n_recs; ulint* folds; @@ -1088,7 +1096,7 @@ retry: index_id = btr_page_get_index_id(page); - ut_a(0 == ut_dulint_cmp(index_id, index->id)); + ut_a(index_id == index->id); prev_fold = 0; @@ -1245,7 +1253,7 @@ btr_search_build_page_hash_index( rec_t* next_rec; ulint fold; ulint next_fold; - dulint index_id; + index_id_t index_id; ulint n_cached; ulint n_recs; ulint* folds; @@ -1376,7 +1384,7 @@ btr_search_build_page_hash_index( rw_lock_x_lock(&btr_search_latch); - if (UNIV_UNLIKELY(!btr_search_enabled)) { + if (UNIV_UNLIKELY(btr_search_fully_disabled)) { goto exit_func; } @@ -1498,7 +1506,7 @@ btr_search_update_hash_on_delete( buf_block_t* block; rec_t* rec; ulint fold; - dulint index_id; + index_id_t index_id; ibool found; ulint offsets_[REC_OFFS_NORMAL_SIZE]; mem_heap_t* heap = NULL; @@ -1604,7 +1612,7 @@ btr_search_update_hash_on_insert( rec_t* rec; rec_t* ins_rec; rec_t* next_rec; - dulint index_id; + index_id_t index_id; ulint fold; ulint ins_fold; ulint next_fold = 0; /* remove warning (??? bug ???) */ @@ -1784,6 +1792,7 @@ btr_search_validate(void) = buf_block_align(node->data); const buf_block_t* hash_block; buf_pool_t* buf_pool; + index_id_t page_index_id; buf_pool = buf_pool_from_bpage((buf_page_t*) block); @@ -1828,12 +1837,15 @@ btr_search_validate(void) + (block->curr_n_bytes > 0), &heap); - if (!block->is_hashed || node->fold - != rec_fold((rec_t*)(node->data), - offsets, - block->curr_n_fields, - block->curr_n_bytes, - btr_page_get_index_id(block->frame))) { + page_index_id = btr_page_get_index_id(block->frame); + + if (UNIV_UNLIKELY + (!block->is_hashed || node->fold + != rec_fold((rec_t*)(node->data), + offsets, + block->curr_n_fields, + block->curr_n_bytes, + page_index_id))) { const page_t* page = block->frame; ok = FALSE; @@ -1843,21 +1855,17 @@ btr_search_validate(void) " InnoDB: Error in an adaptive hash" " index pointer to page %lu\n" "InnoDB: ptr mem address %p" - " index id %lu %lu," + " index id %llu," " node fold %lu, rec fold %lu\n", (ulong) page_get_page_no(page), node->data, - (ulong) ut_dulint_get_high( - btr_page_get_index_id(page)), - (ulong) ut_dulint_get_low( - btr_page_get_index_id(page)), + (ullint) page_index_id, (ulong) node->fold, (ulong) rec_fold((rec_t*)(node->data), offsets, block->curr_n_fields, block->curr_n_bytes, - btr_page_get_index_id( - page))); + page_index_id)); fputs("InnoDB: Record ", stderr); rec_print_new(stderr, (rec_t*)node->data, diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index 4b6b0a82486..ab3c1abf490 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -522,7 +522,9 @@ buf_page_is_corrupted( ib_uint64_t current_lsn; if (log_peek_lsn(¤t_lsn) - && current_lsn < mach_read_ull(read_buf + FIL_PAGE_LSN)) { + && UNIV_UNLIKELY + (current_lsn + < mach_read_from_8(read_buf + FIL_PAGE_LSN))) { ut_print_timestamp(stderr); fprintf(stderr, @@ -538,7 +540,7 @@ buf_page_is_corrupted( "InnoDB: for more information.\n", (ulong) mach_read_from_4(read_buf + FIL_PAGE_OFFSET), - mach_read_ull(read_buf + FIL_PAGE_LSN), + mach_read_from_8(read_buf + FIL_PAGE_LSN), current_lsn); } } @@ -735,17 +737,15 @@ buf_page_print( #endif /* !UNIV_HOTBACKUP */ switch (fil_page_get_type(read_buf)) { + index_id_t index_id; case FIL_PAGE_INDEX: + index_id = btr_page_get_index_id(read_buf); fprintf(stderr, "InnoDB: Page may be an index page where" - " index id is %lu %lu\n", - (ulong) ut_dulint_get_high( - btr_page_get_index_id(read_buf)), - (ulong) ut_dulint_get_low( - btr_page_get_index_id(read_buf))); + " index id is %llu\n", + (ullint) index_id); #ifndef UNIV_HOTBACKUP - index = dict_index_find_on_id_low( - btr_page_get_index_id(read_buf)); + index = dict_index_find_on_id_low(index_id); if (index) { fputs("InnoDB: (", stderr); dict_index_name_print(stderr, NULL, index); @@ -4461,12 +4461,12 @@ buf_print_instance( /*===============*/ buf_pool_t* buf_pool) { - dulint* index_ids; + index_id_t* index_ids; ulint* counts; ulint size; ulint i; ulint j; - dulint id; + index_id_t id; ulint n_found; buf_chunk_t* chunk; dict_index_t* index; @@ -4475,7 +4475,7 @@ buf_print_instance( size = buf_pool->curr_size; - index_ids = mem_alloc(sizeof(dulint) * size); + index_ids = mem_alloc(size * sizeof *index_ids); counts = mem_alloc(sizeof(ulint) * size); buf_pool_mutex_enter(buf_pool); @@ -4530,8 +4530,7 @@ buf_print_instance( while (j < n_found) { - if (ut_dulint_cmp(index_ids[j], - id) == 0) { + if (index_ids[j] == id) { counts[j]++; break; @@ -4554,8 +4553,8 @@ buf_print_instance( index = dict_index_get_if_in_cache(index_ids[i]); fprintf(stderr, - "Block count for index %lu in buffer is about %lu", - (ulong) ut_dulint_get_low(index_ids[i]), + "Block count for index %llu in buffer is about %lu", + (ullint) index_ids[i], (ulong) counts[i]); if (index) { diff --git a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c index 046f1ed51e8..3737627301f 100644 --- a/storage/innobase/buf/buf0flu.c +++ b/storage/innobase/buf/buf0flu.c @@ -114,7 +114,9 @@ buf_flush_insert_in_flush_rbt( p_node = rbt_prev(buf_pool->flush_rbt, c_node); if (p_node != NULL) { - prev = *rbt_value(buf_page_t*, p_node); + buf_page_t** value; + value = rbt_value(buf_page_t*, p_node); + prev = *value; ut_a(prev != NULL); } @@ -980,8 +982,8 @@ buf_flush_init_for_writing( case FIL_PAGE_TYPE_ZBLOB: case FIL_PAGE_TYPE_ZBLOB2: case FIL_PAGE_INDEX: - mach_write_ull(page_zip->data - + FIL_PAGE_LSN, newest_lsn); + mach_write_to_8(page_zip->data + + FIL_PAGE_LSN, newest_lsn); memset(page_zip->data + FIL_PAGE_FILE_FLUSH_LSN, 0, 8); mach_write_to_4(page_zip->data + FIL_PAGE_SPACE_OR_CHKSUM, @@ -1003,10 +1005,10 @@ buf_flush_init_for_writing( } /* Write the newest modification lsn to the page header and trailer */ - mach_write_ull(page + FIL_PAGE_LSN, newest_lsn); + mach_write_to_8(page + FIL_PAGE_LSN, newest_lsn); - mach_write_ull(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM, - newest_lsn); + mach_write_to_8(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM, + newest_lsn); /* Store the new formula checksum */ @@ -1094,8 +1096,8 @@ buf_flush_write_block_low( ut_a(mach_read_from_4(frame + FIL_PAGE_SPACE_OR_CHKSUM) == page_zip_calc_checksum(frame, zip_size)); } - mach_write_ull(frame + FIL_PAGE_LSN, - bpage->newest_modification); + mach_write_to_8(frame + FIL_PAGE_LSN, + bpage->newest_modification); memset(frame + FIL_PAGE_FILE_FLUSH_LSN, 0, 8); break; case BUF_BLOCK_FILE_PAGE: @@ -2088,13 +2090,13 @@ buf_flush_validate_low( ut_a(om > 0); if (UNIV_LIKELY_NULL(buf_pool->flush_rbt)) { - buf_page_t* rpage; + buf_page_t** prpage; ut_a(rnode); - rpage = *rbt_value(buf_page_t*, rnode); + prpage = rbt_value(buf_page_t*, rnode); - ut_a(rpage); - ut_a(rpage == bpage); + ut_a(*prpage); + ut_a(*prpage == bpage); rnode = rbt_next(buf_pool->flush_rbt, rnode); } diff --git a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c index a539c4e894b..e1d4b5081b8 100644 --- a/storage/innobase/buf/buf0lru.c +++ b/storage/innobase/buf/buf0lru.c @@ -2278,19 +2278,17 @@ buf_LRU_print_instance( case BUF_BLOCK_FILE_PAGE: frame = buf_block_get_frame((buf_block_t*) bpage); fprintf(stderr, "\ntype %lu" - " index id %lu\n", + " index id %llu\n", (ulong) fil_page_get_type(frame), - (ulong) ut_dulint_get_low( - btr_page_get_index_id(frame))); + (ullint) btr_page_get_index_id(frame)); break; case BUF_BLOCK_ZIP_PAGE: frame = bpage->zip.data; fprintf(stderr, "\ntype %lu size %lu" - " index id %lu\n", + " index id %llu\n", (ulong) fil_page_get_type(frame), (ulong) buf_page_get_zip_size(bpage), - (ulong) ut_dulint_get_low( - btr_page_get_index_id(frame))); + (ullint) btr_page_get_index_id(frame)); break; default: diff --git a/storage/innobase/data/data0data.c b/storage/innobase/data/data0data.c index 0715b49bf9c..0ef0cfa554a 100644 --- a/storage/innobase/data/data0data.c +++ b/storage/innobase/data/data0data.c @@ -367,7 +367,7 @@ dfield_print_also_hex( prtype = dtype_get_prtype(dfield_get_type(dfield)); switch (dtype_get_mtype(dfield_get_type(dfield))) { - dulint id; + ib_id_t id; case DATA_INT: switch (len) { ulint val; @@ -417,22 +417,16 @@ dfield_print_also_hex( case 6: id = mach_read_from_6(data); - fprintf(stderr, "{%lu %lu}", - ut_dulint_get_high(id), - ut_dulint_get_low(id)); + fprintf(stderr, "%llu", (ullint) id); break; case 7: id = mach_read_from_7(data); - fprintf(stderr, "{%lu %lu}", - ut_dulint_get_high(id), - ut_dulint_get_low(id)); + fprintf(stderr, "%llu", (ullint) id); break; case 8: id = mach_read_from_8(data); - fprintf(stderr, "{%lu %lu}", - ut_dulint_get_high(id), - ut_dulint_get_low(id)); + fprintf(stderr, "%llu", (ullint) id); break; default: goto print_hex; @@ -444,29 +438,25 @@ dfield_print_also_hex( case DATA_TRX_ID: id = mach_read_from_6(data); - fprintf(stderr, "trx_id " TRX_ID_FMT, - TRX_ID_PREP_PRINTF(id)); + fprintf(stderr, "trx_id " TRX_ID_FMT, (ullint) id); break; case DATA_ROLL_PTR: id = mach_read_from_7(data); - fprintf(stderr, "roll_ptr {%lu %lu}", - ut_dulint_get_high(id), ut_dulint_get_low(id)); + fprintf(stderr, "roll_ptr " TRX_ID_FMT, (ullint) id); break; case DATA_ROW_ID: id = mach_read_from_6(data); - fprintf(stderr, "row_id {%lu %lu}", - ut_dulint_get_high(id), ut_dulint_get_low(id)); + fprintf(stderr, "row_id " TRX_ID_FMT, (ullint) id); break; default: - id = mach_dulint_read_compressed(data); + id = mach_ull_read_compressed(data); - fprintf(stderr, "mix_id {%lu %lu}", - ut_dulint_get_high(id), ut_dulint_get_low(id)); + fprintf(stderr, "mix_id " TRX_ID_FMT, (ullint) id); } break; diff --git a/storage/innobase/data/data0type.c b/storage/innobase/data/data0type.c index e834fd2ec55..20d1f5db8d3 100644 --- a/storage/innobase/data/data0type.c +++ b/storage/innobase/data/data0type.c @@ -49,10 +49,8 @@ ulint dtype_get_at_most_n_mbchars( /*========================*/ ulint prtype, /*!< in: precise type */ - ulint mbminlen, /*!< in: minimum length of a - multi-byte character */ - ulint mbmaxlen, /*!< in: maximum length of a - multi-byte character */ + ulint mbminmaxlen, /*!< in: minimum and maximum length of + a multi-byte character */ ulint prefix_len, /*!< in: length of the requested prefix, in characters, multiplied by dtype_get_mbmaxlen(dtype) */ @@ -60,6 +58,9 @@ dtype_get_at_most_n_mbchars( const char* str) /*!< in: the string whose prefix length is being determined */ { + ulint mbminlen = DATA_MBMINLEN(mbminmaxlen); + ulint mbmaxlen = DATA_MBMAXLEN(mbminmaxlen); + ut_a(data_len != UNIV_SQL_NULL); ut_ad(!mbmaxlen || !(prefix_len % mbmaxlen)); @@ -180,7 +181,7 @@ dtype_validate( } #ifndef UNIV_HOTBACKUP - ut_a(type->mbminlen <= type->mbmaxlen); + ut_a(dtype_get_mbminlen(type) <= dtype_get_mbmaxlen(type)); #endif /* !UNIV_HOTBACKUP */ return(TRUE); diff --git a/storage/innobase/dict/dict0boot.c b/storage/innobase/dict/dict0boot.c index e63c1dc94b9..20d676e6129 100644 --- a/storage/innobase/dict/dict0boot.c +++ b/storage/innobase/dict/dict0boot.c @@ -67,12 +67,15 @@ UNIV_INTERN void dict_hdr_get_new_id( /*================*/ - dulint* table_id, /*!< out: table id (not assigned if NULL) */ - dulint* index_id, /*!< out: index id (not assigned if NULL) */ - ulint* space_id) /*!< out: space id (not assigned if NULL) */ + table_id_t* table_id, /*!< out: table id + (not assigned if NULL) */ + index_id_t* index_id, /*!< out: index id + (not assigned if NULL) */ + ulint* space_id) /*!< out: space id + (not assigned if NULL) */ { dict_hdr_t* dict_hdr; - dulint id; + ib_id_t id; mtr_t mtr; mtr_start(&mtr); @@ -80,16 +83,16 @@ dict_hdr_get_new_id( dict_hdr = dict_hdr_get(&mtr); if (table_id) { - id = mtr_read_dulint(dict_hdr + DICT_HDR_TABLE_ID, &mtr); - id = ut_dulint_add(id, 1); - mlog_write_dulint(dict_hdr + DICT_HDR_TABLE_ID, id, &mtr); + id = mach_read_from_8(dict_hdr + DICT_HDR_TABLE_ID); + id++; + mlog_write_ull(dict_hdr + DICT_HDR_TABLE_ID, id, &mtr); *table_id = id; } if (index_id) { - id = mtr_read_dulint(dict_hdr + DICT_HDR_INDEX_ID, &mtr); - id = ut_dulint_add(id, 1); - mlog_write_dulint(dict_hdr + DICT_HDR_INDEX_ID, id, &mtr); + id = mach_read_from_8(dict_hdr + DICT_HDR_INDEX_ID); + id++; + mlog_write_ull(dict_hdr + DICT_HDR_INDEX_ID, id, &mtr); *index_id = id; } @@ -114,7 +117,7 @@ dict_hdr_flush_row_id(void) /*=======================*/ { dict_hdr_t* dict_hdr; - dulint id; + row_id_t id; mtr_t mtr; ut_ad(mutex_own(&(dict_sys->mutex))); @@ -125,7 +128,7 @@ dict_hdr_flush_row_id(void) dict_hdr = dict_hdr_get(&mtr); - mlog_write_dulint(dict_hdr + DICT_HDR_ROW_ID, id, &mtr); + mlog_write_ull(dict_hdr + DICT_HDR_ROW_ID, id, &mtr); mtr_commit(&mtr); } @@ -157,14 +160,14 @@ dict_hdr_create( /* Start counting row, table, index, and tree ids from DICT_HDR_FIRST_ID */ - mlog_write_dulint(dict_header + DICT_HDR_ROW_ID, - ut_dulint_create(0, DICT_HDR_FIRST_ID), mtr); + mlog_write_ull(dict_header + DICT_HDR_ROW_ID, + DICT_HDR_FIRST_ID, mtr); - mlog_write_dulint(dict_header + DICT_HDR_TABLE_ID, - ut_dulint_create(0, DICT_HDR_FIRST_ID), mtr); + mlog_write_ull(dict_header + DICT_HDR_TABLE_ID, + DICT_HDR_FIRST_ID, mtr); - mlog_write_dulint(dict_header + DICT_HDR_INDEX_ID, - ut_dulint_create(0, DICT_HDR_FIRST_ID), mtr); + mlog_write_ull(dict_header + DICT_HDR_INDEX_ID, + DICT_HDR_FIRST_ID, mtr); mlog_write_ulint(dict_header + DICT_HDR_MAX_SPACE_ID, 0, MLOG_4BYTES, mtr); @@ -273,11 +276,9 @@ dict_boot(void) ..._MARGIN, it will immediately be updated to the disk-based header. */ - dict_sys->row_id = ut_dulint_add( - ut_dulint_align_up(mtr_read_dulint(dict_hdr + DICT_HDR_ROW_ID, - &mtr), - DICT_HDR_ROW_ID_WRITE_MARGIN), - DICT_HDR_ROW_ID_WRITE_MARGIN); + dict_sys->row_id = DICT_HDR_ROW_ID_WRITE_MARGIN + + ut_uint64_align_up(mach_read_from_8(dict_hdr + DICT_HDR_ROW_ID), + DICT_HDR_ROW_ID_WRITE_MARGIN); /* Insert into the dictionary cache the descriptions of the basic system tables */ diff --git a/storage/innobase/dict/dict0crea.c b/storage/innobase/dict/dict0crea.c index 09353c45c8c..6824d0fa9f9 100644 --- a/storage/innobase/dict/dict0crea.c +++ b/storage/innobase/dict/dict0crea.c @@ -590,7 +590,7 @@ dict_build_index_def_step( ins_node_set_new_row(node->ind_def, row); /* Note that the index was created by this transaction. */ - index->trx_id = (ib_uint64_t) ut_conv_dulint_to_longlong(trx->id); + index->trx_id = trx->id; return(DB_SUCCESS); } @@ -761,7 +761,7 @@ dict_truncate_index_tree( ibool drop = !space; ulint zip_size; ulint type; - dulint index_id; + index_id_t index_id; rec_t* rec; const byte* ptr; ulint len; @@ -854,7 +854,7 @@ create: for (index = UT_LIST_GET_FIRST(table->indexes); index; index = UT_LIST_GET_NEXT(indexes, index)) { - if (!ut_dulint_cmp(index->id, index_id)) { + if (index->id == index_id) { root_page_no = btr_create(type, space, zip_size, index_id, index, mtr); index->page = (unsigned int) root_page_no; @@ -864,10 +864,9 @@ create: ut_print_timestamp(stderr); fprintf(stderr, - " InnoDB: Index %lu %lu of table %s is missing\n" + " InnoDB: Index %llu of table %s is missing\n" "InnoDB: from the data dictionary during TRUNCATE!\n", - ut_dulint_get_high(index_id), - ut_dulint_get_low(index_id), + (ullint) index_id, table->name); return(FIL_NULL); @@ -1119,7 +1118,7 @@ dict_create_index_step( if (node->state == INDEX_ADD_TO_CACHE) { - dulint index_id = node->index->id; + index_id_t index_id = node->index->id; err = dict_index_add_to_cache( node->table, node->index, FIL_NULL, diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index a298d785449..802f0bd8b6f 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -256,8 +256,8 @@ dict_mutex_exit_for_mysql(void) /** Get the mutex that protects index->stat_n_diff_key_vals[] */ #define GET_INDEX_STAT_MUTEX(index) \ - (&dict_index_stat_mutex[ut_fold_dulint(index->id) \ - % DICT_INDEX_STAT_MUTEX_SIZE]) + (&dict_index_stat_mutex[ut_fold_ull(index->id) \ + % DICT_INDEX_STAT_MUTEX_SIZE]) /**********************************************************************//** Lock the appropriate mutex to protect index->stat_n_diff_key_vals[]. @@ -425,14 +425,14 @@ dict_index_t* dict_index_get_on_id_low( /*=====================*/ dict_table_t* table, /*!< in: table */ - dulint id) /*!< in: index id */ + index_id_t id) /*!< in: index id */ { dict_index_t* index; index = dict_table_get_first_index(table); while (index) { - if (0 == ut_dulint_cmp(id, index->id)) { + if (id == index->id) { /* Found */ return(index); @@ -574,20 +574,18 @@ UNIV_INTERN dict_table_t* dict_table_get_on_id( /*=================*/ - dulint table_id, /*!< in: table id */ - trx_t* trx) /*!< in: transaction handle */ + table_id_t table_id, /*!< in: table id */ + trx_t* trx) /*!< in: transaction handle */ { dict_table_t* table; - if (ut_dulint_cmp(table_id, DICT_FIELDS_ID) <= 0 + if (table_id <= DICT_FIELDS_ID || trx->dict_operation_lock_mode == RW_X_LATCH) { - /* It is a system table which will always exist in the table - cache: we avoid acquiring the dictionary mutex, because - if we are doing a rollback to handle an error in TABLE - CREATE, for example, we already have the mutex! */ - ut_ad(mutex_own(&(dict_sys->mutex)) - || trx->dict_operation_lock_mode == RW_X_LATCH); + /* Note: An X latch implies that the transaction + already owns the dictionary mutex. */ + + ut_ad(mutex_own(&dict_sys->mutex)); return(dict_table_get_on_id_low(table_id)); } @@ -800,7 +798,7 @@ dict_table_add_to_cache( table->cached = TRUE; fold = ut_fold_string(table->name); - id_fold = ut_fold_dulint(table->id); + id_fold = ut_fold_ull(table->id); row_len = 0; for (i = 0; i < table->n_def; i++) { @@ -842,7 +840,7 @@ dict_table_add_to_cache( dict_table_t* table2; HASH_SEARCH(id_hash, dict_sys->table_id_hash, id_fold, dict_table_t*, table2, ut_ad(table2->cached), - ut_dulint_cmp(table2->id, table->id) == 0); + table2->id == table->id); ut_a(table2 == NULL); #ifdef UNIV_DEBUG @@ -864,7 +862,8 @@ dict_table_add_to_cache( /* Add table to LRU list of tables */ UT_LIST_ADD_FIRST(table_LRU, dict_sys->table_LRU, table); - dict_sys->size += mem_heap_get_size(table->heap); + dict_sys->size += mem_heap_get_size(table->heap) + + strlen(table->name) + 1; } /**********************************************************************//** @@ -876,7 +875,7 @@ UNIV_INTERN dict_index_t* dict_index_find_on_id_low( /*======================*/ - dulint id) /*!< in: index id */ + index_id_t id) /*!< in: index id */ { dict_table_t* table; dict_index_t* index; @@ -887,7 +886,7 @@ dict_index_find_on_id_low( index = dict_table_get_first_index(table); while (index) { - if (0 == ut_dulint_cmp(id, index->id)) { + if (id == index->id) { /* Found */ return(index); @@ -918,14 +917,21 @@ dict_table_rename_in_cache( dict_foreign_t* foreign; dict_index_t* index; ulint fold; - ulint old_size; - const char* old_name; + char old_name[MAX_TABLE_NAME_LEN + 1]; ut_ad(table); ut_ad(mutex_own(&(dict_sys->mutex))); - old_size = mem_heap_get_size(table->heap); - old_name = table->name; + /* store the old/current name to an automatic variable */ + if (strlen(table->name) + 1 <= sizeof(old_name)) { + memcpy(old_name, table->name, strlen(table->name) + 1); + } else { + ut_print_timestamp(stderr); + fprintf(stderr, "InnoDB: too long table name: '%s', " + "max length is %d\n", table->name, + MAX_TABLE_NAME_LEN); + ut_error; + } fold = ut_fold_string(new_name); @@ -971,12 +977,22 @@ dict_table_rename_in_cache( /* Remove table from the hash tables of tables */ HASH_DELETE(dict_table_t, name_hash, dict_sys->table_hash, ut_fold_string(old_name), table); - table->name = mem_heap_strdup(table->heap, new_name); + + if (strlen(new_name) > strlen(table->name)) { + /* We allocate MAX_TABLE_NAME_LEN+1 bytes here to avoid + memory fragmentation, we assume a repeated calls of + ut_realloc() with the same size do not cause fragmentation */ + ut_a(strlen(new_name) <= MAX_TABLE_NAME_LEN); + table->name = ut_realloc(table->name, MAX_TABLE_NAME_LEN + 1); + } + memcpy(table->name, new_name, strlen(new_name) + 1); /* Add table to hash table of tables */ HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold, table); - dict_sys->size += (mem_heap_get_size(table->heap) - old_size); + + dict_sys->size += strlen(new_name) - strlen(old_name); + ut_a(dict_sys->size > 0); /* Update the table_name field in indexes */ index = dict_table_get_first_index(table); @@ -1126,7 +1142,7 @@ void dict_table_change_id_in_cache( /*==========================*/ dict_table_t* table, /*!< in/out: table object already in cache */ - dulint new_id) /*!< in: new id to set */ + table_id_t new_id) /*!< in: new id to set */ { ut_ad(table); ut_ad(mutex_own(&(dict_sys->mutex))); @@ -1135,12 +1151,12 @@ dict_table_change_id_in_cache( /* Remove the table from the hash table of id's */ HASH_DELETE(dict_table_t, id_hash, dict_sys->table_id_hash, - ut_fold_dulint(table->id), table); + ut_fold_ull(table->id), table); table->id = new_id; /* Add the table back to the hash table */ HASH_INSERT(dict_table_t, id_hash, dict_sys->table_id_hash, - ut_fold_dulint(table->id), table); + ut_fold_ull(table->id), table); } /**********************************************************************//** @@ -1196,12 +1212,12 @@ dict_table_remove_from_cache( HASH_DELETE(dict_table_t, name_hash, dict_sys->table_hash, ut_fold_string(table->name), table); HASH_DELETE(dict_table_t, id_hash, dict_sys->table_id_hash, - ut_fold_dulint(table->id), table); + ut_fold_ull(table->id), table); /* Remove table from LRU list of tables */ UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table); - size = mem_heap_get_size(table->heap); + size = mem_heap_get_size(table->heap) + strlen(table->name) + 1; ut_ad(dict_sys->size >= size); @@ -2458,8 +2474,7 @@ dict_table_get_index_by_max_id( /* We found a matching index, select the index with the higher id*/ - if (!found - || ut_dulint_cmp(index->id, found->id) > 0) { + if (!found || index->id > found->id) { found = index; } @@ -3947,7 +3962,7 @@ UNIV_INTERN dict_index_t* dict_index_get_if_in_cache_low( /*===========================*/ - dulint index_id) /*!< in: index id */ + index_id_t index_id) /*!< in: index id */ { ut_ad(mutex_own(&(dict_sys->mutex))); @@ -3962,7 +3977,7 @@ UNIV_INTERN dict_index_t* dict_index_get_if_in_cache( /*=======================*/ - dulint index_id) /*!< in: index id */ + index_id_t index_id) /*!< in: index id */ { dict_index_t* index; @@ -4358,12 +4373,11 @@ dict_table_print_low( fprintf(stderr, "--------------------------------------\n" - "TABLE: name %s, id %lu %lu, flags %lx, columns %lu," + "TABLE: name %s, id %llu, flags %lx, columns %lu," " indexes %lu, appr.rows %lu\n" " COLUMNS: ", table->name, - (ulong) ut_dulint_get_high(table->id), - (ulong) ut_dulint_get_low(table->id), + (ullint) table->id, (ulong) table->flags, (ulong) table->n_cols, (ulong) UT_LIST_GET_LEN(table->indexes), @@ -4452,14 +4466,13 @@ dict_index_print_low( } fprintf(stderr, - " INDEX: name %s, id %lu %lu, fields %lu/%lu," + " INDEX: name %s, id %llu, fields %lu/%lu," " uniq %lu, type %lu\n" " root page %lu, appr.key vals %lu," " leaf pages %lu, size pages %lu\n" " FIELDS: ", index->name, - (ulong) ut_dulint_get_high(index->id), - (ulong) ut_dulint_get_low(index->id), + (ullint) index->id, (ulong) index->n_user_defined_cols, (ulong) index->n_fields, (ulong) index->n_uniq, @@ -4831,8 +4844,7 @@ dict_table_get_index_on_name_and_min_id( while (index != NULL) { if (ut_strcmp(index->name, name) == 0) { - if (!min_index - || ut_dulint_cmp(index->id, min_index->id) < 0) { + if (!min_index || index->id < min_index->id) { min_index = index; } diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c index 6bf2c1d9d81..20a18c72a39 100644 --- a/storage/innobase/dict/dict0load.c +++ b/storage/innobase/dict/dict0load.c @@ -364,7 +364,7 @@ dict_process_sys_indexes_rec( mem_heap_t* heap, /*!< in/out: heap memory */ const rec_t* rec, /*!< in: current SYS_INDEXES rec */ dict_index_t* index, /*!< out: index to be filled */ - dulint* table_id) /*!< out: index table id */ + table_id_t* table_id) /*!< out: index table id */ { const char* err_msg; byte* buf; @@ -390,7 +390,7 @@ dict_process_sys_columns_rec( mem_heap_t* heap, /*!< in/out: heap memory */ const rec_t* rec, /*!< in: current SYS_COLUMNS rec */ dict_col_t* column, /*!< out: dict_col_t to be filled */ - dulint* table_id, /*!< out: table id */ + table_id_t* table_id, /*!< out: table id */ const char** col_name) /*!< out: column name */ { const char* err_msg; @@ -414,8 +414,8 @@ dict_process_sys_fields_rec( dict_field_t* sys_field, /*!< out: dict_field_t to be filled */ ulint* pos, /*!< out: Field position */ - dulint* index_id, /*!< out: current index id */ - dulint last_id) /*!< in: previous index id */ + index_id_t* index_id, /*!< out: current index id */ + index_id_t last_id) /*!< in: previous index id */ { byte* buf; byte* last_index_id; @@ -644,7 +644,7 @@ dict_check_tablespaces_and_store_max_id( dict_index_t* sys_index; btr_pcur_t pcur; const rec_t* rec; - ulint max_space_id = 0; + ulint max_space_id; mtr_t mtr; mutex_enter(&(dict_sys->mutex)); @@ -655,6 +655,11 @@ dict_check_tablespaces_and_store_max_id( sys_index = UT_LIST_GET_FIRST(sys_tables->indexes); ut_a(!dict_table_is_comp(sys_tables)); + max_space_id = mtr_read_ulint(dict_hdr_get(&mtr) + + DICT_HDR_MAX_SPACE_ID, + MLOG_4BYTES, &mtr); + fil_set_max_space_id_if_bigger(max_space_id); + btr_pcur_open_at_index_side(TRUE, sys_index, BTR_SEARCH_LEAF, &pcur, TRUE, &mtr); loop: @@ -777,13 +782,14 @@ const char* dict_load_column_low( /*=================*/ dict_table_t* table, /*!< in/out: table, could be NULL - if we just polulate a dict_column_t + if we just populate a dict_column_t struct with information from a SYS_COLUMNS record */ mem_heap_t* heap, /*!< in/out: memory heap for temporary storage */ - dict_col_t* column, /*!< out: dict_column_t to fill */ - dulint* table_id, /*!< out: table id */ + dict_col_t* column, /*!< out: dict_column_t to fill, + or NULL if table != NULL */ + table_id_t* table_id, /*!< out: table id */ const char** col_name, /*!< out: column name */ const rec_t* rec) /*!< in: SYS_COLUMNS record */ { @@ -795,6 +801,8 @@ dict_load_column_low( ulint col_len; ulint pos; + ut_ad(table || column); + if (UNIV_UNLIKELY(rec_get_deleted_flag(rec, 0))) { return("delete-marked record in SYS_COLUMNS"); } @@ -811,8 +819,7 @@ err_len: if (table_id) { *table_id = mach_read_from_8(field); - } else if (UNIV_UNLIKELY(ut_dulint_cmp(table->id, - mach_read_from_8(field)))) { + } else if (UNIV_UNLIKELY(table->id != mach_read_from_8(field))) { return("SYS_COLUMNS.TABLE_ID mismatch"); } @@ -822,9 +829,9 @@ err_len: goto err_len; } - if (!table) { - pos = mach_read_from_4(field); - } else if (UNIV_UNLIKELY(table->n_def != mach_read_from_4(field))) { + pos = mach_read_from_4(field); + + if (UNIV_UNLIKELY(table && table->n_def != pos)) { return("SYS_COLUMNS.POS mismatch"); } @@ -1191,7 +1198,7 @@ dict_load_index_low( ulint len; ulint name_len; char* name_buf; - dulint id; + index_id_t id; ulint n_fields; ulint type; ulint space; @@ -1308,19 +1315,11 @@ dict_load_indexes( dfield_t* dfield; const rec_t* rec; byte* buf; - ibool is_sys_table; mtr_t mtr; ulint error = DB_SUCCESS; ut_ad(mutex_own(&(dict_sys->mutex))); - if ((ut_dulint_get_high(table->id) == 0) - && (ut_dulint_get_low(table->id) < DICT_HDR_FIRST_ID)) { - is_sys_table = TRUE; - } else { - is_sys_table = FALSE; - } - mtr_start(&mtr); sys_indexes = dict_table_get_low("SYS_INDEXES"); @@ -1406,7 +1405,7 @@ corrupted: " is not clustered!\n", stderr); goto corrupted; - } else if (is_sys_table + } else if (table->id < DICT_HDR_FIRST_ID && (dict_index_is_clust(index) || ((table == dict_sys->sys_tables) && !strcmp("ID_IND", index->name)))) { @@ -1766,7 +1765,7 @@ UNIV_INTERN dict_table_t* dict_load_table_on_id( /*==================*/ - dulint table_id) /*!< in: table id */ + table_id_t table_id) /*!< in: table id */ { byte id_buf[8]; btr_pcur_t pcur; @@ -1829,7 +1828,7 @@ dict_load_table_on_id( ut_ad(len == 8); /* Check if the table id in record is the one searched for */ - if (ut_dulint_cmp(table_id, mach_read_from_8(field)) != 0) { + if (table_id != mach_read_from_8(field)) { btr_pcur_close(&pcur); mtr_commit(&mtr); diff --git a/storage/innobase/dict/dict0mem.c b/storage/innobase/dict/dict0mem.c index b6e516783c7..bbb8f810f44 100644 --- a/storage/innobase/dict/dict0mem.c +++ b/storage/innobase/dict/dict0mem.c @@ -73,7 +73,8 @@ dict_mem_table_create( table->heap = heap; table->flags = (unsigned int) flags; - table->name = mem_heap_strdup(heap, name); + table->name = ut_malloc(strlen(name) + 1); + memcpy(table->name, name, strlen(name) + 1); table->space = (unsigned int) space; table->n_cols = (unsigned int) (n_cols + DATA_N_SYS_COLS); @@ -112,6 +113,7 @@ dict_mem_table_free( #ifndef UNIV_HOTBACKUP mutex_free(&(table->autoinc_mutex)); #endif /* UNIV_HOTBACKUP */ + ut_free(table->name); mem_heap_free(table->heap); } @@ -204,6 +206,37 @@ dict_mem_table_add_col( dict_mem_fill_column_struct(col, i, mtype, prtype, len); } + +/**********************************************************************//** +This function populates a dict_col_t memory structure with +supplied information. */ +UNIV_INTERN +void +dict_mem_fill_column_struct( +/*========================*/ + dict_col_t* column, /*!< out: column struct to be + filled */ + ulint col_pos, /*!< in: column position */ + ulint mtype, /*!< in: main data type */ + ulint prtype, /*!< in: precise type */ + ulint col_len) /*!< in: column length */ +{ +#ifndef UNIV_HOTBACKUP + ulint mbminlen; + ulint mbmaxlen; +#endif /* !UNIV_HOTBACKUP */ + + column->ind = (unsigned int) col_pos; + column->ord_part = 0; + column->mtype = (unsigned int) mtype; + column->prtype = (unsigned int) prtype; + column->len = (unsigned int) col_len; +#ifndef UNIV_HOTBACKUP + dtype_get_mblen(mtype, prtype, &mbminlen, &mbmaxlen); + dict_col_set_mbminmaxlen(column, mbminlen, mbmaxlen); +#endif /* !UNIV_HOTBACKUP */ +} + /**********************************************************************//** Creates an index memory object. @return own: index object */ diff --git a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c index 0d033c37879..710f0ac8603 100644 --- a/storage/innobase/fil/fil0fil.c +++ b/storage/innobase/fil/fil0fil.c @@ -1214,7 +1214,7 @@ try_again: space->tablespace_version = fil_system->tablespace_version; space->mark = FALSE; - if (UNIV_LIKELY(purpose == FIL_TABLESPACE) + if (UNIV_LIKELY(purpose == FIL_TABLESPACE && !recv_recovery_on) && UNIV_UNLIKELY(id > fil_system->max_assigned_id)) { if (!fil_system->space_id_reuse_warned) { fil_system->space_id_reuse_warned = TRUE; @@ -1705,7 +1705,7 @@ fil_write_lsn_and_arch_no_to_file( fil_read(TRUE, 0, 0, sum_of_sizes, 0, UNIV_PAGE_SIZE, buf, NULL); - mach_write_ull(buf + FIL_PAGE_FILE_FLUSH_LSN, lsn); + mach_write_to_8(buf + FIL_PAGE_FILE_FLUSH_LSN, lsn); fil_write(TRUE, 0, 0, sum_of_sizes, 0, UNIV_PAGE_SIZE, buf, NULL); @@ -1799,7 +1799,7 @@ fil_read_flushed_lsn_and_arch_log_no( os_file_read(data_file, buf, 0, 0, UNIV_PAGE_SIZE); - flushed_lsn = mach_read_ull(buf + FIL_PAGE_FILE_FLUSH_LSN); + flushed_lsn = mach_read_from_8(buf + FIL_PAGE_FILE_FLUSH_LSN); ut_free(buf2); @@ -2850,7 +2850,7 @@ fil_reset_too_high_lsns( /* We have to read the file flush lsn from the header of the file */ - flush_lsn = mach_read_ull(page + FIL_PAGE_FILE_FLUSH_LSN); + flush_lsn = mach_read_from_8(page + FIL_PAGE_FILE_FLUSH_LSN); if (current_lsn >= flush_lsn) { /* Ok */ @@ -2898,7 +2898,7 @@ fil_reset_too_high_lsns( goto func_exit; } - if (mach_read_ull(page + FIL_PAGE_LSN) > current_lsn) { + if (mach_read_from_8(page + FIL_PAGE_LSN) > current_lsn) { /* We have to reset the lsn */ if (zip_size) { @@ -2940,7 +2940,7 @@ fil_reset_too_high_lsns( goto func_exit; } - mach_write_ull(page + FIL_PAGE_FILE_FLUSH_LSN, current_lsn); + mach_write_to_8(page + FIL_PAGE_FILE_FLUSH_LSN, current_lsn); success = os_file_write(filepath, file, page, 0, 0, zip_size ? zip_size : UNIV_PAGE_SIZE); diff --git a/storage/innobase/fsp/fsp0fsp.c b/storage/innobase/fsp/fsp0fsp.c index 2bae8481d20..3efe147b998 100644 --- a/storage/innobase/fsp/fsp0fsp.c +++ b/storage/innobase/fsp/fsp0fsp.c @@ -127,9 +127,8 @@ typedef byte fseg_inode_t; #define FSEG_ARR_OFFSET (FSEG_PAGE_DATA + FLST_NODE_SIZE) /*-------------------------------------*/ -#define FSEG_ID 0 /* 8 bytes of segment id: if this is - ut_dulint_zero, it means that the - header is unused */ +#define FSEG_ID 0 /* 8 bytes of segment id: if this is 0, + it means that the header is unused */ #define FSEG_NOT_FULL_N_USED 8 /* number of used segment pages in the FSEG_NOT_FULL list */ @@ -999,11 +998,11 @@ fsp_header_init( flst_init(header + FSP_SEG_INODES_FULL, mtr); flst_init(header + FSP_SEG_INODES_FREE, mtr); - mlog_write_dulint(header + FSP_SEG_ID, ut_dulint_create(0, 1), mtr); + mlog_write_ull(header + FSP_SEG_ID, 1, mtr); if (space == 0) { fsp_fill_free_list(FALSE, space, header, mtr); btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF, - 0, 0, ut_dulint_add(DICT_IBUF_ID_MIN, space), + 0, 0, DICT_IBUF_ID_MIN + space, dict_ind_redundant, mtr); } else { fsp_fill_free_list(TRUE, space, header, mtr); @@ -1841,7 +1840,7 @@ fsp_seg_inode_page_find_used( inode = fsp_seg_inode_page_get_nth_inode( page, i, zip_size, mtr); - if (!ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID))) { + if (mach_read_from_8(inode + FSEG_ID)) { /* This is used */ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) @@ -1872,7 +1871,7 @@ fsp_seg_inode_page_find_free( inode = fsp_seg_inode_page_get_nth_inode( page, i, zip_size, mtr); - if (ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID))) { + if (!mach_read_from_8(inode + FSEG_ID)) { /* This is unused */ return(i); @@ -1931,7 +1930,7 @@ fsp_alloc_seg_inode_page( inode = fsp_seg_inode_page_get_nth_inode(page, i, zip_size, mtr); - mlog_write_dulint(inode + FSEG_ID, ut_dulint_zero, mtr); + mlog_write_ull(inode + FSEG_ID, 0, mtr); } flst_add_last(space_header + FSP_SEG_INODES_FREE, @@ -1998,7 +1997,7 @@ fsp_alloc_seg_inode( page + FSEG_INODE_PAGE_NODE, mtr); } - ut_ad(ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID)) + ut_ad(!mach_read_from_8(inode + FSEG_ID) || mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE); return(inode); } @@ -2036,7 +2035,7 @@ fsp_free_seg_inode( page + FSEG_INODE_PAGE_NODE, mtr); } - mlog_write_dulint(inode + FSEG_ID, ut_dulint_zero, mtr); + mlog_write_ull(inode + FSEG_ID, 0, mtr); mlog_write_ulint(inode + FSEG_MAGIC_N, 0xfa051ce3, MLOG_4BYTES, mtr); if (ULINT_UNDEFINED @@ -2073,8 +2072,7 @@ fseg_inode_try_get( inode = fut_get_ptr(space, zip_size, inode_addr, RW_X_LATCH, mtr); - if (UNIV_UNLIKELY - (ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID)))) { + if (UNIV_UNLIKELY(!mach_read_from_8(inode + FSEG_ID))) { inode = NULL; } else { @@ -2249,7 +2247,7 @@ fseg_create_general( ulint zip_size; fsp_header_t* space_header; fseg_inode_t* inode; - dulint seg_id; + ib_id_t seg_id; buf_block_t* block = 0; /* remove warning */ fseg_header_t* header = 0; /* remove warning */ rw_lock_t* latch; @@ -2303,12 +2301,11 @@ fseg_create_general( /* Read the next segment id from space header and increment the value in space header */ - seg_id = mtr_read_dulint(space_header + FSP_SEG_ID, mtr); + seg_id = mach_read_from_8(space_header + FSP_SEG_ID); - mlog_write_dulint(space_header + FSP_SEG_ID, ut_dulint_add(seg_id, 1), - mtr); + mlog_write_ull(space_header + FSP_SEG_ID, seg_id + 1, mtr); - mlog_write_dulint(inode + FSEG_ID, seg_id, mtr); + mlog_write_ull(inode + FSEG_ID, seg_id, mtr); mlog_write_ulint(inode + FSEG_NOT_FULL_N_USED, 0, MLOG_4BYTES, mtr); flst_init(inode + FSEG_FREE, mtr); @@ -2460,7 +2457,7 @@ fseg_fill_free_list( { xdes_t* descr; ulint i; - dulint seg_id; + ib_id_t seg_id; ulint reserved; ulint used; @@ -2497,10 +2494,10 @@ fseg_fill_free_list( xdes_set_state(descr, XDES_FSEG, mtr); - seg_id = mtr_read_dulint(inode + FSEG_ID, mtr); + seg_id = mach_read_from_8(inode + FSEG_ID); ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE); - mlog_write_dulint(descr + XDES_ID, seg_id, mtr); + mlog_write_ull(descr + XDES_ID, seg_id, mtr); flst_add_last(inode + FSEG_FREE, descr + XDES_FLST_NODE, mtr); hint += FSP_EXTENT_SIZE; @@ -2524,7 +2521,7 @@ fseg_alloc_free_extent( mtr_t* mtr) /*!< in: mtr */ { xdes_t* descr; - dulint seg_id; + ib_id_t seg_id; fil_addr_t first; ut_ad(!((page_offset(inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE)); @@ -2545,10 +2542,10 @@ fseg_alloc_free_extent( return(NULL); } - seg_id = mtr_read_dulint(inode + FSEG_ID, mtr); + seg_id = mach_read_from_8(inode + FSEG_ID); xdes_set_state(descr, XDES_FSEG, mtr); - mlog_write_dulint(descr + XDES_ID, seg_id, mtr); + mlog_write_ull(descr + XDES_ID, seg_id, mtr); flst_add_last(inode + FSEG_FREE, descr + XDES_FLST_NODE, mtr); /* Try to fill the segment free list */ @@ -2583,7 +2580,7 @@ fseg_alloc_free_page_low( { fsp_header_t* space_header; ulint space_size; - dulint seg_id; + ib_id_t seg_id; ulint used; ulint reserved; xdes_t* descr; /*!< extent of the hinted page */ @@ -2599,9 +2596,9 @@ fseg_alloc_free_page_low( ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE); ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE)); - seg_id = mtr_read_dulint(seg_inode + FSEG_ID, mtr); + seg_id = mach_read_from_8(seg_inode + FSEG_ID); - ut_ad(!ut_dulint_is_zero(seg_id)); + ut_ad(seg_id); reserved = fseg_n_reserved_pages_low(seg_inode, &used, mtr); @@ -2619,8 +2616,7 @@ fseg_alloc_free_page_low( /* In the big if-else below we look for ret_page and ret_descr */ /*-------------------------------------------------------------*/ if ((xdes_get_state(descr, mtr) == XDES_FSEG) - && (0 == ut_dulint_cmp(mtr_read_dulint(descr + XDES_ID, - mtr), seg_id)) + && mach_read_from_8(descr + XDES_ID) == seg_id && (xdes_get_bit(descr, XDES_FREE_BIT, hint % FSP_EXTENT_SIZE, mtr) == TRUE)) { @@ -2642,7 +2638,7 @@ fseg_alloc_free_page_low( ut_a(ret_descr == descr); xdes_set_state(ret_descr, XDES_FSEG, mtr); - mlog_write_dulint(ret_descr + XDES_ID, seg_id, mtr); + mlog_write_ull(ret_descr + XDES_ID, seg_id, mtr); flst_add_last(seg_inode + FSEG_FREE, ret_descr + XDES_FLST_NODE, mtr); @@ -2671,8 +2667,7 @@ fseg_alloc_free_page_low( } /*-----------------------------------------------------------*/ } else if ((xdes_get_state(descr, mtr) == XDES_FSEG) - && (0 == ut_dulint_cmp(mtr_read_dulint(descr + XDES_ID, - mtr), seg_id)) + && mach_read_from_8(descr + XDES_ID) == seg_id && (!xdes_is_full(descr, mtr))) { /* 4. We can take the page from the same extent as the @@ -3243,8 +3238,8 @@ fseg_free_page_low( xdes_t* descr; ulint not_full_n_used; ulint state; - dulint descr_id; - dulint seg_id; + ib_id_t descr_id; + ib_id_t seg_id; ulint i; ut_ad(seg_inode && mtr); @@ -3303,20 +3298,18 @@ crash: /* If we get here, the page is in some extent of the segment */ - descr_id = mtr_read_dulint(descr + XDES_ID, mtr); - seg_id = mtr_read_dulint(seg_inode + FSEG_ID, mtr); + descr_id = mach_read_from_8(descr + XDES_ID); + seg_id = mach_read_from_8(seg_inode + FSEG_ID); #if 0 fprintf(stderr, "InnoDB: InnoDB is freeing space %lu page %lu,\n" - "InnoDB: which belongs to descr seg %lu %lu\n" - "InnoDB: segment %lu %lu.\n", + "InnoDB: which belongs to descr seg %llu\n" + "InnoDB: segment %llu.\n", (ulong) space, (ulong) page, - (ulong) ut_dulint_get_high(descr_id), - (ulong) ut_dulint_get_low(descr_id), - (ulong) ut_dulint_get_high(seg_id), - (ulong) ut_dulint_get_low(seg_id)); + (ullint) descr_id, + (ullint) seg_id); #endif /* 0 */ - if (0 != ut_dulint_cmp(descr_id, seg_id)) { + if (UNIV_UNLIKELY(descr_id != seg_id)) { fputs("InnoDB: Dump of the tablespace extent descriptor: ", stderr); ut_print_buf(stderr, descr, 40); @@ -3328,13 +3321,11 @@ crash: "InnoDB: Serious error: InnoDB is trying to" " free space %lu page %lu,\n" "InnoDB: which does not belong to" - " segment %lu %lu but belongs\n" - "InnoDB: to segment %lu %lu.\n", + " segment %llu but belongs\n" + "InnoDB: to segment %llu.\n", (ulong) space, (ulong) page, - (ulong) ut_dulint_get_high(descr_id), - (ulong) ut_dulint_get_low(descr_id), - (ulong) ut_dulint_get_high(seg_id), - (ulong) ut_dulint_get_low(seg_id)); + (ullint) descr_id, + (ullint) seg_id); goto crash; } @@ -3423,8 +3414,7 @@ fseg_free_extent( descr = xdes_get_descriptor(space, zip_size, page, mtr); ut_a(xdes_get_state(descr, mtr) == XDES_FSEG); - ut_a(0 == ut_dulint_cmp(mtr_read_dulint(descr + XDES_ID, mtr), - mtr_read_dulint(seg_inode + FSEG_ID, mtr))); + ut_a(!memcmp(descr + XDES_ID, seg_inode + FSEG_ID, 8)); ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE); @@ -3684,7 +3674,7 @@ fseg_validate_low( mtr_t* mtr2) /*!< in: mtr */ { ulint space; - dulint seg_id; + ib_id_t seg_id; mtr_t mtr; xdes_t* descr; fil_addr_t node_addr; @@ -3696,7 +3686,7 @@ fseg_validate_low( space = page_get_space_id(page_align(inode)); - seg_id = mtr_read_dulint(inode + FSEG_ID, mtr2); + seg_id = mach_read_from_8(inode + FSEG_ID); n_used = mtr_read_ulint(inode + FSEG_NOT_FULL_N_USED, MLOG_4BYTES, mtr2); flst_validate(inode + FSEG_FREE, mtr2); @@ -3719,8 +3709,7 @@ fseg_validate_low( ut_a(xdes_get_n_used(descr, &mtr) == 0); ut_a(xdes_get_state(descr, &mtr) == XDES_FSEG); - ut_a(!ut_dulint_cmp(mtr_read_dulint(descr + XDES_ID, &mtr), - seg_id)); + ut_a(mach_read_from_8(descr + XDES_ID) == seg_id); node_addr = flst_get_next_addr(descr + XDES_FLST_NODE, &mtr); mtr_commit(&mtr); @@ -3744,8 +3733,7 @@ fseg_validate_low( ut_a(xdes_get_n_used(descr, &mtr) > 0); ut_a(xdes_get_n_used(descr, &mtr) < FSP_EXTENT_SIZE); ut_a(xdes_get_state(descr, &mtr) == XDES_FSEG); - ut_a(!ut_dulint_cmp(mtr_read_dulint(descr + XDES_ID, &mtr), - seg_id)); + ut_a(mach_read_from_8(descr + XDES_ID) == seg_id); n_used2 += xdes_get_n_used(descr, &mtr); @@ -3770,8 +3758,7 @@ fseg_validate_low( ut_a(xdes_get_n_used(descr, &mtr) == FSP_EXTENT_SIZE); ut_a(xdes_get_state(descr, &mtr) == XDES_FSEG); - ut_a(!ut_dulint_cmp(mtr_read_dulint(descr + XDES_ID, &mtr), - seg_id)); + ut_a(mach_read_from_8(descr + XDES_ID) == seg_id); node_addr = flst_get_next_addr(descr + XDES_FLST_NODE, &mtr); mtr_commit(&mtr); @@ -3822,8 +3809,6 @@ fseg_print_low( mtr_t* mtr) /*!< in: mtr */ { ulint space; - ulint seg_id_low; - ulint seg_id_high; ulint n_used; ulint n_frag; ulint n_free; @@ -3832,7 +3817,7 @@ fseg_print_low( ulint reserved; ulint used; ulint page_no; - dulint d_var; + ib_id_t seg_id; ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX)); space = page_get_space_id(page_align(inode)); @@ -3840,10 +3825,7 @@ fseg_print_low( reserved = fseg_n_reserved_pages_low(inode, &used, mtr); - d_var = mtr_read_dulint(inode + FSEG_ID, mtr); - - seg_id_low = ut_dulint_get_low(d_var); - seg_id_high = ut_dulint_get_high(d_var); + seg_id = mach_read_from_8(inode + FSEG_ID); n_used = mtr_read_ulint(inode + FSEG_NOT_FULL_N_USED, MLOG_4BYTES, mtr); @@ -3853,11 +3835,11 @@ fseg_print_low( n_full = flst_get_len(inode + FSEG_FULL, mtr); fprintf(stderr, - "SEGMENT id %lu %lu space %lu; page %lu;" + "SEGMENT id %llu space %lu; page %lu;" " res %lu used %lu; full ext %lu\n" "fragm pages %lu; free extents %lu;" " not full extents %lu: pages %lu\n", - (ulong) seg_id_high, (ulong) seg_id_low, + (ullint) seg_id, (ulong) space, (ulong) page_no, (ulong) reserved, (ulong) used, (ulong) n_full, (ulong) n_frag, (ulong) n_free, (ulong) n_not_full, @@ -4059,8 +4041,7 @@ fsp_validate( seg_inode = fsp_seg_inode_page_get_nth_inode( seg_inode_page, n, zip_size, &mtr); - ut_a(!ut_dulint_is_zero( - mach_read_from_8(seg_inode + FSEG_ID))); + ut_a(mach_read_from_8(seg_inode + FSEG_ID) != 0); fseg_validate_low(seg_inode, &mtr); descr_count += flst_get_len(seg_inode + FSEG_FREE, @@ -4105,8 +4086,7 @@ fsp_validate( seg_inode = fsp_seg_inode_page_get_nth_inode( seg_inode_page, n, zip_size, &mtr); - if (!ut_dulint_is_zero( - mach_read_from_8(seg_inode + FSEG_ID))) { + if (mach_read_from_8(seg_inode + FSEG_ID)) { fseg_validate_low(seg_inode, &mtr); descr_count += flst_get_len( @@ -4168,11 +4148,9 @@ fsp_print( ulint n_free; ulint n_free_frag; ulint n_full_frag; - ulint seg_id_low; - ulint seg_id_high; + ib_id_t seg_id; ulint n; ulint n_segs = 0; - dulint d_var; mtr_t mtr; mtr_t mtr2; @@ -4202,21 +4180,18 @@ fsp_print( n_free_frag = flst_get_len(header + FSP_FREE_FRAG, &mtr); n_full_frag = flst_get_len(header + FSP_FULL_FRAG, &mtr); - d_var = mtr_read_dulint(header + FSP_SEG_ID, &mtr); - - seg_id_low = ut_dulint_get_low(d_var); - seg_id_high = ut_dulint_get_high(d_var); + seg_id = mach_read_from_8(header + FSP_SEG_ID); fprintf(stderr, "FILE SPACE INFO: id %lu\n" "size %lu, free limit %lu, free extents %lu\n" "not full frag extents %lu: used pages %lu," " full frag extents %lu\n" - "first seg id not used %lu %lu\n", + "first seg id not used %llu\n", (ulong) space, (ulong) size, (ulong) free_limit, (ulong) n_free, (ulong) n_free_frag, (ulong) frag_n_used, (ulong) n_full_frag, - (ulong) seg_id_high, (ulong) seg_id_low); + (ullint) seg_id); mtr_commit(&mtr); @@ -4246,8 +4221,7 @@ fsp_print( seg_inode = fsp_seg_inode_page_get_nth_inode( seg_inode_page, n, zip_size, &mtr); - ut_a(!ut_dulint_is_zero( - mach_read_from_8(seg_inode + FSEG_ID))); + ut_a(mach_read_from_8(seg_inode + FSEG_ID) != 0); fseg_print_low(seg_inode, &mtr); n_segs++; @@ -4284,8 +4258,7 @@ fsp_print( seg_inode = fsp_seg_inode_page_get_nth_inode( seg_inode_page, n, zip_size, &mtr); - if (!ut_dulint_is_zero( - mach_read_from_8(seg_inode + FSEG_ID))) { + if (mach_read_from_8(seg_inode + FSEG_ID)) { fseg_print_low(seg_inode, &mtr); n_segs++; diff --git a/storage/innobase/ha/ha0ha.c b/storage/innobase/ha/ha0ha.c index 9d9d341ad39..f9e798012f8 100644 --- a/storage/innobase/ha/ha0ha.c +++ b/storage/innobase/ha/ha0ha.c @@ -31,9 +31,7 @@ Created 8/22/1994 Heikki Tuuri #ifdef UNIV_DEBUG # include "buf0buf.h" #endif /* UNIV_DEBUG */ -#ifdef UNIV_SYNC_DEBUG -# include "btr0sea.h" -#endif /* UNIV_SYNC_DEBUG */ +#include "btr0sea.h" #include "page0page.h" /*************************************************************//** @@ -127,7 +125,8 @@ ha_clear( /*************************************************************//** Inserts an entry into a hash table. If an entry with the same fold number is found, its node is updated to point to the new data, and no new node -is inserted. +is inserted. If btr_search_enabled is set to FALSE, we will only allow +updating existing nodes, but no new node is allowed to be added. @return TRUE if succeed, FALSE if no more memory could be allocated */ UNIV_INTERN ibool @@ -174,6 +173,7 @@ ha_insert_for_fold_func( prev_block->n_pointers--; block->n_pointers++; } + ut_ad(!btr_search_fully_disabled); # endif /* !UNIV_HOTBACKUP */ prev_node->block = block; @@ -186,6 +186,13 @@ ha_insert_for_fold_func( prev_node = prev_node->next; } + /* We are in the process of disabling hash index, do not add + new chain node */ + if (!btr_search_enabled) { + ut_ad(!btr_search_fully_disabled); + return(TRUE); + } + /* We have to allocate a new chain node */ node = mem_heap_alloc(hash_get_heap(table, fold), sizeof(ha_node_t)); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 716b7bbbd56..ab9df9a0272 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -571,7 +571,7 @@ innodb_show_status( THD* thd, /*!< in: the MySQL query thread of the caller */ stat_print_fn *stat_print); static -bool innobase_show_status(handlerton *hton, THD* thd, +bool innobase_show_status(handlerton *hton, THD* thd, stat_print_fn* stat_print, enum ha_stat_type stat_type); @@ -1032,6 +1032,8 @@ innobase_get_cset_width( if (cs) { *mbminlen = cs->mbminlen; *mbmaxlen = cs->mbmaxlen; + ut_ad(*mbminlen < DATA_MBMAX); + ut_ad(*mbmaxlen < DATA_MBMAX); } else { THD* thd = current_thd; @@ -1254,7 +1256,7 @@ innobase_mysql_tmpfile(void) my_close(). */ #ifdef _WIN32 - /* Note that on Windows, the integer returned by mysql_tmpfile + /* Note that on Windows, the integer returned by mysql_tmpfile has no relation to C runtime file descriptor. Here, we need to call my_get_osfhandle to get the HANDLE and then convert it to C runtime filedescriptor. */ @@ -2444,6 +2446,7 @@ innobase_change_buffering_inited_ok: /* Get the current high water mark format. */ innobase_file_format_max = (char*) trx_sys_file_format_max_get(); + btr_search_fully_disabled = (!btr_search_enabled); DBUG_RETURN(FALSE); error: DBUG_RETURN(TRUE); @@ -2956,9 +2959,9 @@ innobase_close_connection( global_system_variables.log_warnings) { sql_print_warning( "MySQL is closing a connection that has an active " - "InnoDB transaction. %lu row modifications will " + "InnoDB transaction. %llu row modifications will " "roll back.", - (ulong) trx->undo_no.low); + (ullint) trx->undo_no); } innobase_rollback_trx(trx); @@ -4427,15 +4430,14 @@ ha_innobase::store_key_val_for_row( memcpy(buff, src_start, true_len); buff += true_len; - /* Pad the unused space with spaces. Note that no - padding is ever needed for UCS-2 because in MySQL, - all UCS2 characters are 2 bytes, as MySQL does not - support surrogate pairs, which are needed to represent - characters in the range U+10000 to U+10FFFF. */ + /* Pad the unused space with spaces. */ if (true_len < key_len) { - ulint pad_len = key_len - true_len; - memset(buff, ' ', pad_len); + ulint pad_len = key_len - true_len; + ut_a(!(pad_len % cs->mbminlen)); + + cs->cset->fill(cs, buff, pad_len, + 0x20 /* space */); buff += pad_len; } } @@ -4544,6 +4546,7 @@ build_template( /* Note that in InnoDB, i is the column number. MySQL calls columns 'fields'. */ for (i = 0; i < n_fields; i++) { + const dict_col_t* col = &index->table->cols[i]; templ = prebuilt->mysql_template + n_requested_fields; field = table->field[i]; @@ -4592,7 +4595,7 @@ include_field: if (index == clust_index) { templ->rec_field_no = dict_col_get_clust_pos( - &index->table->cols[i], index); + col, index); } else { templ->rec_field_no = dict_index_get_nth_col_pos( index, i); @@ -4621,7 +4624,7 @@ include_field: mysql_prefix_len = templ->mysql_col_offset + templ->mysql_col_len; } - templ->type = index->table->cols[i].mtype; + templ->type = col->mtype; templ->mysql_type = (ulint)field->type(); if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) { @@ -4629,12 +4632,10 @@ include_field: (((Field_varstring*)field)->length_bytes); } - templ->charset = dtype_get_charset_coll( - index->table->cols[i].prtype); - templ->mbminlen = index->table->cols[i].mbminlen; - templ->mbmaxlen = index->table->cols[i].mbmaxlen; - templ->is_unsigned = index->table->cols[i].prtype - & DATA_UNSIGNED; + templ->charset = dtype_get_charset_coll(col->prtype); + templ->mbminlen = dict_col_get_mbminlen(col); + templ->mbmaxlen = dict_col_get_mbmaxlen(col); + templ->is_unsigned = col->prtype & DATA_UNSIGNED; if (templ->type == DATA_BLOB) { prebuilt->templ_contains_blob = TRUE; } @@ -5562,6 +5563,9 @@ ha_innobase::index_read( prebuilt->index_usable = FALSE; DBUG_RETURN(HA_ERR_CRASHED); } + if (UNIV_UNLIKELY(!prebuilt->index_usable)) { + DBUG_RETURN(HA_ERR_TABLE_DEF_CHANGED); + } /* Note that if the index for which the search template is built is not necessarily prebuilt->index, but can also be the clustered index */ @@ -6655,6 +6659,7 @@ ha_innobase::create( const ulint file_format = srv_file_format; const char* stmt; size_t stmt_len; + enum row_type row_type; DBUG_ENTER("ha_innobase::create"); @@ -6775,94 +6780,94 @@ ha_innobase::create( } } - if (create_info->used_fields & HA_CREATE_USED_ROW_FORMAT) { - if (flags) { - /* KEY_BLOCK_SIZE was specified. */ - if (form->s->row_type != ROW_TYPE_COMPRESSED) { - /* ROW_FORMAT other than COMPRESSED - ignores KEY_BLOCK_SIZE. It does not - make sense to reject conflicting - KEY_BLOCK_SIZE and ROW_FORMAT, because - such combinations can be obtained - with ALTER TABLE anyway. */ - push_warning_printf( - thd, - MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: ignoring KEY_BLOCK_SIZE=%lu" - " unless ROW_FORMAT=COMPRESSED.", - create_info->key_block_size); - flags = 0; - } - } else { - /* No KEY_BLOCK_SIZE */ - if (form->s->row_type == ROW_TYPE_COMPRESSED) { - /* ROW_FORMAT=COMPRESSED without - KEY_BLOCK_SIZE implies half the - maximum KEY_BLOCK_SIZE. */ - flags = (DICT_TF_ZSSIZE_MAX - 1) - << DICT_TF_ZSSIZE_SHIFT - | DICT_TF_COMPACT - | DICT_TF_FORMAT_ZIP - << DICT_TF_FORMAT_SHIFT; + row_type = form->s->row_type; + + if (flags) { + /* KEY_BLOCK_SIZE was specified. */ + if (!(create_info->used_fields & HA_CREATE_USED_ROW_FORMAT)) { + /* ROW_FORMAT was not specified; + default to ROW_FORMAT=COMPRESSED */ + row_type = ROW_TYPE_COMPRESSED; + } else if (row_type != ROW_TYPE_COMPRESSED) { + /* ROW_FORMAT other than COMPRESSED + ignores KEY_BLOCK_SIZE. It does not + make sense to reject conflicting + KEY_BLOCK_SIZE and ROW_FORMAT, because + such combinations can be obtained + with ALTER TABLE anyway. */ + push_warning_printf( + thd, + MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: ignoring KEY_BLOCK_SIZE=%lu" + " unless ROW_FORMAT=COMPRESSED.", + create_info->key_block_size); + flags = 0; + } + } else { + /* No KEY_BLOCK_SIZE */ + if (row_type == ROW_TYPE_COMPRESSED) { + /* ROW_FORMAT=COMPRESSED without + KEY_BLOCK_SIZE implies half the + maximum KEY_BLOCK_SIZE. */ + flags = (DICT_TF_ZSSIZE_MAX - 1) + << DICT_TF_ZSSIZE_SHIFT + | DICT_TF_COMPACT + | DICT_TF_FORMAT_ZIP + << DICT_TF_FORMAT_SHIFT; #if DICT_TF_ZSSIZE_MAX < 1 # error "DICT_TF_ZSSIZE_MAX < 1" #endif - } } + } - switch (form->s->row_type) { - const char* row_format_name; - case ROW_TYPE_REDUNDANT: - break; - case ROW_TYPE_COMPRESSED: - case ROW_TYPE_DYNAMIC: - row_format_name - = form->s->row_type == ROW_TYPE_COMPRESSED - ? "COMPRESSED" - : "DYNAMIC"; - - if (!srv_file_per_table) { - push_warning_printf( - thd, - MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: ROW_FORMAT=%s" - " requires innodb_file_per_table.", - row_format_name); - } else if (file_format < DICT_TF_FORMAT_ZIP) { - push_warning_printf( - thd, - MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: ROW_FORMAT=%s" - " requires innodb_file_format >" - " Antelope.", - row_format_name); - } else { - flags |= DICT_TF_COMPACT - | (DICT_TF_FORMAT_ZIP - << DICT_TF_FORMAT_SHIFT); - break; - } + switch (row_type) { + const char* row_format_name; + case ROW_TYPE_REDUNDANT: + break; + case ROW_TYPE_COMPRESSED: + case ROW_TYPE_DYNAMIC: + row_format_name + = row_type == ROW_TYPE_COMPRESSED + ? "COMPRESSED" + : "DYNAMIC"; - /* fall through */ - case ROW_TYPE_NOT_USED: - case ROW_TYPE_FIXED: - default: - push_warning(thd, - MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: assuming ROW_FORMAT=COMPACT."); - case ROW_TYPE_DEFAULT: - case ROW_TYPE_COMPACT: - flags = DICT_TF_COMPACT; + if (!srv_file_per_table) { + push_warning_printf( + thd, + MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: ROW_FORMAT=%s" + " requires innodb_file_per_table.", + row_format_name); + } else if (file_format < DICT_TF_FORMAT_ZIP) { + push_warning_printf( + thd, + MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: ROW_FORMAT=%s" + " requires innodb_file_format >" + " Antelope.", + row_format_name); + } else { + flags |= DICT_TF_COMPACT + | (DICT_TF_FORMAT_ZIP + << DICT_TF_FORMAT_SHIFT); break; } - } else if (!flags) { - /* No KEY_BLOCK_SIZE or ROW_FORMAT specified: - use ROW_FORMAT=COMPACT by default. */ + + /* fall through */ + case ROW_TYPE_NOT_USED: + case ROW_TYPE_FIXED: + default: + push_warning(thd, + MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: assuming ROW_FORMAT=COMPACT."); + case ROW_TYPE_DEFAULT: + case ROW_TYPE_COMPACT: flags = DICT_TF_COMPACT; + break; } /* Look for a primary key */ @@ -7419,6 +7424,10 @@ ha_innobase::records_in_range( n_rows = HA_POS_ERROR; goto func_exit; } + if (UNIV_UNLIKELY(!row_merge_is_index_usable(prebuilt->trx, index))) { + n_rows = HA_ERR_TABLE_DEF_CHANGED; + goto func_exit; + } heap = mem_heap_create(2 * (key->key_parts * sizeof(dfield_t) + sizeof(dtuple_t))); @@ -10826,7 +10835,7 @@ by the server. Can be set during server startup at command line or configure file, and a read only variable after server startup */ static MYSQL_SYSVAR_BOOL(file_format_check, innobase_file_format_check, - PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY, + PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, "Whether to perform system file format check.", NULL, NULL, TRUE); diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index ec17882590c..3744d16570c 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -99,8 +99,10 @@ innobase_col_to_mysql( #ifdef UNIV_DEBUG case DATA_MYSQL: ut_ad(flen >= len); - ut_ad(col->mbmaxlen >= col->mbminlen); - ut_ad(col->mbmaxlen > col->mbminlen || flen == len); + ut_ad(DATA_MBMAXLEN(col->mbminmaxlen) + >= DATA_MBMINLEN(col->mbminmaxlen)); + ut_ad(DATA_MBMAXLEN(col->mbminmaxlen) + > DATA_MBMINLEN(col->mbminmaxlen) || flen == len); memcpy(dest, data, len); break; diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 2c15a3b87db..0733a558080 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -401,133 +401,7 @@ static ST_FIELD_INFO innodb_trx_fields_info[] = STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, #define IDX_TRX_ADAPTIVE_HASH_LATCHED 20 - {STRUCT_FLD(field_name, "trx_apative_hash_latched"), - STRUCT_FLD(field_length, 1), - STRUCT_FLD(field_type, MYSQL_TYPE_LONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define IDX_TRX_ADAPTIVE_HASH_TIMEOUT 21 - {STRUCT_FLD(field_name, "trx_adaptive_hash_timeout"), - STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define IDX_TRX_OPERATION_STATE 8 - {STRUCT_FLD(field_name, "trx_operation_state"), - STRUCT_FLD(field_length, TRX_I_S_TRX_OP_STATE_MAX_LEN), - STRUCT_FLD(field_type, MYSQL_TYPE_STRING), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define IDX_TRX_TABLES_IN_USE 9 - {STRUCT_FLD(field_name, "trx_tables_in_use"), - STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define IDX_TRX_TABLES_LOCKED 10 - {STRUCT_FLD(field_name, "trx_tables_locked"), - STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define IDX_TRX_LOCK_STRUCTS 11 - {STRUCT_FLD(field_name, "trx_lock_structs"), - STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define IDX_TRX_LOCK_MEMORY_BYTES 12 - {STRUCT_FLD(field_name, "trx_lock_memory_bytes"), - STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define IDX_TRX_ROWS_LOCKED 13 - {STRUCT_FLD(field_name, "trx_rows_locked"), - STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define IDX_TRX_ROWS_MODIFIED 14 - {STRUCT_FLD(field_name, "trx_rows_modified"), - STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define IDX_TRX_CONNCURRENCY_TICKETS 15 - {STRUCT_FLD(field_name, "trx_concurrency_tickets"), - STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define IDX_TRX_ISOLATION_LEVEL 16 - {STRUCT_FLD(field_name, "trx_isolation_level"), - STRUCT_FLD(field_length, TRX_I_S_TRX_ISOLATION_LEVEL_MAX_LEN), - STRUCT_FLD(field_type, MYSQL_TYPE_STRING), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define IDX_TRX_UNIQUE_CHECKS 17 - {STRUCT_FLD(field_name, "trx_unique_checks"), - STRUCT_FLD(field_length, 1), - STRUCT_FLD(field_type, MYSQL_TYPE_LONG), - STRUCT_FLD(value, 1), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define IDX_TRX_FOREIGN_KEY_CHECKS 18 - {STRUCT_FLD(field_name, "trx_foreign_key_checks"), - STRUCT_FLD(field_length, 1), - STRUCT_FLD(field_type, MYSQL_TYPE_LONG), - STRUCT_FLD(value, 1), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define IDX_TRX_LAST_FOREIGN_KEY_ERROR 19 - {STRUCT_FLD(field_name, "trx_last_foreign_key_error"), - STRUCT_FLD(field_length, TRX_I_S_TRX_FK_ERROR_MAX_LEN), - STRUCT_FLD(field_type, MYSQL_TYPE_STRING), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define IDX_TRX_ADAPTIVE_HASH_LATCHED 20 - {STRUCT_FLD(field_name, "trx_apative_hash_latched"), + {STRUCT_FLD(field_name, "trx_adaptive_hash_latched"), STRUCT_FLD(field_length, 1), STRUCT_FLD(field_type, MYSQL_TYPE_LONG), STRUCT_FLD(value, 0), @@ -674,7 +548,7 @@ fill_innodb_trx_from_cache( OK(field_store_string(fields[IDX_TRX_LAST_FOREIGN_KEY_ERROR], row->trx_foreign_key_error)); - /* trx_apative_hash_latched */ + /* trx_adaptive_hash_latched */ OK(fields[IDX_TRX_ADAPTIVE_HASH_LATCHED]->store( row->trx_has_search_latch)); @@ -1973,16 +1847,13 @@ i_s_dict_fill_sys_tables( dict_table_t* table, /*!< in: table */ TABLE* table_to_fill) /*!< in/out: fill this table */ { - longlong table_id; Field** fields; DBUG_ENTER("i_s_dict_fill_sys_tables"); fields = table_to_fill->field; - table_id = ut_conv_dulint_to_longlong(table->id); - - OK(fields[SYS_TABLE_ID]->store(table_id, TRUE)); + OK(fields[SYS_TABLE_ID]->store(longlong(table->id), TRUE)); OK(field_store_string(fields[SYS_TABLE_NAME], table->name)); @@ -2238,16 +2109,13 @@ i_s_dict_fill_sys_tablestats( dict_table_t* table, /*!< in: table */ TABLE* table_to_fill) /*!< in/out: fill this table */ { - longlong table_id; Field** fields; DBUG_ENTER("i_s_dict_fill_sys_tablestats"); fields = table_to_fill->field; - table_id = ut_conv_dulint_to_longlong(table->id); - - OK(fields[SYS_TABLESTATS_ID]->store(table_id, TRUE)); + OK(fields[SYS_TABLESTATS_ID]->store(longlong(table->id), TRUE)); OK(field_store_string(fields[SYS_TABLESTATS_NAME], table->name)); @@ -2495,27 +2363,22 @@ int i_s_dict_fill_sys_indexes( /*======================*/ THD* thd, /*!< in: thread */ - dulint tableid, /*!< in: table id */ + table_id_t table_id, /*!< in: table id */ dict_index_t* index, /*!< in: populated dict_index_t struct with index info */ TABLE* table_to_fill) /*!< in/out: fill this table */ { - longlong table_id; - longlong index_id; Field** fields; DBUG_ENTER("i_s_dict_fill_sys_indexes"); fields = table_to_fill->field; - table_id = ut_conv_dulint_to_longlong(tableid); - index_id = ut_conv_dulint_to_longlong(index->id); - - OK(fields[SYS_INDEX_ID]->store(index_id, TRUE)); + OK(fields[SYS_INDEX_ID]->store(longlong(index->id), TRUE)); OK(field_store_string(fields[SYS_INDEX_NAME], index->name)); - OK(fields[SYS_INDEX_TABLE_ID]->store(table_id, TRUE)); + OK(fields[SYS_INDEX_TABLE_ID]->store(longlong(table_id), TRUE)); OK(fields[SYS_INDEX_TYPE]->store(index->type)); @@ -2564,7 +2427,7 @@ i_s_sys_indexes_fill_table( /* Process each record in the table */ while (rec) { const char* err_msg;; - dulint table_id; + table_id_t table_id; dict_index_t index_rec; /* Populate a dict_index_t structure with information from @@ -2737,22 +2600,19 @@ int i_s_dict_fill_sys_columns( /*======================*/ THD* thd, /*!< in: thread */ - dulint tableid, /*!< in: table ID */ + table_id_t table_id, /*!< in: table ID */ const char* col_name, /*!< in: column name */ dict_col_t* column, /*!< in: dict_col_t struct holding more column information */ TABLE* table_to_fill) /*!< in/out: fill this table */ { - longlong table_id; Field** fields; DBUG_ENTER("i_s_dict_fill_sys_columns"); fields = table_to_fill->field; - table_id = ut_conv_dulint_to_longlong(tableid); - - OK(fields[SYS_COLUMN_TABLE_ID]->store(table_id, TRUE)); + OK(fields[SYS_COLUMN_TABLE_ID]->store(longlong(table_id), TRUE)); OK(field_store_string(fields[SYS_COLUMN_NAME], col_name)); @@ -2803,7 +2663,7 @@ i_s_sys_columns_fill_table( while (rec) { const char* err_msg; dict_col_t column_rec; - dulint table_id; + table_id_t table_id; /* populate a dict_col_t structure with information from a SYS_COLUMNS row */ @@ -2948,21 +2808,18 @@ int i_s_dict_fill_sys_fields( /*=====================*/ THD* thd, /*!< in: thread */ - dulint indexid, /*!< in: index id for the field */ + index_id_t index_id, /*!< in: index id for the field */ dict_field_t* field, /*!< in: table */ ulint pos, /*!< in: Field position */ TABLE* table_to_fill) /*!< in/out: fill this table */ { - longlong index_id; Field** fields; DBUG_ENTER("i_s_dict_fill_sys_fields"); fields = table_to_fill->field; - index_id = ut_conv_dulint_to_longlong(indexid); - - OK(fields[SYS_FIELD_INDEX_ID]->store(index_id, TRUE)); + OK(fields[SYS_FIELD_INDEX_ID]->store(longlong(index_id), TRUE)); OK(field_store_string(fields[SYS_FIELD_NAME], field->name)); @@ -2988,7 +2845,7 @@ i_s_sys_fields_fill_table( btr_pcur_t pcur; const rec_t* rec; mem_heap_t* heap; - dulint last_id; + index_id_t last_id; mtr_t mtr; DBUG_ENTER("i_s_sys_fields_fill_table"); @@ -3005,14 +2862,14 @@ i_s_sys_fields_fill_table( /* will save last index id so that we know whether we move to the next index. This is used to calculate prefix length */ - last_id = ut_dulint_create(0, 0); + last_id = 0; rec = dict_startscan_system(&pcur, &mtr, SYS_FIELDS); while (rec) { ulint pos; const char* err_msg; - dulint index_id; + index_id_t index_id; dict_field_t field_rec; /* Populate a dict_field_t structure with information from diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c index 0397af88ff4..dc8e61e5070 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.c +++ b/storage/innobase/ibuf/ibuf0ibuf.c @@ -565,7 +565,7 @@ ibuf_init_at_db_start(void) dict_mem_table_add_col(table, heap, "DUMMY_COLUMN", DATA_BINARY, 0, 0); - table->id = ut_dulint_add(DICT_IBUF_ID_MIN, IBUF_SPACE_ID); + table->id = DICT_IBUF_ID_MIN + IBUF_SPACE_ID; dict_table_add_to_cache(table, heap); mem_heap_free(heap); @@ -576,7 +576,7 @@ ibuf_init_at_db_start(void) dict_mem_index_add_field(index, "DUMMY_COLUMN", 0); - index->id = ut_dulint_add(DICT_IBUF_ID_MIN, IBUF_SPACE_ID); + index->id = DICT_IBUF_ID_MIN + IBUF_SPACE_ID; error = dict_index_add_to_cache(table, index, FSP_IBUF_TREE_ROOT_PAGE_NO, FALSE); diff --git a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h index cc08cc620c5..3912f315f2a 100644 --- a/storage/innobase/include/btr0btr.h +++ b/storage/innobase/include/btr0btr.h @@ -130,7 +130,7 @@ btr_page_get( Gets the index id field of a page. @return index id */ UNIV_INLINE -dulint +index_id_t btr_page_get_index_id( /*==================*/ const page_t* page); /*!< in: index page */ @@ -226,7 +226,7 @@ btr_create( ulint space, /*!< in: space where created */ ulint zip_size,/*!< in: compressed page size in bytes or 0 for uncompressed pages */ - dulint index_id,/*!< in: index id */ + index_id_t index_id,/*!< in: index id */ dict_index_t* index, /*!< in: index */ mtr_t* mtr); /*!< in: mini-transaction handle */ /************************************************************//** diff --git a/storage/innobase/include/btr0btr.ic b/storage/innobase/include/btr0btr.ic index 97944cc2e26..6c580a0bd6e 100644 --- a/storage/innobase/include/btr0btr.ic +++ b/storage/innobase/include/btr0btr.ic @@ -86,7 +86,7 @@ btr_page_set_index_id( page_t* page, /*!< in: page to be created */ page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed part will be updated, or NULL */ - dulint id, /*!< in: index id */ + index_id_t id, /*!< in: index id */ mtr_t* mtr) /*!< in: mtr */ { if (UNIV_LIKELY_NULL(page_zip)) { @@ -95,8 +95,7 @@ btr_page_set_index_id( page + (PAGE_HEADER + PAGE_INDEX_ID), 8, mtr); } else { - mlog_write_dulint(page + (PAGE_HEADER + PAGE_INDEX_ID), - id, mtr); + mlog_write_ull(page + (PAGE_HEADER + PAGE_INDEX_ID), id, mtr); } } #endif /* !UNIV_HOTBACKUP */ @@ -105,7 +104,7 @@ btr_page_set_index_id( Gets the index id field of a page. @return index id */ UNIV_INLINE -dulint +index_id_t btr_page_get_index_id( /*==================*/ const page_t* page) /*!< in: index page */ diff --git a/storage/innobase/include/btr0cur.h b/storage/innobase/include/btr0cur.h index 136d2d068a1..757477838ee 100644 --- a/storage/innobase/include/btr0cur.h +++ b/storage/innobase/include/btr0cur.h @@ -558,7 +558,7 @@ btr_copy_externally_stored_field_prefix( ulint local_len);/*!< in: length of data, in bytes */ /*******************************************************************//** Copies an externally stored field of a record to mem heap. -@return the field copied to heap */ +@return the field copied to heap, or NULL if the field is incomplete */ UNIV_INTERN byte* btr_rec_copy_externally_stored_field( diff --git a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h index f98ba386f9c..20a2be7f877 100644 --- a/storage/innobase/include/btr0sea.h +++ b/storage/innobase/include/btr0sea.h @@ -190,7 +190,13 @@ btr_search_validate(void); /** Flag: has the search system been enabled? Protected by btr_search_latch and btr_search_enabled_mutex. */ -extern char btr_search_enabled; +extern char btr_search_enabled; + +/** Flag: whether the search system has completed its disabling process, +It is set to TRUE right after buf_pool_drop_hash_index() in +btr_search_disable(), indicating hash index entries are cleaned up. +Protected by btr_search_latch and btr_search_enabled_mutex. */ +extern ibool btr_search_fully_disabled; /** The search info struct in an index */ struct btr_search_struct{ diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index 5326ca9c14f..f33ef65ddf2 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -869,7 +869,8 @@ buf_page_set_accessed( __attribute__((nonnull)); /*********************************************************************//** Gets the buf_block_t handle of a buffered file block if an uncompressed -page frame exists, or NULL. +page frame exists, or NULL. Note: even though bpage is not declared a +const we don't update its value. It is safe to make this pure. @return control block, or NULL */ UNIV_INLINE buf_block_t* diff --git a/storage/innobase/include/data0data.h b/storage/innobase/include/data0data.h index f9fce3f3657..11e4027777a 100644 --- a/storage/innobase/include/data0data.h +++ b/storage/innobase/include/data0data.h @@ -309,7 +309,7 @@ dtuple_fold( ulint n_fields,/*!< in: number of complete fields to fold */ ulint n_bytes,/*!< in: number of bytes to fold in an incomplete last field */ - dulint tree_id)/*!< in: index tree id */ + index_id_t tree_id)/*!< in: index tree id */ __attribute__((pure)); /*******************************************************************//** Sets types of fields binary in a tuple. */ diff --git a/storage/innobase/include/data0data.ic b/storage/innobase/include/data0data.ic index da79aa33702..2e3adf4b707 100644 --- a/storage/innobase/include/data0data.ic +++ b/storage/innobase/include/data0data.ic @@ -518,7 +518,7 @@ dtuple_fold( ulint n_fields,/*!< in: number of complete fields to fold */ ulint n_bytes,/*!< in: number of bytes to fold in an incomplete last field */ - dulint tree_id)/*!< in: index tree id */ + index_id_t tree_id)/*!< in: index tree id */ { const dfield_t* field; ulint i; @@ -530,7 +530,7 @@ dtuple_fold( ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N); ut_ad(dtuple_check_typed(tuple)); - fold = ut_fold_dulint(tree_id); + fold = ut_fold_ull(tree_id); for (i = 0; i < n_fields; i++) { field = dtuple_get_nth_field(tuple, i); diff --git a/storage/innobase/include/data0type.h b/storage/innobase/include/data0type.h index a73bed3a9f5..850cf2e2975 100644 --- a/storage/innobase/include/data0type.h +++ b/storage/innobase/include/data0type.h @@ -128,7 +128,7 @@ columns, and for them the precise type is usually not used at all. /* Precise data types for system columns and the length of those columns; NOTE: the values must run from 0 up in the order given! All codes must be less than 256 */ -#define DATA_ROW_ID 0 /* row id: a dulint */ +#define DATA_ROW_ID 0 /* row id: a 48-bit integer */ #define DATA_ROW_ID_LEN 6 /* stored length for row id */ #define DATA_TRX_ID 1 /* transaction id: 6 bytes */ @@ -168,6 +168,17 @@ SQL null*/ store the charset-collation number; one byte is left unused, though */ #define DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE 6 +/* Maximum multi-byte character length in bytes, plus 1 */ +#define DATA_MBMAX 5 + +/* Pack mbminlen, mbmaxlen to mbminmaxlen. */ +#define DATA_MBMINMAXLEN(mbminlen, mbmaxlen) \ + ((mbmaxlen) * DATA_MBMAX + (mbminlen)) +/* Get mbminlen from mbminmaxlen. */ +#define DATA_MBMINLEN(mbminmaxlen) UNIV_EXPECT(((mbminmaxlen) % DATA_MBMAX), 1) +/* Get mbmaxlen from mbminmaxlen. */ +#define DATA_MBMAXLEN(mbminmaxlen) ((mbminmaxlen) / DATA_MBMAX) + #ifndef UNIV_HOTBACKUP /*********************************************************************//** Gets the MySQL type code from a dtype. @@ -187,10 +198,8 @@ ulint dtype_get_at_most_n_mbchars( /*========================*/ ulint prtype, /*!< in: precise type */ - ulint mbminlen, /*!< in: minimum length of a - multi-byte character */ - ulint mbmaxlen, /*!< in: maximum length of a - multi-byte character */ + ulint mbminmaxlen, /*!< in: minimum and maximum length of + a multi-byte character */ ulint prefix_len, /*!< in: length of the requested prefix, in characters, multiplied by dtype_get_mbmaxlen(dtype) */ @@ -335,6 +344,19 @@ dtype_get_mbmaxlen( /*===============*/ const dtype_t* type); /*!< in: type */ /*********************************************************************//** +Sets the minimum and maximum length of a character, in bytes. */ +UNIV_INLINE +void +dtype_set_mbminmaxlen( +/*==================*/ + dtype_t* type, /*!< in/out: type */ + ulint mbminlen, /*!< in: minimum length of a char, + in bytes, or 0 if this is not + a character type */ + ulint mbmaxlen); /*!< in: maximum length of a char, + in bytes, or 0 if this is not + a character type */ +/*********************************************************************//** Gets the padding character code for the type. @return padding character code, or ULINT_UNDEFINED if no padding specified */ UNIV_INLINE @@ -354,8 +376,8 @@ dtype_get_fixed_size_low( ulint mtype, /*!< in: main type */ 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 mbminmaxlen, /*!< in: minimum and maximum length of a + multibyte character, in bytes */ ulint comp); /*!< in: nonzero=ROW_FORMAT=COMPACT */ #ifndef UNIV_HOTBACKUP /***********************************************************************//** @@ -368,8 +390,8 @@ dtype_get_min_size_low( ulint mtype, /*!< in: main type */ 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 mbminmaxlen); /*!< in: minimum and maximum length of a + multibyte character */ /***********************************************************************//** Returns the maximum size of a data type. Note: types in system tables may be incomplete and return incorrect information. @@ -472,10 +494,11 @@ struct dtype_struct{ the string, MySQL uses 1 or 2 bytes to store the string length) */ #ifndef UNIV_HOTBACKUP - unsigned mbminlen:2; /*!< minimum length of a - character, in bytes */ - unsigned mbmaxlen:3; /*!< maximum length of a - character, in bytes */ + unsigned mbminmaxlen:5; /*!< minimum and maximum length of a + character, in bytes; + DATA_MBMINMAXLEN(mbminlen,mbmaxlen); + mbminlen=DATA_MBMINLEN(mbminmaxlen); + mbmaxlen=DATA_MBMINLEN(mbminmaxlen) */ #endif /* !UNIV_HOTBACKUP */ }; diff --git a/storage/innobase/include/data0type.ic b/storage/innobase/include/data0type.ic index 2bf67a941bd..757dd815c5e 100644 --- a/storage/innobase/include/data0type.ic +++ b/storage/innobase/include/data0type.ic @@ -93,14 +93,35 @@ dtype_get_mblen( innobase_get_cset_width(dtype_get_charset_coll(prtype), mbminlen, mbmaxlen); ut_ad(*mbminlen <= *mbmaxlen); - ut_ad(*mbminlen <= 2); /* mbminlen in dtype_t is 0..3 */ - ut_ad(*mbmaxlen < 1 << 3); /* mbmaxlen in dtype_t is 0..7 */ + ut_ad(*mbminlen < DATA_MBMAX); + ut_ad(*mbmaxlen < DATA_MBMAX); } else { *mbminlen = *mbmaxlen = 0; } } /*********************************************************************//** +Sets the minimum and maximum length of a character, in bytes. */ +UNIV_INLINE +void +dtype_set_mbminmaxlen( +/*==================*/ + dtype_t* type, /*!< in/out: type */ + ulint mbminlen, /*!< in: minimum length of a char, + in bytes, or 0 if this is not + a character type */ + ulint mbmaxlen) /*!< in: maximum length of a char, + in bytes, or 0 if this is not + a character type */ +{ + ut_ad(mbminlen < DATA_MBMAX); + ut_ad(mbmaxlen < DATA_MBMAX); + ut_ad(mbminlen <= mbmaxlen); + + type->mbminmaxlen = DATA_MBMINMAXLEN(mbminlen, mbmaxlen); +} + +/*********************************************************************//** Compute the mbminlen and mbmaxlen members of a data type structure. */ UNIV_INLINE void @@ -112,8 +133,7 @@ dtype_set_mblen( ulint mbmaxlen; dtype_get_mblen(type->mtype, type->prtype, &mbminlen, &mbmaxlen); - type->mbminlen = mbminlen; - type->mbmaxlen = mbmaxlen; + dtype_set_mbminmaxlen(type, mbminlen, mbmaxlen); ut_ad(dtype_validate(type)); } @@ -210,7 +230,7 @@ dtype_get_mbminlen( const dtype_t* type) /*!< in: type */ { ut_ad(type); - return(type->mbminlen); + return(DATA_MBMINLEN(type->mbminmaxlen)); } /*********************************************************************//** Gets the maximum length of a character, in bytes. @@ -223,7 +243,7 @@ dtype_get_mbmaxlen( const dtype_t* type) /*!< in: type */ { ut_ad(type); - return(type->mbmaxlen); + return(DATA_MBMAXLEN(type->mbminmaxlen)); } /*********************************************************************//** @@ -404,8 +424,8 @@ dtype_get_fixed_size_low( ulint mtype, /*!< in: main type */ 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 mbminmaxlen, /*!< in: minimum and maximum length of + a multibyte character, in bytes */ ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */ { switch (mtype) { @@ -453,8 +473,9 @@ dtype_get_fixed_size_low( dtype_get_charset_coll(prtype), &i_mbminlen, &i_mbmaxlen); - if (UNIV_UNLIKELY(mbminlen != i_mbminlen) - || UNIV_UNLIKELY(mbmaxlen != i_mbmaxlen)) { + if (UNIV_UNLIKELY + (DATA_MBMINMAXLEN(i_mbminlen, i_mbmaxlen) + != mbminmaxlen)) { ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: " @@ -464,10 +485,10 @@ dtype_get_fixed_size_low( "type->mbmaxlen=%lu\n", (ulong) i_mbminlen, (ulong) i_mbmaxlen, - (ulong) mbminlen, - (ulong) mbmaxlen); + (ulong) DATA_MBMINLEN(mbminmaxlen), + (ulong) DATA_MBMAXLEN(mbminmaxlen)); } - if (mbminlen == mbmaxlen) { + if (i_mbminlen == i_mbmaxlen) { return(len); } } @@ -499,8 +520,8 @@ dtype_get_min_size_low( ulint mtype, /*!< in: main type */ 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 mbminmaxlen) /*!< in: minimum and maximum length of a + multi-byte character */ { switch (mtype) { case DATA_SYS: @@ -527,14 +548,22 @@ dtype_get_min_size_low( case DATA_DOUBLE: return(len); case DATA_MYSQL: - if ((prtype & DATA_BINARY_TYPE) || mbminlen == mbmaxlen) { + if (prtype & DATA_BINARY_TYPE) { return(len); + } else { + ulint mbminlen = DATA_MBMINLEN(mbminmaxlen); + ulint mbmaxlen = DATA_MBMAXLEN(mbminmaxlen); + + if (mbminlen == mbmaxlen) { + return(len); + } + + /* this is a variable-length character set */ + ut_a(mbminlen > 0); + ut_a(mbmaxlen > mbminlen); + ut_a(len % mbmaxlen == 0); + return(len * mbminlen / mbmaxlen); } - /* this is a variable-length character set */ - ut_a(mbminlen > 0); - ut_a(mbmaxlen > mbminlen); - ut_a(len % mbmaxlen == 0); - return(len * mbminlen / mbmaxlen); case DATA_VARCHAR: case DATA_BINARY: case DATA_DECIMAL: @@ -595,9 +624,9 @@ dtype_get_sql_null_size( { #ifndef UNIV_HOTBACKUP return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len, - type->mbminlen, type->mbmaxlen, comp)); + type->mbminmaxlen, 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/storage/innobase/include/dict0boot.h b/storage/innobase/include/dict0boot.h index 148b5cbe250..22df826da65 100644 --- a/storage/innobase/include/dict0boot.h +++ b/storage/innobase/include/dict0boot.h @@ -51,32 +51,35 @@ UNIV_INTERN void dict_hdr_get_new_id( /*================*/ - dulint* table_id, /*!< out: table id (not assigned if NULL) */ - dulint* index_id, /*!< out: index id (not assigned if NULL) */ - ulint* space_id); /*!< out: space id (not assigned if NULL) */ + table_id_t* table_id, /*!< out: table id + (not assigned if NULL) */ + index_id_t* index_id, /*!< out: index id + (not assigned if NULL) */ + ulint* space_id); /*!< out: space id + (not assigned if NULL) */ /**********************************************************************//** Returns a new row id. @return the new id */ UNIV_INLINE -dulint +row_id_t dict_sys_get_new_row_id(void); /*=========================*/ /**********************************************************************//** Reads a row id from a record or other 6-byte stored form. @return row id */ UNIV_INLINE -dulint +row_id_t dict_sys_read_row_id( /*=================*/ - byte* field); /*!< in: record field */ + const byte* field); /*!< in: record field */ /**********************************************************************//** Writes a row id to a record or other 6-byte stored form. */ UNIV_INLINE void dict_sys_write_row_id( /*==================*/ - byte* field, /*!< in: record field */ - dulint row_id);/*!< in: row id */ + byte* field, /*!< in: record field */ + row_id_t row_id);/*!< in: row id */ /*****************************************************************//** Initializes the data dictionary memory structures when the database is started. This function is also called when the data dictionary is created. */ @@ -97,12 +100,12 @@ dict_create(void); #define DICT_HDR_PAGE_NO FSP_DICT_HDR_PAGE_NO /* The ids for the basic system tables and their indexes */ -#define DICT_TABLES_ID ut_dulint_create(0, 1) -#define DICT_COLUMNS_ID ut_dulint_create(0, 2) -#define DICT_INDEXES_ID ut_dulint_create(0, 3) -#define DICT_FIELDS_ID ut_dulint_create(0, 4) +#define DICT_TABLES_ID 1 +#define DICT_COLUMNS_ID 2 +#define DICT_INDEXES_ID 3 +#define DICT_FIELDS_ID 4 /* The following is a secondary index on SYS_TABLES */ -#define DICT_TABLE_IDS_ID ut_dulint_create(0, 5) +#define DICT_TABLE_IDS_ID 5 #define DICT_HDR_FIRST_ID 10 /* the ids for tables etc. start from this number, except for basic @@ -110,7 +113,7 @@ dict_create(void); indexes; ibuf tables and indexes are assigned as the id the number DICT_IBUF_ID_MIN plus the space id */ -#define DICT_IBUF_ID_MIN ut_dulint_create(0xFFFFFFFFUL, 0) +#define DICT_IBUF_ID_MIN 0xFFFFFFFF00000000ULL /* The offset of the dictionary header on the page */ #define DICT_HDR FSEG_PAGE_DATA diff --git a/storage/innobase/include/dict0boot.ic b/storage/innobase/include/dict0boot.ic index d5f372e38c4..d3ba9eee78f 100644 --- a/storage/innobase/include/dict0boot.ic +++ b/storage/innobase/include/dict0boot.ic @@ -36,22 +36,22 @@ dict_hdr_flush_row_id(void); Returns a new row id. @return the new id */ UNIV_INLINE -dulint +row_id_t dict_sys_get_new_row_id(void) /*=========================*/ { - dulint id; + row_id_t id; mutex_enter(&(dict_sys->mutex)); id = dict_sys->row_id; - if (0 == (ut_dulint_get_low(id) % DICT_HDR_ROW_ID_WRITE_MARGIN)) { + if (0 == (id % DICT_HDR_ROW_ID_WRITE_MARGIN)) { dict_hdr_flush_row_id(); } - UT_DULINT_INC(dict_sys->row_id); + dict_sys->row_id++; mutex_exit(&(dict_sys->mutex)); @@ -62,10 +62,10 @@ dict_sys_get_new_row_id(void) Reads a row id from a record or other 6-byte stored form. @return row id */ UNIV_INLINE -dulint +row_id_t dict_sys_read_row_id( /*=================*/ - byte* field) /*!< in: record field */ + const byte* field) /*!< in: record field */ { #if DATA_ROW_ID_LEN != 6 # error "DATA_ROW_ID_LEN != 6" @@ -80,8 +80,8 @@ UNIV_INLINE void dict_sys_write_row_id( /*==================*/ - byte* field, /*!< in: record field */ - dulint row_id) /*!< in: row id */ + byte* field, /*!< in: record field */ + row_id_t row_id) /*!< in: row id */ { #if DATA_ROW_ID_LEN != 6 # error "DATA_ROW_ID_LEN != 6" diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 3a1bee4cd89..971173a65a5 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -75,8 +75,8 @@ UNIV_INTERN dict_table_t* dict_table_get_on_id( /*=================*/ - dulint table_id, /*!< in: table id */ - trx_t* trx); /*!< in: transaction handle */ + table_id_t table_id, /*!< in: table id */ + trx_t* trx); /*!< in: transaction handle */ /********************************************************************//** Decrements the count of open MySQL handles to a table. */ UNIV_INTERN @@ -102,6 +102,33 @@ void dict_load_space_id_list(void); /*=========================*/ /*********************************************************************//** +Gets the minimum number of bytes per character. +@return minimum multi-byte char size, in bytes */ +UNIV_INLINE +ulint +dict_col_get_mbminlen( +/*==================*/ + const dict_col_t* col); /*!< in: column */ +/*********************************************************************//** +Gets the maximum number of bytes per character. +@return maximum multi-byte char size, in bytes */ +UNIV_INLINE +ulint +dict_col_get_mbmaxlen( +/*==================*/ + const dict_col_t* col); /*!< in: column */ +/*********************************************************************//** +Sets the minimum and maximum number of bytes per character. */ +UNIV_INLINE +void +dict_col_set_mbminmaxlen( +/*=====================*/ + dict_col_t* col, /*!< in/out: column */ + ulint mbminlen, /*!< in: minimum multi-byte + character size, in bytes */ + ulint mbmaxlen); /*!< in: minimum multi-byte + character size, in bytes */ +/*********************************************************************//** Gets the column data type. */ UNIV_INLINE void @@ -277,7 +304,7 @@ void dict_table_change_id_in_cache( /*==========================*/ dict_table_t* table, /*!< in/out: table object already in cache */ - dulint new_id);/*!< in: new id to set */ + table_id_t new_id);/*!< in: new id to set */ /**********************************************************************//** Adds a foreign key constraint object to the dictionary cache. May free the object if there already is an object with the same identifier in. @@ -397,7 +424,7 @@ dict_index_t* dict_index_get_on_id_low( /*=====================*/ dict_table_t* table, /*!< in: table */ - dulint index_id); /*!< in: index id */ + index_id_t index_id); /*!< in: index id */ /**********************************************************************//** Checks if a table is in the dictionary cache. @return table, NULL if not found */ @@ -423,7 +450,7 @@ UNIV_INLINE dict_table_t* dict_table_get_on_id_low( /*=====================*/ - dulint table_id); /*!< in: table id */ + table_id_t table_id); /*!< in: table id */ /**********************************************************************//** Find an index that is equivalent to the one passed in and is not marked for deletion. @@ -710,7 +737,7 @@ UNIV_INTERN dict_index_t* dict_index_find_on_id_low( /*======================*/ - dulint id); /*!< in: index id */ + index_id_t id); /*!< in: index id */ /**********************************************************************//** Adds an index to the dictionary cache. @return DB_SUCCESS, DB_TOO_BIG_RECORD, or DB_CORRUPTION */ @@ -901,7 +928,7 @@ UNIV_INTERN dict_index_t* dict_index_get_if_in_cache_low( /*===========================*/ - dulint index_id); /*!< in: index id */ + index_id_t index_id); /*!< in: index id */ #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG /**********************************************************************//** Returns an index object if it is found in the dictionary cache. @@ -910,7 +937,7 @@ UNIV_INTERN dict_index_t* dict_index_get_if_in_cache( /*=======================*/ - dulint index_id); /*!< in: index id */ + index_id_t index_id); /*!< in: index id */ #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ #ifdef UNIV_DEBUG /**********************************************************************//** @@ -1135,7 +1162,7 @@ struct dict_sys_struct{ and DROP TABLE, as well as reading the dictionary data for a table from system tables */ - dulint row_id; /*!< the next row id to assign; + row_id_t row_id; /*!< the next row id to assign; NOTE that at a checkpoint this must be written to the dict system header and flushed to a file; in diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic index 93c3f8d4733..09f967aa74a 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -29,6 +29,46 @@ Created 1/8/1996 Heikki Tuuri #include "rem0types.h" /*********************************************************************//** +Gets the minimum number of bytes per character. +@return minimum multi-byte char size, in bytes */ +UNIV_INLINE +ulint +dict_col_get_mbminlen( +/*==================*/ + const dict_col_t* col) /*!< in: column */ +{ + return(DATA_MBMINLEN(col->mbminmaxlen)); +} +/*********************************************************************//** +Gets the maximum number of bytes per character. +@return maximum multi-byte char size, in bytes */ +UNIV_INLINE +ulint +dict_col_get_mbmaxlen( +/*==================*/ + const dict_col_t* col) /*!< in: column */ +{ + return(DATA_MBMAXLEN(col->mbminmaxlen)); +} +/*********************************************************************//** +Sets the minimum and maximum number of bytes per character. */ +UNIV_INLINE +void +dict_col_set_mbminmaxlen( +/*=====================*/ + dict_col_t* col, /*!< in/out: column */ + ulint mbminlen, /*!< in: minimum multi-byte + character size, in bytes */ + ulint mbmaxlen) /*!< in: minimum multi-byte + character size, in bytes */ +{ + ut_ad(mbminlen < DATA_MBMAX); + ut_ad(mbmaxlen < DATA_MBMAX); + ut_ad(mbminlen <= mbmaxlen); + + col->mbminmaxlen = DATA_MBMINMAXLEN(mbminlen, mbmaxlen); +} +/*********************************************************************//** Gets the column data type. */ UNIV_INLINE void @@ -42,8 +82,7 @@ dict_col_copy_type( type->mtype = col->mtype; type->prtype = col->prtype; type->len = col->len; - type->mbminlen = col->mbminlen; - type->mbmaxlen = col->mbmaxlen; + type->mbminmaxlen = col->mbminmaxlen; } #endif /* !UNIV_HOTBACKUP */ @@ -65,8 +104,7 @@ dict_col_type_assert_equal( ut_ad(col->prtype == type->prtype); ut_ad(col->len == type->len); # ifndef UNIV_HOTBACKUP - ut_ad(col->mbminlen == type->mbminlen); - ut_ad(col->mbmaxlen == type->mbmaxlen); + ut_ad(col->mbminmaxlen == type->mbminmaxlen); # endif /* !UNIV_HOTBACKUP */ return(TRUE); @@ -84,7 +122,7 @@ dict_col_get_min_size( const dict_col_t* col) /*!< in: column */ { return(dtype_get_min_size_low(col->mtype, col->prtype, col->len, - col->mbminlen, col->mbmaxlen)); + col->mbminmaxlen)); } /***********************************************************************//** Returns the maximum size of the column. @@ -109,7 +147,7 @@ dict_col_get_fixed_size( ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */ { return(dtype_get_fixed_size_low(col->mtype, col->prtype, col->len, - col->mbminlen, col->mbmaxlen, comp)); + col->mbminmaxlen, comp)); } /***********************************************************************//** Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column. @@ -780,7 +818,7 @@ UNIV_INLINE dict_table_t* dict_table_get_on_id_low( /*=====================*/ - dulint table_id) /*!< in: table id */ + table_id_t table_id) /*!< in: table id */ { dict_table_t* table; ulint fold; @@ -788,11 +826,11 @@ dict_table_get_on_id_low( ut_ad(mutex_own(&(dict_sys->mutex))); /* Look for the table name in the hash table */ - fold = ut_fold_dulint(table_id); + fold = ut_fold_ull(table_id); HASH_SEARCH(id_hash, dict_sys->table_id_hash, fold, dict_table_t*, table, ut_ad(table->cached), - !ut_dulint_cmp(table->id, table_id)); + table->id == table_id); if (table == NULL) { table = dict_load_table_on_id(table_id); } diff --git a/storage/innobase/include/dict0load.h b/storage/innobase/include/dict0load.h index d85f8f7fc3e..6a718a464ab 100644 --- a/storage/innobase/include/dict0load.h +++ b/storage/innobase/include/dict0load.h @@ -109,8 +109,9 @@ dict_load_column_low( a SYS_COLUMNS record */ mem_heap_t* heap, /*!< in/out: memory heap for temporary storage */ - dict_col_t* column, /*!< out: dict_column_t to fill */ - dulint* table_id, /*!< out: table id */ + dict_col_t* column, /*!< out: dict_column_t to fill, + or NULL if table != NULL */ + table_id_t* table_id, /*!< out: table id */ const char** col_name, /*!< out: column name */ const rec_t* rec); /*!< in: SYS_COLUMNS record */ /********************************************************************//** @@ -173,7 +174,7 @@ UNIV_INTERN dict_table_t* dict_load_table_on_id( /*==================*/ - dulint table_id); /*!< in: table id */ + table_id_t table_id); /*!< in: table id */ /********************************************************************//** This function is called when the database is booted. Loads system table index definitions except for the clustered index which @@ -255,7 +256,7 @@ dict_process_sys_indexes_rec( const rec_t* rec, /*!< in: current SYS_INDEXES rec */ dict_index_t* index, /*!< out: dict_index_t to be filled */ - dulint* table_id); /*!< out: table id */ + table_id_t* table_id); /*!< out: table id */ /********************************************************************//** This function parses a SYS_COLUMNS record and populate a dict_column_t structure with the information from the record. @@ -267,7 +268,7 @@ dict_process_sys_columns_rec( mem_heap_t* heap, /*!< in/out: heap memory */ const rec_t* rec, /*!< in: current SYS_COLUMNS rec */ dict_col_t* column, /*!< out: dict_col_t to be filled */ - dulint* table_id, /*!< out: table id */ + table_id_t* table_id, /*!< out: table id */ const char** col_name); /*!< out: column name */ /********************************************************************//** This function parses a SYS_FIELDS record and populate a dict_field_t @@ -282,8 +283,8 @@ dict_process_sys_fields_rec( dict_field_t* sys_field, /*!< out: dict_field_t to be filled */ ulint* pos, /*!< out: Field position */ - dulint* index_id, /*!< out: current index id */ - dulint last_id); /*!< in: previous index id */ + index_id_t* index_id, /*!< out: current index id */ + index_id_t last_id); /*!< in: previous index id */ /********************************************************************//** This function parses a SYS_FOREIGN record and populate a dict_foreign_t structure with the information from the record. For detail information diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 57e5b5394ee..75f9acd6b26 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -151,9 +151,9 @@ dict_mem_table_add_col( ulint prtype, /*!< in: precise type */ ulint len); /*!< in: precision */ /**********************************************************************//** -This function poplulates a dict_col_t memory structure with +This function populates a dict_col_t memory structure with supplied information. */ -UNIV_INLINE +UNIV_INTERN void dict_mem_fill_column_struct( /*========================*/ @@ -162,7 +162,7 @@ dict_mem_fill_column_struct( ulint col_pos, /*!< in: column position */ ulint mtype, /*!< in: main data type */ ulint prtype, /*!< in: precise type */ - ulint col_len); /*!< in: column lenght */ + ulint col_len); /*!< in: column length */ /**********************************************************************//** This function poplulates a dict_index_t index memory structure with supplied information. */ @@ -249,10 +249,11 @@ struct dict_col_struct{ the string, MySQL uses 1 or 2 bytes to store the string length) */ - unsigned mbminlen:2; /*!< minimum length of a - character, in bytes */ - unsigned mbmaxlen:3; /*!< maximum length of a - character, in bytes */ + unsigned mbminmaxlen:5; /*!< minimum and maximum length of a + character, in bytes; + DATA_MBMINMAXLEN(mbminlen,mbmaxlen); + mbminlen=DATA_MBMINLEN(mbminmaxlen); + mbmaxlen=DATA_MBMINLEN(mbminmaxlen) */ /*----------------------*/ /* End of definitions copied from dtype_t */ /* @} */ @@ -293,7 +294,7 @@ struct dict_field_struct{ /** Data structure for an index. Most fields will be initialized to 0, NULL or FALSE in dict_mem_index_create(). */ struct dict_index_struct{ - dulint id; /*!< id of the index */ + index_id_t id; /*!< id of the index */ mem_heap_t* heap; /*!< memory heap */ const char* name; /*!< index name */ const char* table_name;/*!< table name */ @@ -349,7 +350,7 @@ struct dict_index_struct{ /* @} */ rw_lock_t lock; /*!< read-write lock protecting the upper levels of the index tree */ - ib_uint64_t trx_id; /*!< id of the transaction that created this + trx_id_t trx_id; /*!< id of the transaction that created this index, or 0 if the index existed when InnoDB was started up */ #endif /* !UNIV_HOTBACKUP */ @@ -414,9 +415,9 @@ a foreign key constraint is enforced, therefore RESTRICT just means no flag */ /** Data structure for a database table. Most fields will be initialized to 0, NULL or FALSE in dict_mem_table_create(). */ struct dict_table_struct{ - dulint id; /*!< id of the table */ + table_id_t id; /*!< id of the table */ mem_heap_t* heap; /*!< memory heap */ - const char* name; /*!< table name */ + char* name; /*!< table name */ const char* dir_path_of_temp_table;/*!< NULL or the directory path where a TEMPORARY table that was explicitly created by a user should be placed if diff --git a/storage/innobase/include/dict0mem.ic b/storage/innobase/include/dict0mem.ic index 5a851da5640..1d80ffc9b94 100644 --- a/storage/innobase/include/dict0mem.ic +++ b/storage/innobase/include/dict0mem.ic @@ -70,35 +70,3 @@ dict_mem_fill_index_struct( index->magic_n = DICT_INDEX_MAGIC_N; #endif /* UNIV_DEBUG */ } - -/**********************************************************************//** -This function poplulates a dict_col_t memory structure with -supplied information. */ -UNIV_INLINE -void -dict_mem_fill_column_struct( -/*========================*/ - dict_col_t* column, /*!< out: column struct to be - filled */ - ulint col_pos, /*!< in: column position */ - ulint mtype, /*!< in: main data type */ - ulint prtype, /*!< in: precise type */ - ulint col_len) /*!< in: column lenght */ -{ -#ifndef UNIV_HOTBACKUP - ulint mbminlen; - ulint mbmaxlen; -#endif /* !UNIV_HOTBACKUP */ - - column->ind = (unsigned int) col_pos; - column->ord_part = 0; - column->mtype = (unsigned int) mtype; - column->prtype = (unsigned int) prtype; - column->len = (unsigned int) col_len; -#ifndef UNIV_HOTBACKUP - dtype_get_mblen(mtype, prtype, &mbminlen, &mbmaxlen); - - column->mbminlen = (unsigned int) mbminlen; - column->mbmaxlen = (unsigned int) mbmaxlen; -#endif /* !UNIV_HOTBACKUP */ -} diff --git a/storage/innobase/include/dict0types.h b/storage/innobase/include/dict0types.h index 7ad69193cc9..0a9edfbfe70 100644 --- a/storage/innobase/include/dict0types.h +++ b/storage/innobase/include/dict0types.h @@ -45,4 +45,7 @@ typedef struct tab_node_struct tab_node_t; #define DICT_HDR_SPACE 0 /* the SYSTEM tablespace */ #define DICT_HDR_PAGE_NO FSP_DICT_HDR_PAGE_NO +typedef ib_id_t table_id_t; +typedef ib_id_t index_id_t; + #endif diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index c746915844b..d7d98787bcf 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -26,6 +26,7 @@ Created 10/25/1995 Heikki Tuuri #ifndef fil0fil_h #define fil0fil_h +#include "univ.i" #include "dict0types.h" #include "ut0byte.h" #include "os0file.h" diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index 0319c0e9261..3eca80beda4 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -670,7 +670,7 @@ lock_get_type( Gets the id of the transaction owning a lock. @return transaction id */ UNIV_INTERN -ullint +trx_id_t lock_get_trx_id( /*============*/ const lock_t* lock); /*!< in: lock */ @@ -699,7 +699,7 @@ lock_get_type_str( Gets the id of the table on which the lock is. @return id of the table */ UNIV_INTERN -ullint +table_id_t lock_get_table_id( /*==============*/ const lock_t* lock); /*!< in: lock */ diff --git a/storage/innobase/include/log0log.ic b/storage/innobase/include/log0log.ic index 139f4041a36..1ce00fd7313 100644 --- a/storage/innobase/include/log0log.ic +++ b/storage/innobase/include/log0log.ic @@ -433,7 +433,10 @@ void log_free_check(void) /*================*/ { - /* ut_ad(sync_thread_levels_empty()); */ + +#ifdef UNIV_SYNC_DEBUG + ut_ad(sync_thread_levels_empty_gen(TRUE)); +#endif /* UNIV_SYNC_DEBUG */ if (log_sys->check_flush_or_checkpoint) { diff --git a/storage/innobase/include/mach0data.h b/storage/innobase/include/mach0data.h index 44ee3df22ce..8434bc73586 100644 --- a/storage/innobase/include/mach0data.h +++ b/storage/innobase/include/mach0data.h @@ -166,14 +166,14 @@ UNIV_INLINE void mach_write_to_6( /*============*/ - byte* b, /*!< in: pointer to 6 bytes where to store */ - dulint n); /*!< in: dulint integer to be stored */ + byte* b, /*!< in: pointer to 6 bytes where to store */ + ib_uint64_t id); /*!< in: 48-bit integer */ /********************************************************//** The following function is used to fetch data from 6 consecutive bytes. The most significant byte is at the lowest address. -@return dulint integer */ +@return 48-bit integer */ UNIV_INLINE -dulint +ib_uint64_t mach_read_from_6( /*=============*/ const byte* b) /*!< in: pointer to 6 bytes */ @@ -185,14 +185,14 @@ UNIV_INLINE void mach_write_to_7( /*============*/ - byte* b, /*!< in: pointer to 7 bytes where to store */ - dulint n); /*!< in: dulint integer to be stored */ + byte* b, /*!< in: pointer to 7 bytes where to store */ + ib_uint64_t n); /*!< in: 56-bit integer */ /********************************************************//** The following function is used to fetch data from 7 consecutive bytes. The most significant byte is at the lowest address. -@return dulint integer */ +@return 56-bit integer */ UNIV_INLINE -dulint +ib_uint64_t mach_read_from_7( /*=============*/ const byte* b) /*!< in: pointer to 7 bytes */ @@ -204,88 +204,69 @@ UNIV_INLINE void mach_write_to_8( /*============*/ - byte* b, /*!< in: pointer to 8 bytes where to store */ - dulint n); /*!< in: dulint integer to be stored */ -/*******************************************************//** -The following function is used to store data in 8 consecutive -bytes. We store the most significant byte to the lowest address. */ -UNIV_INLINE -void -mach_write_ull( -/*===========*/ byte* b, /*!< in: pointer to 8 bytes where to store */ ib_uint64_t n); /*!< in: 64-bit integer to be stored */ /********************************************************//** The following function is used to fetch data from 8 consecutive bytes. The most significant byte is at the lowest address. -@return dulint integer */ -UNIV_INLINE -dulint -mach_read_from_8( -/*=============*/ - const byte* b) /*!< in: pointer to 8 bytes */ - __attribute__((nonnull, pure)); -/********************************************************//** -The following function is used to fetch data from 8 consecutive -bytes. The most significant byte is at the lowest address. @return 64-bit integer */ UNIV_INLINE ib_uint64_t -mach_read_ull( -/*==========*/ +mach_read_from_8( +/*=============*/ const byte* b) /*!< in: pointer to 8 bytes */ __attribute__((nonnull, pure)); /*********************************************************//** -Writes a dulint in a compressed form (5..9 bytes). +Writes a 64-bit integer in a compressed form (5..9 bytes). @return size in bytes */ UNIV_INLINE ulint -mach_dulint_write_compressed( -/*=========================*/ - byte* b, /*!< in: pointer to memory where to store */ - dulint n); /*!< in: dulint integer to be stored */ +mach_ull_write_compressed( +/*======================*/ + byte* b, /*!< in: pointer to memory where to store */ + ib_uint64_t n); /*!< in: 64-bit integer to be stored */ /*********************************************************//** -Returns the size of a dulint when written in the compressed form. +Returns the size of a 64-bit integer when written in the compressed form. @return compressed size in bytes */ UNIV_INLINE ulint -mach_dulint_get_compressed_size( -/*============================*/ - dulint n); /*!< in: dulint integer to be stored */ +mach_ull_get_compressed_size( +/*=========================*/ + ib_uint64_t n); /*!< in: 64-bit integer to be stored */ /*********************************************************//** -Reads a dulint in a compressed form. -@return read dulint */ +Reads a 64-bit integer in a compressed form. +@return the value read */ UNIV_INLINE -dulint -mach_dulint_read_compressed( -/*========================*/ +ib_uint64_t +mach_ull_read_compressed( +/*=====================*/ const byte* b) /*!< in: pointer to memory from where to read */ __attribute__((nonnull, pure)); /*********************************************************//** -Writes a dulint in a compressed form (1..11 bytes). +Writes a 64-bit integer in a compressed form (1..11 bytes). @return size in bytes */ UNIV_INLINE ulint -mach_dulint_write_much_compressed( -/*==============================*/ - byte* b, /*!< in: pointer to memory where to store */ - dulint n); /*!< in: dulint integer to be stored */ +mach_ull_write_much_compressed( +/*===========================*/ + byte* b, /*!< in: pointer to memory where to store */ + ib_uint64_t n); /*!< in: 64-bit integer to be stored */ /*********************************************************//** -Returns the size of a dulint when written in the compressed form. +Returns the size of a 64-bit integer when written in the compressed form. @return compressed size in bytes */ UNIV_INLINE ulint -mach_dulint_get_much_compressed_size( -/*=================================*/ - dulint n) /*!< in: dulint integer to be stored */ +mach_ull_get_much_compressed_size( +/*==============================*/ + ib_uint64_t n) /*!< in: 64-bit integer to be stored */ __attribute__((const)); /*********************************************************//** -Reads a dulint in a compressed form. -@return read dulint */ +Reads a 64-bit integer in a compressed form. +@return the value read */ UNIV_INLINE -dulint -mach_dulint_read_much_compressed( -/*=============================*/ +ib_uint64_t +mach_ull_read_much_compressed( +/*==========================*/ const byte* b) /*!< in: pointer to memory from where to read */ __attribute__((nonnull, pure)); /*********************************************************//** @@ -299,15 +280,16 @@ mach_parse_compressed( byte* end_ptr,/*!< in: pointer to end of the buffer */ ulint* val); /*!< out: read value */ /*********************************************************//** -Reads a dulint in a compressed form if the log record fully contains it. -@return pointer to end of the stored field, NULL if not complete */ -UNIV_INTERN +Reads a 64-bit integer in a compressed form +if the log record fully contains it. +@return pointer to end of the stored field, NULL if not complete */ +UNIV_INLINE byte* -mach_dulint_parse_compressed( -/*=========================*/ - byte* ptr, /*!< in: pointer to buffer from where to read */ - byte* end_ptr,/*!< in: pointer to end of the buffer */ - dulint* val); /*!< out: read value */ +mach_ull_parse_compressed( +/*======================*/ + byte* ptr, /*!< in: pointer to buffer from where to read */ + byte* end_ptr,/*!< in: pointer to end of the buffer */ + ib_uint64_t* val); /*!< out: read value */ #ifndef UNIV_HOTBACKUP /*********************************************************//** Reads a double. It is stored in a little-endian format. diff --git a/storage/innobase/include/mach0data.ic b/storage/innobase/include/mach0data.ic index 96d2417ac81..b1e5991d39e 100644 --- a/storage/innobase/include/mach0data.ic +++ b/storage/innobase/include/mach0data.ic @@ -280,22 +280,6 @@ UNIV_INLINE void mach_write_to_8( /*============*/ - byte* b, /*!< in: pointer to 8 bytes where to store */ - dulint n) /*!< in: dulint integer to be stored */ -{ - ut_ad(b); - - mach_write_to_4(b, ut_dulint_get_high(n)); - mach_write_to_4(b + 4, ut_dulint_get_low(n)); -} - -/*******************************************************//** -The following function is used to store data in 8 consecutive -bytes. We store the most significant byte to the lowest address. */ -UNIV_INLINE -void -mach_write_ull( -/*===========*/ byte* b, /*!< in: pointer to 8 bytes where to store */ ib_uint64_t n) /*!< in: 64-bit integer to be stored */ { @@ -308,32 +292,11 @@ mach_write_ull( /********************************************************//** The following function is used to fetch data from 8 consecutive bytes. The most significant byte is at the lowest address. -@return dulint integer */ -UNIV_INLINE -dulint -mach_read_from_8( -/*=============*/ - const byte* b) /*!< in: pointer to 8 bytes */ -{ - ulint high; - ulint low; - - ut_ad(b); - - high = mach_read_from_4(b); - low = mach_read_from_4(b + 4); - - return(ut_dulint_create(high, low)); -} - -/********************************************************//** -The following function is used to fetch data from 8 consecutive -bytes. The most significant byte is at the lowest address. @return 64-bit integer */ UNIV_INLINE ib_uint64_t -mach_read_ull( -/*==========*/ +mach_read_from_8( +/*=============*/ const byte* b) /*!< in: pointer to 8 bytes */ { ib_uint64_t ull; @@ -351,34 +314,28 @@ UNIV_INLINE void mach_write_to_7( /*============*/ - byte* b, /*!< in: pointer to 7 bytes where to store */ - dulint n) /*!< in: dulint integer to be stored */ + byte* b, /*!< in: pointer to 7 bytes where to store */ + ib_uint64_t n) /*!< in: 56-bit integer */ { ut_ad(b); - mach_write_to_3(b, ut_dulint_get_high(n)); - mach_write_to_4(b + 3, ut_dulint_get_low(n)); + mach_write_to_3(b, (ulint) (n >> 32)); + mach_write_to_4(b + 3, (ulint) n); } /********************************************************//** The following function is used to fetch data from 7 consecutive bytes. The most significant byte is at the lowest address. -@return dulint integer */ +@return 56-bit integer */ UNIV_INLINE -dulint +ib_uint64_t mach_read_from_7( /*=============*/ const byte* b) /*!< in: pointer to 7 bytes */ { - ulint high; - ulint low; - ut_ad(b); - high = mach_read_from_3(b); - low = mach_read_from_4(b + 3); - - return(ut_dulint_create(high, low)); + return(ut_ull_create(mach_read_from_3(b), mach_read_from_4(b + 3))); } /*******************************************************//** @@ -388,162 +345,196 @@ UNIV_INLINE void mach_write_to_6( /*============*/ - byte* b, /*!< in: pointer to 6 bytes where to store */ - dulint n) /*!< in: dulint integer to be stored */ + byte* b, /*!< in: pointer to 6 bytes where to store */ + ib_uint64_t n) /*!< in: 48-bit integer */ { ut_ad(b); - mach_write_to_2(b, ut_dulint_get_high(n)); - mach_write_to_4(b + 2, ut_dulint_get_low(n)); + mach_write_to_2(b, (ulint) (n >> 32)); + mach_write_to_4(b + 2, (ulint) n); } /********************************************************//** The following function is used to fetch data from 6 consecutive bytes. The most significant byte is at the lowest address. -@return dulint integer */ +@return 48-bit integer */ UNIV_INLINE -dulint +ib_uint64_t mach_read_from_6( /*=============*/ const byte* b) /*!< in: pointer to 6 bytes */ { - ulint high; - ulint low; - ut_ad(b); - high = mach_read_from_2(b); - low = mach_read_from_4(b + 2); - - return(ut_dulint_create(high, low)); + return(ut_ull_create(mach_read_from_2(b), mach_read_from_4(b + 2))); } /*********************************************************//** -Writes a dulint in a compressed form (5..9 bytes). +Writes a 64-bit integer in a compressed form (5..9 bytes). @return size in bytes */ UNIV_INLINE ulint -mach_dulint_write_compressed( -/*=========================*/ - byte* b, /*!< in: pointer to memory where to store */ - dulint n) /*!< in: dulint integer to be stored */ +mach_ull_write_compressed( +/*======================*/ + byte* b, /*!< in: pointer to memory where to store */ + ib_uint64_t n) /*!< in: 64-bit integer to be stored */ { ulint size; ut_ad(b); - size = mach_write_compressed(b, ut_dulint_get_high(n)); - mach_write_to_4(b + size, ut_dulint_get_low(n)); + size = mach_write_compressed(b, (ulint) (n >> 32)); + mach_write_to_4(b + size, (ulint) n); return(size + 4); } /*********************************************************//** -Returns the size of a dulint when written in the compressed form. +Returns the size of a 64-bit integer when written in the compressed form. @return compressed size in bytes */ UNIV_INLINE ulint -mach_dulint_get_compressed_size( -/*============================*/ - dulint n) /*!< in: dulint integer to be stored */ +mach_ull_get_compressed_size( +/*=========================*/ + ib_uint64_t n) /*!< in: 64-bit integer to be stored */ { - return(4 + mach_get_compressed_size(ut_dulint_get_high(n))); + return(4 + mach_get_compressed_size((ulint) (n >> 32))); } /*********************************************************//** -Reads a dulint in a compressed form. -@return read dulint */ +Reads a 64-bit integer in a compressed form. +@return the value read */ UNIV_INLINE -dulint -mach_dulint_read_compressed( -/*========================*/ +ib_uint64_t +mach_ull_read_compressed( +/*=====================*/ const byte* b) /*!< in: pointer to memory from where to read */ { - ulint high; - ulint low; - ulint size; + ib_uint64_t n; + ulint size; ut_ad(b); - high = mach_read_compressed(b); + n = (ib_uint64_t) mach_read_compressed(b); - size = mach_get_compressed_size(high); + size = mach_get_compressed_size((ulint) n); - low = mach_read_from_4(b + size); + n <<= 32; + n |= (ib_uint64_t) mach_read_from_4(b + size); - return(ut_dulint_create(high, low)); + return(n); } /*********************************************************//** -Writes a dulint in a compressed form (1..11 bytes). +Writes a 64-bit integer in a compressed form (1..11 bytes). @return size in bytes */ UNIV_INLINE ulint -mach_dulint_write_much_compressed( -/*==============================*/ - byte* b, /*!< in: pointer to memory where to store */ - dulint n) /*!< in: dulint integer to be stored */ +mach_ull_write_much_compressed( +/*===========================*/ + byte* b, /*!< in: pointer to memory where to store */ + ib_uint64_t n) /*!< in: 64-bit integer to be stored */ { ulint size; ut_ad(b); - if (ut_dulint_get_high(n) == 0) { - return(mach_write_compressed(b, ut_dulint_get_low(n))); + if (!(n >> 32)) { + return(mach_write_compressed(b, (ulint) n)); } *b = (byte)0xFF; - size = 1 + mach_write_compressed(b + 1, ut_dulint_get_high(n)); + size = 1 + mach_write_compressed(b + 1, (ulint) (n >> 32)); - size += mach_write_compressed(b + size, ut_dulint_get_low(n)); + size += mach_write_compressed(b + size, (ulint) n & 0xFFFFFFFF); return(size); } /*********************************************************//** -Returns the size of a dulint when written in the compressed form. +Returns the size of a 64-bit integer when written in the compressed form. @return compressed size in bytes */ UNIV_INLINE ulint -mach_dulint_get_much_compressed_size( -/*=================================*/ - dulint n) /*!< in: dulint integer to be stored */ +mach_ull_get_much_compressed_size( +/*==============================*/ + ib_uint64_t n) /*!< in: 64-bit integer to be stored */ { - if (0 == ut_dulint_get_high(n)) { - return(mach_get_compressed_size(ut_dulint_get_low(n))); + if (!(n >> 32)) { + return(mach_get_compressed_size((ulint) n)); } - return(1 + mach_get_compressed_size(ut_dulint_get_high(n)) - + mach_get_compressed_size(ut_dulint_get_low(n))); + return(1 + mach_get_compressed_size((ulint) (n >> 32)) + + mach_get_compressed_size((ulint) n & ULINT32_MASK)); } /*********************************************************//** -Reads a dulint in a compressed form. -@return read dulint */ +Reads a 64-bit integer in a compressed form. +@return the value read */ UNIV_INLINE -dulint -mach_dulint_read_much_compressed( -/*=============================*/ +ib_uint64_t +mach_ull_read_much_compressed( +/*==========================*/ const byte* b) /*!< in: pointer to memory from where to read */ { - ulint high; - ulint low; - ulint size; + ib_uint64_t n; + ulint size; ut_ad(b); if (*b != (byte)0xFF) { - high = 0; + n = 0; size = 0; } else { - high = mach_read_compressed(b + 1); + n = (ib_uint64_t) mach_read_compressed(b + 1); + + size = 1 + mach_get_compressed_size((ulint) n); + n <<= 32; + } + + n |= mach_read_compressed(b + size); + + return(n); +} + +/*********************************************************//** +Reads a 64-bit integer in a compressed form +if the log record fully contains it. +@return pointer to end of the stored field, NULL if not complete */ +UNIV_INLINE +byte* +mach_ull_parse_compressed( +/*======================*/ + byte* ptr, /* in: pointer to buffer from where to read */ + byte* end_ptr,/* in: pointer to end of the buffer */ + ib_uint64_t* val) /* out: read value */ +{ + ulint size; + + ut_ad(ptr); + ut_ad(end_ptr); + ut_ad(val); + + if (end_ptr < ptr + 5) { + + return(NULL); + } + + *val = mach_read_compressed(ptr); + + size = mach_get_compressed_size((ulint) *val); + + ptr += size; + + if (end_ptr < ptr + 4) { - size = 1 + mach_get_compressed_size(high); + return(NULL); } - low = mach_read_compressed(b + size); + *val <<= 32; + *val |= mach_read_from_4(ptr); - return(ut_dulint_create(high, low)); + return(ptr + 4); } #ifndef UNIV_HOTBACKUP /*********************************************************//** diff --git a/storage/innobase/include/mtr0log.h b/storage/innobase/include/mtr0log.h index 6322af2a569..d271002a5fe 100644 --- a/storage/innobase/include/mtr0log.h +++ b/storage/innobase/include/mtr0log.h @@ -47,11 +47,11 @@ Writes 8 bytes to a file page buffered in the buffer pool. Writes the corresponding log record to the mini-transaction log. */ UNIV_INTERN void -mlog_write_dulint( -/*==============*/ - byte* ptr, /*!< in: pointer where to write */ - dulint val, /*!< in: value to write */ - mtr_t* mtr); /*!< in: mini-transaction handle */ +mlog_write_ull( +/*===========*/ + byte* ptr, /*!< in: pointer where to write */ + ib_uint64_t val, /*!< in: value to write */ + mtr_t* mtr); /*!< in: mini-transaction handle */ /********************************************************//** Writes a string to a file page buffered in the buffer pool. Writes the corresponding log record to the mini-transaction log. */ @@ -125,13 +125,13 @@ mlog_catenate_ulint_compressed( mtr_t* mtr, /*!< in: mtr */ ulint val); /*!< in: value to write */ /********************************************************//** -Catenates a compressed dulint to mlog. */ +Catenates a compressed 64-bit integer to mlog. */ UNIV_INLINE void -mlog_catenate_dulint_compressed( -/*============================*/ - mtr_t* mtr, /*!< in: mtr */ - dulint val); /*!< in: value to write */ +mlog_catenate_ull_compressed( +/*=========================*/ + mtr_t* mtr, /*!< in: mtr */ + ib_uint64_t val); /*!< in: value to write */ /********************************************************//** Opens a buffer to mlog. It must be closed with mlog_close. @return buffer, NULL if log mode MTR_LOG_NONE */ @@ -183,7 +183,7 @@ mlog_parse_initial_log_record( ulint* space, /*!< out: space id */ ulint* page_no);/*!< out: page number */ /********************************************************//** -Parses a log record written by mlog_write_ulint or mlog_write_dulint. +Parses a log record written by mlog_write_ulint or mlog_write_ull. @return parsed record end, NULL if not a complete record */ UNIV_INTERN byte* diff --git a/storage/innobase/include/mtr0log.ic b/storage/innobase/include/mtr0log.ic index 5c24c38b337..c670a0a8c82 100644 --- a/storage/innobase/include/mtr0log.ic +++ b/storage/innobase/include/mtr0log.ic @@ -142,13 +142,13 @@ mlog_catenate_ulint_compressed( } /********************************************************//** -Catenates a compressed dulint to mlog. */ +Catenates a compressed 64-bit integer to mlog. */ UNIV_INLINE void -mlog_catenate_dulint_compressed( -/*============================*/ - mtr_t* mtr, /*!< in: mtr */ - dulint val) /*!< in: value to write */ +mlog_catenate_ull_compressed( +/*=========================*/ + mtr_t* mtr, /*!< in: mtr */ + ib_uint64_t val) /*!< in: value to write */ { byte* log_ptr; @@ -160,7 +160,7 @@ mlog_catenate_dulint_compressed( return; } - log_ptr += mach_dulint_write_compressed(log_ptr, val); + log_ptr += mach_ull_write_compressed(log_ptr, val); mlog_close(mtr, log_ptr); } diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h index bc3f1951be9..8abca093548 100644 --- a/storage/innobase/include/mtr0mtr.h +++ b/storage/innobase/include/mtr0mtr.h @@ -264,15 +264,6 @@ mtr_read_ulint( const byte* ptr, /*!< in: pointer from where to read */ ulint type, /*!< in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */ mtr_t* mtr); /*!< in: mini-transaction handle */ -/********************************************************//** -Reads 8 bytes from a file page buffered in the buffer pool. -@return value read */ -UNIV_INTERN -dulint -mtr_read_dulint( -/*============*/ - const byte* ptr, /*!< in: pointer from where to read */ - mtr_t* mtr); /*!< in: mini-transaction handle */ #ifndef UNIV_HOTBACKUP /*********************************************************************//** This macro locks an rw-lock in s-mode. */ diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h index 197e361b2b1..6d95b280330 100644 --- a/storage/innobase/include/os0file.h +++ b/storage/innobase/include/os0file.h @@ -177,6 +177,13 @@ log. */ #define OS_WIN95 2 /*!< Microsoft Windows 95 */ #define OS_WINNT 3 /*!< Microsoft Windows NT 3.x */ #define OS_WIN2000 4 /*!< Microsoft Windows 2000 */ +#define OS_WINXP 5 /*!< Microsoft Windows XP + or Windows Server 2003 */ +#define OS_WINVISTA 6 /*!< Microsoft Windows Vista + or Windows Server 2008 */ +#define OS_WIN7 7 /*!< Microsoft Windows 7 + or Windows Server 2008 R2 */ + extern ulint os_n_file_reads; extern ulint os_n_file_writes; @@ -368,7 +375,8 @@ typedef DIR* os_file_dir_t; /*!< directory stream */ /***********************************************************************//** Gets the operating system version. Currently works only on Windows. -@return OS_WIN95, OS_WIN31, OS_WINNT, or OS_WIN2000 */ +@return OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000, OS_WINXP, OS_WINVISTA, +OS_WIN7. */ UNIV_INTERN ulint os_get_os_version(void); diff --git a/storage/innobase/include/os0sync.h b/storage/innobase/include/os0sync.h index 0c22162b900..0b600c80ce3 100644 --- a/storage/innobase/include/os0sync.h +++ b/storage/innobase/include/os0sync.h @@ -38,28 +38,18 @@ Created 9/6/1995 Heikki Tuuri #include "ut0lst.h" #ifdef __WIN__ - +/** Native event (slow)*/ +typedef HANDLE os_native_event_t; /** Native mutex */ -#define os_fast_mutex_t CRITICAL_SECTION - -/** Native event */ -typedef HANDLE os_native_event_t; - -/** Operating system event */ -typedef struct os_event_struct os_event_struct_t; -/** Operating system event handle */ -typedef os_event_struct_t* os_event_t; - -/** An asynchronous signal sent between threads */ -struct os_event_struct { - os_native_event_t handle; - /*!< Windows event */ - UT_LIST_NODE_T(os_event_struct_t) os_event_list; - /*!< list of all created events */ -}; +typedef CRITICAL_SECTION os_fast_mutex_t; +/** Native condition variable. */ +typedef CONDITION_VARIABLE os_cond_t; #else /** Native mutex */ -typedef pthread_mutex_t os_fast_mutex_t; +typedef pthread_mutex_t os_fast_mutex_t; +/** Native condition variable */ +typedef pthread_cond_t os_cond_t; +#endif /** Operating system event */ typedef struct os_event_struct os_event_struct_t; @@ -68,6 +58,10 @@ typedef os_event_struct_t* os_event_t; /** An asynchronous signal sent between threads */ struct os_event_struct { +#ifdef __WIN__ + HANDLE handle; /*!< kernel event object, slow, + used on older Windows */ +#endif os_fast_mutex_t os_mutex; /*!< this mutex protects the next fields */ ibool is_set; /*!< this is TRUE when the event is @@ -76,24 +70,17 @@ struct os_event_struct { this event */ ib_int64_t signal_count; /*!< this is incremented each time the event becomes signaled */ - pthread_cond_t cond_var; /*!< condition variable is used in + os_cond_t cond_var; /*!< condition variable is used in waiting for the event */ UT_LIST_NODE_T(os_event_struct_t) os_event_list; /*!< list of all created events */ }; -#endif /** Operating system mutex */ typedef struct os_mutex_struct os_mutex_str_t; /** Operating system mutex handle */ typedef os_mutex_str_t* os_mutex_t; -/** Denotes an infinite delay for os_event_wait_time() */ -#define OS_SYNC_INFINITE_TIME ((ulint)(-1)) - -/** Return value of os_event_wait_time() when the time is exceeded */ -#define OS_SYNC_TIME_EXCEEDED 1 - /** Mutex protecting counts and the event and OS 'slow' mutex lists */ extern os_mutex_t os_sync_mutex; @@ -187,42 +174,14 @@ os_event_wait_low( #define os_event_wait(event) os_event_wait_low(event, 0) -/**********************************************************//** -Waits for an event object until it is in the signaled state or -a timeout is exceeded. In Unix the timeout is always infinite. -@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */ -UNIV_INTERN -ulint -os_event_wait_time( -/*===============*/ - os_event_t event, /*!< in: event to wait */ - ulint time); /*!< in: timeout in microseconds, or - OS_SYNC_INFINITE_TIME */ -#ifdef __WIN__ -/**********************************************************//** -Waits for any event in an OS native event array. Returns if even a single -one is signaled or becomes signaled. -@return index of the event which was signaled */ -UNIV_INTERN -ulint -os_event_wait_multiple( -/*===================*/ - ulint n, /*!< in: number of events in the - array */ - os_native_event_t* native_event_array); - /*!< in: pointer to an array of event - handles */ -#endif /*********************************************************//** Creates an operating system mutex semaphore. Because these are slow, the mutex semaphore of InnoDB itself (mutex_t) should be used where possible. @return the mutex handle */ UNIV_INTERN os_mutex_t -os_mutex_create( -/*============*/ - const char* name); /*!< in: the name of the mutex, if NULL - the mutex is created without a name */ +os_mutex_create(void); +/*=================*/ /**********************************************************//** Acquires ownership of a mutex semaphore. */ UNIV_INTERN diff --git a/storage/innobase/include/os0sync.ic b/storage/innobase/include/os0sync.ic index 1f3ce38fa65..c33f13aaad6 100644 --- a/storage/innobase/include/os0sync.ic +++ b/storage/innobase/include/os0sync.ic @@ -28,8 +28,7 @@ Created 9/6/1995 Heikki Tuuri #endif /**********************************************************//** -Acquires ownership of a fast mutex. Currently in Windows this is the same -as os_fast_mutex_lock! +Acquires ownership of a fast mutex. @return 0 if success, != 0 if was reserved by another thread */ UNIV_INLINE ulint @@ -38,9 +37,13 @@ os_fast_mutex_trylock( os_fast_mutex_t* fast_mutex) /*!< in: mutex to acquire */ { #ifdef __WIN__ - EnterCriticalSection(fast_mutex); + if (TryEnterCriticalSection(fast_mutex)) { - return(0); + return(0); + } else { + + return(1); + } #else /* NOTE that the MySQL my_pthread.h redefines pthread_mutex_trylock so that it returns 0 on success. In the operating system diff --git a/storage/innobase/include/page0page.h b/storage/innobase/include/page0page.h index 3899499fb6a..826fd13125d 100644 --- a/storage/innobase/include/page0page.h +++ b/storage/innobase/include/page0page.h @@ -66,7 +66,7 @@ typedef byte page_header_t; direction */ #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 + a record on the page; trx_id_t; defined 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, diff --git a/storage/innobase/include/page0page.ic b/storage/innobase/include/page0page.ic index 8f794410f20..e9624c2360f 100644 --- a/storage/innobase/include/page0page.ic +++ b/storage/innobase/include/page0page.ic @@ -94,11 +94,10 @@ page_update_max_trx_id( 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(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) { + if (page_get_max_trx_id(buf_block_get_frame(block)) < trx_id) { page_set_max_trx_id(block, page_zip, trx_id, mtr); } diff --git a/storage/innobase/include/pars0pars.h b/storage/innobase/include/pars0pars.h index 524fe4ac3e7..141b2706d7d 100644 --- a/storage/innobase/include/pars0pars.h +++ b/storage/innobase/include/pars0pars.h @@ -520,35 +520,18 @@ pars_info_add_int4_literal( Equivalent to: char buf[8]; -mach_write_ull(buf, val); -pars_info_add_literal(info, name, buf, 8, DATA_INT, 0); - -except that the buffer is dynamically allocated from the info struct's -heap. */ -UNIV_INTERN -void -pars_info_add_uint64_literal( -/*=========================*/ - pars_info_t* info, /*!< in: info struct */ - const char* name, /*!< in: name */ - ib_uint64_t val); /*!< in: value */ - -/****************************************************************//** -Equivalent to: - -char buf[8]; mach_write_to_8(buf, val); -pars_info_add_literal(info, name, buf, 8, DATA_BINARY, 0); +pars_info_add_literal(info, name, buf, 8, DATA_FIXBINARY, 0); except that the buffer is dynamically allocated from the info struct's heap. */ UNIV_INTERN void -pars_info_add_dulint_literal( -/*=========================*/ +pars_info_add_ull_literal( +/*======================*/ pars_info_t* info, /*!< in: info struct */ const char* name, /*!< in: name */ - dulint val); /*!< in: value */ + ib_uint64_t val); /*!< in: value */ /****************************************************************//** Add user function. */ UNIV_INTERN diff --git a/storage/innobase/include/que0que.h b/storage/innobase/include/que0que.h index 39f8d07af89..09734bbb197 100644 --- a/storage/innobase/include/que0que.h +++ b/storage/innobase/include/que0que.h @@ -421,9 +421,6 @@ struct que_fork_struct{ ibool cur_on_row; /*!< TRUE if cursor is on a row, i.e., it is not before the first row or after the last row */ - dulint n_inserts; /*!< number of rows inserted */ - dulint n_updates; /*!< number of rows updated */ - dulint n_deletes; /*!< number of rows deleted */ sel_node_t* last_sel_node; /*!< last executed select node, or NULL if none */ UT_LIST_NODE_T(que_fork_t) diff --git a/storage/innobase/include/read0read.h b/storage/innobase/include/read0read.h index 4d9a9fade36..73ea66f4da2 100644 --- a/storage/innobase/include/read0read.h +++ b/storage/innobase/include/read0read.h @@ -43,8 +43,7 @@ read_view_t* read_view_open_now( /*===============*/ trx_id_t cr_trx_id, /*!< in: trx_id of creating - transaction, or ut_dulint_zero - used in purge */ + transaction, or 0 used in purge */ mem_heap_t* heap); /*!< in: memory heap from which allocated */ /*********************************************************************//** @@ -56,8 +55,7 @@ read_view_t* read_view_oldest_copy_or_open_new( /*==============================*/ trx_id_t cr_trx_id, /*!< in: trx_id of creating - transaction, or ut_dulint_zero - used in purge */ + transaction, or 0 used in purge */ mem_heap_t* heap); /*!< in: memory heap from which allocated */ /*********************************************************************//** @@ -125,7 +123,7 @@ read should not see the modifications to the database. */ struct read_view_struct{ ulint type; /*!< VIEW_NORMAL, VIEW_HIGH_GRANULARITY */ - undo_no_t undo_no;/*!< ut_dulint_zero or if type is + undo_no_t undo_no;/*!< 0 or if type is VIEW_HIGH_GRANULARITY transaction undo_no when this high-granularity consistent read view was created */ @@ -156,7 +154,7 @@ struct read_view_struct{ that is, up_limit_id and low_limit_id. */ trx_id_t creator_trx_id; /*!< trx id of creating transaction, or - ut_dulint_zero used in purge */ + 0 used in purge */ UT_LIST_NODE_T(read_view_t) view_list; /*!< List of read views in trx_sys */ }; diff --git a/storage/innobase/include/read0read.ic b/storage/innobase/include/read0read.ic index 9924967cc2d..5bb5249b591 100644 --- a/storage/innobase/include/read0read.ic +++ b/storage/innobase/include/read0read.ic @@ -64,15 +64,14 @@ read_view_sees_trx_id( trx_id_t trx_id) /*!< in: trx id */ { ulint n_ids; - int cmp; ulint i; - if (ut_dulint_cmp(trx_id, view->up_limit_id) < 0) { + if (trx_id < view->up_limit_id) { return(TRUE); } - if (ut_dulint_cmp(trx_id, view->low_limit_id) >= 0) { + if (trx_id >= view->low_limit_id) { return(FALSE); } @@ -85,12 +84,11 @@ read_view_sees_trx_id( n_ids = view->n_trx_ids; for (i = 0; i < n_ids; i++) { + trx_id_t view_trx_id + = read_view_get_nth_trx_id(view, n_ids - i - 1); - cmp = ut_dulint_cmp( - trx_id, - read_view_get_nth_trx_id(view, n_ids - i - 1)); - if (cmp <= 0) { - return(cmp < 0); + if (trx_id <= view_trx_id) { + return(trx_id != view_trx_id); } } diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h index 17d08afabb9..53402e8d3a9 100644 --- a/storage/innobase/include/rem0rec.h +++ b/storage/innobase/include/rem0rec.h @@ -659,7 +659,7 @@ rec_fold( fields to fold */ ulint n_bytes, /*!< in: number of bytes to fold in an incomplete last field */ - dulint tree_id) /*!< in: index tree id */ + index_id_t tree_id) /*!< in: index tree id */ __attribute__((pure)); #endif /* !UNIV_HOTBACKUP */ /*********************************************************//** diff --git a/storage/innobase/include/rem0rec.ic b/storage/innobase/include/rem0rec.ic index 8e5bd9a7fcd..ba306eaf27f 100644 --- a/storage/innobase/include/rem0rec.ic +++ b/storage/innobase/include/rem0rec.ic @@ -1594,7 +1594,7 @@ rec_fold( fields to fold */ ulint n_bytes, /*!< in: number of bytes to fold in an incomplete last field */ - dulint tree_id) /*!< in: index tree id */ + index_id_t tree_id) /*!< in: index tree id */ { ulint i; const byte* data; @@ -1618,7 +1618,7 @@ rec_fold( n_bytes = 0; } - fold = ut_fold_dulint(tree_id); + fold = ut_fold_ull(tree_id); for (i = 0; i < n_fields; i++) { data = rec_get_nth_field(rec, offsets, i, &len); diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 39ea240772c..d9c26a2ee3b 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -103,6 +103,17 @@ row_mysql_read_blob_ref( ulint col_len); /*!< in: BLOB reference length (not BLOB length) */ /**************************************************************//** +Pad a column with spaces. */ +UNIV_INTERN +void +row_mysql_pad_col( +/*==============*/ + ulint mbminlen, /*!< in: minimum size of a character, + in bytes */ + byte* pad, /*!< out: padded buffer */ + ulint len); /*!< in: number of bytes to pad */ + +/**************************************************************//** Stores a non-SQL-NULL field given in the MySQL format in the InnoDB format. The counterpart of this function is row_sel_field_store_in_mysql_format() in row0sel.c. @@ -622,7 +633,11 @@ struct row_prebuilt_struct { the secondary index, then this is set to TRUE */ unsigned templ_contains_blob:1;/*!< TRUE if the template contains - BLOB column(s) */ + a column with DATA_BLOB == + get_innobase_type_from_mysql_type(); + not to be confused with InnoDB + externally stored columns + (VARCHAR can be off-page too) */ mysql_row_templ_t* mysql_template;/*!< template used to transform rows fast between MySQL and Innobase formats; memory for this template diff --git a/storage/innobase/include/row0upd.h b/storage/innobase/include/row0upd.h index 635d746d5a1..f7bec6f7561 100644 --- a/storage/innobase/include/row0upd.h +++ b/storage/innobase/include/row0upd.h @@ -132,7 +132,7 @@ row_upd_index_entry_sys_field( them */ dict_index_t* index, /*!< in: clustered index */ ulint type, /*!< in: DATA_TRX_ID or DATA_ROLL_PTR */ - dulint val); /*!< in: value to write */ + ib_uint64_t val); /*!< in: value to write */ /*********************************************************************//** Creates an update node for a query graph. @return own: update node */ diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 18f7c07c3c6..d78c8113aee 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -112,6 +112,9 @@ OS (provided we compiled Innobase with it in), otherwise we will use simulated aio we build below with threads. Currently we support native aio on windows and linux */ extern my_bool srv_use_native_aio; +#ifdef __WIN__ +extern ibool srv_use_native_conditions; +#endif extern ulint srv_n_data_files; extern char** srv_data_file_names; extern ulint* srv_data_file_sizes; @@ -161,9 +164,9 @@ is 5% of the max where max is srv_io_capacity. */ #define PCT_IO(p) ((ulong) (srv_io_capacity * ((double) p / 100.0))) #ifdef UNIV_LOG_ARCHIVE -extern ibool srv_log_archive_on; -extern ibool srv_archive_recovery; -extern dulint srv_archive_recovery_limit_lsn; +extern ibool srv_log_archive_on; +extern ibool srv_archive_recovery; +extern ib_uint64_t srv_archive_recovery_limit_lsn; #endif /* UNIV_LOG_ARCHIVE */ extern char* srv_file_flush_method_str; diff --git a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h index 4e73bee9108..940e583350a 100644 --- a/storage/innobase/include/sync0sync.h +++ b/storage/innobase/include/sync0sync.h @@ -621,7 +621,7 @@ or row lock! */ #define SYNC_FILE_FORMAT_TAG 1200 /* Used to serialize access to the file format tag */ #define SYNC_DICT_OPERATION 1001 /* table create, drop, etc. reserve - this in X-mode, implicit or backround + this in X-mode; implicit or backround operations purge, rollback, foreign key checks reserve this in S-mode */ #define SYNC_DICT 1000 diff --git a/storage/innobase/include/trx0i_s.h b/storage/innobase/include/trx0i_s.h index c610782c229..8f8b7367fb0 100644 --- a/storage/innobase/include/trx0i_s.h +++ b/storage/innobase/include/trx0i_s.h @@ -30,6 +30,7 @@ Created July 17, 2007 Vasil Dimov #include "univ.i" #include "trx0types.h" +#include "dict0types.h" #include "ut0ut.h" /** The maximum amount of memory that can be consumed by innodb_trx, @@ -95,7 +96,7 @@ struct i_s_hash_chain_struct { /** This structure represents INFORMATION_SCHEMA.innodb_locks row */ struct i_s_locks_row_struct { - ullint lock_trx_id; /*!< transaction identifier */ + trx_id_t lock_trx_id; /*!< transaction identifier */ const char* lock_mode; /*!< lock mode from lock_get_mode_str() */ const char* lock_type; /*!< lock type from @@ -116,7 +117,7 @@ struct i_s_locks_row_struct { /** The following are auxiliary and not included in the table */ /* @{ */ - ullint lock_table_id; + table_id_t lock_table_id; /*!< table identifier from lock_get_table_id */ i_s_hash_chain_t hash_chain; /*!< hash table chain node for @@ -126,10 +127,10 @@ struct i_s_locks_row_struct { /** This structure represents INFORMATION_SCHEMA.innodb_trx row */ struct i_s_trx_row_struct { - ullint trx_id; /*!< transaction identifier */ - const char* trx_state; /*!< transaction state from - trx_get_que_state_str() */ - ib_time_t trx_started; /*!< trx_struct::start_time */ + trx_id_t trx_id; /*!< transaction identifier */ + const char* trx_state; /*!< transaction state from + trx_get_que_state_str() */ + ib_time_t trx_started; /*!< trx_struct::start_time */ const i_s_locks_row_t* requested_lock_row; /*!< pointer to a row in innodb_locks if trx diff --git a/storage/innobase/include/trx0rec.h b/storage/innobase/include/trx0rec.h index a6e56e963c6..477748f6f89 100644 --- a/storage/innobase/include/trx0rec.h +++ b/storage/innobase/include/trx0rec.h @@ -108,7 +108,7 @@ trx_undo_rec_get_pars( ibool* updated_extern, /*!< out: TRUE if we updated an externally stored fild */ undo_no_t* undo_no, /*!< out: undo log record number */ - dulint* table_id); /*!< out: table id */ + table_id_t* table_id); /*!< out: table id */ /*******************************************************************//** Builds a row reference from an undo log record. @return pointer to remaining part of undo record */ @@ -227,7 +227,7 @@ trx_undo_report_row_operation( index, otherwise NULL */ roll_ptr_t* roll_ptr); /*!< out: rollback pointer to the inserted undo log record, - ut_dulint_zero if BTR_NO_UNDO_LOG + 0 if BTR_NO_UNDO_LOG flag was specified */ /******************************************************************//** Copies an undo record to heap. This function can be called if we know that diff --git a/storage/innobase/include/trx0rec.ic b/storage/innobase/include/trx0rec.ic index e7e41d6d9f6..f0b3276ed44 100644 --- a/storage/innobase/include/trx0rec.ic +++ b/storage/innobase/include/trx0rec.ic @@ -78,7 +78,7 @@ trx_undo_rec_get_undo_no( ptr = undo_rec + 3; - return(mach_dulint_read_much_compressed(ptr)); + return(mach_ull_read_much_compressed(ptr)); } /**********************************************************************//** @@ -90,7 +90,7 @@ trx_undo_rec_get_offset( /*====================*/ undo_no_t undo_no) /*!< in: undo no read from node */ { - return (3 + mach_dulint_get_much_compressed_size(undo_no)); + return (3 + mach_ull_get_much_compressed_size(undo_no)); } /***********************************************************************//** diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h index fc92b4317d5..63e3f6be934 100644 --- a/storage/innobase/include/trx0sys.h +++ b/storage/innobase/include/trx0sys.h @@ -568,11 +568,16 @@ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_NO. */ (TRX_SYS_PAGE_NO of TRX_SYS_SPACE) */ #define TRX_SYS_FILE_FORMAT_TAG (UNIV_PAGE_SIZE - 16) -/** Contents of TRX_SYS_FILE_FORMAT_TAG when valid. The file format +/** Contents of TRX_SYS_FILE_FORMAT_TAG when valid. The file format identifier is added to this constant. */ #define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW 3645922177UL /** Contents of TRX_SYS_FILE_FORMAT_TAG+4 when valid */ #define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH 2745987765UL +/** Contents of TRX_SYS_FILE_FORMAT_TAG when valid. The file format +identifier is added to this 64-bit constant. */ +#define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N \ + ((ib_uint64_t) TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH << 32 \ + | TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW) /* @} */ /** Doublewrite control struct */ diff --git a/storage/innobase/include/trx0sys.ic b/storage/innobase/include/trx0sys.ic index 820d31d0692..385c7f4f0cc 100644 --- a/storage/innobase/include/trx0sys.ic +++ b/storage/innobase/include/trx0sys.ic @@ -266,7 +266,7 @@ trx_get_on_id( trx = UT_LIST_GET_FIRST(trx_sys->trx_list); while (trx != NULL) { - if (0 == ut_dulint_cmp(trx_id, trx->id)) { + if (trx_id == trx->id) { return(trx); } @@ -315,12 +315,12 @@ trx_is_active( ut_ad(mutex_own(&(kernel_mutex))); - if (ut_dulint_cmp(trx_id, trx_list_get_min_trx_id()) < 0) { + if (trx_id < trx_list_get_min_trx_id()) { return(FALSE); } - if (ut_dulint_cmp(trx_id, trx_sys->max_trx_id) >= 0) { + if (UNIV_UNLIKELY(trx_id >= trx_sys->max_trx_id)) { /* There must be corruption: we return TRUE because this function is only called by lock_clust_rec_some_has_impl() @@ -359,15 +359,12 @@ trx_sys_get_new_trx_id(void) Thus trx id values will not overlap when the database is repeatedly started! */ - if (ut_dulint_get_low(trx_sys->max_trx_id) - % TRX_SYS_TRX_ID_WRITE_MARGIN == 0) { + if ((ulint) trx_sys->max_trx_id % TRX_SYS_TRX_ID_WRITE_MARGIN == 0) { trx_sys_flush_max_trx_id(); } - id = trx_sys->max_trx_id; - - UT_DULINT_INC(trx_sys->max_trx_id); + id = trx_sys->max_trx_id++; return(id); } diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index abd175d365b..6a817ccdc8e 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -408,30 +408,20 @@ Calculates the "weight" of a transaction. The weight of one transaction is estimated as the number of altered rows + the number of locked rows. @param t transaction @return transaction weight */ -#define TRX_WEIGHT(t) \ - ut_dulint_add((t)->undo_no, UT_LIST_GET_LEN((t)->trx_locks)) +#define TRX_WEIGHT(t) ((t)->undo_no + UT_LIST_GET_LEN((t)->trx_locks)) /*******************************************************************//** Compares the "weight" (or size) of two transactions. Transactions that have edited non-transactional tables are considered heavier than ones that have not. -@return <0, 0 or >0; similar to strcmp(3) */ +@return TRUE if weight(a) >= weight(b) */ UNIV_INTERN -int -trx_weight_cmp( -/*===========*/ +ibool +trx_weight_ge( +/*==========*/ const trx_t* a, /*!< in: the first transaction to be compared */ const trx_t* b); /*!< in: the second transaction to be compared */ -/*******************************************************************//** -Retrieves transacion's id, represented as unsigned long long. -@return transaction's id */ -UNIV_INLINE -ullint -trx_get_id( -/*=======*/ - const trx_t* trx); /*!< in: transaction */ - /* Maximum length of a string that can be returned by trx_get_que_state_str(). */ #define TRX_QUE_STATE_STR_MAX_LEN 12 /* "ROLLING BACK" */ @@ -555,8 +545,8 @@ struct trx_struct{ 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 */ - trx_id_t table_id; /*!< Table to drop iff dict_operation - is TRUE, or ut_dulint_zero. */ + table_id_t table_id; /*!< Table to drop iff dict_operation + is TRUE, or 0. */ /*------------------------------*/ void* mysql_thd; /*!< MySQL thread handle corresponding to this trx, or NULL */ diff --git a/storage/innobase/include/trx0trx.ic b/storage/innobase/include/trx0trx.ic index 7332eeece85..4a1d3bcde0b 100644 --- a/storage/innobase/include/trx0trx.ic +++ b/storage/innobase/include/trx0trx.ic @@ -69,18 +69,6 @@ trx_get_error_info( } /*******************************************************************//** -Retrieves transacion's id, represented as unsigned long long. -@return transaction's id */ -UNIV_INLINE -ullint -trx_get_id( -/*=======*/ - const trx_t* trx) /*!< in: transaction */ -{ - return((ullint)ut_conv_dulint_to_longlong(trx->id)); -} - -/*******************************************************************//** Retrieves transaction's que state in a human readable string. The string should not be free()'d or modified. @return string in the data segment */ diff --git a/storage/innobase/include/trx0types.h b/storage/innobase/include/trx0types.h index 40a7256cbfd..a4115b5aca7 100644 --- a/storage/innobase/include/trx0types.h +++ b/storage/innobase/include/trx0types.h @@ -28,10 +28,7 @@ Created 3/26/1996 Heikki Tuuri #include "ut0byte.h" -/** prepare trx_t::id for being printed via printf(3) */ -#define TRX_ID_PREP_PRINTF(id) (ullint) ut_conv_dulint_to_longlong(id) - -/** printf(3) format used for printing TRX_ID_PRINTF_PREP() */ +/** printf(3) format used for printing DB_TRX_ID and other system fields */ #define TRX_ID_FMT "%llX" /** maximum length that a formatted trx_t::id could take, not including @@ -81,12 +78,14 @@ enum trx_rb_ctx { in crash recovery */ }; +/** Row identifier (DB_ROW_ID, DATA_ROW_ID) */ +typedef ib_id_t row_id_t; /** Transaction identifier (DB_TRX_ID, DATA_TRX_ID) */ -typedef dulint trx_id_t; +typedef ib_id_t trx_id_t; /** Rollback pointer (DB_ROLL_PTR, DATA_ROLL_PTR) */ -typedef dulint roll_ptr_t; +typedef ib_id_t roll_ptr_t; /** Undo number */ -typedef dulint undo_no_t; +typedef ib_id_t undo_no_t; /** Transaction savepoint */ typedef struct trx_savept_struct trx_savept_t; diff --git a/storage/innobase/include/trx0undo.h b/storage/innobase/include/trx0undo.h index a084f2394b5..54809f9c2d5 100644 --- a/storage/innobase/include/trx0undo.h +++ b/storage/innobase/include/trx0undo.h @@ -383,7 +383,7 @@ struct trx_undo_struct{ XID xid; /*!< X/Open XA transaction identification */ ibool dict_operation; /*!< TRUE if a dict operation trx */ - dulint table_id; /*!< if a dict operation, then the table + table_id_t table_id; /*!< if a dict operation, then the table id */ trx_rseg_t* rseg; /*!< rseg where the undo log belongs */ /*-----------------------------*/ diff --git a/storage/innobase/include/trx0undo.ic b/storage/innobase/include/trx0undo.ic index 6502ee826e5..b81330f7f8b 100644 --- a/storage/innobase/include/trx0undo.ic +++ b/storage/innobase/include/trx0undo.ic @@ -39,16 +39,19 @@ trx_undo_build_roll_ptr( ulint page_no, /*!< in: page number */ ulint offset) /*!< in: offset of the undo entry within page */ { + roll_ptr_t roll_ptr; #if DATA_ROLL_PTR_LEN != 7 # error "DATA_ROLL_PTR_LEN != 7" #endif + ut_ad(is_insert == 0 || is_insert == 1); ut_ad(rseg_id < TRX_SYS_N_RSEGS); + ut_ad(offset < 65536); - return(ut_dulint_create(is_insert * 128 * 256 * 256 - + rseg_id * 256 * 256 - + (page_no / 256) / 256, - (page_no % (256 * 256)) * 256 * 256 - + offset)); + roll_ptr = (roll_ptr_t) is_insert << 55 + | (roll_ptr_t) rseg_id << 48 + | (roll_ptr_t) page_no << 16 + | offset; + return(roll_ptr); } /***********************************************************************//** @@ -64,24 +67,20 @@ trx_undo_decode_roll_ptr( ulint* offset) /*!< out: offset of the undo entry within page */ { - ulint low; - ulint high; #if DATA_ROLL_PTR_LEN != 7 # error "DATA_ROLL_PTR_LEN != 7" #endif #if TRUE != 1 # error "TRUE != 1" #endif - high = ut_dulint_get_high(roll_ptr); - low = ut_dulint_get_low(roll_ptr); - - *offset = low % (256 * 256); - - *is_insert = high / (256 * 256 * 128); /* TRUE == 1 */ - *rseg_id = (high / (256 * 256)) % 128; - - *page_no = (high % (256 * 256)) * 256 * 256 - + (low / 256) / 256; + ut_ad(roll_ptr < (1ULL << 56)); + *offset = (ulint) roll_ptr & 0xFFFF; + roll_ptr >>= 16; + *page_no = (ulint) roll_ptr & 0xFFFFFFFF; + roll_ptr >>= 32; + *rseg_id = (ulint) roll_ptr & 0x7F; + roll_ptr >>= 7; + *is_insert = (ibool) roll_ptr; /* TRUE==1 */ } /***********************************************************************//** @@ -93,16 +92,14 @@ trx_undo_roll_ptr_is_insert( /*========================*/ roll_ptr_t roll_ptr) /*!< in: roll pointer */ { - ulint high; #if DATA_ROLL_PTR_LEN != 7 # error "DATA_ROLL_PTR_LEN != 7" #endif #if TRUE != 1 # error "TRUE != 1" #endif - high = ut_dulint_get_high(roll_ptr); - - return(high / (256 * 256 * 128)); + ut_ad(roll_ptr < (1ULL << 56)); + return((ibool) (roll_ptr >> 55)); } #endif /* !UNIV_HOTBACKUP */ diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index ea213486445..ac87942f255 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -46,7 +46,7 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_MAJOR 1 #define INNODB_VERSION_MINOR 1 -#define INNODB_VERSION_BUGFIX 1 +#define INNODB_VERSION_BUGFIX 2 /* The following is the InnoDB version as shown in SELECT plugin_version FROM information_schema.plugins; @@ -310,6 +310,12 @@ management to ensure correct alignment for doubles etc. */ /* Maximum number of parallel threads in a parallelized operation */ #define UNIV_MAX_PARALLELISM 32 +/* The maximum length of a table name. This is the MySQL limit and is +defined in mysql_com.h like NAME_CHAR_LEN*SYSTEM_CHARSET_MBMAXLEN, the +number does not include a terminating '\0'. InnoDB probably can handle +longer names internally */ +#define MAX_TABLE_NAME_LEN 192 + /* UNIVERSAL TYPE DEFINITIONS ========================== @@ -365,8 +371,10 @@ typedef unsigned long long int ullint; /* The 'undefined' value for a ulint */ #define ULINT_UNDEFINED ((ulint)(-1)) +/** The bitmask of 32-bit unsigned integer */ +#define ULINT32_MASK 0xFFFFFFFF /* The undefined 32-bit unsigned integer */ -#define ULINT32_UNDEFINED 0xFFFFFFFF +#define ULINT32_UNDEFINED ULINT32_MASK /* Maximum value for a ulint */ #define ULINT_MAX ((ulint)(-2)) @@ -374,6 +382,9 @@ typedef unsigned long long int ullint; /* Maximum value for ib_uint64_t */ #define IB_ULONGLONG_MAX ((ib_uint64_t) (~0ULL)) +/** The generic InnoDB system object identifier data type */ +typedef ib_uint64_t ib_id_t; + /* This 'ibool' type is used within Innobase. Remember that different included headers may define 'bool' differently. Do not assume that 'bool' is a ulint! */ #define ibool ulint diff --git a/storage/innobase/include/ut0byte.h b/storage/innobase/include/ut0byte.h index f55e2888c60..b99d7175b94 100644 --- a/storage/innobase/include/ut0byte.h +++ b/storage/innobase/include/ut0byte.h @@ -27,145 +27,22 @@ Created 1/20/1994 Heikki Tuuri #define ut0byte_h -#include "univ.i" - -/** Pair of ulint integers. */ -typedef struct dulint_struct dulint; -/** Type definition for a 64-bit unsigned integer, which works also -in 32-bit machines. NOTE! Access the fields only with the accessor -functions. This definition appears here only for the compiler to -know the size of a dulint. */ -struct dulint_struct{ - ulint high; /*!< most significant 32 bits */ - ulint low; /*!< least significant 32 bits */ -}; - -/** Zero value for a dulint */ -extern const dulint ut_dulint_zero; -/** Maximum value for a dulint */ -extern const dulint ut_dulint_max; +#include "univ.i" /*******************************************************//** -Creates a 64-bit dulint out of two ulints. +Creates a 64-bit integer out of two 32-bit integers. @return created dulint */ UNIV_INLINE -dulint -ut_dulint_create( -/*=============*/ - ulint high, /*!< in: high-order 32 bits */ - ulint low); /*!< in: low-order 32 bits */ -/*******************************************************//** -Gets the high-order 32 bits of a dulint. -@return 32 bits in ulint */ -UNIV_INLINE -ulint -ut_dulint_get_high( -/*===============*/ - dulint d); /*!< in: dulint */ -/*******************************************************//** -Gets the low-order 32 bits of a dulint. -@return 32 bits in ulint */ -UNIV_INLINE -ulint -ut_dulint_get_low( -/*==============*/ - dulint d); /*!< in: dulint */ -/*******************************************************//** -Converts a dulint (a struct of 2 ulints) to ib_int64_t, which is a 64-bit -integer type. -@return value in ib_int64_t type */ -UNIV_INLINE -ib_int64_t -ut_conv_dulint_to_longlong( -/*=======================*/ - dulint d); /*!< in: dulint */ -/*******************************************************//** -Tests if a dulint is zero. -@return TRUE if zero */ -UNIV_INLINE -ibool -ut_dulint_is_zero( -/*==============*/ - dulint a); /*!< in: dulint */ -/*******************************************************//** -Compares two dulints. -@return -1 if a < b, 0 if a == b, 1 if a > b */ -UNIV_INLINE -int -ut_dulint_cmp( -/*==========*/ - dulint a, /*!< in: dulint */ - dulint b); /*!< in: dulint */ -/*******************************************************//** -Calculates the max of two dulints. -@return max(a, b) */ -UNIV_INLINE -dulint -ut_dulint_get_max( -/*==============*/ - dulint a, /*!< in: dulint */ - dulint b); /*!< in: dulint */ -/*******************************************************//** -Calculates the min of two dulints. -@return min(a, b) */ -UNIV_INLINE -dulint -ut_dulint_get_min( -/*==============*/ - dulint a, /*!< in: dulint */ - dulint b); /*!< in: dulint */ -/*******************************************************//** -Adds a ulint to a dulint. -@return sum a + b */ -UNIV_INLINE -dulint -ut_dulint_add( +ib_uint64_t +ut_ull_create( /*==========*/ - dulint a, /*!< in: dulint */ - ulint b); /*!< in: ulint */ -/*******************************************************//** -Subtracts a ulint from a dulint. -@return a - b */ -UNIV_INLINE -dulint -ut_dulint_subtract( -/*===============*/ - dulint a, /*!< in: dulint */ - ulint b); /*!< in: ulint, b <= a */ -/*******************************************************//** -Subtracts a dulint from another. NOTE that the difference must be positive -and smaller that 4G. -@return a - b */ -UNIV_INLINE -ulint -ut_dulint_minus( -/*============*/ - dulint a, /*!< in: dulint; NOTE a must be >= b and at most - 2 to power 32 - 1 greater */ - dulint b); /*!< in: dulint */ -/********************************************************//** -Rounds a dulint downward to a multiple of a power of 2. -@return rounded value */ -UNIV_INLINE -dulint -ut_dulint_align_down( -/*=================*/ - dulint n, /*!< in: number to be rounded */ - ulint align_no); /*!< in: align by this number which must be a - power of 2 */ -/********************************************************//** -Rounds a dulint upward to a multiple of a power of 2. -@return rounded value */ -UNIV_INLINE -dulint -ut_dulint_align_up( -/*===============*/ - dulint n, /*!< in: number to be rounded */ - ulint align_no); /*!< in: align by this number which must be a - power of 2 */ + ulint high, /*!< in: high-order 32 bits */ + ulint low) /*!< in: low-order 32 bits */ + __attribute__((const)); + /********************************************************//** -Rounds a dulint downward to a multiple of a power of 2. +Rounds a 64-bit integer downward to a multiple of a power of 2. @return rounded value */ UNIV_INLINE ib_uint64_t @@ -184,34 +61,6 @@ ut_uint64_align_up( ib_uint64_t n, /*!< in: number to be rounded */ ulint align_no); /*!< in: align by this number which must be a power of 2 */ -/*******************************************************//** -Increments a dulint variable by 1. */ -#define UT_DULINT_INC(D)\ -{\ - if ((D).low == 0xFFFFFFFFUL) {\ - (D).high = (D).high + 1;\ - (D).low = 0;\ - } else {\ - (D).low = (D).low + 1;\ - }\ -} -/*******************************************************//** -Tests if two dulints are equal. */ -#define UT_DULINT_EQ(D1, D2) (((D1).low == (D2).low)\ - && ((D1).high == (D2).high)) -#ifdef notdefined -/************************************************************//** -Sort function for dulint arrays. */ -UNIV_INTERN -void -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 */ - /*********************************************************//** The following function rounds up a pointer to the nearest aligned address. @return aligned pointer */ diff --git a/storage/innobase/include/ut0byte.ic b/storage/innobase/include/ut0byte.ic index 3dd51890cb4..e7908efa41a 100644 --- a/storage/innobase/include/ut0byte.ic +++ b/storage/innobase/include/ut0byte.ic @@ -24,260 +24,22 @@ Created 5/30/1994 Heikki Tuuri *******************************************************************/ /*******************************************************//** -Creates a 64-bit dulint out of two ulints. +Creates a 64-bit integer out of two 32-bit integers. @return created dulint */ UNIV_INLINE -dulint -ut_dulint_create( -/*=============*/ +ib_uint64_t +ut_ull_create( +/*==========*/ ulint high, /*!< in: high-order 32 bits */ ulint low) /*!< in: low-order 32 bits */ { - dulint res; - - ut_ad(high <= 0xFFFFFFFF); - ut_ad(low <= 0xFFFFFFFF); - - res.high = high; - res.low = low; - - return(res); -} - -/*******************************************************//** -Gets the high-order 32 bits of a dulint. -@return 32 bits in ulint */ -UNIV_INLINE -ulint -ut_dulint_get_high( -/*===============*/ - dulint d) /*!< in: dulint */ -{ - return(d.high); -} - -/*******************************************************//** -Gets the low-order 32 bits of a dulint. -@return 32 bits in ulint */ -UNIV_INLINE -ulint -ut_dulint_get_low( -/*==============*/ - dulint d) /*!< in: dulint */ -{ - return(d.low); -} - -/*******************************************************//** -Converts a dulint (a struct of 2 ulints) to ib_int64_t, which is a 64-bit -integer type. -@return value in ib_int64_t type */ -UNIV_INLINE -ib_int64_t -ut_conv_dulint_to_longlong( -/*=======================*/ - dulint d) /*!< in: dulint */ -{ - return((ib_int64_t)d.low - + (((ib_int64_t)d.high) << 32)); -} - -/*******************************************************//** -Tests if a dulint is zero. -@return TRUE if zero */ -UNIV_INLINE -ibool -ut_dulint_is_zero( -/*==============*/ - dulint a) /*!< in: dulint */ -{ - if ((a.low == 0) && (a.high == 0)) { - - return(TRUE); - } - - return(FALSE); -} - -/*******************************************************//** -Compares two dulints. -@return -1 if a < b, 0 if a == b, 1 if a > b */ -UNIV_INLINE -int -ut_dulint_cmp( -/*==========*/ - dulint a, /*!< in: dulint */ - dulint b) /*!< in: dulint */ -{ - if (a.high > b.high) { - return(1); - } else if (a.high < b.high) { - return(-1); - } else if (a.low > b.low) { - return(1); - } else if (a.low < b.low) { - return(-1); - } else { - return(0); - } -} - -/*******************************************************//** -Calculates the max of two dulints. -@return max(a, b) */ -UNIV_INLINE -dulint -ut_dulint_get_max( -/*==============*/ - dulint a, /*!< in: dulint */ - dulint b) /*!< in: dulint */ -{ - if (ut_dulint_cmp(a, b) > 0) { - - return(a); - } - - return(b); -} - -/*******************************************************//** -Calculates the min of two dulints. -@return min(a, b) */ -UNIV_INLINE -dulint -ut_dulint_get_min( -/*==============*/ - dulint a, /*!< in: dulint */ - dulint b) /*!< in: dulint */ -{ - if (ut_dulint_cmp(a, b) > 0) { - - return(b); - } - - return(a); -} - -/*******************************************************//** -Adds a ulint to a dulint. -@return sum a + b */ -UNIV_INLINE -dulint -ut_dulint_add( -/*==========*/ - dulint a, /*!< in: dulint */ - ulint b) /*!< in: ulint */ -{ - if (0xFFFFFFFFUL - b >= a.low) { - a.low += b; - - return(a); - } - - a.low = a.low - (0xFFFFFFFFUL - b) - 1; - - a.high++; - - return(a); -} - -/*******************************************************//** -Subtracts a ulint from a dulint. -@return a - b */ -UNIV_INLINE -dulint -ut_dulint_subtract( -/*===============*/ - dulint a, /*!< in: dulint */ - ulint b) /*!< in: ulint, b <= a */ -{ - if (a.low >= b) { - a.low -= b; - - return(a); - } - - b -= a.low + 1; - - a.low = 0xFFFFFFFFUL - b; - - ut_ad(a.high > 0); - - a.high--; - - return(a); -} - -/*******************************************************//** -Subtracts a dulint from another. NOTE that the difference must be positive -and smaller that 4G. -@return a - b */ -UNIV_INLINE -ulint -ut_dulint_minus( -/*============*/ - dulint a, /*!< in: dulint; NOTE a must be >= b and at most - 2 to power 32 - 1 greater */ - dulint b) /*!< in: dulint */ -{ - ulint diff; - - if (a.high == b.high) { - ut_ad(a.low >= b.low); - - return(a.low - b.low); - } - - ut_ad(a.high == b.high + 1); - - diff = (ulint)(0xFFFFFFFFUL - b.low); - diff += 1 + a.low; - - ut_ad(diff > a.low); - - return(diff); -} - -/********************************************************//** -Rounds a dulint downward to a multiple of a power of 2. -@return rounded value */ -UNIV_INLINE -dulint -ut_dulint_align_down( -/*=================*/ - dulint n, /*!< in: number to be rounded */ - ulint align_no) /*!< in: align by this number which must be a - power of 2 */ -{ - ulint low, high; - - ut_ad(align_no > 0); - ut_ad(((align_no - 1) & align_no) == 0); - - low = ut_dulint_get_low(n); - high = ut_dulint_get_high(n); - - low = low & ~(align_no - 1); - - return(ut_dulint_create(high, low)); -} - -/********************************************************//** -Rounds a dulint upward to a multiple of a power of 2. -@return rounded value */ -UNIV_INLINE -dulint -ut_dulint_align_up( -/*===============*/ - dulint n, /*!< in: number to be rounded */ - ulint align_no) /*!< in: align by this number which must be a - power of 2 */ -{ - return(ut_dulint_align_down(ut_dulint_add(n, align_no - 1), align_no)); + ut_ad(high <= ULINT32_MASK); + ut_ad(low <= ULINT32_MASK); + return(((ib_uint64_t) high) << 32 | low); } /********************************************************//** -Rounds ib_uint64_t downward to a multiple of a power of 2. +Rounds a 64-bit integer downward to a multiple of a power of 2. @return rounded value */ UNIV_INLINE ib_uint64_t diff --git a/storage/innobase/include/ut0rnd.h b/storage/innobase/include/ut0rnd.h index ce5152e942f..946b1117af7 100644 --- a/storage/innobase/include/ut0rnd.h +++ b/storage/innobase/include/ut0rnd.h @@ -97,13 +97,13 @@ ut_fold_ulint_pair( ulint n2) /*!< in: ulint */ __attribute__((const)); /*************************************************************//** -Folds a dulint. +Folds a 64-bit integer. @return folded value */ UNIV_INLINE ulint -ut_fold_dulint( -/*===========*/ - dulint d) /*!< in: dulint */ +ut_fold_ull( +/*========*/ + ib_uint64_t d) /*!< in: 64-bit integer */ __attribute__((const)); /*************************************************************//** Folds a character string ending in the null character. diff --git a/storage/innobase/include/ut0rnd.ic b/storage/innobase/include/ut0rnd.ic index c3dbd86923c..a6ba4ec2ba2 100644 --- a/storage/innobase/include/ut0rnd.ic +++ b/storage/innobase/include/ut0rnd.ic @@ -173,16 +173,16 @@ ut_fold_ulint_pair( } /*************************************************************//** -Folds a dulint. +Folds a 64-bit integer. @return folded value */ UNIV_INLINE ulint -ut_fold_dulint( -/*===========*/ - dulint d) /*!< in: dulint */ +ut_fold_ull( +/*========*/ + ib_uint64_t d) /*!< in: 64-bit integer */ { - return(ut_fold_ulint_pair(ut_dulint_get_low(d), - ut_dulint_get_high(d))); + return(ut_fold_ulint_pair((ulint) d & ULINT32_MASK, + (ulint) (d >> 32))); } /*************************************************************//** diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index 0e57a52666e..dcfca1b6315 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -468,7 +468,7 @@ lock_check_trx_id_sanity( /* A sanity check: the trx_id in rec must be smaller than the global trx id counter */ - if (ut_dulint_cmp(trx_id, trx_sys->max_trx_id) >= 0) { + if (UNIV_UNLIKELY(trx_id >= trx_sys->max_trx_id)) { ut_print_timestamp(stderr); fputs(" InnoDB: Error: transaction id associated" " with record\n", @@ -481,8 +481,7 @@ lock_check_trx_id_sanity( " global trx id counter " TRX_ID_FMT "!\n" "InnoDB: The table is corrupt. You have to do" " dump + drop + reimport.\n", - TRX_ID_PREP_PRINTF(trx_id), - TRX_ID_PREP_PRINTF(trx_sys->max_trx_id)); + (ullint) trx_id, (ullint) trx_sys->max_trx_id); is_ok = FALSE; } @@ -556,9 +555,9 @@ 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)); + ut_ad(max_trx_id); - return(ut_dulint_cmp(max_trx_id, view->up_limit_id) < 0); + return(max_trx_id < view->up_limit_id); } /*********************************************************************//** @@ -1594,8 +1593,7 @@ lock_sec_rec_some_has_impl_off_kernel( max trx id to the log, and therefore during recovery, this value for a page may be incorrect. */ - if (!(ut_dulint_cmp(page_get_max_trx_id(page), - trx_list_get_min_trx_id()) >= 0) + if (page_get_max_trx_id(page) < trx_list_get_min_trx_id() && !recv_recovery_is_on()) { return(NULL); @@ -1820,8 +1818,8 @@ lock_rec_enqueue_waiting( #ifdef UNIV_DEBUG if (lock_print_waits) { - fprintf(stderr, "Lock wait for trx %lu in index ", - (ulong) ut_dulint_get_low(trx->id)); + fprintf(stderr, "Lock wait for trx " TRX_ID_FMT " in index ", + (ullint) trx->id); ut_print_name(stderr, trx, FALSE, index->name); } #endif /* UNIV_DEBUG */ @@ -2193,8 +2191,8 @@ lock_grant( #ifdef UNIV_DEBUG if (lock_print_waits) { - fprintf(stderr, "Lock wait for trx %lu ends\n", - (ulong) ut_dulint_get_low(lock->trx->id)); + fprintf(stderr, "Lock wait for trx " TRX_ID_FMT " ends\n", + (ullint) lock->trx->id); } #endif /* UNIV_DEBUG */ @@ -3486,8 +3484,7 @@ lock_deadlock_recursive( } #endif /* UNIV_DEBUG */ - if (trx_weight_cmp(wait_lock->trx, - start) >= 0) { + if (trx_weight_ge(wait_lock->trx, start)) { /* Our recursion starting point transaction is 'smaller', let us choose 'start' as the victim and roll @@ -4023,7 +4020,7 @@ lock_release_off_kernel( ut_ad(lock_get_type_low(lock) & LOCK_TABLE); if (lock_get_mode(lock) != LOCK_IS - && !ut_dulint_is_zero(trx->undo_no)) { + && trx->undo_no != 0) { /* The trx may have modified the table. We block the use of the MySQL query cache for @@ -4222,8 +4219,7 @@ lock_table_print( fputs("TABLE LOCK table ", file); ut_print_name(file, lock->trx, TRUE, lock->un_member.tab_lock.table->name); - fprintf(file, " trx id " TRX_ID_FMT, - TRX_ID_PREP_PRINTF(lock->trx->id)); + fprintf(file, " trx id " TRX_ID_FMT, (ullint) lock->trx->id); if (lock_get_mode(lock) == LOCK_S) { fputs(" lock mode S", file); @@ -4276,8 +4272,7 @@ lock_rec_print( (ulong) space, (ulong) page_no, (ulong) lock_rec_get_n_bits(lock)); dict_index_name_print(file, lock->trx, lock->index); - fprintf(file, " trx id " TRX_ID_FMT, - TRX_ID_PREP_PRINTF(lock->trx->id)); + fprintf(file, " trx id " TRX_ID_FMT, (ullint) lock->trx->id); if (lock_get_mode(lock) == LOCK_S) { fputs(" lock mode S", file); @@ -4412,13 +4407,13 @@ lock_print_info_summary( "------------\n", file); fprintf(file, "Trx id counter " TRX_ID_FMT "\n", - TRX_ID_PREP_PRINTF(trx_sys->max_trx_id)); + (ullint) trx_sys->max_trx_id); fprintf(file, "Purge done for trx's n:o < " TRX_ID_FMT " undo n:o < " TRX_ID_FMT "\n", - TRX_ID_PREP_PRINTF(purge_sys->purge_trx_no), - TRX_ID_PREP_PRINTF(purge_sys->purge_undo_no)); + (ullint) purge_sys->purge_trx_no, + (ullint) purge_sys->purge_undo_no); fprintf(file, "History list length %lu\n", @@ -4495,10 +4490,8 @@ loop: "Trx read view will not see trx with" " id >= " TRX_ID_FMT ", sees < " TRX_ID_FMT "\n", - TRX_ID_PREP_PRINTF( - trx->read_view->low_limit_id), - TRX_ID_PREP_PRINTF( - trx->read_view->up_limit_id)); + (ullint) trx->read_view->low_limit_id, + (ullint) trx->read_view->up_limit_id); } if (trx->que_state == TRX_QUE_LOCK_WAIT) { @@ -4912,12 +4905,12 @@ ibool lock_validate(void) /*===============*/ { - lock_t* lock; - trx_t* trx; - dulint limit; - ulint space; - ulint page_no; - ulint i; + lock_t* lock; + trx_t* trx; + ib_uint64_t limit; + ulint space; + ulint page_no; + ulint i; lock_mutex_enter_kernel(); @@ -4941,20 +4934,21 @@ lock_validate(void) for (i = 0; i < hash_get_n_cells(lock_sys->rec_hash); i++) { - limit = ut_dulint_zero; + limit = 0; for (;;) { lock = HASH_GET_FIRST(lock_sys->rec_hash, i); while (lock) { + ib_uint64_t space_page; ut_a(trx_in_trx_list(lock->trx)); space = lock->un_member.rec_lock.space; page_no = lock->un_member.rec_lock.page_no; - if (ut_dulint_cmp( - ut_dulint_create(space, page_no), - limit) >= 0) { + space_page = ut_ull_create(space, page_no); + + if (space_page >= limit) { break; } @@ -4974,7 +4968,7 @@ lock_validate(void) lock_mutex_enter_kernel(); - limit = ut_dulint_create(space, page_no + 1); + limit = ut_ull_create(space, page_no + 1); } } @@ -5348,8 +5342,7 @@ lock_sec_rec_read_check_and_lock( if the max trx id for the page >= min trx id for the trx list or a database recovery is running. */ - if (((ut_dulint_cmp(page_get_max_trx_id(block->frame), - trx_list_get_min_trx_id()) >= 0) + if ((page_get_max_trx_id(block->frame) >= trx_list_get_min_trx_id() || recv_recovery_is_on()) && !page_rec_is_supremum(rec)) { @@ -5572,12 +5565,12 @@ lock_get_type( Gets the id of the transaction owning a lock. @return transaction id */ UNIV_INTERN -ullint +trx_id_t lock_get_trx_id( /*============*/ const lock_t* lock) /*!< in: lock */ { - return(trx_get_id(lock->trx)); + return(lock->trx->id); } /*******************************************************************//** @@ -5671,7 +5664,7 @@ lock_get_table( Gets the id of the table on which the lock is. @return id of the table */ UNIV_INTERN -ullint +table_id_t lock_get_table_id( /*==============*/ const lock_t* lock) /*!< in: lock */ @@ -5680,7 +5673,7 @@ lock_get_table_id( table = lock_get_table(lock); - return((ullint)ut_conv_dulint_to_longlong(table->id)); + return(table->id); } /*******************************************************************//** diff --git a/storage/innobase/log/log0log.c b/storage/innobase/log/log0log.c index 386f9630baa..401cede1d8f 100644 --- a/storage/innobase/log/log0log.c +++ b/storage/innobase/log/log0log.c @@ -1166,7 +1166,7 @@ log_group_file_header_flush( buf = *(group->file_header_bufs + nth_file); mach_write_to_4(buf + LOG_GROUP_ID, group->id); - mach_write_ull(buf + LOG_FILE_START_LSN, start_lsn); + mach_write_to_8(buf + LOG_FILE_START_LSN, start_lsn); /* Wipe over possible label of ibbackup --restore */ memcpy(buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, " ", 4); @@ -1769,8 +1769,8 @@ log_group_checkpoint( buf = group->checkpoint_buf; - mach_write_ull(buf + LOG_CHECKPOINT_NO, log_sys->next_checkpoint_no); - mach_write_ull(buf + LOG_CHECKPOINT_LSN, log_sys->next_checkpoint_lsn); + mach_write_to_8(buf + LOG_CHECKPOINT_NO, log_sys->next_checkpoint_no); + mach_write_to_8(buf + LOG_CHECKPOINT_LSN, log_sys->next_checkpoint_lsn); mach_write_to_4(buf + LOG_CHECKPOINT_OFFSET, log_group_calc_lsn_offset( @@ -1790,9 +1790,9 @@ log_group_checkpoint( } } - mach_write_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN, archived_lsn); + mach_write_to_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN, archived_lsn); #else /* UNIV_LOG_ARCHIVE */ - mach_write_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN, IB_ULONGLONG_MAX); + mach_write_to_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN, IB_ULONGLONG_MAX); #endif /* UNIV_LOG_ARCHIVE */ for (i = 0; i < LOG_MAX_N_GROUPS; i++) { @@ -1884,7 +1884,7 @@ log_reset_first_header_and_checkpoint( ib_uint64_t lsn; mach_write_to_4(hdr_buf + LOG_GROUP_ID, 0); - mach_write_ull(hdr_buf + LOG_FILE_START_LSN, start); + mach_write_to_8(hdr_buf + LOG_FILE_START_LSN, start); lsn = start + LOG_BLOCK_HDR_SIZE; @@ -1896,15 +1896,15 @@ log_reset_first_header_and_checkpoint( + (sizeof "ibbackup ") - 1)); buf = hdr_buf + LOG_CHECKPOINT_1; - mach_write_ull(buf + LOG_CHECKPOINT_NO, 0); - mach_write_ull(buf + LOG_CHECKPOINT_LSN, lsn); + mach_write_to_8(buf + LOG_CHECKPOINT_NO, 0); + mach_write_to_8(buf + LOG_CHECKPOINT_LSN, lsn); mach_write_to_4(buf + LOG_CHECKPOINT_OFFSET, LOG_FILE_HDR_SIZE + LOG_BLOCK_HDR_SIZE); mach_write_to_4(buf + LOG_CHECKPOINT_LOG_BUF_SIZE, 2 * 1024 * 1024); - mach_write_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN, IB_ULONGLONG_MAX); + mach_write_to_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN, IB_ULONGLONG_MAX); fold = ut_fold_binary(buf, LOG_CHECKPOINT_CHECKSUM_1); mach_write_to_4(buf + LOG_CHECKPOINT_CHECKSUM_1, fold); @@ -2272,7 +2272,7 @@ log_group_archive_file_header_write( buf = *(group->archive_file_header_bufs + nth_file); mach_write_to_4(buf + LOG_GROUP_ID, group->id); - mach_write_ull(buf + LOG_FILE_START_LSN, start_lsn); + mach_write_to_8(buf + LOG_FILE_START_LSN, start_lsn); mach_write_to_4(buf + LOG_FILE_NO, file_no); mach_write_to_4(buf + LOG_FILE_ARCH_COMPLETED, FALSE); @@ -2308,7 +2308,7 @@ log_group_archive_completed_header_write( buf = *(group->archive_file_header_bufs + nth_file); mach_write_to_4(buf + LOG_FILE_ARCH_COMPLETED, TRUE); - mach_write_ull(buf + LOG_FILE_END_LSN, end_lsn); + mach_write_to_8(buf + LOG_FILE_END_LSN, end_lsn); dest_offset = nth_file * group->file_size + LOG_FILE_ARCH_COMPLETED; diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c index f47f47e6a68..f983c4fb974 100644 --- a/storage/innobase/log/log0recv.c +++ b/storage/innobase/log/log0recv.c @@ -704,11 +704,11 @@ recv_find_max_checkpoint( group->state = LOG_GROUP_OK; - group->lsn = mach_read_ull( + group->lsn = mach_read_from_8( buf + LOG_CHECKPOINT_LSN); group->lsn_offset = mach_read_from_4( buf + LOG_CHECKPOINT_OFFSET); - checkpoint_no = mach_read_ull( + checkpoint_no = mach_read_from_8( buf + LOG_CHECKPOINT_NO); #ifdef UNIV_DEBUG @@ -778,14 +778,14 @@ recv_read_cp_info_for_backup( cp_buf = hdr + LOG_CHECKPOINT_1; if (recv_check_cp_is_consistent(cp_buf)) { - max_cp_no = mach_read_ull(cp_buf + LOG_CHECKPOINT_NO); + max_cp_no = mach_read_from_8(cp_buf + LOG_CHECKPOINT_NO); max_cp = LOG_CHECKPOINT_1; } cp_buf = hdr + LOG_CHECKPOINT_2; if (recv_check_cp_is_consistent(cp_buf)) { - if (mach_read_ull(cp_buf + LOG_CHECKPOINT_NO) > max_cp_no) { + if (mach_read_from_8(cp_buf + LOG_CHECKPOINT_NO) > max_cp_no) { max_cp = LOG_CHECKPOINT_2; } } @@ -796,7 +796,7 @@ recv_read_cp_info_for_backup( cp_buf = hdr + max_cp; - *lsn = mach_read_ull(cp_buf + LOG_CHECKPOINT_LSN); + *lsn = mach_read_from_8(cp_buf + LOG_CHECKPOINT_LSN); *offset = mach_read_from_4(cp_buf + LOG_CHECKPOINT_OFFSET); /* If the user is running a pre-3.23.50 version of InnoDB, its @@ -816,9 +816,9 @@ recv_read_cp_info_for_backup( /* fprintf(stderr, "fsp limit %lu MB\n", *fsp_limit); */ - *cp_no = mach_read_ull(cp_buf + LOG_CHECKPOINT_NO); + *cp_no = mach_read_from_8(cp_buf + LOG_CHECKPOINT_NO); - *first_header_lsn = mach_read_ull(hdr + LOG_FILE_START_LSN); + *first_header_lsn = mach_read_from_8(hdr + LOG_FILE_START_LSN); return(TRUE); } @@ -1541,7 +1541,7 @@ recv_recover_page_func( #endif /* !UNIV_HOTBACKUP */ /* Read the newest modification lsn from the page */ - page_lsn = mach_read_ull(page + FIL_PAGE_LSN); + page_lsn = mach_read_from_8(page + FIL_PAGE_LSN); #ifndef UNIV_HOTBACKUP /* It may be that the page has been modified in the buffer @@ -1616,14 +1616,14 @@ recv_recover_page_func( block, &mtr); end_lsn = recv->start_lsn + recv->len; - mach_write_ull(FIL_PAGE_LSN + page, end_lsn); - mach_write_ull(UNIV_PAGE_SIZE - - FIL_PAGE_END_LSN_OLD_CHKSUM - + page, end_lsn); + mach_write_to_8(FIL_PAGE_LSN + page, end_lsn); + mach_write_to_8(UNIV_PAGE_SIZE + - FIL_PAGE_END_LSN_OLD_CHKSUM + + page, end_lsn); if (page_zip) { - mach_write_ull(FIL_PAGE_LSN - + page_zip->data, end_lsn); + mach_write_to_8(FIL_PAGE_LSN + + page_zip->data, end_lsn); } } @@ -1995,7 +1995,7 @@ recv_apply_log_recs_for_backup(void) buf_flush_init_for_writing( block->frame, buf_block_get_page_zip(block), - mach_read_ull(block->frame + FIL_PAGE_LSN)); + mach_read_from_8(block->frame + FIL_PAGE_LSN)); if (zip_size) { error = fil_io(OS_FILE_WRITE, TRUE, @@ -2961,9 +2961,9 @@ recv_recovery_from_checkpoint_start_func( buf = log_sys->checkpoint_buf; - checkpoint_lsn = mach_read_ull(buf + LOG_CHECKPOINT_LSN); - checkpoint_no = mach_read_ull(buf + LOG_CHECKPOINT_NO); - archived_lsn = mach_read_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN); + checkpoint_lsn = mach_read_from_8(buf + LOG_CHECKPOINT_LSN); + checkpoint_no = mach_read_from_8(buf + LOG_CHECKPOINT_NO); + archived_lsn = mach_read_from_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN); /* Read the first log file header to print a note if this is a recovery from a restored InnoDB Hot Backup */ @@ -3613,8 +3613,8 @@ ask_again: return(TRUE); } - start_lsn = mach_read_ull(buf + LOG_FILE_START_LSN); - file_end_lsn = mach_read_ull(buf + LOG_FILE_END_LSN); + start_lsn = mach_read_from_8(buf + LOG_FILE_START_LSN); + file_end_lsn = mach_read_from_8(buf + LOG_FILE_END_LSN); if (!recv_sys->scanned_lsn) { diff --git a/storage/innobase/mach/mach0data.c b/storage/innobase/mach/mach0data.c index e030ce9aadf..647d9e57384 100644 --- a/storage/innobase/mach/mach0data.c +++ b/storage/innobase/mach/mach0data.c @@ -92,43 +92,3 @@ mach_parse_compressed( return(ptr + 5); } } - -/*********************************************************//** -Reads a dulint in a compressed form if the log record fully contains it. -@return pointer to end of the stored field, NULL if not complete */ -UNIV_INTERN -byte* -mach_dulint_parse_compressed( -/*=========================*/ - byte* ptr, /*!< in: pointer to buffer from where to read */ - byte* end_ptr,/*!< in: pointer to end of the buffer */ - dulint* val) /*!< out: read value */ -{ - ulint high; - ulint low; - ulint size; - - ut_ad(ptr && end_ptr && val); - - if (end_ptr < ptr + 5) { - - return(NULL); - } - - high = mach_read_compressed(ptr); - - size = mach_get_compressed_size(high); - - ptr += size; - - if (end_ptr < ptr + 4) { - - return(NULL); - } - - low = mach_read_from_4(ptr); - - *val = ut_dulint_create(high, low); - - return(ptr + 4); -} diff --git a/storage/innobase/mtr/mtr0log.c b/storage/innobase/mtr/mtr0log.c index 3f3dab36b76..04eeb4391cd 100644 --- a/storage/innobase/mtr/mtr0log.c +++ b/storage/innobase/mtr/mtr0log.c @@ -133,7 +133,7 @@ mlog_parse_initial_log_record( } /********************************************************//** -Parses a log record written by mlog_write_ulint or mlog_write_dulint. +Parses a log record written by mlog_write_ulint or mlog_write_ull. @return parsed record end, NULL if not a complete record or a corrupt record */ UNIV_INTERN byte* @@ -145,9 +145,9 @@ mlog_parse_nbytes( byte* page, /*!< in: page where to apply the log record, or NULL */ void* page_zip)/*!< in/out: compressed page, or NULL */ { - ulint offset; - ulint val; - dulint dval; + ulint offset; + ulint val; + ib_uint64_t dval; ut_a(type <= MLOG_8BYTES); ut_a(!page || !page_zip || fil_page_get_type(page) != FIL_PAGE_INDEX); @@ -167,7 +167,7 @@ mlog_parse_nbytes( } if (type == MLOG_8BYTES) { - ptr = mach_dulint_parse_compressed(ptr, end_ptr, &dval); + ptr = mach_ull_parse_compressed(ptr, end_ptr, &dval); if (ptr == NULL) { @@ -290,11 +290,11 @@ Writes 8 bytes to a file page buffered in the buffer pool. Writes the corresponding log record to the mini-transaction log. */ UNIV_INTERN void -mlog_write_dulint( -/*==============*/ - byte* ptr, /*!< in: pointer where to write */ - dulint val, /*!< in: value to write */ - mtr_t* mtr) /*!< in: mini-transaction handle */ +mlog_write_ull( +/*===========*/ + byte* ptr, /*!< in: pointer where to write */ + ib_uint64_t val, /*!< in: value to write */ + mtr_t* mtr) /*!< in: mini-transaction handle */ { byte* log_ptr; @@ -316,7 +316,7 @@ mlog_write_dulint( mach_write_to_2(log_ptr, page_offset(ptr)); log_ptr += 2; - log_ptr += mach_dulint_write_compressed(log_ptr, val); + log_ptr += mach_ull_write_compressed(log_ptr, val); mlog_close(mtr, log_ptr); } diff --git a/storage/innobase/mtr/mtr0mtr.c b/storage/innobase/mtr/mtr0mtr.c index b01462f6b9b..74d04a22b86 100644 --- a/storage/innobase/mtr/mtr0mtr.c +++ b/storage/innobase/mtr/mtr0mtr.c @@ -337,9 +337,12 @@ mtr_memo_release( slot = dyn_array_get_element(memo, offset); if (object == slot->object && type == slot->type) { - if (mtr->modifications) { - mtr_memo_slot_note_modification(mtr, slot); - } + + /* We cannot release a page that has been written + to in the middle of a mini-transaction. */ + + ut_ad(!(mtr->modifications + && slot->type == MTR_MEMO_PAGE_X_FIX)); mtr_memo_slot_release(mtr, slot); @@ -375,23 +378,6 @@ mtr_read_ulint( } } -/********************************************************//** -Reads 8 bytes from a file page buffered in the buffer pool. -@return value read */ -UNIV_INTERN -dulint -mtr_read_dulint( -/*============*/ - const byte* ptr, /*!< in: pointer from where to read */ - mtr_t* mtr __attribute__((unused))) - /*!< in: mini-transaction handle */ -{ - ut_ad(mtr->state == MTR_ACTIVE); - ut_ad(mtr_memo_contains_page(mtr, ptr, MTR_MEMO_PAGE_S_FIX) - || mtr_memo_contains_page(mtr, ptr, MTR_MEMO_PAGE_X_FIX)); - return(mach_read_from_8(ptr)); -} - #ifdef UNIV_DEBUG # ifndef UNIV_HOTBACKUP /**********************************************************//** diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c index a7117386608..65c5d65f860 100644 --- a/storage/innobase/os/os0file.c +++ b/storage/innobase/os/os0file.c @@ -183,7 +183,7 @@ struct os_aio_slot_struct{ which pending aio operation was completed */ #ifdef WIN_ASYNC_IO - os_event_t event; /*!< event object we need in the + HANDLE handle; /*!< handle object we need in the OVERLAPPED struct */ OVERLAPPED control; /*!< Windows control block for the aio request */ @@ -225,7 +225,7 @@ struct os_aio_array_struct{ aio array outside the ibuf segment */ os_aio_slot_t* slots; /*!< Pointer to the slots in the array */ #ifdef __WIN__ - os_native_event_t* native_events; + HANDLE* handles; /*!< Pointer to an array of OS native event handles where we copied the handles from slots, in the same @@ -304,7 +304,8 @@ UNIV_INTERN ulint os_n_pending_reads = 0; /***********************************************************************//** Gets the operating system version. Currently works only on Windows. -@return OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000 */ +@return OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000, OS_WINXP, OS_WINVISTA, +OS_WIN7. */ UNIV_INTERN ulint os_get_os_version(void) @@ -322,10 +323,18 @@ os_get_os_version(void) } else if (os_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { return(OS_WIN95); } else if (os_info.dwPlatformId == VER_PLATFORM_WIN32_NT) { - if (os_info.dwMajorVersion <= 4) { - return(OS_WINNT); - } else { - return(OS_WIN2000); + switch (os_info.dwMajorVersion) { + case 3: + case 4: + return OS_WINNT; + case 5: + return (os_info.dwMinorVersion == 0) ? OS_WIN2000 + : OS_WINXP; + case 6: + return (os_info.dwMinorVersion == 0) ? OS_WINVISTA + : OS_WIN7; + default: + return OS_WIN7; } } else { ut_error; @@ -673,10 +682,10 @@ os_io_init_simple(void) { ulint i; - os_file_count_mutex = os_mutex_create(NULL); + os_file_count_mutex = os_mutex_create(); for (i = 0; i < OS_FILE_N_SEEK_MUTEXES; i++) { - os_file_seek_mutexes[i] = os_mutex_create(NULL); + os_file_seek_mutexes[i] = os_mutex_create(); } } @@ -3217,7 +3226,7 @@ os_aio_array_create( array = ut_malloc(sizeof(os_aio_array_t)); - array->mutex = os_mutex_create(NULL); + array->mutex = os_mutex_create(); array->not_full = os_event_create(NULL); array->is_empty = os_event_create(NULL); @@ -3229,10 +3238,13 @@ os_aio_array_create( array->cur_seg = 0; array->slots = ut_malloc(n * sizeof(os_aio_slot_t)); #ifdef __WIN__ - array->native_events = ut_malloc(n * sizeof(os_native_event_t)); + array->handles = ut_malloc(n * sizeof(HANDLE)); #endif #if defined(LINUX_NATIVE_AIO) + array->aio_ctx = NULL; + array->aio_events = NULL; + /* If we are not using native aio interface then skip this part of initialization. */ if (!srv_use_native_aio) { @@ -3270,13 +3282,13 @@ skip_native_aio: slot->pos = i; slot->reserved = FALSE; #ifdef WIN_ASYNC_IO - slot->event = os_event_create(NULL); + slot->handle = CreateEvent(NULL,TRUE, FALSE, NULL); over = &(slot->control); - over->hEvent = slot->event->handle; + over->hEvent = slot->handle; - *((array->native_events) + i) = over->hEvent; + *((array->handles) + i) = over->hEvent; #elif defined(LINUX_NATIVE_AIO) @@ -3302,17 +3314,24 @@ os_aio_array_free( for (i = 0; i < array->n_slots; i++) { os_aio_slot_t* slot = os_aio_array_get_nth_slot(array, i); - os_event_free(slot->event); + CloseHandle(slot->handle); } #endif /* WIN_ASYNC_IO */ #ifdef __WIN__ - ut_free(array->native_events); + ut_free(array->handles); #endif /* __WIN__ */ os_mutex_free(array->mutex); os_event_free(array->not_full); os_event_free(array->is_empty); +#if defined(LINUX_NATIVE_AIO) + if (srv_use_native_aio) { + ut_free(array->aio_events); + ut_free(array->aio_ctx); + } +#endif /* LINUX_NATIVE_AIO */ + ut_free(array->slots); ut_free(array); } @@ -3453,7 +3472,7 @@ os_aio_array_wake_win_aio_at_shutdown( for (i = 0; i < array->n_slots; i++) { - os_event_set((array->slots + i)->event); + SetEvent((array->slots + i)->handle); } } #endif @@ -3692,7 +3711,7 @@ found: control = &(slot->control); control->Offset = (DWORD)offset; control->OffsetHigh = (DWORD)offset_high; - os_event_reset(slot->event); + ResetEvent(slot->handle); #elif defined(LINUX_NATIVE_AIO) @@ -3764,7 +3783,7 @@ os_aio_array_free_slot( #ifdef WIN_ASYNC_IO - os_event_reset(slot->event); + ResetEvent(slot->handle); #elif defined(LINUX_NATIVE_AIO) @@ -4198,13 +4217,20 @@ os_aio_windows_handle( n = array->n_slots / array->n_segments; if (array == os_aio_sync_array) { - os_event_wait(os_aio_array_get_nth_slot(array, pos)->event); + WaitForSingleObject( + os_aio_array_get_nth_slot(array, pos)->handle, + INFINITE); i = pos; } else { srv_set_io_thread_op_info(orig_seg, "wait Windows aio"); - i = os_event_wait_multiple(n, - (array->native_events) - + segment * n); + i = WaitForMultipleObjects((DWORD) n, + array->handles + segment * n, + FALSE, + INFINITE); + } + + if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) { + os_thread_exit(NULL); } os_mutex_enter(array->mutex); diff --git a/storage/innobase/os/os0sync.c b/storage/innobase/os/os0sync.c index 60467242e14..3c70e93aae0 100644 --- a/storage/innobase/os/os0sync.c +++ b/storage/innobase/os/os0sync.c @@ -35,6 +35,7 @@ Created 9/6/1995 Heikki Tuuri #include "ut0mem.h" #include "srv0start.h" +#include "srv0srv.h" /* Type definition for an operating system mutex struct */ struct os_mutex_struct{ @@ -76,6 +77,155 @@ event embedded inside a mutex, on free, this generates a recursive call. This version of the free event function doesn't acquire the global lock */ static void os_event_free_internal(os_event_t event); +/* On Windows (Vista and later), load function pointers for condition +variable handling. Those functions are not available in prior versions, +so we have to use them via runtime loading, as long as we support XP. */ +static void os_cond_module_init(void); + +#ifdef __WIN__ +/* Prototypes and function pointers for condition variable functions */ +typedef VOID (WINAPI* InitializeConditionVariableProc) + (PCONDITION_VARIABLE ConditionVariable); +static InitializeConditionVariableProc initialize_condition_variable; + +typedef BOOL (WINAPI* SleepConditionVariableCSProc) + (PCONDITION_VARIABLE ConditionVariable, + PCRITICAL_SECTION CriticalSection, + DWORD dwMilliseconds); +static SleepConditionVariableCSProc sleep_condition_variable; + +typedef VOID (WINAPI* WakeAllConditionVariableProc) + (PCONDITION_VARIABLE ConditionVariable); +static WakeAllConditionVariableProc wake_all_condition_variable; + +typedef VOID (WINAPI* WakeConditionVariableProc) + (PCONDITION_VARIABLE ConditionVariable); +static WakeConditionVariableProc wake_condition_variable; +#endif + +/*********************************************************//** +Initialitze condition variable */ +UNIV_INLINE +void +os_cond_init( +/*=========*/ + os_cond_t* cond) /*!< in: condition variable. */ +{ + ut_a(cond); + +#ifdef __WIN__ + ut_a(initialize_condition_variable != NULL); + initialize_condition_variable(cond); +#else + ut_a(pthread_cond_init(cond, NULL) == 0); +#endif +} + +/*********************************************************//** +Wait on condition variable */ +UNIV_INLINE +void +os_cond_wait( +/*=========*/ + os_cond_t* cond, /*!< in: condition variable. */ + os_fast_mutex_t* mutex) /*!< in: fast mutex */ +{ + ut_a(cond); + ut_a(mutex); + +#ifdef __WIN__ + ut_a(sleep_condition_variable != NULL); + ut_a(sleep_condition_variable(cond, mutex, INFINITE)); +#else + ut_a(pthread_cond_wait(cond, mutex) == 0); +#endif +} + +/*********************************************************//** +Wakes all threads waiting for condition variable */ +UNIV_INLINE +void +os_cond_broadcast( +/*==============*/ + os_cond_t* cond) /*!< in: condition variable. */ +{ + ut_a(cond); + +#ifdef __WIN__ + ut_a(wake_all_condition_variable != NULL); + wake_all_condition_variable(cond); +#else + ut_a(pthread_cond_broadcast(cond) == 0); +#endif +} + +/*********************************************************//** +Wakes one thread waiting for condition variable */ +UNIV_INLINE +void +os_cond_signal( +/*==========*/ + os_cond_t* cond) /*!< in: condition variable. */ +{ + ut_a(cond); + +#ifdef __WIN__ + ut_a(wake_condition_variable != NULL); + wake_condition_variable(cond); +#else + ut_a(pthread_cond_signal(cond) == 0); +#endif +} + +/*********************************************************//** +Destroys condition variable */ +UNIV_INLINE +void +os_cond_destroy( +/*============*/ + os_cond_t* cond) /*!< in: condition variable. */ +{ +#ifdef __WIN__ + /* Do nothing */ +#else + ut_a(pthread_cond_destroy(cond) == 0); +#endif +} + +/*********************************************************//** +On Windows (Vista and later), load function pointers for condition variable +handling. Those functions are not available in prior versions, so we have to +use them via runtime loading, as long as we support XP. */ +static +void +os_cond_module_init(void) +/*=====================*/ +{ +#ifdef __WIN__ + HMODULE h_dll; + + if (!srv_use_native_conditions) + return; + + h_dll = GetModuleHandle("kernel32"); + + initialize_condition_variable = (InitializeConditionVariableProc) + GetProcAddress(h_dll, "InitializeConditionVariable"); + sleep_condition_variable = (SleepConditionVariableCSProc) + GetProcAddress(h_dll, "SleepConditionVariableCS"); + wake_all_condition_variable = (WakeAllConditionVariableProc) + GetProcAddress(h_dll, "WakeAllConditionVariable"); + wake_condition_variable = (WakeConditionVariableProc) + GetProcAddress(h_dll, "WakeConditionVariable"); + + /* When using native condition variables, check function pointers */ + ut_a(initialize_condition_variable); + ut_a(sleep_condition_variable); + ut_a(wake_all_condition_variable); + ut_a(wake_condition_variable); +#endif +} + /*********************************************************//** Initializes global event and OS 'slow' mutex lists. */ UNIV_INTERN @@ -89,7 +239,10 @@ os_sync_init(void) os_sync_mutex = NULL; os_sync_mutex_inited = FALSE; - os_sync_mutex = os_mutex_create(NULL); + /* Now for Windows only */ + os_cond_module_init(); + + os_sync_mutex = os_mutex_create(); os_sync_mutex_inited = TRUE; } @@ -143,42 +296,45 @@ os_event_create( const char* name) /*!< in: the name of the event, if NULL the event is created without a name */ { -#ifdef __WIN__ - os_event_t event; - - event = ut_malloc(sizeof(struct os_event_struct)); - - event->handle = CreateEvent(NULL, /* No security attributes */ - TRUE, /* Manual reset */ - FALSE, /* Initial state nonsignaled */ - (LPCTSTR) name); - if (!event->handle) { - fprintf(stderr, - "InnoDB: Could not create a Windows event semaphore;" - " Windows error %lu\n", - (ulong) GetLastError()); - } -#else /* Unix */ os_event_t event; - UT_NOT_USED(name); +#ifdef __WIN__ + if(!srv_use_native_conditions) { + + event = ut_malloc(sizeof(struct os_event_struct)); + + event->handle = CreateEvent(NULL, + TRUE, + FALSE, + (LPCTSTR) name); + if (!event->handle) { + fprintf(stderr, + "InnoDB: Could not create a Windows event" + " semaphore; Windows error %lu\n", + (ulong) GetLastError()); + } + } else /* Windows with condition variables */ +#endif - event = ut_malloc(sizeof(struct os_event_struct)); + { + UT_NOT_USED(name); - os_fast_mutex_init(&(event->os_mutex)); + event = ut_malloc(sizeof(struct os_event_struct)); - ut_a(0 == pthread_cond_init(&(event->cond_var), NULL)); + os_fast_mutex_init(&(event->os_mutex)); - event->is_set = FALSE; + os_cond_init(&(event->cond_var)); - /* We return this value in os_event_reset(), which can then be - be used to pass to the os_event_wait_low(). The value of zero - is reserved in os_event_wait_low() for the case when the - caller does not want to pass any signal_count value. To - distinguish between the two cases we initialize signal_count - to 1 here. */ - event->signal_count = 1; -#endif /* __WIN__ */ + event->is_set = FALSE; + + /* We return this value in os_event_reset(), which can then be + be used to pass to the os_event_wait_low(). The value of zero + is reserved in os_event_wait_low() for the case when the + caller does not want to pass any signal_count value. To + distinguish between the two cases we initialize signal_count + to 1 here. */ + event->signal_count = 1; + } /* The os_sync_mutex can be NULL because during startup an event can be created [ because it's embedded in the mutex/rwlock ] before @@ -208,10 +364,15 @@ os_event_set( /*=========*/ os_event_t event) /*!< in: event to set */ { -#ifdef __WIN__ ut_a(event); - ut_a(SetEvent(event->handle)); -#else + +#ifdef __WIN__ + if (!srv_use_native_conditions) { + ut_a(SetEvent(event->handle)); + return; + } +#endif + ut_a(event); os_fast_mutex_lock(&(event->os_mutex)); @@ -221,11 +382,10 @@ os_event_set( } else { event->is_set = TRUE; event->signal_count += 1; - ut_a(0 == pthread_cond_broadcast(&(event->cond_var))); + os_cond_broadcast(&(event->cond_var)); } os_fast_mutex_unlock(&(event->os_mutex)); -#endif } /**********************************************************//** @@ -244,12 +404,14 @@ os_event_reset( { ib_int64_t ret = 0; -#ifdef __WIN__ ut_a(event); - ut_a(ResetEvent(event->handle)); -#else - ut_a(event); +#ifdef __WIN__ + if(!srv_use_native_conditions) { + ut_a(ResetEvent(event->handle)); + return(0); + } +#endif os_fast_mutex_lock(&(event->os_mutex)); @@ -261,7 +423,6 @@ os_event_reset( ret = event->signal_count; os_fast_mutex_unlock(&(event->os_mutex)); -#endif return(ret); } @@ -274,19 +435,21 @@ os_event_free_internal( os_event_t event) /*!< in: event to free */ { #ifdef __WIN__ - ut_a(event); + if(!srv_use_native_conditions) { + ut_a(event); + ut_a(CloseHandle(event->handle)); + } else +#endif + { + ut_a(event); - ut_a(CloseHandle(event->handle)); -#else - ut_a(event); + /* This is to avoid freeing the mutex twice */ + os_fast_mutex_free(&(event->os_mutex)); - /* This is to avoid freeing the mutex twice */ - os_fast_mutex_free(&(event->os_mutex)); + os_cond_destroy(&(event->cond_var)); + } - ut_a(0 == pthread_cond_destroy(&(event->cond_var))); -#endif /* Remove from the list of events */ - UT_LIST_REMOVE(os_event_list, os_event_list, event); os_event_count--; @@ -303,18 +466,19 @@ os_event_free( os_event_t event) /*!< in: event to free */ { -#ifdef __WIN__ ut_a(event); +#ifdef __WIN__ + if(!srv_use_native_conditions){ + ut_a(CloseHandle(event->handle)); + } else /*Windows with condition variables */ +#endif + { + os_fast_mutex_free(&(event->os_mutex)); - ut_a(CloseHandle(event->handle)); -#else - ut_a(event); + os_cond_destroy(&(event->cond_var)); + } - os_fast_mutex_free(&(event->os_mutex)); - ut_a(0 == pthread_cond_destroy(&(event->cond_var))); -#endif /* Remove from the list of events */ - os_mutex_enter(os_sync_mutex); UT_LIST_REMOVE(os_event_list, os_event_list, event); @@ -355,23 +519,27 @@ os_event_wait_low( returned by previous call of os_event_reset(). */ { + ib_int64_t old_signal_count; + #ifdef __WIN__ - DWORD err; + if(!srv_use_native_conditions) { + DWORD err; - ut_a(event); + ut_a(event); - UT_NOT_USED(reset_sig_count); + UT_NOT_USED(reset_sig_count); - /* Specify an infinite time limit for waiting */ - err = WaitForSingleObject(event->handle, INFINITE); + /* Specify an infinite wait */ + err = WaitForSingleObject(event->handle, INFINITE); - ut_a(err == WAIT_OBJECT_0); + ut_a(err == WAIT_OBJECT_0); - if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) { - os_thread_exit(NULL); + if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) { + os_thread_exit(NULL); + } + return; } -#else - ib_int64_t old_signal_count; +#endif os_fast_mutex_lock(&(event->os_mutex)); @@ -396,93 +564,13 @@ os_event_wait_low( return; } - pthread_cond_wait(&(event->cond_var), &(event->os_mutex)); + os_cond_wait(&(event->cond_var), &(event->os_mutex)); /* Solaris manual said that spurious wakeups may occur: we have to check if the event really has been signaled after we came here to wait */ } -#endif -} - -/**********************************************************//** -Waits for an event object until it is in the signaled state or -a timeout is exceeded. In Unix the timeout is always infinite. -@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */ -UNIV_INTERN -ulint -os_event_wait_time( -/*===============*/ - os_event_t event, /*!< in: event to wait */ - ulint time) /*!< in: timeout in microseconds, or - OS_SYNC_INFINITE_TIME */ -{ -#ifdef __WIN__ - DWORD err; - - ut_a(event); - - if (time != OS_SYNC_INFINITE_TIME) { - err = WaitForSingleObject(event->handle, (DWORD) time / 1000); - } else { - err = WaitForSingleObject(event->handle, INFINITE); - } - - if (err == WAIT_OBJECT_0) { - - return(0); - } else if (err == WAIT_TIMEOUT) { - - return(OS_SYNC_TIME_EXCEEDED); - } else { - ut_error; - return(1000000); /* dummy value to eliminate compiler warn. */ - } -#else - UT_NOT_USED(time); - - /* In Posix this is just an ordinary, infinite wait */ - - os_event_wait(event); - - return(0); -#endif -} - -#ifdef __WIN__ -/**********************************************************//** -Waits for any event in an OS native event array. Returns if even a single -one is signaled or becomes signaled. -@return index of the event which was signaled */ -UNIV_INTERN -ulint -os_event_wait_multiple( -/*===================*/ - ulint n, /*!< in: number of events in the - array */ - os_native_event_t* native_event_array) - /*!< in: pointer to an array of event - handles */ -{ - DWORD index; - - ut_a(native_event_array); - ut_a(n > 0); - - index = WaitForMultipleObjects((DWORD) n, native_event_array, - FALSE, /* Wait for any 1 event */ - INFINITE); /* Infinite wait time - limit */ - ut_a(index >= WAIT_OBJECT_0); /* NOTE: Pointless comparison */ - ut_a(index < WAIT_OBJECT_0 + n); - - if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) { - os_thread_exit(NULL); - } - - return(index - WAIT_OBJECT_0); } -#endif /*********************************************************//** Creates an operating system mutex semaphore. Because these are slow, the @@ -490,29 +578,15 @@ mutex semaphore of InnoDB itself (mutex_t) should be used where possible. @return the mutex handle */ UNIV_INTERN os_mutex_t -os_mutex_create( -/*============*/ - const char* name) /*!< in: the name of the mutex, if NULL - the mutex is created without a name */ +os_mutex_create(void) +/*=================*/ { -#ifdef __WIN__ - HANDLE mutex; - os_mutex_t mutex_str; - - mutex = CreateMutex(NULL, /* No security attributes */ - FALSE, /* Initial state: no owner */ - (LPCTSTR) name); - ut_a(mutex); -#else os_fast_mutex_t* mutex; os_mutex_t mutex_str; - UT_NOT_USED(name); - mutex = ut_malloc(sizeof(os_fast_mutex_t)); os_fast_mutex_init(mutex); -#endif mutex_str = ut_malloc(sizeof(os_mutex_str_t)); mutex_str->handle = mutex; @@ -543,25 +617,11 @@ os_mutex_enter( /*===========*/ os_mutex_t mutex) /*!< in: mutex to acquire */ { -#ifdef __WIN__ - DWORD err; - - ut_a(mutex); - - /* Specify infinite time limit for waiting */ - err = WaitForSingleObject(mutex->handle, INFINITE); - - ut_a(err == WAIT_OBJECT_0); - - (mutex->count)++; - ut_a(mutex->count == 1); -#else os_fast_mutex_lock(mutex->handle); (mutex->count)++; ut_a(mutex->count == 1); -#endif } /**********************************************************//** @@ -577,11 +637,7 @@ os_mutex_exit( ut_a(mutex->count == 1); (mutex->count)--; -#ifdef __WIN__ - ut_a(ReleaseMutex(mutex->handle)); -#else os_fast_mutex_unlock(mutex->handle); -#endif } /**********************************************************//** @@ -610,15 +666,9 @@ os_mutex_free( os_mutex_exit(os_sync_mutex); } -#ifdef __WIN__ - ut_a(CloseHandle(mutex->handle)); - - ut_free(mutex); -#else os_fast_mutex_free(mutex->handle); ut_free(mutex->handle); ut_free(mutex); -#endif } /*********************************************************//** diff --git a/storage/innobase/os/os0thread.c b/storage/innobase/os/os0thread.c index 632199b56bc..adc876be5d5 100644 --- a/storage/innobase/os/os0thread.c +++ b/storage/innobase/os/os0thread.c @@ -242,7 +242,7 @@ os_thread_yield(void) /*=================*/ { #if defined(__WIN__) - Sleep(0); + SwitchToThread(); #elif (defined(HAVE_SCHED_YIELD) && defined(HAVE_SCHED_H)) sched_yield(); #elif defined(HAVE_PTHREAD_YIELD_ZERO_ARG) diff --git a/storage/innobase/page/page0page.c b/storage/innobase/page/page0page.c index 10008f9ac25..2e785412ac9 100644 --- a/storage/innobase/page/page0page.c +++ b/storage/innobase/page/page0page.c @@ -235,8 +235,8 @@ page_set_max_trx_id( 8, mtr); #ifndef UNIV_HOTBACKUP } else if (mtr) { - mlog_write_dulint(page + (PAGE_HEADER + PAGE_MAX_TRX_ID), - trx_id, mtr); + mlog_write_ull(page + (PAGE_HEADER + PAGE_MAX_TRX_ID), + trx_id, mtr); #endif /* !UNIV_HOTBACKUP */ } else { mach_write_to_8(page + (PAGE_HEADER + PAGE_MAX_TRX_ID), trx_id); @@ -457,7 +457,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, NULL); + page_set_max_trx_id(block, NULL, 0, NULL); memset(heap_top, 0, UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START - page_offset(heap_top)); diff --git a/storage/innobase/page/page0zip.c b/storage/innobase/page/page0zip.c index 14ec3e7a94f..98640a8e6fb 100644 --- a/storage/innobase/page/page0zip.c +++ b/storage/innobase/page/page0zip.c @@ -1464,6 +1464,7 @@ page_zip_fields_free( dict_table_t* table = index->table; mem_heap_free(index->heap); mutex_free(&(table->autoinc_mutex)); + ut_free(table->name); mem_heap_free(table->heap); } } @@ -4467,7 +4468,7 @@ page_zip_reorganize( /* 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)); + ut_ad(max_trx_id != 0); } /* Restore logging. */ @@ -4527,7 +4528,7 @@ page_zip_copy_recs( /* 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))); + || 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)); diff --git a/storage/innobase/pars/pars0pars.c b/storage/innobase/pars/pars0pars.c index 613e7962f0e..ef107f2896f 100644 --- a/storage/innobase/pars/pars0pars.c +++ b/storage/innobase/pars/pars0pars.c @@ -2031,29 +2031,6 @@ pars_info_add_int4_literal( Equivalent to: char buf[8]; -mach_write_ull(buf, val); -pars_info_add_literal(info, name, buf, 8, DATA_INT, 0); - -except that the buffer is dynamically allocated from the info struct's -heap. */ -UNIV_INTERN -void -pars_info_add_uint64_literal( -/*=========================*/ - pars_info_t* info, /*!< in: info struct */ - const char* name, /*!< in: name */ - ib_uint64_t val) /*!< in: value */ -{ - byte* buf = mem_heap_alloc(info->heap, 8); - - mach_write_ull(buf, val); - pars_info_add_literal(info, name, buf, 8, DATA_INT, 0); -} - -/****************************************************************//** -Equivalent to: - -char buf[8]; mach_write_to_8(buf, val); pars_info_add_literal(info, name, buf, 8, DATA_FIXBINARY, 0); @@ -2061,11 +2038,11 @@ except that the buffer is dynamically allocated from the info struct's heap. */ UNIV_INTERN void -pars_info_add_dulint_literal( -/*=========================*/ +pars_info_add_ull_literal( +/*======================*/ pars_info_t* info, /*!< in: info struct */ const char* name, /*!< in: name */ - dulint val) /*!< in: value */ + ib_uint64_t val) /*!< in: value */ { byte* buf = mem_heap_alloc(info->heap, 8); diff --git a/storage/innobase/read/read0read.c b/storage/innobase/read/read0read.c index 85adae4ddff..9975b8c2c57 100644 --- a/storage/innobase/read/read0read.c +++ b/storage/innobase/read/read0read.c @@ -168,8 +168,7 @@ read_view_t* read_view_oldest_copy_or_open_new( /*==============================*/ trx_id_t cr_trx_id, /*!< in: trx_id of creating - transaction, or ut_dulint_zero - used in purge */ + transaction, or 0 used in purge */ mem_heap_t* heap) /*!< in: memory heap from which allocated */ { @@ -191,7 +190,7 @@ read_view_oldest_copy_or_open_new( n = old_view->n_trx_ids; - if (!ut_dulint_is_zero(old_view->creator_trx_id)) { + if (old_view->creator_trx_id) { n++; } else { needs_insert = FALSE; @@ -206,9 +205,8 @@ read_view_oldest_copy_or_open_new( while (i < n) { if (needs_insert && (i >= old_view->n_trx_ids - || ut_dulint_cmp(old_view->creator_trx_id, - read_view_get_nth_trx_id(old_view, i)) - > 0)) { + || old_view->creator_trx_id + > read_view_get_nth_trx_id(old_view, i))) { read_view_set_nth_trx_id(view_copy, i, old_view->creator_trx_id); @@ -252,8 +250,7 @@ read_view_t* read_view_open_now( /*===============*/ trx_id_t cr_trx_id, /*!< in: trx_id of creating - transaction, or ut_dulint_zero - used in purge */ + transaction, or 0 used in purge */ mem_heap_t* heap) /*!< in: memory heap from which allocated */ { @@ -267,7 +264,7 @@ read_view_open_now( view->creator_trx_id = cr_trx_id; view->type = VIEW_NORMAL; - view->undo_no = ut_dulint_zero; + view->undo_no = 0; /* No future transactions should be visible in the view */ @@ -280,7 +277,7 @@ read_view_open_now( /* No active transaction should be visible, except cr_trx */ while (trx) { - if (ut_dulint_cmp(trx->id, cr_trx_id) != 0 + if (trx->id != cr_trx_id && (trx->conc_state == TRX_ACTIVE || trx->conc_state == TRX_PREPARED)) { @@ -292,9 +289,9 @@ read_view_open_now( trx_sys->max_trx_id can still be active, if it is in the middle of its commit! Note that when a transaction starts, we initialize trx->no to - ut_dulint_max. */ + IB_ULONGLONG_MAX. */ - if (ut_dulint_cmp(view->low_limit_no, trx->no) > 0) { + if (view->low_limit_no > trx->no) { view->low_limit_no = trx->no; } @@ -367,22 +364,20 @@ read_view_print( if (view->type == VIEW_HIGH_GRANULARITY) { fprintf(stderr, - "High-granularity read view undo_n:o %lu %lu\n", - (ulong) ut_dulint_get_high(view->undo_no), - (ulong) ut_dulint_get_low(view->undo_no)); + "High-granularity read view undo_n:o %llu\n", + (ullint) view->undo_no); } else { fprintf(stderr, "Normal read view\n"); } - fprintf(stderr, "Read view low limit trx n:o %lu %lu\n", - (ulong) ut_dulint_get_high(view->low_limit_no), - (ulong) ut_dulint_get_low(view->low_limit_no)); + fprintf(stderr, "Read view low limit trx n:o " TRX_ID_FMT "\n", + (ullint) view->low_limit_no); fprintf(stderr, "Read view up limit trx id " TRX_ID_FMT "\n", - TRX_ID_PREP_PRINTF(view->up_limit_id)); + (ullint) view->up_limit_id); fprintf(stderr, "Read view low limit trx id " TRX_ID_FMT "\n", - TRX_ID_PREP_PRINTF(view->low_limit_id)); + (ullint) view->low_limit_id); fprintf(stderr, "Read view individually stored trx ids:\n"); @@ -390,8 +385,7 @@ read_view_print( for (i = 0; i < n_ids; i++) { fprintf(stderr, "Read view trx id " TRX_ID_FMT "\n", - TRX_ID_PREP_PRINTF( - read_view_get_nth_trx_id(view, i))); + (ullint) read_view_get_nth_trx_id(view, i)); } } @@ -460,9 +454,9 @@ read_cursor_view_create_for_mysql( trx_sys->max_trx_id can still be active, if it is in the middle of its commit! Note that when a transaction starts, we initialize trx->no to - ut_dulint_max. */ + IB_ULONGLONG_MAX. */ - if (ut_dulint_cmp(view->low_limit_no, trx->no) > 0) { + if (view->low_limit_no > trx->no) { view->low_limit_no = trx->no; } diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c index c882a065cd1..8fd8c4f8532 100644 --- a/storage/innobase/row/row0ins.c +++ b/storage/innobase/row/row0ins.c @@ -51,6 +51,15 @@ Created 4/20/1996 Heikki Tuuri #define ROW_INS_PREV 1 #define ROW_INS_NEXT 2 +/************************************************************************* +IMPORTANT NOTE: Any operation that generates redo MUST check that there +is enough space in the redo log before for that operation. This is +done by calling log_free_check(). The reason for checking the +availability of the redo log space before the start of the operation is +that we MUST not hold any synchonization objects when performing the +check. +If you make a change in this module make sure that no codepath is +introduced where a call to log_free_check() is bypassed. */ /*********************************************************************//** Creates an insert node struct. @@ -78,7 +87,7 @@ ins_node_create( node->select = NULL; - node->trx_id = ut_dulint_zero; + node->trx_id = 0; node->entry_sys_heap = mem_heap_create(128); @@ -198,7 +207,7 @@ ins_node_set_new_row( /* As we allocated a new trx id buf, the trx id should be written there again: */ - node->trx_id = ut_dulint_zero; + node->trx_id = 0; } /*******************************************************************//** @@ -506,8 +515,7 @@ row_ins_cascade_calc_update_vec( if (!dfield_is_null(&ufield->new_val) && dtype_get_at_most_n_mbchars( - col->prtype, - col->mbminlen, col->mbmaxlen, + col->prtype, col->mbminmaxlen, col->len, ufield_len, dfield_get_data(&ufield->new_val)) @@ -530,49 +538,37 @@ row_ins_cascade_calc_update_vec( if (min_size > ufield_len) { - char* pad_start; - const char* pad_end; - char* padded_data - = mem_heap_alloc( - heap, min_size); - pad_start = padded_data + ufield_len; - pad_end = padded_data + min_size; + byte* pad; + ulint pad_len; + byte* padded_data; + ulint mbminlen; + + padded_data = mem_heap_alloc( + heap, min_size); + + pad = padded_data + ufield_len; + pad_len = min_size - ufield_len; memcpy(padded_data, dfield_get_data(&ufield ->new_val), - dfield_get_len(&ufield - ->new_val)); + ufield_len); - switch (UNIV_EXPECT(col->mbminlen,1)) { - default: - ut_error; - return(ULINT_UNDEFINED); - case 1: - if (UNIV_UNLIKELY - (dtype_get_charset_coll( - col->prtype) - == DATA_MYSQL_BINARY_CHARSET_COLL)) { - /* Do not pad BINARY - columns. */ - return(ULINT_UNDEFINED); - } + mbminlen = dict_col_get_mbminlen(col); + + ut_ad(!(ufield_len % mbminlen)); + ut_ad(!(min_size % mbminlen)); - /* space=0x20 */ - memset(pad_start, 0x20, - pad_end - pad_start); - break; - case 2: - /* space=0x0020 */ - ut_a(!(ufield_len % 2)); - ut_a(!(min_size % 2)); - do { - *pad_start++ = 0x00; - *pad_start++ = 0x20; - } while (pad_start < pad_end); - break; + if (mbminlen == 1 + && dtype_get_charset_coll( + col->prtype) + == DATA_MYSQL_BINARY_CHARSET_COLL) { + /* Do not pad BINARY columns */ + return(ULINT_UNDEFINED); } + row_mysql_pad_col(mbminlen, + pad, pad_len); dfield_set_data(&ufield->new_val, padded_data, min_size); } @@ -2223,7 +2219,7 @@ row_ins_index_entry_set_vals( = dict_field_get_col(ind_field); len = dtype_get_at_most_n_mbchars( - col->prtype, col->mbminlen, col->mbmaxlen, + col->prtype, col->mbminmaxlen, ind_field->prefix_len, len, dfield_get_data(row_field)); @@ -2270,7 +2266,7 @@ row_ins_alloc_row_id_step( /*======================*/ ins_node_t* node) /*!< in: row insert node */ { - dulint row_id; + row_id_t row_id; ut_ad(node->state == INS_NODE_ALLOC_ROW_ID); @@ -2457,7 +2453,7 @@ row_ins_step( /* It may be that the current session has not yet started its transaction, or it has been committed: */ - if (UT_DULINT_EQ(trx->id, node->trx_id)) { + if (trx->id == node->trx_id) { /* No need to do IX-locking */ goto same_trx; diff --git a/storage/innobase/row/row0merge.c b/storage/innobase/row/row0merge.c index eac2f9fb377..38ec4bff08f 100644 --- a/storage/innobase/row/row0merge.c +++ b/storage/innobase/row/row0merge.c @@ -338,7 +338,7 @@ row_merge_buf_add( if (ifield->prefix_len) { len = dtype_get_at_most_n_mbchars( col->prtype, - col->mbminlen, col->mbmaxlen, + col->mbminmaxlen, ifield->prefix_len, len, dfield_get_data(field)); dfield_set_len(field, len); @@ -1779,6 +1779,11 @@ row_merge_copy_blobs( (below). */ data = btr_rec_copy_externally_stored_field( mrec, offsets, zip_size, i, &len, heap); + /* Because we have locked the table, any records + written by incomplete transactions must have been + rolled back already. There must not be any incomplete + BLOB columns. */ + ut_a(data); dfield_set_data(field, data, len); } @@ -2023,7 +2028,7 @@ row_merge_drop_index( ut_ad(index && table && trx); - pars_info_add_dulint_literal(info, "indexid", index->id); + pars_info_add_ull_literal(info, "indexid", index->id); trx_start_if_not_started(trx); trx->op_info = "dropping index"; @@ -2093,7 +2098,7 @@ row_merge_drop_temp_indexes(void) const rec_t* rec; const byte* field; ulint len; - dulint table_id; + table_id_t table_id; dict_table_t* table; btr_pcur_move_to_next_user_rec(&pcur, &mtr); @@ -2322,7 +2327,7 @@ row_merge_rename_indexes( trx->op_info = "renaming indexes"; - pars_info_add_dulint_literal(info, "tableid", table->id); + pars_info_add_ull_literal(info, "tableid", table->id); err = que_eval_sql(info, rename_indexes, FALSE, trx); @@ -2359,7 +2364,7 @@ row_merge_rename_tables( { ulint err = DB_ERROR; pars_info_t* info; - const char* old_name= old_table->name; + char old_name[MAX_TABLE_NAME_LEN + 1]; ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); ut_ad(old_table != new_table); @@ -2367,6 +2372,17 @@ row_merge_rename_tables( ut_a(trx->dict_operation_lock_mode == RW_X_LATCH); + /* store the old/current name to an automatic variable */ + if (strlen(old_table->name) + 1 <= sizeof(old_name)) { + memcpy(old_name, old_table->name, strlen(old_table->name) + 1); + } else { + ut_print_timestamp(stderr); + fprintf(stderr, "InnoDB: too long table name: '%s', " + "max length is %d\n", old_table->name, + MAX_TABLE_NAME_LEN); + ut_error; + } + trx->op_info = "renaming tables"; /* We use the private SQL parser of Innobase to generate the query @@ -2499,8 +2515,7 @@ row_merge_create_index( /* Note the id of the transaction that created this index, we use it to restrict readers from accessing this index, to ensure read consistency. */ - index->trx_id = (ib_uint64_t) - ut_conv_dulint_to_longlong(trx->id); + index->trx_id = trx->id; } else { index = NULL; } @@ -2517,10 +2532,8 @@ row_merge_is_index_usable( const trx_t* trx, /*!< in: transaction */ const dict_index_t* index) /*!< in: index to check */ { - return(!trx->read_view || read_view_sees_trx_id( - trx->read_view, - ut_dulint_create((ulint) (index->trx_id >> 32), - (ulint) index->trx_id & 0xFFFFFFFF))); + return(!trx->read_view + || read_view_sees_trx_id(trx->read_view, index->trx_id)); } /*********************************************************************//** diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 1f7f98a59a2..1262ac71e98 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -266,6 +266,49 @@ row_mysql_read_blob_ref( } /**************************************************************//** +Pad a column with spaces. */ +UNIV_INTERN +void +row_mysql_pad_col( +/*==============*/ + ulint mbminlen, /*!< in: minimum size of a character, + in bytes */ + byte* pad, /*!< out: padded buffer */ + ulint len) /*!< in: number of bytes to pad */ +{ + const byte* pad_end; + + switch (UNIV_EXPECT(mbminlen, 1)) { + default: + ut_error; + case 1: + /* space=0x20 */ + memset(pad, 0x20, len); + break; + case 2: + /* space=0x0020 */ + pad_end = pad + len; + ut_a(!(len % 2)); + do { + *pad++ = 0x00; + *pad++ = 0x20; + } while (pad < pad_end); + break; + case 4: + /* space=0x00000020 */ + pad_end = pad + len; + ut_a(!(len % 4)); + do { + *pad++ = 0x00; + *pad++ = 0x00; + *pad++ = 0x00; + *pad++ = 0x20; + } while (pad < pad_end); + break; + } +} + +/**************************************************************//** Stores a non-SQL-NULL field given in the MySQL format in the InnoDB format. The counterpart of this function is row_sel_field_store_in_mysql_format() in row0sel.c. @@ -357,12 +400,28 @@ row_mysql_store_col_in_innobase_format( /* Remove trailing spaces from old style VARCHAR columns. */ - /* Handle UCS2 strings differently. */ + /* Handle Unicode strings differently. */ ulint mbminlen = dtype_get_mbminlen(dtype); ptr = mysql_data; - if (mbminlen == 2) { + switch (mbminlen) { + default: + ut_error; + case 4: + /* space=0x00000020 */ + /* Trim "half-chars", just in case. */ + col_len &= ~3; + + while (col_len >= 4 + && ptr[col_len - 4] == 0x00 + && ptr[col_len - 3] == 0x00 + && ptr[col_len - 2] == 0x00 + && ptr[col_len - 1] == 0x20) { + col_len -= 4; + } + break; + case 2: /* space=0x0020 */ /* Trim "half-chars", just in case. */ col_len &= ~1; @@ -371,8 +430,8 @@ row_mysql_store_col_in_innobase_format( && ptr[col_len - 1] == 0x20) { col_len -= 2; } - } else { - ut_a(mbminlen == 1); + break; + case 1: /* space=0x20 */ while (col_len > 0 && ptr[col_len - 1] == 0x20) { @@ -1532,7 +1591,7 @@ row_unlock_for_mysql( } } - if (ut_dulint_cmp(rec_trx_id, trx->id) != 0) { + if (rec_trx_id != trx->id) { /* We did not update the record: unlock it */ rec = btr_pcur_get_rec(pcur); @@ -2283,7 +2342,7 @@ row_discard_tablespace_for_mysql( trx_t* trx) /*!< in: transaction handle */ { dict_foreign_t* foreign; - dulint new_id; + table_id_t new_id; dict_table_t* table; ibool success; ulint err; @@ -2405,7 +2464,7 @@ row_discard_tablespace_for_mysql( info = pars_info_create(); pars_info_add_str_literal(info, "table_name", name); - pars_info_add_dulint_literal(info, "new_id", new_id); + pars_info_add_ull_literal(info, "new_id", new_id); err = que_eval_sql(info, "PROCEDURE DISCARD_TABLESPACE_PROC () IS\n" @@ -2619,7 +2678,7 @@ row_truncate_table_for_mysql( dict_index_t* sys_index; btr_pcur_t pcur; mtr_t mtr; - dulint new_id; + table_id_t new_id; ulint recreate_space = 0; pars_info_t* info = NULL; @@ -2873,8 +2932,8 @@ next_rec: info = pars_info_create(); pars_info_add_int4_literal(info, "space", (lint) table->space); - pars_info_add_dulint_literal(info, "old_id", table->id); - pars_info_add_dulint_literal(info, "new_id", new_id); + pars_info_add_ull_literal(info, "old_id", table->id); + pars_info_add_ull_literal(info, "new_id", new_id); err = que_eval_sql(info, "PROCEDURE RENUMBER_TABLESPACE_PROC () IS\n" diff --git a/storage/innobase/row/row0purge.c b/storage/innobase/row/row0purge.c index da9d31f333f..fe7a3e0236e 100644 --- a/storage/innobase/row/row0purge.c +++ b/storage/innobase/row/row0purge.c @@ -44,6 +44,16 @@ Created 3/14/1997 Heikki Tuuri #include "row0mysql.h" #include "log0log.h" +/************************************************************************* +IMPORTANT NOTE: Any operation that generates redo MUST check that there +is enough space in the redo log before for that operation. This is +done by calling log_free_check(). The reason for checking the +availability of the redo log space before the start of the operation is +that we MUST not hold any synchonization objects when performing the +check. +If you make a change in this module make sure that no codepath is +introduced where a call to log_free_check() is bypassed. */ + /********************************************************************//** Creates a purge node to a query graph. @return own: purge node */ @@ -126,6 +136,7 @@ row_purge_remove_clust_if_poss_low( pcur = &(node->pcur); btr_cur = btr_pcur_get_btr_cur(pcur); + log_free_check(); mtr_start(&mtr); success = row_purge_reposition_pcur(mode, node, &mtr); @@ -140,10 +151,9 @@ row_purge_remove_clust_if_poss_low( rec = btr_pcur_get_rec(pcur); - if (0 != ut_dulint_cmp(node->roll_ptr, row_get_rec_roll_ptr( - rec, index, rec_get_offsets( - rec, index, offsets_, - ULINT_UNDEFINED, &heap)))) { + if (node->roll_ptr != row_get_rec_roll_ptr( + rec, index, rec_get_offsets(rec, index, offsets_, + ULINT_UNDEFINED, &heap))) { if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } @@ -606,7 +616,7 @@ row_purge_parse_undo_rec( byte* ptr; trx_t* trx; undo_no_t undo_no; - dulint table_id; + table_id_t table_id; trx_id_t trx_id; roll_ptr_t roll_ptr; ulint info_bits; diff --git a/storage/innobase/row/row0row.c b/storage/innobase/row/row0row.c index 6cdfa410c15..050b8522fa3 100644 --- a/storage/innobase/row/row0row.c +++ b/storage/innobase/row/row0row.c @@ -156,7 +156,7 @@ row_build_index_entry( } len = dtype_get_at_most_n_mbchars( - col->prtype, col->mbminlen, col->mbmaxlen, + col->prtype, col->mbminmaxlen, ind_field->prefix_len, len, dfield_get_data(dfield)); dfield_set_len(dfield, len); } @@ -294,7 +294,13 @@ row_build( ut_ad(dtuple_check_typed(row)); - if (j) { + if (!ext) { + /* REDUNDANT and COMPACT formats store a local + 768-byte prefix of each externally stored + column. No cache is needed. */ + ut_ad(dict_table_get_format(index->table) + < DICT_TF_FORMAT_ZIP); + } else if (j) { *ext = row_ext_create(j, ext_cols, row, dict_table_zip_size(index->table), heap); @@ -514,8 +520,7 @@ row_build_row_ref( dfield_set_len(dfield, dtype_get_at_most_n_mbchars( dtype->prtype, - dtype->mbminlen, - dtype->mbmaxlen, + dtype->mbminmaxlen, clust_col_prefix_len, len, (char*) field)); } @@ -629,8 +634,7 @@ notfound: dfield_set_len(dfield, dtype_get_at_most_n_mbchars( dtype->prtype, - dtype->mbminlen, - dtype->mbmaxlen, + dtype->mbminmaxlen, clust_col_prefix_len, len, (char*) field)); } diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index 2861235a995..39ab2179740 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -88,10 +88,8 @@ row_sel_sec_rec_is_for_blob( /*========================*/ ulint mtype, /*!< in: main type */ ulint prtype, /*!< in: precise type */ - ulint mbminlen, /*!< in: minimum length of a - multi-byte character */ - ulint mbmaxlen, /*!< in: maximum length of a - multi-byte character */ + ulint mbminmaxlen, /*!< in: minimum and maximum length of + a multi-byte character */ const byte* clust_field, /*!< in: the locally stored part of the clustered index column, including the BLOB pointer; the clustered @@ -119,7 +117,7 @@ row_sel_sec_rec_is_for_blob( return(FALSE); } - len = dtype_get_at_most_n_mbchars(prtype, mbminlen, mbmaxlen, + len = dtype_get_at_most_n_mbchars(prtype, mbminmaxlen, sec_len, len, (const char*) buf); return(!cmp_data_data(mtype, prtype, buf, len, sec_field, sec_len)); @@ -202,14 +200,14 @@ row_sel_sec_rec_is_for_clust_rec( } len = dtype_get_at_most_n_mbchars( - col->prtype, col->mbminlen, col->mbmaxlen, + col->prtype, col->mbminmaxlen, ifield->prefix_len, len, (char*) clust_field); if (rec_offs_nth_extern(clust_offs, clust_pos) && len < sec_len) { if (!row_sel_sec_rec_is_for_blob( col->mtype, col->prtype, - col->mbminlen, col->mbmaxlen, + col->mbminmaxlen, clust_field, clust_len, sec_field, sec_len, dict_table_zip_size( @@ -416,7 +414,7 @@ row_sel_fetch_columns( field_no))) { /* Copy an externally stored field to the - temporary heap */ + temporary heap, if possible. */ heap = mem_heap_create(1); @@ -425,6 +423,17 @@ row_sel_fetch_columns( dict_table_zip_size(index->table), field_no, &len, heap); + /* data == NULL means that the + externally stored field was not + written yet. This record + should only be seen by + recv_recovery_rollback_active() or any + TRX_ISO_READ_UNCOMMITTED + transactions. The InnoDB SQL parser + (the sole caller of this function) + does not implement READ UNCOMMITTED, + and it is not involved during rollback. */ + ut_a(data); ut_a(len != UNIV_SQL_NULL); needs_copy = TRUE; @@ -926,6 +935,7 @@ row_sel_get_clust_rec( when plan->clust_pcur was positioned. The latch will not be released until mtr_commit(mtr). */ + ut_ad(!rec_get_deleted_flag(clust_rec, rec_offs_comp(offsets))); row_sel_fetch_columns(index, clust_rec, offsets, UT_LIST_GET_FIRST(plan->columns)); *out_rec = clust_rec; @@ -1628,6 +1638,13 @@ skip_lock: } if (old_vers == NULL) { + /* The record does not exist + in our read view. Skip it, but + first attempt to determine + whether the index segment we + are searching through has been + exhausted. */ + offsets = rec_get_offsets( rec, index, offsets, ULINT_UNDEFINED, &heap); @@ -2508,13 +2525,13 @@ row_sel_field_store_in_mysql_format( ulint len) /*!< in: length of the data */ { byte* ptr; - byte* field_end; - byte* pad_ptr; ut_ad(len != UNIV_SQL_NULL); UNIV_MEM_ASSERT_RW(data, len); switch (templ->type) { + const byte* field_end; + byte* pad; case DATA_INT: /* Convert integer data from Innobase to a little-endian format, sign bit restored to normal */ @@ -2558,38 +2575,32 @@ row_sel_field_store_in_mysql_format( unused end of a >= 5.0.3 true VARCHAR column, just in case MySQL expects its contents to be deterministic. */ - pad_ptr = dest + len; + pad = dest + len; ut_ad(templ->mbminlen <= templ->mbmaxlen); - /* We handle UCS2 charset strings differently. */ - if (templ->mbminlen == 2) { - /* A space char is two bytes, 0x0020 in UCS2 */ + /* We treat some Unicode charset strings specially. */ + switch (templ->mbminlen) { + case 4: + /* InnoDB should never have stripped partial + UTF-32 characters. */ + ut_a(!(len & 3)); + break; + case 2: + /* A space char is two bytes, + 0x0020 in UCS2 and UTF-16 */ - if (len & 1) { + if (UNIV_UNLIKELY(len & 1)) { /* A 0x20 has been stripped from the column. Pad it back. */ - if (pad_ptr < field_end) { - *pad_ptr = 0x20; - pad_ptr++; + if (pad < field_end) { + *pad++ = 0x20; } } - - /* Pad the rest of the string with 0x0020 */ - - while (pad_ptr < field_end) { - *pad_ptr = 0x00; - pad_ptr++; - *pad_ptr = 0x20; - pad_ptr++; - } - } else { - ut_ad(templ->mbminlen == 1); - /* space=0x20 */ - - memset(pad_ptr, 0x20, field_end - pad_ptr); } + + row_mysql_pad_col(templ->mbminlen, pad, field_end - pad); break; case DATA_BLOB: @@ -2614,9 +2625,9 @@ row_sel_field_store_in_mysql_format( || !(templ->mysql_col_len % templ->mbmaxlen)); ut_ad(len * templ->mbmaxlen >= templ->mysql_col_len); - if (templ->mbminlen != templ->mbmaxlen) { + if (templ->mbminlen == 1 && templ->mbmaxlen != 1) { /* Pad with spaces. This undoes the stripping - done in row0mysql.ic, function + done in row0mysql.c, function row_mysql_store_col_in_innobase_format(). */ memset(dest + len, 0x20, templ->mysql_col_len - len); @@ -2647,9 +2658,8 @@ Convert a row in the Innobase format to a row in the MySQL format. Note that the template in prebuilt may advise us to copy only a few columns to mysql_rec, other columns are left blank. All columns may not be needed in the query. -@return TRUE if success, FALSE if could not allocate memory for a BLOB -(though we may also assert in that case) */ -static +@return TRUE on success, FALSE if not all columns could be retrieved */ +static __attribute__((warn_unused_result)) ibool row_sel_store_mysql_rec( /*====================*/ @@ -2672,6 +2682,7 @@ row_sel_store_mysql_rec( ut_ad(prebuilt->mysql_template); ut_ad(prebuilt->default_rec); ut_ad(rec_offs_validate(rec, NULL, offsets)); + ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets))); if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) { mem_heap_free(prebuilt->blob_heap); @@ -2719,6 +2730,21 @@ row_sel_store_mysql_rec( dict_table_zip_size(prebuilt->table), templ->rec_field_no, &len, heap); + if (UNIV_UNLIKELY(!data)) { + /* The externally stored field + was not written yet. This + record should only be seen by + recv_recovery_rollback_active() + or any TRX_ISO_READ_UNCOMMITTED + transactions. */ + + if (extern_field_heap) { + mem_heap_free(extern_field_heap); + } + + return(FALSE); + } + ut_a(len != UNIV_SQL_NULL); } else { /* Field is stored in the row. */ @@ -3136,9 +3162,10 @@ row_sel_pop_cached_row_for_mysql( } /********************************************************************//** -Pushes a row for MySQL to the fetch cache. */ -UNIV_INLINE -void +Pushes a row for MySQL to the fetch cache. +@return TRUE on success, FALSE if the record contains incomplete BLOBs */ +UNIV_INLINE __attribute__((warn_unused_result)) +ibool row_sel_push_cache_row_for_mysql( /*=============================*/ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */ @@ -3180,10 +3207,11 @@ row_sel_push_cache_row_for_mysql( prebuilt->fetch_cache[ prebuilt->n_fetch_cached], prebuilt, rec, offsets))) { - ut_error; + return(FALSE); } prebuilt->n_fetch_cached++; + return(TRUE); } /*********************************************************************//** @@ -3578,11 +3606,21 @@ row_search_for_mysql( if (!row_sel_store_mysql_rec(buf, prebuilt, rec, offsets)) { - err = DB_TOO_BIG_RECORD; - - /* We let the main loop to do the - error handling */ - goto shortcut_fails_too_big_rec; + /* Only fresh inserts may contain + incomplete externally stored + columns. Pretend that such + records do not exist. Such + records may only be accessed + at the READ UNCOMMITTED + isolation level or when + rolling back a recovered + transaction. Rollback happens + at a lower level, not here. */ + ut_a(trx->isolation_level + == TRX_ISO_READ_UNCOMMITTED); + + /* Proceed as in case SEL_RETRY. */ + break; } mtr_commit(&mtr); @@ -3622,7 +3660,7 @@ release_search_latch_if_needed: default: ut_ad(0); } -shortcut_fails_too_big_rec: + mtr_commit(&mtr); mtr_start(&mtr); } @@ -4357,9 +4395,18 @@ requires_clust_rec: not cache rows because there the cursor is a scrollable cursor. */ - row_sel_push_cache_row_for_mysql(prebuilt, result_rec, - offsets); - if (prebuilt->n_fetch_cached == MYSQL_FETCH_CACHE_SIZE) { + if (!row_sel_push_cache_row_for_mysql(prebuilt, result_rec, + offsets)) { + /* Only fresh inserts may contain incomplete + externally stored columns. Pretend that such + records do not exist. Such records may only be + accessed at the READ UNCOMMITTED isolation + level or when rolling back a recovered + transaction. Rollback happens at a lower + level, not here. */ + ut_a(trx->isolation_level == TRX_ISO_READ_UNCOMMITTED); + } else if (prebuilt->n_fetch_cached + == MYSQL_FETCH_CACHE_SIZE) { goto got_row; } @@ -4375,9 +4422,17 @@ requires_clust_rec: } else { if (!row_sel_store_mysql_rec(buf, prebuilt, result_rec, offsets)) { - err = DB_TOO_BIG_RECORD; - - goto lock_wait_or_error; + /* Only fresh inserts may contain + incomplete externally stored + columns. Pretend that such records do + not exist. Such records may only be + accessed at the READ UNCOMMITTED + isolation level or when rolling back a + recovered transaction. Rollback + happens at a lower level, not here. */ + ut_a(trx->isolation_level + == TRX_ISO_READ_UNCOMMITTED); + goto next_rec; } } @@ -4622,8 +4677,7 @@ row_search_check_if_query_cache_permitted( IX type locks actually would require ret = FALSE. */ if (UT_LIST_GET_LEN(table->locks) == 0 - && ut_dulint_cmp(trx->id, - table->query_cache_inv_trx_id) >= 0) { + && trx->id >= table->query_cache_inv_trx_id) { ret = TRUE; diff --git a/storage/innobase/row/row0uins.c b/storage/innobase/row/row0uins.c index c35f1ef7a44..d25afed3840 100644 --- a/storage/innobase/row/row0uins.c +++ b/storage/innobase/row/row0uins.c @@ -46,6 +46,16 @@ Created 2/25/1997 Heikki Tuuri #include "ibuf0ibuf.h" #include "log0log.h" +/************************************************************************* +IMPORTANT NOTE: Any operation that generates redo MUST check that there +is enough space in the redo log before for that operation. This is +done by calling log_free_check(). The reason for checking the +availability of the redo log space before the start of the operation is +that we MUST not hold any synchonization objects when performing the +check. +If you make a change in this module make sure that no codepath is +introduced where a call to log_free_check() is bypassed. */ + /***************************************************************//** Removes a clustered index record. The pcur in node was positioned on the record, now it is detached. @@ -68,7 +78,7 @@ row_undo_ins_remove_clust_rec( &mtr); ut_a(success); - if (ut_dulint_cmp(node->table->id, DICT_INDEXES_ID) == 0) { + if (node->table->id == DICT_INDEXES_ID) { ut_ad(node->trx->dict_operation_lock_mode == RW_X_LATCH); /* Drop the index tree associated with the row in @@ -151,7 +161,6 @@ row_undo_ins_remove_sec_low( mtr_t mtr; enum row_search_result search_result; - log_free_check(); mtr_start(&mtr); btr_cur = btr_pcur_get_btr_cur(&pcur); @@ -251,7 +260,7 @@ row_undo_ins_parse_undo_rec( dict_index_t* clust_index; byte* ptr; undo_no_t undo_no; - dulint table_id; + table_id_t table_id; ulint type; ulint dummy; ibool dummy_extern; @@ -337,6 +346,7 @@ row_undo_ins( transactions. */ ut_a(trx_is_recv(node->trx)); } else { + log_free_check(); err = row_undo_ins_remove_sec(node->index, entry); if (err != DB_SUCCESS) { @@ -348,5 +358,6 @@ row_undo_ins( node->index = dict_table_get_next_index(node->index); } + log_free_check(); return(row_undo_ins_remove_clust_rec(node)); } diff --git a/storage/innobase/row/row0umod.c b/storage/innobase/row/row0umod.c index 75de18a0b7d..aebff0764c8 100644 --- a/storage/innobase/row/row0umod.c +++ b/storage/innobase/row/row0umod.c @@ -58,12 +58,22 @@ delete marked clustered index record was delete unmarked and possibly also some of its fields were changed. Now, it is possible that the delete marked version has become obsolete at the time the undo is started. */ +/************************************************************************* +IMPORTANT NOTE: Any operation that generates redo MUST check that there +is enough space in the redo log before for that operation. This is +done by calling log_free_check(). The reason for checking the +availability of the redo log space before the start of the operation is +that we MUST not hold any synchonization objects when performing the +check. +If you make a change in this module make sure that no codepath is +introduced where a call to log_free_check() is bypassed. */ + /***********************************************************//** Checks if also the previous version of the clustered index record was modified or inserted by the same transaction, and its undo number is such that it should be undone in the same rollback. @return TRUE if also previous modify or insert of this row should be undone */ -UNIV_INLINE +static ibool row_undo_mod_undo_also_prev_vers( /*=============================*/ @@ -75,9 +85,9 @@ row_undo_mod_undo_also_prev_vers( trx = node->trx; - if (0 != ut_dulint_cmp(node->new_trx_id, trx->id)) { + if (node->new_trx_id != trx->id) { - *undo_no = ut_dulint_zero; + *undo_no = 0; return(FALSE); } @@ -85,7 +95,7 @@ row_undo_mod_undo_also_prev_vers( *undo_no = trx_undo_rec_get_undo_no(undo_rec); - return(ut_dulint_cmp(trx->roll_limit, *undo_no) <= 0); + return(trx->roll_limit <= *undo_no); } /***********************************************************//** @@ -231,6 +241,8 @@ row_undo_mod_clust( ut_ad(node && thr); + log_free_check(); + /* Check if also the previous version of the clustered index record should be undone in this same rollback operation */ @@ -778,7 +790,7 @@ row_undo_mod_parse_undo_rec( dict_index_t* clust_index; byte* ptr; undo_no_t undo_no; - dulint table_id; + table_id_t table_id; trx_id_t trx_id; roll_ptr_t roll_ptr; ulint info_bits; diff --git a/storage/innobase/row/row0undo.c b/storage/innobase/row/row0undo.c index 3d739c9689a..09970b7fe21 100644 --- a/storage/innobase/row/row0undo.c +++ b/storage/innobase/row/row0undo.c @@ -185,9 +185,8 @@ row_undo_search_clust_to_pcur( offsets = rec_get_offsets(rec, clust_index, offsets, ULINT_UNDEFINED, &heap); - if (!found || 0 != ut_dulint_cmp(node->roll_ptr, - row_get_rec_roll_ptr(rec, clust_index, - offsets))) { + if (!found || node->roll_ptr + != row_get_rec_roll_ptr(rec, clust_index, offsets)) { /* We must remove the reservation on the undo log record BEFORE releasing the latch on the clustered index page: this @@ -199,8 +198,24 @@ row_undo_search_clust_to_pcur( ret = FALSE; } else { + row_ext_t** ext; + + if (dict_table_get_format(node->table) >= DICT_TF_FORMAT_ZIP) { + /* In DYNAMIC or COMPRESSED format, there is + no prefix of externally stored columns in the + clustered index record. Build a cache of + column prefixes. */ + ext = &node->ext; + } else { + /* REDUNDANT and COMPACT formats store a local + 768-byte prefix of each externally stored + column. No cache is needed. */ + ext = NULL; + node->ext = NULL; + } + node->row = row_build(ROW_COPY_DATA, clust_index, rec, - offsets, NULL, &node->ext, node->heap); + offsets, NULL, ext, node->heap); if (node->update) { node->undo_row = dtuple_copy(node->row, node->heap); row_upd_replace(node->undo_row, &node->undo_ext, @@ -297,7 +312,7 @@ row_undo( if (locked_data_dict) { - row_mysql_lock_data_dictionary(trx); + row_mysql_freeze_data_dictionary(trx); } if (node->state == UNDO_NODE_INSERT) { @@ -312,7 +327,7 @@ row_undo( if (locked_data_dict) { - row_mysql_unlock_data_dictionary(trx); + row_mysql_unfreeze_data_dictionary(trx); } /* Do some cleanup */ diff --git a/storage/innobase/row/row0upd.c b/storage/innobase/row/row0upd.c index f1a90a3bf1c..588ee352ba0 100644 --- a/storage/innobase/row/row0upd.c +++ b/storage/innobase/row/row0upd.c @@ -92,6 +92,16 @@ the x-latch freed? The most efficient way for performing a searched delete is obviously to keep the x-latch for several steps of query graph execution. */ +/************************************************************************* +IMPORTANT NOTE: Any operation that generates redo MUST check that there +is enough space in the redo log before for that operation. This is +done by calling log_free_check(). The reason for checking the +availability of the redo log space before the start of the operation is +that we MUST not hold any synchonization objects when performing the +check. +If you make a change in this module make sure that no codepath is +introduced where a call to log_free_check() is bypassed. */ + /***********************************************************//** Checks if an update vector changes some of the first ordering fields of an index record. This is only used in foreign key checks and we can assume @@ -367,7 +377,7 @@ row_upd_index_entry_sys_field( them */ dict_index_t* index, /*!< in: clustered index */ ulint type, /*!< in: DATA_TRX_ID or DATA_ROLL_PTR */ - dulint val) /*!< in: value to write */ + ib_uint64_t val) /*!< in: value to write */ { dfield_t* dfield; byte* field; @@ -526,7 +536,7 @@ row_upd_write_sys_vals_to_log( trx_write_roll_ptr(log_ptr, roll_ptr); log_ptr += DATA_ROLL_PTR_LEN; - log_ptr += mach_dulint_write_compressed(log_ptr, trx->id); + log_ptr += mach_ull_write_compressed(log_ptr, trx->id); return(log_ptr); } @@ -560,7 +570,7 @@ row_upd_parse_sys_vals( *roll_ptr = trx_read_roll_ptr(ptr); ptr += DATA_ROLL_PTR_LEN; - ptr = mach_dulint_parse_compressed(ptr, end_ptr, trx_id); + ptr = mach_ull_parse_compressed(ptr, end_ptr, trx_id); return(ptr); } @@ -939,7 +949,7 @@ row_upd_index_replace_new_col_val( } len = dtype_get_at_most_n_mbchars(col->prtype, - col->mbminlen, col->mbmaxlen, + col->mbminmaxlen, field->prefix_len, len, (const char*) data); @@ -1388,6 +1398,7 @@ row_upd_store_row( dict_index_t* clust_index; rec_t* rec; mem_heap_t* heap = NULL; + row_ext_t** ext; ulint offsets_[REC_OFFS_NORMAL_SIZE]; const ulint* offsets; rec_offs_init(offsets_); @@ -1404,8 +1415,22 @@ row_upd_store_row( offsets = rec_get_offsets(rec, clust_index, offsets_, ULINT_UNDEFINED, &heap); + + if (dict_table_get_format(node->table) >= DICT_TF_FORMAT_ZIP) { + /* In DYNAMIC or COMPRESSED format, there is no prefix + of externally stored columns in the clustered index + record. Build a cache of column prefixes. */ + ext = &node->ext; + } else { + /* REDUNDANT and COMPACT formats store a local + 768-byte prefix of each externally stored column. + No cache is needed. */ + ext = NULL; + node->ext = NULL; + } + node->row = row_build(ROW_COPY_DATA, clust_index, rec, offsets, - NULL, &node->ext, node->heap); + NULL, ext, node->heap); if (node->is_delete) { node->upd_row = NULL; node->upd_ext = NULL; @@ -1454,7 +1479,6 @@ row_upd_sec_index_entry( entry = row_build_index_entry(node->row, node->ext, index, heap); ut_a(entry); - log_free_check(); mtr_start(&mtr); /* Set the query thread, so that ibuf_insert_low() will be @@ -1557,7 +1581,7 @@ Updates the secondary index record if it is changed in the row update or deletes it if this is a delete. @return DB_SUCCESS if operation successfully completed, else error code or DB_LOCK_WAIT */ -UNIV_INLINE +static ulint row_upd_sec_step( /*=============*/ @@ -1903,8 +1927,7 @@ row_upd_clust_step( then we have to free the file segments of the index tree associated with the index */ - if (node->is_delete - && ut_dulint_cmp(node->table->id, DICT_INDEXES_ID) == 0) { + if (node->is_delete && node->table->id == DICT_INDEXES_ID) { dict_drop_index_tree(btr_pcur_get_rec(pcur), mtr); @@ -2049,6 +2072,7 @@ row_upd( if (node->state == UPD_NODE_UPDATE_CLUSTERED || node->state == UPD_NODE_INSERT_CLUSTERED) { + log_free_check(); err = row_upd_clust_step(node, thr); if (err != DB_SUCCESS) { @@ -2063,6 +2087,8 @@ row_upd( } while (node->index != NULL) { + + log_free_check(); err = row_upd_sec_step(node, thr); if (err != DB_SUCCESS) { diff --git a/storage/innobase/row/row0vers.c b/storage/innobase/row/row0vers.c index a4fbb5289aa..3e6fc3f18b6 100644 --- a/storage/innobase/row/row0vers.c +++ b/storage/innobase/row/row0vers.c @@ -209,7 +209,7 @@ row_vers_impl_x_locked_off_kernel( prev_trx_id must have already committed for the trx_id to be able to modify the row. Therefore, prev_trx_id cannot hold any implicit lock. */ - if (vers_del && 0 != ut_dulint_cmp(trx_id, prev_trx_id)) { + if (vers_del && trx_id != prev_trx_id) { mutex_enter(&kernel_mutex); break; @@ -280,7 +280,7 @@ row_vers_impl_x_locked_off_kernel( break; } - if (0 != ut_dulint_cmp(trx_id, prev_trx_id)) { + if (trx_id != prev_trx_id) { /* The versions modified by the trx_id transaction end to prev_version: no implicit x-lock */ @@ -533,7 +533,7 @@ row_vers_build_for_consistent_read( undo_no of the record is < undo_no in the view. */ if (view->type == VIEW_HIGH_GRANULARITY - && ut_dulint_cmp(view->creator_trx_id, trx_id) == 0) { + && view->creator_trx_id == trx_id) { roll_ptr = row_get_rec_roll_ptr(version, index, *offsets); @@ -541,7 +541,7 @@ row_vers_build_for_consistent_read( undo_no = trx_undo_rec_get_undo_no(undo_rec); mem_heap_empty(heap); - if (ut_dulint_cmp(view->undo_no, undo_no) > 0) { + if (view->undo_no > undo_no) { /* The view already sees this version: we can copy it to in_heap and return */ @@ -632,7 +632,7 @@ row_vers_build_for_semi_consistent_read( mem_heap_t* heap = NULL; byte* buf; ulint err; - trx_id_t rec_trx_id = ut_dulint_zero; + trx_id_t rec_trx_id = 0; ut_ad(dict_index_is_clust(index)); ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX) @@ -684,7 +684,7 @@ row_vers_build_for_semi_consistent_read( rolled back and the transaction is removed from the global list of transactions. */ - if (!ut_dulint_cmp(rec_trx_id, version_trx_id)) { + if (rec_trx_id == version_trx_id) { /* The transaction was committed while we searched for earlier versions. Return the current version as a diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index 6354689105a..97d699dde99 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -142,6 +142,21 @@ use simulated aio we build below with threads. Currently we support native aio on windows and linux */ UNIV_INTERN my_bool srv_use_native_aio = TRUE; +#ifdef __WIN__ +/* Windows native condition variables. We use runtime loading / function +pointers, because they are not available on Windows Server 2003 and +Windows XP/2000. + +We use condition for events on Windows if possible, even if os_event +resembles Windows kernel event object well API-wise. The reason is +performance, kernel objects are heavyweights and WaitForSingleObject() is a +performance killer causing calling thread to context switch. Besides, Innodb +is preallocating large number (often millions) of os_events. With kernel event +objects it takes a big chunk out of non-paged pool, which is better suited +for tasks like IO than for storing idle event objects. */ +UNIV_INTERN ibool srv_use_native_conditions = FALSE; +#endif /* __WIN__ */ + UNIV_INTERN ulint srv_n_data_files = 0; UNIV_INTERN char** srv_data_file_names = NULL; /* size in database pages */ @@ -3007,6 +3022,8 @@ srv_purge_thread( slot_no = srv_table_reserve_slot(SRV_WORKER); + slot = srv_table_get_nth_slot(slot_no); + ++srv_n_threads_active[SRV_WORKER]; mutex_exit(&kernel_mutex); @@ -3058,20 +3075,16 @@ srv_purge_thread( mutex_enter(&kernel_mutex); + ut_ad(srv_table_get_nth_slot(slot_no) == slot); + /* Decrement the active count. */ srv_suspend_thread(); - mutex_exit(&kernel_mutex); + slot->in_use = FALSE; /* Free the thread local memory. */ thr_local_free(os_thread_get_curr_id()); - mutex_enter(&kernel_mutex); - - /* Free the slot for reuse. */ - slot = srv_table_get_nth_slot(slot_no); - slot->in_use = FALSE; - mutex_exit(&kernel_mutex); #ifdef UNIV_DEBUG_THREAD_CREATION diff --git a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c index 686ee6a4198..4da836672ec 100644 --- a/storage/innobase/srv/srv0start.c +++ b/storage/innobase/srv/srv0start.c @@ -1160,9 +1160,17 @@ innobase_start_or_create_for_mysql(void) srv_use_native_aio = FALSE; break; + + case OS_WIN2000: + case OS_WINXP: + /* On 2000 and XP, async IO is available. */ + srv_use_native_aio = TRUE; + break; + default: - /* On Win 2000 and XP use async i/o */ + /* Vista and later have both async IO and condition variables */ srv_use_native_aio = TRUE; + srv_use_native_conditions = TRUE; break; } @@ -1695,20 +1703,6 @@ innobase_start_or_create_for_mysql(void) /* fprintf(stderr, "Max allowed record size %lu\n", page_get_free_space_of_empty() / 2); */ - /* Create the thread which watches the timeouts for lock waits */ - os_thread_create(&srv_lock_timeout_thread, NULL, - thread_ids + 2 + SRV_MAX_N_IO_THREADS); - - /* Create the thread which warns of long semaphore waits */ - os_thread_create(&srv_error_monitor_thread, NULL, - thread_ids + 3 + SRV_MAX_N_IO_THREADS); - - /* Create the thread which prints InnoDB monitor info */ - os_thread_create(&srv_monitor_thread, NULL, - thread_ids + 4 + SRV_MAX_N_IO_THREADS); - - srv_is_being_started = FALSE; - if (trx_doublewrite == NULL) { /* Create the doublewrite buffer to a new tablespace */ @@ -1721,8 +1715,29 @@ innobase_start_or_create_for_mysql(void) We create the new segments only if it's a new database or the database was shutdown cleanly. */ + /* Note: When creating the extra rollback segments during an upgrade + we violate the latching order, even if the change buffer is empty. + We make an exception in sync0sync.c and check srv_is_being_started + for that violation. It cannot create a deadlock because we are still + running in single threaded mode essentially. Only the IO threads + should be running at this stage. */ + trx_sys_create_rsegs(TRX_SYS_N_RSEGS - 1); + /* Create the thread which watches the timeouts for lock waits */ + os_thread_create(&srv_lock_timeout_thread, NULL, + thread_ids + 2 + SRV_MAX_N_IO_THREADS); + + /* Create the thread which warns of long semaphore waits */ + os_thread_create(&srv_error_monitor_thread, NULL, + thread_ids + 3 + SRV_MAX_N_IO_THREADS); + + /* Create the thread which prints InnoDB monitor info */ + os_thread_create(&srv_monitor_thread, NULL, + thread_ids + 4 + SRV_MAX_N_IO_THREADS); + + srv_is_being_started = FALSE; + err = dict_create_or_check_foreign_constraint_tables(); if (err != DB_SUCCESS) { diff --git a/storage/innobase/sync/sync0arr.c b/storage/innobase/sync/sync0arr.c index 248bd2cd25d..753ebd958ac 100644 --- a/storage/innobase/sync/sync0arr.c +++ b/storage/innobase/sync/sync0arr.c @@ -250,7 +250,7 @@ sync_array_create( /* Then create the mutex to protect the wait array complex */ if (protection == SYNC_ARRAY_OS_MUTEX) { - arr->os_mutex = os_mutex_create(NULL); + arr->os_mutex = os_mutex_create(); } else if (protection == SYNC_ARRAY_MUTEX) { mutex_create(syn_arr_mutex_key, &arr->mutex, SYNC_NO_ORDER_CHECK); diff --git a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c index 235f733382d..8062d9e902e 100644 --- a/storage/innobase/sync/sync0sync.c +++ b/storage/innobase/sync/sync0sync.c @@ -40,6 +40,9 @@ Created 9/5/1995 Heikki Tuuri #include "srv0srv.h" #include "buf0types.h" #include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */ +#ifdef UNIV_SYNC_DEBUG +# include "srv0start.h" /* srv_is_being_started */ +#endif /* UNIV_SYNC_DEBUG */ /* REASONS FOR IMPLEMENTING THE SPIN LOCK MUTEX @@ -1152,6 +1155,13 @@ sync_thread_add_level( case SYNC_TREE_NODE_FROM_HASH: /* Do no order checking */ break; + case SYNC_TRX_SYS_HEADER: + if (srv_is_being_started) { + /* This is violated during trx_sys_create_rsegs() + when creating additional rollback segments when + upgrading in innobase_start_or_create_for_mysql(). */ + break; + } case SYNC_MEM_POOL: case SYNC_MEM_HASH: case SYNC_RECV: @@ -1160,7 +1170,6 @@ sync_thread_add_level( case SYNC_LOG_FLUSH_ORDER: case SYNC_THR_LOCAL: case SYNC_ANY_LATCH: - case SYNC_TRX_SYS_HEADER: case SYNC_FILE_FORMAT_TAG: case SYNC_DOUBLEWRITE: case SYNC_SEARCH_SYS: @@ -1222,8 +1231,12 @@ sync_thread_add_level( ut_a(sync_thread_levels_g(array, SYNC_IBUF_BITMAP - 1, TRUE)); } else { - ut_a(sync_thread_levels_g(array, SYNC_IBUF_BITMAP, - TRUE)); + /* This is violated during trx_sys_create_rsegs() + when creating additional rollback segments when + upgrading in innobase_start_or_create_for_mysql(). */ + ut_a(srv_is_being_started + || sync_thread_levels_g(array, SYNC_IBUF_BITMAP, + TRUE)); } break; case SYNC_FSP_PAGE: @@ -1492,14 +1505,16 @@ sync_print_wait_info( fprintf(file, "Mutex spin waits %llu, rounds %llu, OS waits %llu\n" - "RW-shared spins %llu, OS waits %llu;" - " RW-excl spins %llu, OS waits %llu\n", + "RW-shared spins %llu, rounds %llu, OS waits %llu\n" + "RW-excl spins %llu, rounds %llu, OS waits %llu\n", mutex_spin_wait_count, mutex_spin_round_count, mutex_os_wait_count, rw_s_spin_wait_count, + rw_s_spin_round_count, rw_s_os_wait_count, rw_x_spin_wait_count, + rw_x_spin_round_count, rw_x_os_wait_count); fprintf(file, diff --git a/storage/innobase/trx/trx0i_s.c b/storage/innobase/trx/trx0i_s.c index 8b719646023..1ad074769c7 100644 --- a/storage/innobase/trx/trx0i_s.c +++ b/storage/innobase/trx/trx0i_s.c @@ -444,7 +444,7 @@ fill_trx_row( ut_ad(mutex_own(&kernel_mutex)); - row->trx_id = trx_get_id(trx); + row->trx_id = trx->id; row->trx_started = (ib_time_t) trx->start_time; row->trx_state = trx_get_que_state_str(trx); @@ -462,7 +462,7 @@ fill_trx_row( row->trx_wait_started = 0; } - row->trx_weight = (ullint) ut_conv_dulint_to_longlong(TRX_WEIGHT(trx)); + row->trx_weight = (ullint) TRX_WEIGHT(trx); if (trx->mysql_thd == NULL) { /* For internal transactions e.g., purge and transactions @@ -527,7 +527,7 @@ thd_done: row->trx_rows_locked = lock_number_of_rows_locked(trx); - row->trx_rows_modified = ut_conv_dulint_to_longlong(trx->undo_no); + row->trx_rows_modified = trx->undo_no; row->trx_concurrency_tickets = trx->n_tickets_to_enter_innodb; diff --git a/storage/innobase/trx/trx0purge.c b/storage/innobase/trx/trx0purge.c index 550a8c9c4b3..e17ed547050 100644 --- a/storage/innobase/trx/trx0purge.c +++ b/storage/innobase/trx/trx0purge.c @@ -145,47 +145,44 @@ void trx_purge_arr_get_biggest( /*======================*/ trx_undo_arr_t* arr, /*!< in: purge array */ - trx_id_t* trx_no, /*!< out: transaction number: ut_dulint_zero + trx_id_t* trx_no, /*!< out: transaction number: 0 if array is empty */ undo_no_t* undo_no)/*!< out: undo number */ { trx_undo_inf_t* cell; trx_id_t pair_trx_no; undo_no_t pair_undo_no; - int trx_cmp; - ulint n_used; ulint i; ulint n; - n = 0; - n_used = arr->n_used; - pair_trx_no = ut_dulint_zero; - pair_undo_no = ut_dulint_zero; + n = arr->n_used; + pair_trx_no = 0; + pair_undo_no = 0; - for (i = 0;; i++) { - cell = trx_undo_arr_get_nth_info(arr, i); + if (n) { + for (i = 0;; i++) { + cell = trx_undo_arr_get_nth_info(arr, i); - if (cell->in_use) { - n++; - trx_cmp = ut_dulint_cmp(cell->trx_no, pair_trx_no); + if (!cell->in_use) { + continue; + } - if ((trx_cmp > 0) - || ((trx_cmp == 0) - && (ut_dulint_cmp(cell->undo_no, - pair_undo_no) >= 0))) { + if ((cell->trx_no > pair_trx_no) + || ((cell->trx_no == pair_trx_no) + && cell->undo_no >= pair_undo_no)) { pair_trx_no = cell->trx_no; pair_undo_no = cell->undo_no; } - } - - if (n == n_used) { - *trx_no = pair_trx_no; - *undo_no = pair_undo_no; - return; + if (!--n) { + break; + } } } + + *trx_no = pair_trx_no; + *undo_no = pair_undo_no; } /****************************************************************//** @@ -233,8 +230,8 @@ trx_purge_sys_create(void) purge_sys->n_pages_handled = 0; - purge_sys->purge_trx_no = ut_dulint_zero; - purge_sys->purge_undo_no = ut_dulint_zero; + purge_sys->purge_trx_no = 0; + purge_sys->purge_undo_no = 0; purge_sys->next_stored = FALSE; rw_lock_create(trx_purge_latch_key, @@ -257,7 +254,7 @@ trx_purge_sys_create(void) purge_sys->query = trx_purge_graph_build(); - purge_sys->view = read_view_oldest_copy_or_open_new(ut_dulint_zero, + purge_sys->view = read_view_oldest_copy_or_open_new(0, purge_sys->heap); } @@ -370,7 +367,7 @@ trx_purge_add_update_undo_to_history( } /* Write the trx number to the undo log header */ - mlog_write_dulint(undo_header + TRX_UNDO_TRX_NO, trx->no, mtr); + mlog_write_ull(undo_header + TRX_UNDO_TRX_NO, trx->no, mtr); /* Write information about delete markings to the undo log header */ if (!undo->del_marks) { @@ -512,9 +509,9 @@ trx_purge_truncate_rseg_history( page_t* undo_page; trx_ulogf_t* log_hdr; trx_usegf_t* seg_hdr; - int cmp; ulint n_removed_logs = 0; mtr_t mtr; + trx_id_t undo_trx_no; ut_ad(mutex_own(&(purge_sys->mutex))); @@ -540,15 +537,16 @@ loop: hdr_addr.page, &mtr); log_hdr = undo_page + hdr_addr.boffset; + undo_trx_no = mach_read_from_8(log_hdr + TRX_UNDO_TRX_NO); - cmp = ut_dulint_cmp(mach_read_from_8(log_hdr + TRX_UNDO_TRX_NO), - limit_trx_no); - if (cmp == 0) { - trx_undo_truncate_start(rseg, rseg->space, hdr_addr.page, - hdr_addr.boffset, limit_undo_no); - } + if (undo_trx_no >= limit_trx_no) { + if (undo_trx_no == limit_trx_no) { + trx_undo_truncate_start(rseg, rseg->space, + hdr_addr.page, + hdr_addr.boffset, + limit_undo_no); + } - if (cmp >= 0) { mutex_enter(&kernel_mutex); ut_a(trx_sys->rseg_history_len >= n_removed_logs); trx_sys->rseg_history_len -= n_removed_logs; @@ -614,7 +612,7 @@ trx_purge_truncate_history(void) trx_purge_arr_get_biggest(purge_sys->arr, &limit_trx_no, &limit_undo_no); - if (ut_dulint_is_zero(limit_trx_no)) { + if (limit_trx_no == 0) { limit_trx_no = purge_sys->purge_trx_no; limit_undo_no = purge_sys->purge_undo_no; @@ -623,13 +621,12 @@ trx_purge_truncate_history(void) /* We play safe and set the truncate limit at most to the purge view low_limit number, though this is not necessary */ - if (ut_dulint_cmp(limit_trx_no, purge_sys->view->low_limit_no) >= 0) { + if (limit_trx_no >= purge_sys->view->low_limit_no) { limit_trx_no = purge_sys->view->low_limit_no; - limit_undo_no = ut_dulint_zero; + limit_undo_no = 0; } - ut_ad((ut_dulint_cmp(limit_trx_no, - purge_sys->view->low_limit_no) <= 0)); + ut_ad(limit_trx_no <= purge_sys->view->low_limit_no); rseg = UT_LIST_GET_FIRST(trx_sys->rseg_list); @@ -684,8 +681,8 @@ trx_purge_rseg_get_next_history_log( ut_a(rseg->last_page_no != FIL_NULL); - purge_sys->purge_trx_no = ut_dulint_add(rseg->last_trx_no, 1); - purge_sys->purge_undo_no = ut_dulint_zero; + purge_sys->purge_trx_no = rseg->last_trx_no + 1; + purge_sys->purge_undo_no = 0; purge_sys->next_stored = FALSE; mtr_start(&mtr); @@ -787,7 +784,7 @@ trx_purge_choose_next_log(void) rseg = UT_LIST_GET_FIRST(trx_sys->rseg_list); - min_trx_no = ut_dulint_max; + min_trx_no = IB_ULONGLONG_MAX; min_rseg = NULL; @@ -796,9 +793,8 @@ trx_purge_choose_next_log(void) if (rseg->last_page_no != FIL_NULL) { - if ((min_rseg == NULL) - || (ut_dulint_cmp(min_trx_no, - rseg->last_trx_no) > 0)) { + if (min_rseg == NULL + || min_trx_no > rseg->last_trx_no) { min_rseg = rseg; min_trx_no = rseg->last_trx_no; @@ -848,7 +844,7 @@ trx_purge_choose_next_log(void) if (rec == &trx_purge_dummy_rec) { - purge_sys->purge_undo_no = ut_dulint_zero; + purge_sys->purge_undo_no = 0; purge_sys->page_no = page_no; purge_sys->offset = 0; } else { @@ -1041,8 +1037,7 @@ trx_purge_fetch_next_rec( return(NULL); } - if (ut_dulint_cmp(purge_sys->purge_trx_no, - purge_sys->view->low_limit_no) >= 0) { + if (purge_sys->purge_trx_no >= purge_sys->view->low_limit_no) { purge_sys->state = TRX_STOP_PURGE; trx_purge_truncate_if_arr_empty(); @@ -1052,10 +1047,10 @@ trx_purge_fetch_next_rec( return(NULL); } - /* fprintf(stderr, "Thread %lu purging trx %lu undo record %lu\n", + /* fprintf(stderr, "Thread %lu purging trx %llu undo record %llu\n", os_thread_get_curr_id(), - ut_dulint_get_low(purge_sys->purge_trx_no), - ut_dulint_get_low(purge_sys->purge_undo_no)); */ + (ullint) purge_sys->purge_trx_no, + (ullint) purge_sys->purge_undo_no); */ *roll_ptr = trx_undo_build_roll_ptr(FALSE, (purge_sys->rseg)->id, purge_sys->page_no, @@ -1064,8 +1059,7 @@ trx_purge_fetch_next_rec( *cell = trx_purge_arr_store_info(purge_sys->purge_trx_no, purge_sys->purge_undo_no); - ut_ad(ut_dulint_cmp(purge_sys->purge_trx_no, - (purge_sys->view)->low_limit_no) < 0); + ut_ad(purge_sys->purge_trx_no < purge_sys->view->low_limit_no); /* The following call will advance the stored values of purge_trx_no and purge_undo_no, therefore we had to store them first */ @@ -1157,7 +1151,7 @@ trx_purge( } } - purge_sys->view = read_view_oldest_copy_or_open_new(ut_dulint_zero, + purge_sys->view = read_view_oldest_copy_or_open_new(0, purge_sys->heap); mutex_exit(&kernel_mutex); @@ -1215,8 +1209,8 @@ trx_purge_sys_print(void) fprintf(stderr, "InnoDB: Purge trx n:o " TRX_ID_FMT ", undo n:o " TRX_ID_FMT "\n", - TRX_ID_PREP_PRINTF(purge_sys->purge_trx_no), - TRX_ID_PREP_PRINTF(purge_sys->purge_undo_no)); + (ullint) purge_sys->purge_trx_no, + (ullint) purge_sys->purge_undo_no); fprintf(stderr, "InnoDB: Purge next stored %lu, page_no %lu, offset %lu,\n" "InnoDB: Purge hdr_page_no %lu, hdr_offset %lu\n", diff --git a/storage/innobase/trx/trx0rec.c b/storage/innobase/trx/trx0rec.c index f50e10ed756..e7e9a008db4 100644 --- a/storage/innobase/trx/trx0rec.c +++ b/storage/innobase/trx/trx0rec.c @@ -242,8 +242,8 @@ trx_undo_page_report_insert( /* Store first some general parameters to the undo log */ *ptr++ = TRX_UNDO_INSERT_REC; - ptr += mach_dulint_write_much_compressed(ptr, trx->undo_no); - ptr += mach_dulint_write_much_compressed(ptr, index->table->id); + ptr += mach_ull_write_much_compressed(ptr, trx->undo_no); + ptr += mach_ull_write_much_compressed(ptr, index->table->id); /*----------------------------------------*/ /* Store then the fields required to uniquely determine the record to be inserted in the clustered index */ @@ -289,7 +289,7 @@ trx_undo_rec_get_pars( ibool* updated_extern, /*!< out: TRUE if we updated an externally stored fild */ undo_no_t* undo_no, /*!< out: undo log record number */ - dulint* table_id) /*!< out: table id */ + table_id_t* table_id) /*!< out: table id */ { byte* ptr; ulint type_cmpl; @@ -309,11 +309,11 @@ trx_undo_rec_get_pars( *type = type_cmpl & (TRX_UNDO_CMPL_INFO_MULT - 1); *cmpl_info = type_cmpl / TRX_UNDO_CMPL_INFO_MULT; - *undo_no = mach_dulint_read_much_compressed(ptr); - ptr += mach_dulint_get_much_compressed_size(*undo_no); + *undo_no = mach_ull_read_much_compressed(ptr); + ptr += mach_ull_get_much_compressed_size(*undo_no); - *table_id = mach_dulint_read_much_compressed(ptr); - ptr += mach_dulint_get_much_compressed_size(*table_id); + *table_id = mach_ull_read_much_compressed(ptr); + ptr += mach_ull_get_much_compressed_size(*table_id); return(ptr); } @@ -598,9 +598,9 @@ trx_undo_page_report_modify( type_cmpl_ptr = ptr; *ptr++ = (byte) type_cmpl; - ptr += mach_dulint_write_much_compressed(ptr, trx->undo_no); + ptr += mach_ull_write_much_compressed(ptr, trx->undo_no); - ptr += mach_dulint_write_much_compressed(ptr, table->id); + ptr += mach_ull_write_much_compressed(ptr, table->id); /*----------------------------------------*/ /* Store the state of the info bits */ @@ -620,16 +620,16 @@ trx_undo_page_report_modify( by some other trx as it must have committed by now for us to allow an over-write. */ if (ignore_prefix) { - ignore_prefix = ut_dulint_cmp(trx_id, trx->id) != 0; + ignore_prefix = (trx_id != trx->id); } - ptr += mach_dulint_write_compressed(ptr, trx_id); + ptr += mach_ull_write_compressed(ptr, trx_id); field = rec_get_nth_field(rec, offsets, dict_index_get_sys_col_pos( index, DATA_ROLL_PTR), &flen); ut_ad(flen == DATA_ROLL_PTR_LEN); - ptr += mach_dulint_write_compressed(ptr, trx_read_roll_ptr(field)); + ptr += mach_ull_write_compressed(ptr, trx_read_roll_ptr(field)); /*----------------------------------------*/ /* Store then the fields required to uniquely determine the @@ -848,11 +848,11 @@ trx_undo_update_rec_get_sys_cols( /* Read the values of the system columns */ - *trx_id = mach_dulint_read_compressed(ptr); - ptr += mach_dulint_get_compressed_size(*trx_id); + *trx_id = mach_ull_read_compressed(ptr); + ptr += mach_ull_get_compressed_size(*trx_id); - *roll_ptr = mach_dulint_read_compressed(ptr); - ptr += mach_dulint_get_compressed_size(*roll_ptr); + *roll_ptr = mach_ull_read_compressed(ptr); + ptr += mach_ull_get_compressed_size(*roll_ptr); return(ptr); } @@ -1168,7 +1168,7 @@ trx_undo_report_row_operation( index, otherwise NULL */ roll_ptr_t* roll_ptr) /*!< out: rollback pointer to the inserted undo log record, - ut_dulint_zero if BTR_NO_UNDO_LOG + 0 if BTR_NO_UNDO_LOG flag was specified */ { trx_t* trx; @@ -1186,7 +1186,7 @@ trx_undo_report_row_operation( if (flags & BTR_NO_UNDO_LOG_FLAG) { - *roll_ptr = ut_dulint_zero; + *roll_ptr = 0; return(DB_SUCCESS); } @@ -1284,7 +1284,7 @@ trx_undo_report_row_operation( undo->top_undo_no = trx->undo_no; undo->guess_block = undo_block; - UT_DULINT_INC(trx->undo_no); + trx->undo_no++; mutex_exit(&trx->undo_mutex); @@ -1433,7 +1433,7 @@ trx_undo_prev_version_build( trx_id_t rec_trx_id; ulint type; undo_no_t undo_no; - dulint table_id; + table_id_t table_id; trx_id_t trx_id; roll_ptr_t roll_ptr; roll_ptr_t old_roll_ptr; @@ -1523,7 +1523,7 @@ trx_undo_prev_version_build( roll_ptr, info_bits, NULL, heap, &update); - if (ut_dulint_cmp(table_id, index->table->id) != 0) { + if (UNIV_UNLIKELY(table_id != index->table->id)) { ptr = NULL; fprintf(stderr, @@ -1544,16 +1544,14 @@ trx_undo_prev_version_build( fprintf(stderr, "InnoDB: table %s, index %s, n_uniq %lu\n" "InnoDB: undo rec address %p, type %lu cmpl_info %lu\n" - "InnoDB: undo rec table id %lu %lu," - " index table id %lu %lu\n" + "InnoDB: undo rec table id %llu," + " index table id %llu\n" "InnoDB: dump of 150 bytes in undo rec: ", index->table_name, index->name, (ulong) dict_index_get_n_unique(index), undo_rec, (ulong) type, (ulong) cmpl_info, - (ulong) ut_dulint_get_high(table_id), - (ulong) ut_dulint_get_low(table_id), - (ulong) ut_dulint_get_high(index->table->id), - (ulong) ut_dulint_get_low(index->table->id)); + (ullint) table_id, + (ullint) index->table->id); ut_print_buf(stderr, undo_rec, 150); fputs("\n" "InnoDB: index record ", stderr); @@ -1564,14 +1562,10 @@ trx_undo_prev_version_build( fprintf(stderr, "\n" "InnoDB: Record trx id " TRX_ID_FMT ", update rec trx id " TRX_ID_FMT "\n" - "InnoDB: Roll ptr in rec %lu %lu, in update rec" - " %lu %lu\n", - TRX_ID_PREP_PRINTF(rec_trx_id), - TRX_ID_PREP_PRINTF(trx_id), - (ulong) ut_dulint_get_high(old_roll_ptr), - (ulong) ut_dulint_get_low(old_roll_ptr), - (ulong) ut_dulint_get_high(roll_ptr), - (ulong) ut_dulint_get_low(roll_ptr)); + "InnoDB: Roll ptr in rec " TRX_ID_FMT + ", in update rec" TRX_ID_FMT "\n", + (ullint) rec_trx_id, (ullint) trx_id, + (ullint) old_roll_ptr, (ullint) roll_ptr); trx_purge_sys_print(); return(DB_ERROR); diff --git a/storage/innobase/trx/trx0roll.c b/storage/innobase/trx/trx0roll.c index 4f1a71a5531..42b8a8685ad 100644 --- a/storage/innobase/trx/trx0roll.c +++ b/storage/innobase/trx/trx0roll.c @@ -52,7 +52,7 @@ static trx_t* trx_roll_crash_recv_trx = NULL; /** In crash recovery we set this to the undo n:o of the current trx to be rolled back. Then we can print how many % the rollback has progressed. */ -static ib_int64_t trx_roll_max_undo_no; +static undo_no_t trx_roll_max_undo_no; /** Auxiliary variable which tells the previous progress % we printed */ static ulint trx_roll_progress_printed_pct; @@ -443,7 +443,7 @@ trx_rollback_active( ut_a(thr == que_fork_start_command(fork)); trx_roll_crash_recv_trx = trx; - trx_roll_max_undo_no = ut_conv_dulint_to_longlong(trx->undo_no); + trx_roll_max_undo_no = trx->undo_no; trx_roll_progress_printed_pct = 0; rows_to_undo = trx_roll_max_undo_no; @@ -456,7 +456,7 @@ trx_rollback_active( fprintf(stderr, " InnoDB: Rolling back trx with id " TRX_ID_FMT ", %lu%s" " rows to undo\n", - TRX_ID_PREP_PRINTF(trx->id), + (ullint) trx->id, (ulong) rows_to_undo, unit); mutex_exit(&kernel_mutex); @@ -478,8 +478,9 @@ trx_rollback_active( mutex_exit(&kernel_mutex); fprintf(stderr, - "InnoDB: Waiting for rollback of trx id %lu to end\n", - (ulong) ut_dulint_get_low(trx->id)); + "InnoDB: Waiting for rollback of trx id " + TRX_ID_FMT " to end\n", + (ullint) trx->id); os_thread_sleep(100000); mutex_enter(&kernel_mutex); @@ -488,16 +489,15 @@ trx_rollback_active( mutex_exit(&kernel_mutex); if (trx_get_dict_operation(trx) != TRX_DICT_OP_NONE - && !ut_dulint_is_zero(trx->table_id)) { + && trx->table_id != 0) { /* If the transaction was for a dictionary operation, we drop the relevant table, if it still exists */ fprintf(stderr, - "InnoDB: Dropping table with id %lu %lu" + "InnoDB: Dropping table with id %llu" " in recovery if it exists\n", - (ulong) ut_dulint_get_high(trx->table_id), - (ulong) ut_dulint_get_low(trx->table_id)); + (ullint) trx->table_id); table = dict_table_get_on_id_low(trx->table_id); @@ -521,7 +521,7 @@ trx_rollback_active( fprintf(stderr, "\nInnoDB: Rolling back of trx id " TRX_ID_FMT " completed\n", - TRX_ID_PREP_PRINTF(trx->id)); + (ullint) trx->id); mem_heap_free(heap); trx_roll_crash_recv_trx = NULL; @@ -574,7 +574,7 @@ loop: fprintf(stderr, "InnoDB: Cleaning up trx with id " TRX_ID_FMT "\n", - TRX_ID_PREP_PRINTF(trx->id)); + (ullint) trx->id); trx_cleanup_at_db_startup(trx); goto loop; @@ -710,7 +710,7 @@ trx_undo_arr_store_info( } else { n++; - if (0 == ut_dulint_cmp(cell->undo_no, undo_no)) { + if (cell->undo_no == undo_no) { if (stored_here) { stored_here->in_use = FALSE; @@ -754,7 +754,7 @@ trx_undo_arr_remove_info( cell = trx_undo_arr_get_nth_info(arr, i); if (cell->in_use - && 0 == ut_dulint_cmp(cell->undo_no, undo_no)) { + && cell->undo_no == undo_no) { cell->in_use = FALSE; @@ -769,7 +769,7 @@ trx_undo_arr_remove_info( /*******************************************************************//** Gets the biggest undo number in an array. -@return biggest value, ut_dulint_zero if the array is empty */ +@return biggest value, 0 if the array is empty */ static undo_no_t trx_undo_arr_get_biggest( @@ -784,14 +784,14 @@ trx_undo_arr_get_biggest( n = 0; n_used = arr->n_used; - biggest = ut_dulint_zero; + biggest = 0; for (i = 0;; i++) { cell = trx_undo_arr_get_nth_info(arr, i); if (cell->in_use) { n++; - if (ut_dulint_cmp(cell->undo_no, biggest) > 0) { + if (cell->undo_no > biggest) { biggest = cell->undo_no; } @@ -827,9 +827,9 @@ trx_roll_try_truncate( if (arr->n_used > 0) { biggest = trx_undo_arr_get_biggest(arr); - if (ut_dulint_cmp(biggest, limit) >= 0) { + if (biggest >= limit) { - limit = ut_dulint_add(biggest, 1); + limit = biggest + 1; } } @@ -865,9 +865,9 @@ trx_roll_pop_top_rec( undo->top_page_no, mtr); offset = undo->top_offset; - /* fprintf(stderr, "Thread %lu undoing trx %lu undo record %lu\n", - os_thread_get_curr_id(), ut_dulint_get_low(trx->id), - ut_dulint_get_low(undo->top_undo_no)); */ + /* fprintf(stderr, "Thread %lu undoing trx " TRX_ID_FMT + " undo record " TRX_ID_FMT "\n", + os_thread_get_curr_id(), trx->id, undo->top_undo_no); */ prev_rec = trx_undo_get_prev_rec(undo_page + offset, undo->hdr_page_no, undo->hdr_offset, @@ -938,15 +938,14 @@ try_again: undo = upd_undo; } else if (!upd_undo || upd_undo->empty) { undo = ins_undo; - } else if (ut_dulint_cmp(upd_undo->top_undo_no, - ins_undo->top_undo_no) > 0) { + } else if (upd_undo->top_undo_no > ins_undo->top_undo_no) { undo = upd_undo; } else { undo = ins_undo; } if (!undo || undo->empty - || (ut_dulint_cmp(limit, undo->top_undo_no) > 0)) { + || limit > undo->top_undo_no) { if ((trx->undo_no_arr)->n_used == 0) { /* Rollback is ending */ @@ -978,7 +977,7 @@ try_again: undo_no = trx_undo_rec_get_undo_no(undo_rec); - ut_ad(ut_dulint_cmp(ut_dulint_add(undo_no, 1), trx->undo_no) == 0); + ut_ad(undo_no + 1 == trx->undo_no); /* We print rollback progress info if we are in a crash recovery and the transaction has at least 1000 row operations to undo. */ @@ -986,8 +985,7 @@ try_again: if (trx == trx_roll_crash_recv_trx && trx_roll_max_undo_no > 1000) { progress_pct = 100 - (ulint) - ((ut_conv_dulint_to_longlong(undo_no) * 100) - / trx_roll_max_undo_no); + ((undo_no * 100) / trx_roll_max_undo_no); if (progress_pct != trx_roll_progress_printed_pct) { if (trx_roll_progress_printed_pct == 0) { fprintf(stderr, @@ -1090,22 +1088,21 @@ trx_rollback( /* Initialize the rollback field in the transaction */ - if (sig->type == TRX_SIG_TOTAL_ROLLBACK) { - - trx->roll_limit = ut_dulint_zero; - - } else if (sig->type == TRX_SIG_ROLLBACK_TO_SAVEPT) { - + switch (sig->type) { + case TRX_SIG_TOTAL_ROLLBACK: + trx->roll_limit = 0; + break; + case TRX_SIG_ROLLBACK_TO_SAVEPT: trx->roll_limit = (sig->savept).least_undo_no; - - } else if (sig->type == TRX_SIG_ERROR_OCCURRED) { - + break; + case TRX_SIG_ERROR_OCCURRED: trx->roll_limit = trx->last_sql_stat_start.least_undo_no; - } else { + break; + default: ut_error; } - ut_a(ut_dulint_cmp(trx->roll_limit, trx->undo_no) <= 0); + ut_a(trx->roll_limit <= trx->undo_no); trx->pages_undone = 0; @@ -1269,8 +1266,8 @@ trx_finish_rollback_off_kernel( #ifdef UNIV_DEBUG if (lock_print_waits) { - fprintf(stderr, "Trx %lu rollback finished\n", - (ulong) ut_dulint_get_low(trx->id)); + fprintf(stderr, "Trx " TRX_ID_FMT " rollback finished\n", + (ullint) trx->id); } #endif /* UNIV_DEBUG */ diff --git a/storage/innobase/trx/trx0rseg.c b/storage/innobase/trx/trx0rseg.c index b458364b05d..740320f68c1 100644 --- a/storage/innobase/trx/trx0rseg.c +++ b/storage/innobase/trx/trx0rseg.c @@ -236,8 +236,8 @@ trx_rseg_mem_create( node_addr.page, mtr) + node_addr.boffset; - rseg->last_trx_no = mtr_read_dulint( - undo_log_hdr + TRX_UNDO_TRX_NO, mtr); + rseg->last_trx_no = mach_read_from_8( + undo_log_hdr + TRX_UNDO_TRX_NO); rseg->last_del_marks = mtr_read_ulint( undo_log_hdr + TRX_UNDO_DEL_MARKS, MLOG_2BYTES, mtr); } else { diff --git a/storage/innobase/trx/trx0sys.c b/storage/innobase/trx/trx0sys.c index e2f0ff6d532..640412c4572 100644 --- a/storage/innobase/trx/trx0sys.c +++ b/storage/innobase/trx/trx0sys.c @@ -664,8 +664,8 @@ trx_sys_flush_max_trx_id(void) sys_header = trx_sysf_get(&mtr); - mlog_write_dulint(sys_header + TRX_SYS_TRX_ID_STORE, - trx_sys->max_trx_id, &mtr); + mlog_write_ull(sys_header + TRX_SYS_TRX_ID_STORE, + trx_sys->max_trx_id, &mtr); mtr_commit(&mtr); } @@ -912,8 +912,7 @@ trx_sysf_create( sys_header = trx_sysf_get(mtr); /* Start counting transaction ids from number 1 up */ - mach_write_to_8(sys_header + TRX_SYS_TRX_ID_STORE, - ut_dulint_create(0, 1)); + mach_write_to_8(sys_header + TRX_SYS_TRX_ID_STORE, 1); /* Reset the rollback segment slots. Old versions of InnoDB define TRX_SYS_N_RSEGS as 256 (TRX_SYS_OLD_N_RSEGS) and expect @@ -950,7 +949,7 @@ trx_sys_init_at_db_start(void) /*==========================*/ { trx_sysf_t* sys_header; - ib_int64_t rows_to_undo = 0; + ib_uint64_t rows_to_undo = 0; const char* unit = ""; trx_t* trx; mtr_t mtr; @@ -976,12 +975,10 @@ trx_sys_init_at_db_start(void) to the disk-based header! Thus trx id values will not overlap when the database is repeatedly started! */ - trx_sys->max_trx_id = ut_dulint_add( - ut_dulint_align_up(mtr_read_dulint( - sys_header - + TRX_SYS_TRX_ID_STORE, &mtr), - TRX_SYS_TRX_ID_WRITE_MARGIN), - 2 * TRX_SYS_TRX_ID_WRITE_MARGIN); + trx_sys->max_trx_id = 2 * TRX_SYS_TRX_ID_WRITE_MARGIN + + ut_uint64_align_up(mach_read_from_8(sys_header + + TRX_SYS_TRX_ID_STORE), + TRX_SYS_TRX_ID_WRITE_MARGIN); UT_LIST_INIT(trx_sys->mysql_trx_list); trx_dummy_sess = sess_open(); @@ -992,9 +989,8 @@ trx_sys_init_at_db_start(void) for (;;) { - if ( trx->conc_state != TRX_PREPARED) { - rows_to_undo += ut_conv_dulint_to_longlong( - trx->undo_no); + if (trx->conc_state != TRX_PREPARED) { + rows_to_undo += trx->undo_no; } trx = UT_LIST_GET_NEXT(trx_list, trx); @@ -1017,7 +1013,7 @@ trx_sys_init_at_db_start(void) (ulong) rows_to_undo, unit); fprintf(stderr, "InnoDB: Trx id counter is " TRX_ID_FMT "\n", - TRX_ID_PREP_PRINTF(trx_sys->max_trx_id)); + (ullint) trx_sys->max_trx_id); } UT_LIST_INIT(trx_sys->view_list); @@ -1061,7 +1057,7 @@ trx_sys_file_format_max_write( mtr_t mtr; byte* ptr; buf_block_t* block; - ulint tag_value_low; + ib_uint64_t tag_value; mtr_start(&mtr); @@ -1072,17 +1068,13 @@ trx_sys_file_format_max_write( file_format_max.name = trx_sys_file_format_id_to_name(format_id); ptr = buf_block_get_frame(block) + TRX_SYS_FILE_FORMAT_TAG; - tag_value_low = format_id + TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW; + tag_value = format_id + TRX_SYS_FILE_FORMAT_TAG_MAGIC_N; if (name) { *name = file_format_max.name; } - mlog_write_dulint( - ptr, - ut_dulint_create(TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH, - tag_value_low), - &mtr); + mlog_write_ull(ptr, tag_value, &mtr); mtr_commit(&mtr); @@ -1100,8 +1092,7 @@ trx_sys_file_format_max_read(void) mtr_t mtr; const byte* ptr; const buf_block_t* block; - ulint format_id; - dulint file_format_id; + ib_id_t file_format_id; /* Since this is called during the startup phase it's safe to read the value without a covering mutex. */ @@ -1115,16 +1106,15 @@ trx_sys_file_format_max_read(void) mtr_commit(&mtr); - format_id = file_format_id.low - TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW; + file_format_id -= TRX_SYS_FILE_FORMAT_TAG_MAGIC_N; - if (file_format_id.high != TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH - || format_id >= FILE_FORMAT_NAME_N) { + if (file_format_id >= FILE_FORMAT_NAME_N) { /* Either it has never been tagged, or garbage in it. */ return(ULINT_UNDEFINED); } - return(format_id); + return((ulint) file_format_id); } /*****************************************************************//** @@ -1416,7 +1406,7 @@ trx_sys_read_file_format_id( byte buf[UNIV_PAGE_SIZE * 2]; page_t* page = ut_align(buf, UNIV_PAGE_SIZE); const byte* ptr; - dulint file_format_id; + ib_id_t file_format_id; *format_id = ULINT_UNDEFINED; @@ -1430,9 +1420,9 @@ trx_sys_read_file_format_id( if (!success) { /* The following call prints an error message */ os_file_get_last_error(TRUE); - + ut_print_timestamp(stderr); - + fprintf(stderr, " ibbackup: Error: trying to read system tablespace file format,\n" " ibbackup: but could not open the tablespace file %s!\n", @@ -1449,9 +1439,9 @@ trx_sys_read_file_format_id( if (!success) { /* The following call prints an error message */ os_file_get_last_error(TRUE); - + ut_print_timestamp(stderr); - + fprintf(stderr, " ibbackup: Error: trying to read system table space file format,\n" " ibbackup: but failed to read the tablespace file %s!\n", @@ -1465,17 +1455,16 @@ trx_sys_read_file_format_id( /* get the file format from the page */ ptr = page + TRX_SYS_FILE_FORMAT_TAG; file_format_id = mach_read_from_8(ptr); + file_format_id -= TRX_SYS_FILE_FORMAT_TAG_MAGIC_N; - *format_id = file_format_id.low - TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW; - - if (file_format_id.high != TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH - || *format_id >= FILE_FORMAT_NAME_N) { + if (file_format_id >= FILE_FORMAT_NAME_N) { /* Either it has never been tagged, or garbage in it. */ - *format_id = ULINT_UNDEFINED; return(TRUE); } - + + *format_id = (ulint) file_format_id; + return(TRUE); } diff --git a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c index c794671f7be..19e3eb26421 100644 --- a/storage/innobase/trx/trx0trx.c +++ b/storage/innobase/trx/trx0trx.c @@ -109,8 +109,8 @@ trx_create( trx->isolation_level = TRX_ISO_REPEATABLE_READ; - trx->id = ut_dulint_zero; - trx->no = ut_dulint_max; + trx->id = 0; + trx->no = IB_ULONGLONG_MAX; trx->support_xa = TRUE; @@ -121,7 +121,7 @@ trx_create( trx->must_flush_log_later = FALSE; trx->dict_operation = TRX_DICT_OP_NONE; - trx->table_id = ut_dulint_zero; + trx->table_id = 0; trx->mysql_thd = NULL; trx->active_trans = 0; @@ -137,8 +137,8 @@ trx_create( trx->rseg = NULL; - trx->undo_no = ut_dulint_zero; - trx->last_sql_stat_start.least_undo_no = ut_dulint_zero; + trx->undo_no = 0; + trx->last_sql_stat_start.least_undo_no = 0; trx->insert_undo = NULL; trx->update_undo = NULL; trx->undo_no_arr = NULL; @@ -392,9 +392,9 @@ trx_list_insert_ordered( trx2 = UT_LIST_GET_FIRST(trx_sys->trx_list); while (trx2 != NULL) { - if (ut_dulint_cmp(trx->id, trx2->id) >= 0) { + if (trx->id >= trx2->id) { - ut_ad(ut_dulint_cmp(trx->id, trx2->id) == 1); + ut_ad(trx->id > trx2->id); break; } trx2 = UT_LIST_GET_NEXT(trx_list, trx2); @@ -463,7 +463,7 @@ trx_lists_init_at_db_start(void) TRX_ID_FMT " was in the" " XA prepared state.\n", - TRX_ID_PREP_PRINTF(trx->id)); + (ullint) trx->id); if (srv_force_recovery == 0) { @@ -495,9 +495,9 @@ trx_lists_init_at_db_start(void) trx->conc_state = TRX_ACTIVE; /* A running transaction always has the number - field inited to ut_dulint_max */ + field inited to IB_ULONGLONG_MAX */ - trx->no = ut_dulint_max; + trx->no = IB_ULONGLONG_MAX; } if (undo->dict_operation) { @@ -507,8 +507,7 @@ trx_lists_init_at_db_start(void) } if (!undo->empty) { - trx->undo_no = ut_dulint_add(undo->top_undo_no, - 1); + trx->undo_no = undo->top_undo_no + 1; } trx_list_insert_ordered(trx); @@ -539,8 +538,7 @@ trx_lists_init_at_db_start(void) "InnoDB: Transaction " TRX_ID_FMT " was in the" " XA prepared state.\n", - TRX_ID_PREP_PRINTF( - trx->id)); + (ullint) trx->id); if (srv_force_recovery == 0) { @@ -571,9 +569,9 @@ trx_lists_init_at_db_start(void) /* A running transaction always has the number field inited to - ut_dulint_max */ + IB_ULONGLONG_MAX */ - trx->no = ut_dulint_max; + trx->no = IB_ULONGLONG_MAX; } trx->rseg = rseg; @@ -589,11 +587,9 @@ trx_lists_init_at_db_start(void) trx->update_undo = undo; if ((!undo->empty) - && (ut_dulint_cmp(undo->top_undo_no, - trx->undo_no) >= 0)) { + && undo->top_undo_no >= trx->undo_no) { - trx->undo_no = ut_dulint_add(undo->top_undo_no, - 1); + trx->undo_no = undo->top_undo_no + 1; } undo = UT_LIST_GET_NEXT(undo_list, undo); @@ -655,7 +651,7 @@ trx_start_low( ut_ad(trx->rseg == NULL); if (trx->is_purge) { - trx->id = ut_dulint_zero; + trx->id = 0; trx->conc_state = TRX_ACTIVE; trx->start_time = time(NULL); @@ -673,10 +669,10 @@ trx_start_low( trx->id = trx_sys_get_new_trx_id(); - /* The initial value for trx->no: ut_dulint_max is used in + /* The initial value for trx->no: IB_ULONGLONG_MAX is used in read_view_open_now: */ - trx->no = ut_dulint_max; + trx->no = IB_ULONGLONG_MAX; trx->rseg = rseg; @@ -941,8 +937,8 @@ trx_commit_off_kernel( trx->conc_state = TRX_NOT_STARTED; trx->rseg = NULL; - trx->undo_no = ut_dulint_zero; - trx->last_sql_stat_start.least_undo_no = ut_dulint_zero; + trx->undo_no = 0; + trx->last_sql_stat_start.least_undo_no = 0; ut_ad(UT_LIST_GET_LEN(trx->wait_thrs) == 0); ut_ad(UT_LIST_GET_LEN(trx->trx_locks) == 0); @@ -967,8 +963,8 @@ trx_cleanup_at_db_startup( trx->conc_state = TRX_NOT_STARTED; trx->rseg = NULL; - trx->undo_no = ut_dulint_zero; - trx->last_sql_stat_start.least_undo_no = ut_dulint_zero; + trx->undo_no = 0; + trx->last_sql_stat_start.least_undo_no = 0; UT_LIST_REMOVE(trx_list, trx_sys->trx_list, trx); } @@ -1631,7 +1627,7 @@ trx_mark_sql_stat_end( ut_a(trx); if (trx->conc_state == TRX_NOT_STARTED) { - trx->undo_no = ut_dulint_zero; + trx->undo_no = 0; } trx->last_sql_stat_start.least_undo_no = trx->undo_no; @@ -1651,7 +1647,7 @@ trx_print( { ibool newline; - fprintf(f, "TRANSACTION " TRX_ID_FMT, TRX_ID_PREP_PRINTF(trx->id)); + fprintf(f, "TRANSACTION " TRX_ID_FMT, (ullint) trx->id); switch (trx->conc_state) { case TRX_NOT_STARTED: @@ -1735,10 +1731,10 @@ trx_print( fputs(", holds adaptive hash latch", f); } - if (!ut_dulint_is_zero(trx->undo_no)) { + if (trx->undo_no != 0) { newline = TRUE; - fprintf(f, ", undo log entries %lu", - (ulong) ut_dulint_get_low(trx->undo_no)); + fprintf(f, ", undo log entries %llu", + (ullint) trx->undo_no); } if (newline) { @@ -1754,11 +1750,11 @@ trx_print( Compares the "weight" (or size) of two transactions. Transactions that have edited non-transactional tables are considered heavier than ones that have not. -@return <0, 0 or >0; similar to strcmp(3) */ +@return TRUE if weight(a) >= weight(b) */ UNIV_INTERN -int -trx_weight_cmp( -/*===========*/ +ibool +trx_weight_ge( +/*==========*/ const trx_t* a, /*!< in: the first transaction to be compared */ const trx_t* b) /*!< in: the second transaction to be compared */ { @@ -1769,19 +1765,14 @@ trx_weight_cmp( not edited non-transactional tables. */ a_notrans_edit = a->mysql_thd != NULL - && thd_has_edited_nontrans_tables(a->mysql_thd); + && thd_has_edited_nontrans_tables(a->mysql_thd); b_notrans_edit = b->mysql_thd != NULL - && thd_has_edited_nontrans_tables(b->mysql_thd); - - if (a_notrans_edit && !b_notrans_edit) { - - return(1); - } + && thd_has_edited_nontrans_tables(b->mysql_thd); - if (!a_notrans_edit && b_notrans_edit) { + if (a_notrans_edit != b_notrans_edit) { - return(-1); + return(a_notrans_edit); } /* Either both had edited non-transactional tables or both had @@ -1792,13 +1783,11 @@ trx_weight_cmp( fprintf(stderr, "%s TRX_WEIGHT(a): %lld+%lu, TRX_WEIGHT(b): %lld+%lu\n", __func__, - ut_conv_dulint_to_longlong(a->undo_no), - UT_LIST_GET_LEN(a->trx_locks), - ut_conv_dulint_to_longlong(b->undo_no), - UT_LIST_GET_LEN(b->trx_locks)); + a->undo_no, UT_LIST_GET_LEN(a->trx_locks), + b->undo_no, UT_LIST_GET_LEN(b->trx_locks)); #endif - return(ut_dulint_cmp(TRX_WEIGHT(a), TRX_WEIGHT(b))); + return(TRX_WEIGHT(a) >= TRX_WEIGHT(b)); } /****************************************************************//** @@ -1980,14 +1969,13 @@ trx_recover_for_mysql( fprintf(stderr, " InnoDB: Transaction " TRX_ID_FMT " in" " prepared state after recovery\n", - TRX_ID_PREP_PRINTF(trx->id)); + (ullint) trx->id); ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Transaction contains changes" - " to %lu rows\n", - (ulong) ut_conv_dulint_to_longlong( - trx->undo_no)); + " to %llu rows\n", + (ullint) trx->undo_no); count++; @@ -2036,7 +2024,7 @@ trx_get_trx_by_xid( while (trx) { /* Compare two X/Open XA transaction id's: their length should be the same and binary comparison - of gtrid_lenght+bqual_length bytes should be + of gtrid_length+bqual_length bytes should be the same */ if (xid->gtrid_length == trx->xid.gtrid_length diff --git a/storage/innobase/trx/trx0undo.c b/storage/innobase/trx/trx0undo.c index eb5112c4d31..90fc98f419d 100644 --- a/storage/innobase/trx/trx0undo.c +++ b/storage/innobase/trx/trx0undo.c @@ -515,7 +515,7 @@ trx_undo_header_create_log( { mlog_write_initial_log_record(undo_page, MLOG_UNDO_HDR_CREATE, mtr); - mlog_catenate_dulint_compressed(mtr, trx_id); + mlog_catenate_ull_compressed(mtr, trx_id); } #else /* !UNIV_HOTBACKUP */ # define trx_undo_header_create_log(undo_page,trx_id,mtr) ((void) 0) @@ -687,7 +687,7 @@ trx_undo_insert_header_reuse_log( { mlog_write_initial_log_record(undo_page, MLOG_UNDO_HDR_REUSE, mtr); - mlog_catenate_dulint_compressed(mtr, trx_id); + mlog_catenate_ull_compressed(mtr, trx_id); } #else /* !UNIV_HOTBACKUP */ # define trx_undo_insert_header_reuse_log(undo_page,trx_id,mtr) ((void) 0) @@ -707,8 +707,14 @@ trx_undo_parse_page_header( mtr_t* mtr) /*!< in: mtr or NULL */ { trx_id_t trx_id; + /* Silence a GCC warning about possibly uninitialized variable + when mach_ull_parse_compressed() is not inlined. */ + ut_d(trx_id = 0); + /* Declare the variable uninitialized in Valgrind, so that the + above initialization will not mask any bugs. */ + UNIV_MEM_INVALID(&trx_id, sizeof trx_id); - ptr = mach_dulint_parse_compressed(ptr, end_ptr, &trx_id); + ptr = mach_ull_parse_compressed(ptr, end_ptr, &trx_id); if (ptr == NULL) { @@ -1098,8 +1104,7 @@ trx_undo_truncate_end( break; } - if (ut_dulint_cmp(trx_undo_rec_get_undo_no(rec), limit) - >= 0) { + if (trx_undo_rec_get_undo_no(rec) >= limit) { /* Truncate at least this record off, maybe more */ trunc_here = rec; @@ -1152,7 +1157,7 @@ trx_undo_truncate_start( ut_ad(mutex_own(&(rseg->mutex))); - if (ut_dulint_is_zero(limit)) { + if (!limit) { return; } @@ -1174,7 +1179,7 @@ loop: last_rec = trx_undo_page_get_last_rec(undo_page, hdr_page_no, hdr_offset); - if (ut_dulint_cmp(trx_undo_rec_get_undo_no(last_rec), limit) >= 0) { + if (trx_undo_rec_get_undo_no(last_rec) >= limit) { mtr_commit(&mtr); @@ -1296,7 +1301,7 @@ trx_undo_mem_create_at_db_start( undo_header = undo_page + offset; - trx_id = mtr_read_dulint(undo_header + TRX_UNDO_TRX_ID, mtr); + trx_id = mach_read_from_8(undo_header + TRX_UNDO_TRX_ID); xid_exists = mtr_read_ulint(undo_header + TRX_UNDO_XID_EXISTS, MLOG_1BYTE, mtr); @@ -1320,7 +1325,7 @@ trx_undo_mem_create_at_db_start( undo->dict_operation = mtr_read_ulint( undo_header + TRX_UNDO_DICT_TRANS, MLOG_1BYTE, mtr); - undo->table_id = mtr_read_dulint(undo_header + TRX_UNDO_TABLE_ID, mtr); + undo->table_id = mach_read_from_8(undo_header + TRX_UNDO_TABLE_ID); undo->state = state; undo->size = flst_get_len(seg_header + TRX_UNDO_PAGE_LIST, mtr); @@ -1709,7 +1714,7 @@ trx_undo_mark_as_dict_operation( ut_error; case TRX_DICT_OP_INDEX: /* Do not discard the table on recovery. */ - undo->table_id = ut_dulint_zero; + undo->table_id = 0; break; case TRX_DICT_OP_TABLE: undo->table_id = trx->table_id; @@ -1720,8 +1725,8 @@ trx_undo_mark_as_dict_operation( + TRX_UNDO_DICT_TRANS, TRUE, MLOG_1BYTE, mtr); - mlog_write_dulint(hdr_page + undo->hdr_offset + TRX_UNDO_TABLE_ID, - undo->table_id, mtr); + mlog_write_ull(hdr_page + undo->hdr_offset + TRX_UNDO_TABLE_ID, + undo->table_id, mtr); undo->dict_operation = TRUE; } diff --git a/storage/innobase/ut/ut0byte.c b/storage/innobase/ut/ut0byte.c index 4e093f72ce2..535f74b8907 100644 --- a/storage/innobase/ut/ut0byte.c +++ b/storage/innobase/ut/ut0byte.c @@ -28,28 +28,3 @@ Created 5/11/1994 Heikki Tuuri #ifdef UNIV_NONINL #include "ut0byte.ic" #endif - -/** Zero value for a dulint */ -UNIV_INTERN const dulint ut_dulint_zero = {0, 0}; - -/** Maximum value for a dulint */ -UNIV_INTERN const dulint ut_dulint_max = {0xFFFFFFFFUL, 0xFFFFFFFFUL}; - -#ifdef notdefined /* unused code */ -#include "ut0sort.h" - -/************************************************************//** -Sort function for dulint arrays. */ -UNIV_INTERN -void -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); -} -#endif /* notdefined */ |