diff options
author | Alexander Barkov <bar@mariadb.org> | 2017-05-05 16:12:54 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2017-05-05 16:12:54 +0400 |
commit | ac53b49b1be807f588aebd83883ec93b764f5d54 (patch) | |
tree | c86cbdb535eefb15e2077a7ac2ffaeff9d76955e /storage | |
parent | 583b68e89961c35fa95a06c38988f82e33c73f4a (diff) | |
parent | db0917f68f2681882974afd53935aa8cba29c6b8 (diff) | |
download | mariadb-git-ac53b49b1be807f588aebd83883ec93b764f5d54.tar.gz |
Merge remote-tracking branch 'origin/10.2' into bb-10.2-ext
Diffstat (limited to 'storage')
141 files changed, 4414 insertions, 3987 deletions
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index e1446b409d1..489b612a17a 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -1602,7 +1602,8 @@ btr_page_reorganize_low( /* Copy the PAGE_MAX_TRX_ID or PAGE_ROOT_AUTO_INC. */ memcpy(page + (PAGE_HEADER + PAGE_MAX_TRX_ID), temp_page + (PAGE_HEADER + PAGE_MAX_TRX_ID), 8); - /* PAGE_MAX_TRX_ID is unused in clustered index pages, + /* PAGE_MAX_TRX_ID is unused in clustered index pages + (other than the root where it is repurposed as PAGE_ROOT_AUTO_INC), non-leaf pages, and in temporary tables. It was always zero-initialized in page_create() in all InnoDB versions. PAGE_MAX_TRX_ID must be nonzero on dict_index_is_sec_or_ibuf() @@ -1983,6 +1984,36 @@ btr_root_raise_and_insert( index); } + if (dict_index_is_sec_or_ibuf(index)) { + /* In secondary indexes and the change buffer, + PAGE_MAX_TRX_ID can be reset on the root page, because + the field only matters on leaf pages, and the root no + longer is a leaf page. (Older versions of InnoDB did + set PAGE_MAX_TRX_ID on all secondary index pages.) */ + if (root_page_zip) { + page_zip_write_header( + root_page_zip, + PAGE_HEADER + PAGE_MAX_TRX_ID + + root, 0, mtr); + } else { + mlog_write_ull(PAGE_HEADER + PAGE_MAX_TRX_ID + + root, 0, mtr); + } + } else { + /* PAGE_ROOT_AUTO_INC is only present in the clustered index + root page; on other clustered index pages, we want to reserve + the field PAGE_MAX_TRX_ID for future use. */ + if (new_page_zip) { + page_zip_write_header( + new_page_zip, + PAGE_HEADER + PAGE_MAX_TRX_ID + + new_page, 0, mtr); + } else { + mlog_write_ull(PAGE_HEADER + PAGE_MAX_TRX_ID + + new_page, 0, mtr); + } + } + /* If this is a pessimistic insert which is actually done to perform a pessimistic update then we have stored the lock information of the record to be inserted on the infimum of the @@ -2943,7 +2974,7 @@ func_start: btr_page_create(new_block, new_page_zip, cursor->index, btr_page_get_level(page, mtr), mtr); /* Only record the leaf level page splits. */ - if (btr_page_get_level(page, mtr) == 0) { + if (page_is_leaf(page)) { cursor->index->stat_defrag_n_page_split ++; cursor->index->stat_defrag_modified_counter ++; btr_defragment_save_defrag_stats_if_needed(cursor->index); @@ -5132,9 +5163,9 @@ loop: rec = btr_cur_get_rec(&node_cur); fprintf(stderr, "\n" - "InnoDB: node ptr child page n:o %lu\n", - (ulong) btr_node_ptr_get_child_page_no( - rec, offsets)); + "InnoDB: node ptr child page n:o " + ULINTPF "\n", + btr_node_ptr_get_child_page_no(rec, offsets)); fputs("InnoDB: record on page ", stderr); rec_print_new(stderr, rec, offsets); diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index c15784a97a4..773b03775be 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -2175,7 +2175,7 @@ btr_cur_open_at_index_side_func( page = buf_block_get_frame(block); if (height == ULINT_UNDEFINED - && btr_page_get_level(page, mtr) == 0 + && page_is_leaf(page) && rw_latch != RW_NO_LATCH && rw_latch != root_leaf_rw_latch) { /* We should retry to get the page, because the root page @@ -2532,7 +2532,7 @@ btr_cur_open_at_rnd_pos_func( page = buf_block_get_frame(block); if (height == ULINT_UNDEFINED - && btr_page_get_level(page, mtr) == 0 + && page_is_leaf(page) && rw_latch != RW_NO_LATCH && rw_latch != root_leaf_rw_latch) { /* We should retry to get the page, because the root page @@ -3683,6 +3683,8 @@ btr_cur_update_in_place( btr_search_x_lock(index); } + + assert_block_ahi_valid(block); #endif /* BTR_CUR_HASH_ADAPT */ row_upd_rec_in_place(rec, index, offsets, update, page_zip); diff --git a/storage/innobase/btr/btr0defragment.cc b/storage/innobase/btr/btr0defragment.cc index 8c4f27cc78a..06cd1315590 100644 --- a/storage/innobase/btr/btr0defragment.cc +++ b/storage/innobase/btr/btr0defragment.cc @@ -233,7 +233,9 @@ btr_defragment_add_index( return NULL; } - if (btr_page_get_level(page, &mtr) == 0) { + ut_ad(page_is_root(page)); + + if (page_is_leaf(page)) { // Index root is a leaf page, no need to defragment. mtr_commit(&mtr); return NULL; diff --git a/storage/innobase/btr/btr0scrub.cc b/storage/innobase/btr/btr0scrub.cc index 0d59481c4b5..307d6d0ec6c 100644 --- a/storage/innobase/btr/btr0scrub.cc +++ b/storage/innobase/btr/btr0scrub.cc @@ -1,4 +1,5 @@ // Copyright (c) 2014, Google Inc. +// Copyright (c) 2017, MariaDB Corporation. /**************************************************//** @file btr/btr0scrub.cc @@ -102,16 +103,9 @@ log_scrub_failure( scrub_data->scrub_stat.page_split_failures_unknown++; } - buf_frame_t* buf = buf_block_get_frame(block); - const ulint space_id = mach_read_from_4(buf + FIL_PAGE_SPACE_ID); - const ulint page_no = mach_read_from_4(buf + FIL_PAGE_OFFSET); - fprintf(stderr, - "InnoDB: Warning: Failed to scrub index %s table %s page %lu in space %lu : %s\n", - index->name(), - index->table->name.m_name, - page_no, - space_id, - reason); + ib::warn() << "Failed to scrub index " << index->name + << " of table " << index->table->name + << " page " << block->page.id << ": " << reason; } /**************************************************************** @@ -152,11 +146,10 @@ btr_scrub_lock_dict_func(ulint space_id, bool lock_to_close_table, if (now >= last + 30) { fprintf(stderr, - "WARNING: %s:%u waited %lu seconds for" + "WARNING: %s:%u waited %ld seconds for" " dict_sys lock, space: " ULINTPF - " lock_to_close_table: %u\n", - file, line, (unsigned long)(now - start), - space_id, + " lock_to_close_table: %d\n", + file, line, long(now - start), space_id, lock_to_close_table); last = now; diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc index f7a430591ac..3ae9e95819a 100644 --- a/storage/innobase/btr/btr0sea.cc +++ b/storage/innobase/btr/btr0sea.cc @@ -611,6 +611,7 @@ btr_search_update_hash_ref( || rw_lock_own(&(block->lock), RW_LOCK_X)); ut_ad(page_align(btr_cur_get_rec(cursor)) == buf_block_get_frame(block)); + assert_block_ahi_valid(block); index = block->index; @@ -1122,14 +1123,13 @@ btr_search_drop_page_hash_index(buf_block_t* block) rw_lock_t* latch; btr_search_t* info; - if (!btr_search_enabled) { - return; - } - retry: /* Do a dirty check on block->index, return if the block is not in the adaptive hash index. */ index = block->index; + /* This debug check uses a dirty read that could theoretically cause + false positives while buf_pool_clear_hash_index() is executing. */ + assert_block_ahi_valid(block); if (index == NULL) { return; @@ -1156,6 +1156,7 @@ retry: ut_ad(!btr_search_own_any(RW_LOCK_X)); rw_lock_s_lock(latch); + assert_block_ahi_valid(block); if (block->index == NULL) { rw_lock_s_unlock(latch); @@ -1172,6 +1173,7 @@ retry: #ifdef MYSQL_INDEX_DISABLE_AHI ut_ad(!index->disable_ahi); #endif + ut_ad(btr_search_enabled); ut_ad(block->page.id.space() == index->space); ut_a(index_id == index->id); @@ -1290,23 +1292,8 @@ next_rec: MONITOR_INC_VALUE(MONITOR_ADAPTIVE_HASH_ROW_REMOVED, n_cached); cleanup: -#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG - if (UNIV_UNLIKELY(block->n_pointers)) { - /* Corruption */ - ib::error() << "Corruption of adaptive hash index." - << " After dropping, the hash index to a page of " - << index->name - << ", still " << block->n_pointers - << " hash nodes remain."; - rw_lock_x_unlock(latch); - - ut_ad(btr_search_validate()); - } else { - rw_lock_x_unlock(latch); - } -#else /* UNIV_AHI_DEBUG || UNIV_DEBUG */ + assert_block_ahi_valid(block); rw_lock_x_unlock(latch); -#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ ut_free(folds); } @@ -1533,6 +1520,7 @@ btr_search_build_page_hash_index( have to take care not to increment the counter in that case. */ if (!block->index) { + assert_block_ahi_empty(block); index->search_info->ref_count++; } @@ -1551,6 +1539,7 @@ btr_search_build_page_hash_index( MONITOR_INC(MONITOR_ADAPTIVE_HASH_PAGE_ADDED); MONITOR_INC_VALUE(MONITOR_ADAPTIVE_HASH_ROW_ADDED, n_cached); exit_func: + assert_block_ahi_valid(block); btr_search_x_unlock(index); ut_free(folds); @@ -1590,6 +1579,8 @@ btr_search_move_or_delete_hash_entries( ut_a(!block->index || block->index == index); ut_a(!(new_block->index || block->index) || !dict_index_is_ibuf(index)); + assert_block_ahi_valid(block); + assert_block_ahi_valid(new_block); if (new_block->index) { @@ -1650,6 +1641,7 @@ btr_search_update_hash_on_delete(btr_cur_t* cursor) ut_ad(rw_lock_own(&(block->lock), RW_LOCK_X)); + assert_block_ahi_valid(block); index = block->index; if (!index) { @@ -1674,6 +1666,7 @@ btr_search_update_hash_on_delete(btr_cur_t* cursor) } btr_search_x_lock(index); + assert_block_ahi_valid(block); if (block->index) { ut_a(block->index == index); @@ -1684,6 +1677,8 @@ btr_search_update_hash_on_delete(btr_cur_t* cursor) MONITOR_INC( MONITOR_ADAPTIVE_HASH_ROW_REMOVE_NOT_FOUND); } + + assert_block_ahi_valid(block); } btr_search_x_unlock(index); @@ -1747,6 +1742,7 @@ btr_search_update_hash_node_on_insert(btr_cur_t* cursor) } func_exit: + assert_block_ahi_valid(block); btr_search_x_unlock(index); } else { btr_search_x_unlock(index); @@ -1791,6 +1787,7 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor) block = btr_cur_get_block(cursor); ut_ad(rw_lock_own(&(block->lock), RW_LOCK_X)); + assert_block_ahi_valid(block); index = block->index; diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index a6ed277a90e..754b2cd1c25 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -2,7 +2,7 @@ Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. -Copyright (c) 2013, 2017, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2013, 2017, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -347,7 +347,7 @@ typedef std::map< const byte*, buf_chunk_t*, std::less<const byte*>, - ut_allocator<std::pair<const byte*, buf_chunk_t*> > > + ut_allocator<std::pair<const byte* const, buf_chunk_t*> > > buf_pool_chunk_map_t; static buf_pool_chunk_map_t* buf_chunk_map_reg; @@ -405,10 +405,22 @@ buf_pool_register_chunk( /** Decrypt a page. @param[in,out] bpage Page control block +@param[in,out] space tablespace @return whether the operation was successful */ static bool -buf_page_decrypt_after_read(buf_page_t* bpage); +buf_page_decrypt_after_read(buf_page_t* bpage, fil_space_t* space) + MY_ATTRIBUTE((nonnull)); + +/** Check if page is maybe compressed, encrypted or both when we encounter +corrupted page. Note that we can't be 100% sure if page is corrupted +or decrypt/decompress just failed. +@param[in,out] bpage Page +@return true if page corrupted, false if not */ +static +bool +buf_page_check_corrupt(buf_page_t* bpage) + MY_ATTRIBUTE((nonnull, warn_unused_result)); /* prototypes for new functions added to ha_innodb.cc */ trx_t* innobase_get_trx(); @@ -600,10 +612,6 @@ buf_page_is_zeroes( @param[in] read_buf database page @param[in] checksum_field1 new checksum field @param[in] checksum_field2 old checksum field -@param[in] page_no page number of given read_buf -@param[in] is_log_enabled true if log option is enabled -@param[in] log_file file pointer to log_file -@param[in] curr_algo current checksum algorithm @param[in] use_legacy_big_endian use legacy big endian algorithm @return true if the page is in crc32 checksum format. */ bool @@ -611,24 +619,18 @@ buf_page_is_checksum_valid_crc32( const byte* read_buf, ulint checksum_field1, ulint checksum_field2, -#ifdef UNIV_INNOCHECKSUM - uintmax_t page_no, - bool is_log_enabled, - FILE* log_file, - const srv_checksum_algorithm_t curr_algo, -#endif /* UNIV_INNOCHECKSUM */ bool use_legacy_big_endian) { const uint32_t crc32 = buf_calc_page_crc32(read_buf, use_legacy_big_endian); #ifdef UNIV_INNOCHECKSUM - if (is_log_enabled - && curr_algo == SRV_CHECKSUM_ALGORITHM_STRICT_CRC32) { + if (log_file + && srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_STRICT_CRC32) { fprintf(log_file, "page::%lu;" " crc32 calculated = %u;" " recorded checksum field1 = %lu recorded" - " checksum field2 =%lu\n", page_no, + " checksum field2 =%lu\n", cur_page_num, crc32, checksum_field1, checksum_field2); } #endif /* UNIV_INNOCHECKSUM */ @@ -659,23 +661,12 @@ invalid: @param[in] read_buf database page @param[in] checksum_field1 new checksum field @param[in] checksum_field2 old checksum field -@param[in] page_no page number of given read_buf -@param[in] is_log_enabled true if log option is enabled -@param[in] log_file file pointer to log_file -@param[in] curr_algo current checksum algorithm @return true if the page is in innodb checksum format. */ bool buf_page_is_checksum_valid_innodb( const byte* read_buf, ulint checksum_field1, - ulint checksum_field2 -#ifdef UNIV_INNOCHECKSUM - ,uintmax_t page_no, - bool is_log_enabled, - FILE* log_file, - const srv_checksum_algorithm_t curr_algo -#endif /* UNIV_INNOCHECKSUM */ - ) + ulint checksum_field2) { /* There are 2 valid formulas for checksum_field2 (old checksum field) which algo=innodb could have @@ -691,31 +682,31 @@ buf_page_is_checksum_valid_innodb( ulint new_checksum = buf_calc_page_new_checksum(read_buf); #ifdef UNIV_INNOCHECKSUM - if (is_log_enabled - && curr_algo == SRV_CHECKSUM_ALGORITHM_INNODB) { + if (log_file + && srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_INNODB) { fprintf(log_file, "page::%lu;" " old style: calculated =" " %lu; recorded = %lu\n", - page_no, old_checksum, + cur_page_num, old_checksum, checksum_field2); fprintf(log_file, "page::%lu;" " new style: calculated =" " %lu; crc32 = %u; recorded = %lu\n", - page_no, new_checksum, + cur_page_num, new_checksum, buf_calc_page_crc32(read_buf), checksum_field1); } - if (is_log_enabled - && curr_algo == SRV_CHECKSUM_ALGORITHM_STRICT_INNODB) { + if (log_file + && srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_STRICT_INNODB) { fprintf(log_file, "page::%lu;" " old style: calculated =" " %lu; recorded checksum = %lu\n", - page_no, old_checksum, + cur_page_num, old_checksum, checksum_field2); fprintf(log_file, "page::%lu;" " new style: calculated =" " %lu; recorded checksum = %lu\n", - page_no, new_checksum, + cur_page_num, new_checksum, checksum_field1); } #endif /* UNIV_INNOCHECKSUM */ @@ -755,23 +746,12 @@ buf_page_is_checksum_valid_innodb( @param[in] read_buf database page @param[in] checksum_field1 new checksum field @param[in] checksum_field2 old checksum field -@param[in] page_no page number of given read_buf -@param[in] is_log_enabled true if log option is enabled -@param[in] log_file file pointer to log_file -@param[in] curr_algo current checksum algorithm @return true if the page is in none checksum format. */ bool buf_page_is_checksum_valid_none( const byte* read_buf, ulint checksum_field1, - ulint checksum_field2 -#ifdef UNIV_INNOCHECKSUM - ,uintmax_t page_no, - bool is_log_enabled, - FILE* log_file, - const srv_checksum_algorithm_t curr_algo -#endif /* UNIV_INNOCHECKSUM */ - ) + ulint checksum_field2) { #ifndef DBUG_OFF if (checksum_field1 != checksum_field2 @@ -787,13 +767,13 @@ buf_page_is_checksum_valid_none( #endif /* DBUG_OFF */ #ifdef UNIV_INNOCHECKSUM - if (is_log_enabled - && curr_algo == SRV_CHECKSUM_ALGORITHM_STRICT_NONE) { + if (log_file + && srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_STRICT_NONE) { fprintf(log_file, "page::%lu; none checksum: calculated" " = %lu; recorded checksum_field1 = %lu" " recorded checksum_field2 = %lu\n", - page_no, BUF_NO_CHECKSUM_MAGIC, + cur_page_num, BUF_NO_CHECKSUM_MAGIC, checksum_field1, checksum_field2); } #endif /* UNIV_INNOCHECKSUM */ @@ -808,10 +788,6 @@ the LSN @param[in] read_buf database page @param[in] page_size page size @param[in] space tablespace -@param[in] page_no page number of given read_buf -@param[in] strict_check true if strict-check option is enabled -@param[in] is_log_enabled true if log option is enabled -@param[in] log_file file pointer to log_file @return TRUE if corrupted */ bool buf_page_is_corrupted( @@ -819,12 +795,6 @@ buf_page_is_corrupted( const byte* read_buf, const page_size_t& page_size, const fil_space_t* space -#ifdef UNIV_INNOCHECKSUM - ,uintmax_t page_no, - bool strict_check, - bool is_log_enabled, - FILE* log_file -#endif /* UNIV_INNOCHECKSUM */ ) { ulint checksum_field1; @@ -914,15 +884,8 @@ buf_page_is_corrupted( } if (page_size.is_compressed()) { -#ifdef UNIV_INNOCHECKSUM - return(!page_zip_verify_checksum(read_buf, - page_size.physical(), - page_no, strict_check, - is_log_enabled, log_file)); -#else return(!page_zip_verify_checksum(read_buf, page_size.physical())); -#endif /* UNIV_INNOCHECKSUM */ } checksum_field1 = mach_read_from_4( @@ -964,10 +927,10 @@ buf_page_is_corrupted( } #ifdef UNIV_INNOCHECKSUM if (i >= page_size.logical()) { - if (is_log_enabled) { + if (log_file) { fprintf(log_file, "Page::%lu" " is empty and uncorrupted\n", - page_no); + cur_page_num); } return(false); } @@ -993,20 +956,13 @@ buf_page_is_corrupted( case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32: if (buf_page_is_checksum_valid_crc32(read_buf, - checksum_field1, checksum_field2, -#ifdef UNIV_INNOCHECKSUM - page_no, is_log_enabled, log_file, curr_algo, -#endif /* UNIV_INNOCHECKSUM */ - false)) { + checksum_field1, checksum_field2, false)) { return(false); } if (buf_page_is_checksum_valid_none(read_buf, - checksum_field1, checksum_field2 -#ifdef UNIV_INNOCHECKSUM - , page_no, is_log_enabled, log_file, curr_algo)) { -#else /* UNIV_INNOCHECKSUM */ - )) { + checksum_field1, checksum_field2)) { +#ifndef UNIV_INNOCHECKSUM if (curr_algo == SRV_CHECKSUM_ALGORITHM_STRICT_CRC32) { page_warn_strict_checksum( @@ -1014,20 +970,20 @@ buf_page_is_corrupted( SRV_CHECKSUM_ALGORITHM_NONE, page_id); } -#endif /* UNIV_INNOCHECKSUM */ +#endif /* !UNIV_INNOCHECKSUM */ #ifdef UNIV_INNOCHECKSUM - if (is_log_enabled) { + if (log_file) { fprintf(log_file, "page::%lu;" " old style: calculated = " ULINTPF ";" - " recorded = " ULINTPF "\n", page_no, + " recorded = " ULINTPF "\n", cur_page_num, buf_calc_page_old_checksum(read_buf), checksum_field2); fprintf(log_file, "page::%lu;" " new style: calculated = " ULINTPF ";" " crc32 = %u; recorded = " ULINTPF "\n", - page_no, + cur_page_num, buf_calc_page_new_checksum(read_buf), buf_calc_page_crc32(read_buf), checksum_field1); @@ -1043,11 +999,7 @@ buf_page_is_corrupted( Otherwise we check innodb checksum first. */ if (legacy_big_endian_checksum) { if (buf_page_is_checksum_valid_crc32(read_buf, - checksum_field1, checksum_field2, -#ifdef UNIV_INNOCHECKSUM - page_no, is_log_enabled, log_file, curr_algo, -#endif /* UNIV_INNOCHECKSUM */ - true)) { + checksum_field1, checksum_field2, true)) { return(false); } @@ -1055,11 +1007,8 @@ buf_page_is_corrupted( } if (buf_page_is_checksum_valid_innodb(read_buf, - checksum_field1, checksum_field2 -#ifdef UNIV_INNOCHECKSUM - , page_no, is_log_enabled, log_file, curr_algo)) { -#else /* UNIV_INNOCHECKSUM */ - )) { + checksum_field1, checksum_field2)) { +#ifndef UNIV_INNOCHECKSUM if (curr_algo == SRV_CHECKSUM_ALGORITHM_STRICT_CRC32) { page_warn_strict_checksum( @@ -1067,27 +1016,23 @@ buf_page_is_corrupted( SRV_CHECKSUM_ALGORITHM_INNODB, page_id); } -#endif /* UNIV_INNOCHECKSUM */ +#endif /* !UNIV_INNOCHECKSUM */ return(false); } /* If legacy checksum is not checked, do it now. */ if (!legacy_checksum_checked && buf_page_is_checksum_valid_crc32( - read_buf, checksum_field1, checksum_field2, -#ifdef UNIV_INNOCHECKSUM - page_no, is_log_enabled, log_file, curr_algo, -#endif /* UNIV_INNOCHECKSUM */ - true)) { + read_buf, checksum_field1, checksum_field2, true)) { legacy_big_endian_checksum = true; return(false); } #ifdef UNIV_INNOCHECKSUM - if (is_log_enabled) { + if (log_file) { fprintf(log_file, "Fail; page %lu" " invalid (fails crc32 checksum)\n", - page_no); + cur_page_num); } #endif /* UNIV_INNOCHECKSUM */ return(true); @@ -1096,20 +1041,13 @@ buf_page_is_corrupted( case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB: if (buf_page_is_checksum_valid_innodb(read_buf, - checksum_field1, checksum_field2 -#ifdef UNIV_INNOCHECKSUM - , page_no, is_log_enabled, log_file, curr_algo -#endif /* UNIV_INNOCHECKSUM */ - )) { + checksum_field1, checksum_field2)) { return(false); } if (buf_page_is_checksum_valid_none(read_buf, - checksum_field1, checksum_field2 -#ifdef UNIV_INNOCHECKSUM - , page_no, is_log_enabled, log_file, curr_algo)) { -#else /* UNIV_INNOCHECKSUM */ - )) { + checksum_field1, checksum_field2)) { +#ifndef UNIV_INNOCHECKSUM if (curr_algo == SRV_CHECKSUM_ALGORITHM_STRICT_INNODB) { page_warn_strict_checksum( @@ -1117,19 +1055,19 @@ buf_page_is_corrupted( SRV_CHECKSUM_ALGORITHM_NONE, page_id); } -#endif /* UNIV_INNOCHECKSUM */ +#endif /* !UNIV_INNOCHECKSUM */ #ifdef UNIV_INNOCHECKSUM - if (is_log_enabled) { + if (log_file) { fprintf(log_file, "page::%lu;" " old style: calculated = %lu;" - " recorded = %lu\n", page_no, + " recorded = %lu\n", cur_page_num, buf_calc_page_old_checksum(read_buf), checksum_field2); fprintf(log_file, "page::%lu;" " new style: calculated = %lu;" " crc32 = %u; recorded = %lu\n", - page_no, + cur_page_num, buf_calc_page_new_checksum(read_buf), buf_calc_page_crc32(read_buf), checksum_field1); @@ -1138,19 +1076,11 @@ buf_page_is_corrupted( return(false); } -#ifdef UNIV_INNOCHECKSUM - if (buf_page_is_checksum_valid_crc32(read_buf, - checksum_field1, checksum_field2, - page_no, is_log_enabled, log_file, curr_algo, false) - || buf_page_is_checksum_valid_crc32(read_buf, - checksum_field1, checksum_field2, - page_no, is_log_enabled, log_file, curr_algo, true)) { -#else /* UNIV_INNOCHECKSUM */ if (buf_page_is_checksum_valid_crc32(read_buf, checksum_field1, checksum_field2, false) || buf_page_is_checksum_valid_crc32(read_buf, checksum_field1, checksum_field2, true)) { - +#ifndef UNIV_INNOCHECKSUM if (curr_algo == SRV_CHECKSUM_ALGORITHM_STRICT_INNODB) { page_warn_strict_checksum( @@ -1158,16 +1088,16 @@ buf_page_is_corrupted( SRV_CHECKSUM_ALGORITHM_CRC32, page_id); } -#endif /* UNIV_INNOCHECKSUM */ +#endif /* !UNIV_INNOCHECKSUM */ return(false); } #ifdef UNIV_INNOCHECKSUM - if (is_log_enabled) { + if (log_file) { fprintf(log_file, "Fail; page %lu" " invalid (fails innodb checksum)\n", - page_no); + cur_page_num); } #endif /* UNIV_INNOCHECKSUM */ return(true); @@ -1175,54 +1105,39 @@ buf_page_is_corrupted( case SRV_CHECKSUM_ALGORITHM_STRICT_NONE: if (buf_page_is_checksum_valid_none(read_buf, - checksum_field1, checksum_field2 -#ifdef UNIV_INNOCHECKSUM - , page_no, is_log_enabled, log_file, curr_algo -#endif /* UNIV_INNOCHECKSUM */ - )) { + checksum_field1, checksum_field2)) { return(false); } -#ifdef UNIV_INNOCHECKSUM - if (buf_page_is_checksum_valid_crc32(read_buf, - checksum_field1, checksum_field2, - page_no, is_log_enabled, log_file, curr_algo, false) - || buf_page_is_checksum_valid_crc32(read_buf, - checksum_field1, checksum_field2, - page_no, is_log_enabled, log_file, curr_algo, true)) { -#else /* UNIV_INNOCHECKSUM */ if (buf_page_is_checksum_valid_crc32(read_buf, checksum_field1, checksum_field2, false) || buf_page_is_checksum_valid_crc32(read_buf, checksum_field1, checksum_field2, true)) { - +#ifndef UNIV_INNOCHECKSUM page_warn_strict_checksum( curr_algo, SRV_CHECKSUM_ALGORITHM_CRC32, page_id); -#endif /* UNIV_INNOCHECKSUM */ +#endif /* !UNIV_INNOCHECKSUM */ return(false); } if (buf_page_is_checksum_valid_innodb(read_buf, - checksum_field1, checksum_field2 -#ifdef UNIV_INNOCHECKSUM - , page_no, is_log_enabled, log_file, curr_algo)) { -#else /* UNIV_INNOCHECKSUM */ - )) { + checksum_field1, checksum_field2)) { +#ifndef UNIV_INNOCHECKSUM page_warn_strict_checksum( curr_algo, SRV_CHECKSUM_ALGORITHM_INNODB, page_id); -#endif /* UNIV_INNOCHECKSUM */ +#endif /* !UNIV_INNOCHECKSUM */ return(false); } #ifdef UNIV_INNOCHECKSUM - if (is_log_enabled) { + if (log_file) { fprintf(log_file, "Fail; page %lu" " invalid (fails none checksum)\n", - page_no); + cur_page_num); } #endif /* UNIV_INNOCHECKSUM */ return(true); @@ -1496,6 +1411,10 @@ buf_block_init( { UNIV_MEM_DESC(frame, UNIV_PAGE_SIZE); + /* This function should only be executed at database startup or by + buf_pool_resize(). Either way, adaptive hash index must not exist. */ + assert_block_ahi_empty_on_init(block); + block->frame = frame; block->page.buf_pool_index = buf_pool_index(buf_pool); @@ -1526,11 +1445,6 @@ buf_block_init( ut_d(block->in_unzip_LRU_list = FALSE); ut_d(block->in_withdraw_list = FALSE); -#ifdef BTR_CUR_HASH_ADAPT -# if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG - block->n_pointers = 0; -# endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ -#endif /* BTR_CUR_HASH_ADAPT */ page_zip_des_init(&block->page.zip); mutex_create(LATCH_ID_BUF_BLOCK_MUTEX, &block->mutex); @@ -1763,7 +1677,9 @@ buf_chunk_not_freed( == block->page.newest_modification); ut_ad(block->page.oldest_modification == 0 || block->page.oldest_modification - == recv_sys->recovered_lsn); + == recv_sys->recovered_lsn + || srv_force_recovery + == SRV_FORCE_NO_LOG_REDO); ut_ad(block->page.buf_fix_count == 0); ut_ad(block->page.io_fix == BUF_IO_NONE); break; @@ -2244,6 +2160,10 @@ buf_page_realloc( /* set other flags of buf_block_t */ #ifdef BTR_CUR_HASH_ADAPT + /* This code should only be executed by buf_pool_resize(), + while the adaptive hash index is disabled. */ + assert_block_ahi_empty(block); + assert_block_ahi_empty_on_init(new_block); ut_ad(!block->index); new_block->index = NULL; new_block->n_hash_helps = 0; @@ -3210,20 +3130,23 @@ buf_pool_clear_hash_index() for (; i--; block++) { dict_index_t* index = block->index; + assert_block_ahi_valid(block); /* We can set block->index = NULL - when we have an x-latch on search latch; - see the comment in buf0buf.h */ + and block->n_pointers = 0 + when btr_search_own_all(RW_LOCK_X); + see the comments in buf0buf.h */ if (!index) { - /* Not hashed */ continue; } - block->index = NULL; + ut_ad(buf_block_get_state(block) + == BUF_BLOCK_FILE_PAGE); # if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG block->n_pointers = 0; # endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ + block->index = NULL; } } } @@ -3915,6 +3838,9 @@ buf_block_init_low( { block->skip_flush_check = false; #ifdef BTR_CUR_HASH_ADAPT + /* No adaptive hash index entries may point to a previously + unused (and now freshly allocated) block. */ + assert_block_ahi_empty_on_init(block); block->index = NULL; block->n_hash_helps = 0; @@ -5266,7 +5192,7 @@ buf_page_init( ut_d(buf_LRU_print()); ut_d(buf_validate()); ut_d(buf_LRU_validate()); - ut_ad(0); + ut_error; } ut_ad(!block->page.in_zip_hash); @@ -5833,16 +5759,14 @@ buf_mark_space_corrupt( return(ret); } -/********************************************************************//** -Check if page is maybe compressed, encrypted or both when we encounter +/** Check if page is maybe compressed, encrypted or both when we encounter corrupted page. Note that we can't be 100% sure if page is corrupted or decrypt/decompress just failed. @param[in,out] bpage Page @return true if page corrupted, false if not */ -UNIV_INTERN +static bool -buf_page_check_corrupt( - buf_page_t* bpage) +buf_page_check_corrupt(buf_page_t* bpage) { byte* dst_frame = (bpage->zip.data) ? bpage->zip.data : ((buf_block_t*) bpage)->frame; @@ -5945,8 +5869,13 @@ buf_page_io_complete( ulint read_space_id; ut_ad(bpage->zip.data != NULL || ((buf_block_t*)bpage)->frame != NULL); + fil_space_t* space = fil_space_acquire_for_io( + bpage->id.space()); + if (!space) { + return false; + } - buf_page_decrypt_after_read(bpage); + buf_page_decrypt_after_read(bpage, space); if (bpage->size.is_compressed()) { frame = bpage->zip.data; @@ -6020,21 +5949,17 @@ database_corrupted: && buf_mark_space_corrupt(bpage)) { ib::info() << "Simulated IMPORT " "corruption"; + fil_space_release_for_io(space); return(true); } goto page_not_corrupt; ); if (!bpage->encrypted) { - fil_system_enter(); - fil_space_t* space = fil_space_get_by_id(bpage->id.space()); - fil_system_exit(); - ib::error() << "Database page corruption on disk" " or a failed file read of tablespace " - << (space->name ? space->name : "NULL") - << " page " << bpage->id + << space->name << " page " << bpage->id << ". You may have to recover from " << "a backup."; @@ -6063,6 +5988,7 @@ database_corrupted: if (bpage->id.space() > TRX_SYS_SPACE && buf_mark_space_corrupt(bpage)) { + fil_space_release_for_io(space); return(false); } else { if (!bpage->encrypted) { @@ -6076,7 +6002,7 @@ database_corrupted: } ib_push_warning(innobase_get_trx(), DB_DECRYPTION_FAILED, - "Table in tablespace %lu encrypted." + "Table in tablespace %u encrypted." "However key management plugin or used key_id %lu is not found or" " used encryption algorithm or method does not match." " Can't continue opening the table.", @@ -6088,6 +6014,7 @@ database_corrupted: ut_error; } + fil_space_release_for_io(space); return(false); } } @@ -6131,6 +6058,8 @@ database_corrupted: } } + + fil_space_release_for_io(space); } else { /* io_type == BUF_IO_WRITE */ if (bpage->slot) { @@ -7066,15 +6995,16 @@ buf_print_io_instance( ut_ad(pool_info); fprintf(file, - "Buffer pool size %lu\n" - "Free buffers %lu\n" - "Database pages %lu\n" - "Old database pages %lu\n" - "Modified db pages %lu\n" + "Buffer pool size " ULINTPF "\n" + "Free buffers " ULINTPF "\n" + "Database pages " ULINTPF "\n" + "Old database pages " ULINTPF "\n" + "Modified db pages " ULINTPF "\n" "Percent of dirty pages(LRU & free pages): %.3f\n" "Max dirty pages percent: %.3f\n" - "Pending reads %lu\n" - "Pending writes: LRU %lu, flush list %lu, single page %lu\n", + "Pending reads " ULINTPF "\n" + "Pending writes: LRU " ULINTPF ", flush list " ULINTPF + ", single page " ULINTPF "\n", pool_info->pool_size, pool_info->free_list_len, pool_info->lru_len, @@ -7089,9 +7019,10 @@ buf_print_io_instance( pool_info->n_pending_flush_single_page); fprintf(file, - "Pages made young %lu, not young %lu\n" + "Pages made young " ULINTPF ", not young " ULINTPF "\n" "%.2f youngs/s, %.2f non-youngs/s\n" - "Pages read %lu, created %lu, written %lu\n" + "Pages read " ULINTPF ", created " ULINTPF + ", written " ULINTPF "\n" "%.2f reads/s, %.2f creates/s, %.2f writes/s\n", pool_info->n_pages_made_young, pool_info->n_pages_not_made_young, @@ -7105,23 +7036,22 @@ buf_print_io_instance( pool_info->pages_written_rate); if (pool_info->n_page_get_delta) { - double hit_rate = ((1000 * pool_info->page_read_delta) - / pool_info->n_page_get_delta); + double hit_rate = double(pool_info->page_read_delta) + / pool_info->n_page_get_delta; - if (hit_rate > 1000) { - hit_rate = 1000; + if (hit_rate > 1) { + hit_rate = 1; } - hit_rate = 1000 - hit_rate; - fprintf(file, - "Buffer pool hit rate %lu / 1000," - " young-making rate %lu / 1000 not %lu / 1000\n", - (ulint) hit_rate, - (ulint) (1000 * pool_info->young_making_delta - / pool_info->n_page_get_delta), - (ulint) (1000 * pool_info->not_young_making_delta - / pool_info->n_page_get_delta)); + "Buffer pool hit rate " ULINTPF " / 1000," + " young-making rate " ULINTPF " / 1000 not " + ULINTPF " / 1000\n", + ulint(1000 * (1 - hit_rate)), + ulint(1000 * double(pool_info->young_making_delta) + / pool_info->n_page_get_delta), + ulint(1000 * double(pool_info->not_young_making_delta) + / pool_info->n_page_get_delta)); } else { fputs("No buffer pool page gets since the last printout\n", file); @@ -7372,72 +7302,55 @@ buf_pool_reserve_tmp_slot( return (free_slot); } -/********************************************************************//** -Encrypts a buffer page right before it's flushed to disk -@param[in,out] bpage Page control block -@param[in,out] src_frame Source page -@param[in] space_id Tablespace id -@return either unencrypted source page or decrypted page. -*/ +/** Encryption and page_compression hook that is called just before +a page is written to disk. +@param[in,out] space tablespace +@param[in,out] bpage buffer page +@param[in] src_frame physical page frame that is being encrypted +@return page frame to be written to file +(may be src_frame or an encrypted/compressed copy of it) */ UNIV_INTERN byte* buf_page_encrypt_before_write( + fil_space_t* space, buf_page_t* bpage, - byte* src_frame, - ulint space_id) + byte* src_frame) { + ut_ad(space->id == bpage->id.space()); bpage->real_size = UNIV_PAGE_SIZE; fil_page_type_validate(src_frame); - if (bpage->id.page_no() == 0) { + switch (bpage->id.page_no()) { + case 0: /* Page 0 of a tablespace is not encrypted/compressed */ ut_ad(bpage->key_version == 0); return src_frame; - } - - if (space_id == TRX_SYS_SPACE && bpage->id.page_no() == TRX_SYS_PAGE_NO) { - /* don't encrypt/compress page as it contains address to dblwr buffer */ - bpage->key_version = 0; - return src_frame; - } - - fil_space_t* space = fil_space_acquire_silent(space_id); - - /* Tablespace must exist during write operation */ - if (!space) { - /* This could be true on discard if we have injected a error - case e.g. in innodb.innodb-wl5522-debug-zip so that space - is already marked as stop_new_ops = true. */ - return src_frame; + case TRX_SYS_PAGE_NO: + if (bpage->id.space() == TRX_SYS_SPACE) { + /* don't encrypt/compress page as it contains + address to dblwr buffer */ + bpage->key_version = 0; + return src_frame; + } } const page_size_t page_size(space->flags); fil_space_crypt_t* crypt_data = space->crypt_data; - bool encrypted = true; - - if (space->crypt_data != NULL && space->crypt_data->not_encrypted()) { - /* Encryption is disabled */ - encrypted = false; - } - - if (!srv_encrypt_tables && (crypt_data == NULL || crypt_data->is_default_encryption())) { - /* Encryption is disabled */ - encrypted = false; - } + const bool encrypted = crypt_data + && !crypt_data->not_encrypted() + && crypt_data->type != CRYPT_SCHEME_UNENCRYPTED + && (!crypt_data->is_default_encryption() + || srv_encrypt_tables); - /* Is encryption needed? */ - if (crypt_data == NULL || crypt_data->type == CRYPT_SCHEME_UNENCRYPTED) { - /* An unencrypted table */ + if (!encrypted) { bpage->key_version = 0; - encrypted = false; } - bool page_compressed = fil_space_is_page_compressed(bpage->id.space()); + bool page_compressed = FSP_FLAGS_HAS_PAGE_COMPRESSION(space->flags); if (!encrypted && !page_compressed) { /* No need to encrypt or page compress the page */ - fil_space_release(space); return src_frame; } @@ -7464,25 +7377,21 @@ buf_page_encrypt_before_write( bpage->real_size = page_size.physical(); slot->out_buf = dst_frame = tmp; -#ifdef UNIV_DEBUG - fil_page_type_validate(tmp); -#endif - + ut_d(fil_page_type_validate(tmp)); } else { /* First we compress the page content */ ulint out_len = 0; - ulint block_size = fil_space_get_block_size(space_id, bpage->id.page_no(), page_size.logical()); - - byte *tmp = fil_compress_page(space_id, - (byte *)src_frame, - slot->comp_buf, - page_size.logical(), - fil_space_get_page_compression_level(space_id), - block_size, - encrypted, - &out_len, - IF_LZO(slot->lzo_mem, NULL) - ); + + byte *tmp = fil_compress_page( + space, + (byte *)src_frame, + slot->comp_buf, + page_size.logical(), + fsp_flags_get_page_compression_level(space->flags), + fil_space_get_block_size(space, bpage->id.page_no()), + encrypted, + &out_len, + IF_LZO(slot->lzo_mem, NULL)); bpage->real_size = out_len; @@ -7505,18 +7414,21 @@ buf_page_encrypt_before_write( ut_d(fil_page_type_validate(dst_frame)); - fil_space_release(space); // return dst_frame which will be written return dst_frame; } /** Decrypt a page. @param[in,out] bpage Page control block +@param[in,out] space tablespace @return whether the operation was successful */ static bool -buf_page_decrypt_after_read(buf_page_t* bpage) +buf_page_decrypt_after_read(buf_page_t* bpage, fil_space_t* space) { + ut_ad(space->n_pending_ios > 0); + ut_ad(space->id == bpage->id.space()); + bool compressed = bpage->size.is_compressed(); const page_size_t& size = bpage->size; byte* dst_frame = compressed ? bpage->zip.data : @@ -7535,12 +7447,10 @@ buf_page_decrypt_after_read(buf_page_t* bpage) return (true); } - FilSpace space(bpage->id.space(), true); - /* Page is encrypted if encryption information is found from tablespace and page contains used key_version. This is true also for pages first compressed and then encrypted. */ - if (!space() || !space()->crypt_data) { + if (!space->crypt_data) { key_version = 0; } @@ -7553,9 +7463,9 @@ buf_page_decrypt_after_read(buf_page_t* bpage) /* decompress using comp_buf to dst_frame */ fil_decompress_page(slot->comp_buf, - dst_frame, - size.logical(), - &bpage->write_size); + dst_frame, + ulong(size.logical()), + &bpage->write_size); /* Mark this slot as free */ slot->reserved = false; @@ -7600,9 +7510,9 @@ buf_page_decrypt_after_read(buf_page_t* bpage) ut_d(fil_page_type_validate(dst_frame)); /* decompress using comp_buf to dst_frame */ fil_decompress_page(slot->comp_buf, - dst_frame, - size.logical(), - &bpage->write_size); + dst_frame, + ulong(size.logical()), + &bpage->write_size); ut_d(fil_page_type_validate(dst_frame)); } @@ -7612,6 +7522,7 @@ buf_page_decrypt_after_read(buf_page_t* bpage) } } + ut_ad(space->n_pending_ios > 0); return (success); } diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index fcf6d55f660..f99fc6434de 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2017, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2013, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -168,8 +168,7 @@ doublewrite buffer is placed on the trx system header page. @return true if successful, false if not. */ MY_ATTRIBUTE((warn_unused_result)) bool -buf_dblwr_create(void) -/*==================*/ +buf_dblwr_create() { buf_block_t* block2; buf_block_t* new_block; @@ -510,7 +509,7 @@ buf_dblwr_init_or_load_pages( /** Process and remove the double write buffer pages for all tablespaces. */ void -buf_dblwr_process(void) +buf_dblwr_process() { ulint page_no_dblwr = 0; byte* read_buf; @@ -527,9 +526,7 @@ buf_dblwr_process(void) i != recv_dblwr.pages.end(); ++i, ++page_no_dblwr) { byte* page = *i; - ulint page_no = page_get_page_no(page); ulint space_id = page_get_space_id(page); - fil_space_t* space = fil_space_get(space_id); if (space == NULL) { @@ -540,6 +537,7 @@ buf_dblwr_process(void) fil_space_open_if_needed(space); + const ulint page_no = page_get_page_no(page); const page_id_t page_id(space_id, page_no); if (page_no >= space->size) { @@ -595,7 +593,7 @@ buf_dblwr_process(void) /* Decompress the page before validating the checksum. */ fil_decompress_page( - NULL, read_buf, UNIV_PAGE_SIZE, + NULL, read_buf, srv_page_size, NULL, true); } @@ -621,7 +619,7 @@ buf_dblwr_process(void) /* Decompress the page before validating the checksum. */ fil_decompress_page( - NULL, page, UNIV_PAGE_SIZE, NULL, true); + NULL, page, srv_page_size, NULL, true); } if (!fil_space_verify_crypt_checksum(page, page_size, @@ -676,8 +674,7 @@ buf_dblwr_process(void) /****************************************************************//** Frees doublewrite buffer. */ void -buf_dblwr_free(void) -/*================*/ +buf_dblwr_free() { /* Free the double write data structures. */ ut_a(buf_dblwr != NULL); @@ -932,8 +929,7 @@ important to call this function after a batch of writes has been posted, and also when we may have to wait for a page latch! Otherwise a deadlock of threads can occur. */ void -buf_dblwr_flush_buffered_writes(void) -/*=================================*/ +buf_dblwr_flush_buffered_writes() { byte* write_buf; ulint first_free; diff --git a/storage/innobase/buf/buf0dump.cc b/storage/innobase/buf/buf0dump.cc index 9b86b1c16da..ce7488e3d1f 100644 --- a/storage/innobase/buf/buf0dump.cc +++ b/storage/innobase/buf/buf0dump.cc @@ -1,7 +1,7 @@ /***************************************************************************** -Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2011, 2017, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -796,6 +796,7 @@ extern "C" os_thread_ret_t DECLARE_THREAD(buf_dump_thread)(void*) { + my_thread_init(); ut_ad(!srv_read_only_mode); /* JAN: TODO: MySQL 5.7 PSI #ifdef UNIV_PFS_THREAD @@ -836,6 +837,7 @@ DECLARE_THREAD(buf_dump_thread)(void*) srv_buf_dump_thread_active = false; + my_thread_end(); /* We count the number of threads in os_thread_exit(). A created thread should always use that to exit and not use return() to exit. */ os_thread_exit(); diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index a0ed243d74b..d0c0316bf13 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -1006,11 +1006,16 @@ buf_flush_write_block_low( buf_flush_t flush_type, /*!< in: type of flush */ bool sync) /*!< in: true if sync IO request */ { + fil_space_t* space = fil_space_acquire_for_io(bpage->id.space()); + if (!space) { + return; + } + ut_ad(space->purpose == FIL_TYPE_TEMPORARY + || space->purpose == FIL_TYPE_IMPORT + || space->purpose == FIL_TYPE_TABLESPACE); + const bool is_temp = space->purpose == FIL_TYPE_TEMPORARY; + ut_ad(is_temp == fsp_is_system_temporary(space->id)); page_t* frame = NULL; - ulint space_id = bpage->id.space(); - const bool is_temp = fsp_is_system_temporary(space_id); - bool atomic_writes = is_temp || fil_space_get_atomic_writes(space_id); - #ifdef UNIV_DEBUG buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); ut_ad(!buf_pool_mutex_own(buf_pool)); @@ -1076,28 +1081,27 @@ buf_flush_write_block_low( break; } - frame = buf_page_encrypt_before_write(bpage, frame, space_id); + frame = buf_page_encrypt_before_write(space, bpage, frame); /* Disable use of double-write buffer for temporary tablespace. Given the nature and load of temporary tablespace doublewrite buffer adds an overhead during flushing. */ - if (!srv_use_doublewrite_buf - || buf_dblwr == NULL - || srv_read_only_mode - || atomic_writes) { - - ut_ad(!srv_read_only_mode - || fsp_is_system_temporary(bpage->id.space())); + if (is_temp || space->atomic_write_supported + || !srv_use_doublewrite_buf + || buf_dblwr == NULL) { ulint type = IORequest::WRITE | IORequest::DO_NOT_WAKE; IORequest request(type, bpage); + /* TODO: pass the tablespace to fil_io() */ fil_io(request, sync, bpage->id, bpage->size, 0, bpage->size.physical(), - frame, bpage); + frame, bpage); } else { + ut_ad(!srv_read_only_mode); + if (flush_type == BUF_FLUSH_SINGLE_PAGE) { buf_dblwr_write_single_page(bpage, sync); } else { @@ -1111,13 +1115,23 @@ buf_flush_write_block_low( are working on. */ if (sync) { ut_ad(flush_type == BUF_FLUSH_SINGLE_PAGE); - fil_flush(bpage->id.space()); + if (!is_temp) { + fil_flush(space); + } /* true means we want to evict this page from the LRU list as well. */ + /* The tablespace could already have been dropped, + because fil_io(request, sync) would already have + decremented the node->n_pending. However, + buf_page_io_complete() only needs to look up the + tablespace during read requests, not during writes. */ + ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_WRITE); buf_page_io_complete(bpage, true); } + fil_space_release_for_io(space); + /* Increment the counter of I/O operations used for selecting LRU policy. */ buf_LRU_stat_inc_io(); diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc index d6d5db3dfa9..10a8561d38d 100644 --- a/storage/innobase/buf/buf0lru.cc +++ b/storage/innobase/buf/buf0lru.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -294,21 +295,29 @@ next_page: continue; } - mutex_enter(&((buf_block_t*) bpage)->mutex); + buf_block_t* block = reinterpret_cast<buf_block_t*>(bpage); - { - bool skip = bpage->buf_fix_count > 0 - || !((buf_block_t*) bpage)->index; + mutex_enter(&block->mutex); - mutex_exit(&((buf_block_t*) bpage)->mutex); + /* This debug check uses a dirty read that could + theoretically cause false positives while + buf_pool_clear_hash_index() is executing. + (Other conflicting access paths to the adaptive hash + index should not be possible, because when a + tablespace is being discarded or dropped, there must + be no concurrect access to the contained tables.) */ + assert_block_ahi_valid(block); - if (skip) { - /* Skip this block, because there are - no adaptive hash index entries - pointing to it, or because we cannot - drop them due to the buffer-fix. */ - goto next_page; - } + bool skip = bpage->buf_fix_count > 0 || !block->index; + + mutex_exit(&block->mutex); + + if (skip) { + /* Skip this block, because there are + no adaptive hash index entries + pointing to it, or because we cannot + drop them due to the buffer-fix. */ + goto next_page; } /* Store the page number so that we can drop the hash @@ -799,6 +808,17 @@ scan_again: bpage->id, bpage->size); goto scan_again; + } else { + /* This debug check uses a dirty read that could + theoretically cause false positives while + buf_pool_clear_hash_index() is executing, + if the writes to block->index=NULL and + block->n_pointers=0 are reordered. + (Other conflicting access paths to the adaptive hash + index should not be possible, because when a + tablespace is being discarded or dropped, there must + be no concurrect access to the contained tables.) */ + assert_block_ahi_empty((buf_block_t*) bpage); } #endif /* BTR_CUR_HASH_ADAPT */ @@ -1155,6 +1175,9 @@ buf_LRU_get_free_only( || !buf_block_will_withdrawn(buf_pool, block)) { /* found valid free block */ buf_page_mutex_enter(block); + /* No adaptive hash index entries may point to + a free block. */ + assert_block_ahi_empty(block); buf_block_set_state(block, BUF_BLOCK_READY_FOR_USE); UNIV_MEM_ALLOC(block->frame, UNIV_PAGE_SIZE); @@ -2029,17 +2052,10 @@ buf_LRU_block_free_non_file_page( case BUF_BLOCK_READY_FOR_USE: break; default: - ib::error() << "Block:" << block - << " incorrect state:" << buf_get_state_name(block) - << " in buf_LRU_block_free_non_file_page"; - return; /* Continue */ + ut_error; } -#ifdef BTR_CUR_HASH_ADAPT -# if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG - ut_a(block->n_pointers == 0); -# endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ -#endif /* BTR_CUR_HASH_ADAPT */ + assert_block_ahi_empty(block); ut_ad(!block->page.in_free_list); ut_ad(!block->page.in_flush_list); ut_ad(!block->page.in_LRU_list); @@ -2664,13 +2680,13 @@ buf_LRU_print_instance( } if (bpage->buf_fix_count) { - fprintf(stderr, "buffix count %lu ", - (ulong) bpage->buf_fix_count); + fprintf(stderr, "buffix count %u ", + bpage->buf_fix_count); } if (buf_page_get_io_fix(bpage)) { - fprintf(stderr, "io_fix %lu ", - (ulong) buf_page_get_io_fix(bpage)); + fprintf(stderr, "io_fix %d ", + buf_page_get_io_fix(bpage)); } if (bpage->oldest_modification) { @@ -2681,23 +2697,23 @@ buf_LRU_print_instance( const byte* frame; case BUF_BLOCK_FILE_PAGE: frame = buf_block_get_frame((buf_block_t*) bpage); - fprintf(stderr, "\ntype %lu" + fprintf(stderr, "\ntype " ULINTPF " index id " IB_ID_FMT "\n", - (ulong) fil_page_get_type(frame), + fil_page_get_type(frame), btr_page_get_index_id(frame)); break; case BUF_BLOCK_ZIP_PAGE: frame = bpage->zip.data; - fprintf(stderr, "\ntype %lu size %lu" + fprintf(stderr, "\ntype " ULINTPF " size " ULINTPF " index id " IB_ID_FMT "\n", - (ulong) fil_page_get_type(frame), - (ulong) bpage->size.physical(), + fil_page_get_type(frame), + bpage->size.physical(), btr_page_get_index_id(frame)); break; default: - fprintf(stderr, "\n!state %lu!\n", - (ulong) buf_page_get_state(bpage)); + fprintf(stderr, "\n!state %d!\n", + buf_page_get_state(bpage)); break; } diff --git a/storage/innobase/buf/buf0rea.cc b/storage/innobase/buf/buf0rea.cc index 4d68ad5ac51..f5bd088ce5c 100644 --- a/storage/innobase/buf/buf0rea.cc +++ b/storage/innobase/buf/buf0rea.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2015, 2016 MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -290,6 +290,24 @@ buf_read_ahead_random( below: if DISCARD + IMPORT changes the actual .ibd file meanwhile, we do not try to read outside the bounds of the tablespace! */ if (fil_space_t* space = fil_space_acquire(page_id.space())) { + +#ifdef UNIV_DEBUG + if (srv_file_per_table) { + ulint size = 0; + + for (const fil_node_t* node = + UT_LIST_GET_FIRST(space->chain); + node != NULL; + node = UT_LIST_GET_NEXT(chain, node)) { + + size += os_file_get_size(node->handle) + / page_size.physical(); + } + + ut_ad(size == space->size); + } +#endif /* UNIV_DEBUG */ + if (high > space->size) { high = space->size; } @@ -896,4 +914,3 @@ buf_read_recv_pages( DBUG_PRINT("ib_buf", ("recovery read-ahead (%u pages)", unsigned(n_stored))); } - diff --git a/storage/innobase/data/data0data.cc b/storage/innobase/data/data0data.cc index 8b1900face7..d819ad50ed9 100644 --- a/storage/innobase/data/data0data.cc +++ b/storage/innobase/data/data0data.cc @@ -429,7 +429,7 @@ print_hex: fputs(" Hex: ",stderr); for (i = 0; i < len; i++) { - fprintf(stderr, "%02lx", static_cast<ulong>(*data++)); + fprintf(stderr, "%02x", *data++); } if (dfield_is_ext(dfield)) { diff --git a/storage/innobase/dict/dict0boot.cc b/storage/innobase/dict/dict0boot.cc index 8d5bde4e0e2..3ae6639cd73 100644 --- a/storage/innobase/dict/dict0boot.cc +++ b/storage/innobase/dict/dict0boot.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2016, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -488,7 +488,9 @@ dict_boot(void) err = ibuf_init_at_db_start(); if (err == DB_SUCCESS) { - if (srv_read_only_mode && !ibuf_is_empty()) { + if (srv_read_only_mode + && srv_force_recovery != SRV_FORCE_NO_LOG_REDO + && !ibuf_is_empty()) { if (srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE) { ib::error() << "Change buffer must be empty when" diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 0db194b7e52..0d949a00b27 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -6597,7 +6597,7 @@ dict_table_schema_check( if ((ulint) table->n_def - n_sys_cols != req_schema->n_cols) { /* the table has a different number of columns than required */ ut_snprintf(errstr, errstr_sz, - "%s has %lu columns but should have %lu.", + "%s has %lu columns but should have " ULINTPF ".", ut_format_name(req_schema->table_name, buf, sizeof(buf)), table->n_def - n_sys_cols, @@ -6695,7 +6695,7 @@ dict_table_schema_check( ut_snprintf( errstr, errstr_sz, "Table %s has " ULINTPF " foreign key(s) pointing" - " to other tables, but it must have %lu.", + " to other tables, but it must have " ULINTPF ".", ut_format_name(req_schema->table_name, buf, sizeof(buf)), static_cast<ulint>(table->foreign_set.size()), @@ -6707,7 +6707,7 @@ dict_table_schema_check( ut_snprintf( errstr, errstr_sz, "There are " ULINTPF " foreign key(s) pointing to %s, " - "but there must be %lu.", + "but there must be " ULINTPF ".", static_cast<ulint>(table->referenced_set.size()), ut_format_name(req_schema->table_name, buf, sizeof(buf)), @@ -6747,7 +6747,7 @@ dict_fs2utf8( strconvert( &my_charset_filename, db, db_len, system_charset_info, - db_utf8, db_utf8_size, &errors); + db_utf8, uint(db_utf8_size), &errors); /* convert each # to @0023 in table name and store the result in buf */ const char* table = dict_remove_db_name(db_and_table); @@ -6774,7 +6774,7 @@ dict_fs2utf8( strconvert( &my_charset_filename, buf, (uint) (buf_p - buf), system_charset_info, - table_utf8, table_utf8_size, + table_utf8, uint(table_utf8_size), &errors); if (errors != 0) { diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc index 13db213259c..7a6f09569a6 100644 --- a/storage/innobase/dict/dict0mem.cc +++ b/storage/innobase/dict/dict0mem.cc @@ -810,7 +810,12 @@ dict_mem_fill_vcol_from_v_indexes( index; index = dict_table_get_next_index(index)) { - if (!dict_index_has_virtual(index)) { + /* Skip if the index have newly added + virtual column because field name is NULL. + Later virtual column set will be + refreshed during loading of table. */ + if (!dict_index_has_virtual(index) + || index->has_new_v_col) { continue; } diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index 9eb033a7eb9..537a70c2069 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -1,6 +1,7 @@ /***************************************************************************** -Copyright (c) 2009, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2009, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -138,7 +139,7 @@ then we would store 5,7,10,11,12 in the array. */ typedef std::vector<ib_uint64_t, ut_allocator<ib_uint64_t> > boundaries_t; /** Allocator type used for index_map_t. */ -typedef ut_allocator<std::pair<const char*, dict_index_t*> > +typedef ut_allocator<std::pair<const char* const, dict_index_t*> > index_map_t_allocator; /** Auxiliary map used for sorting indexes by name in dict_stats_save(). */ @@ -1046,8 +1047,8 @@ dict_stats_analyze_index_level( ulint* prev_rec_offsets; ulint i; - DEBUG_PRINTF(" %s(table=%s, index=%s, level=%lu)\n", __func__, - index->table->name, index->name, level); + DEBUG_PRINTF(" %s(table=%s, index=%s, level=" ULINTPF ")\n", + __func__, index->table->name, index->name, level); ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index), MTR_MEMO_SX_LOCK)); @@ -1151,10 +1152,11 @@ dict_stats_analyze_index_level( them away) which brings non-determinism. We skip only leaf-level delete marks because delete marks on non-leaf level do not make sense. */ - if (level == 0 && + + if (level == 0 && (srv_stats_include_delete_marked ? 0: rec_get_deleted_flag( rec, - page_is_comp(btr_pcur_get_page(&pcur)))) { + page_is_comp(btr_pcur_get_page(&pcur))))) { if (rec_is_last_on_page && !prev_rec_is_copied @@ -1175,7 +1177,6 @@ dict_stats_analyze_index_level( continue; } - rec_offsets = rec_get_offsets( rec, index, rec_offsets, n_uniq, &heap); @@ -1292,7 +1293,7 @@ dict_stats_analyze_index_level( DEBUG_PRINTF(" %s(): total recs: " UINT64PF ", total pages: " UINT64PF - ", n_diff[%lu]: " UINT64PF "\n", + ", n_diff[" ULINTPF "]: " UINT64PF "\n", __func__, *total_recs, *total_pages, i, n_diff[i]); @@ -1333,8 +1334,12 @@ enum page_scan_method_t { the given page and count the number of distinct ones, also ignore delete marked records */ - QUIT_ON_FIRST_NON_BORING/* quit when the first record that differs + QUIT_ON_FIRST_NON_BORING,/* quit when the first record that differs from its right neighbor is found */ + COUNT_ALL_NON_BORING_INCLUDE_DEL_MARKED/* scan all records on + the given page and count the number of + distinct ones, include delete marked + records */ }; /* @} */ @@ -1553,7 +1558,7 @@ dict_stats_analyze_index_below_cur( page = buf_block_get_frame(block); - if (btr_page_get_level(page, mtr) == 0) { + if (page_is_leaf(page)) { /* leaf level */ break; } @@ -1598,7 +1603,7 @@ dict_stats_analyze_index_below_cur( } /* make sure we got a leaf page as a result from the above loop */ - ut_ad(btr_page_get_level(page, &mtr) == 0); + ut_ad(page_is_leaf(page)); /* scan the leaf page and find the number of distinct keys, when looking only at the first n_prefix columns; also estimate @@ -1607,6 +1612,8 @@ dict_stats_analyze_index_below_cur( offsets_rec = dict_stats_scan_page( &rec, offsets1, offsets2, index, page, n_prefix, + srv_stats_include_delete_marked ? + COUNT_ALL_NON_BORING_INCLUDE_DEL_MARKED: COUNT_ALL_NON_BORING_AND_SKIP_DEL_MARKED, n_diff, n_external_pages); @@ -1912,8 +1919,9 @@ dict_stats_index_set_n_diff( index->stat_n_sample_sizes[n_prefix - 1] = data->n_leaf_pages_to_analyze; - DEBUG_PRINTF(" %s(): n_diff=" UINT64PF " for n_prefix=%lu" - " (%lu" + DEBUG_PRINTF(" %s(): n_diff=" UINT64PF + " for n_prefix=" ULINTPF + " (" ULINTPF " * " UINT64PF " / " UINT64PF " * " UINT64PF " / " UINT64PF ")\n", __func__, @@ -2068,8 +2076,8 @@ dict_stats_analyze_index( for (n_prefix = n_uniq; n_prefix >= 1; n_prefix--) { - DEBUG_PRINTF(" %s(): searching level with >=%llu" - " distinct records, n_prefix=%lu\n", + DEBUG_PRINTF(" %s(): searching level with >=%llu " + "distinct records, n_prefix=" ULINTPF "\n", __func__, N_DIFF_REQUIRED(index), n_prefix); /* Commit the mtr to release the tree S lock to allow @@ -2173,8 +2181,9 @@ dict_stats_analyze_index( } found_level: - DEBUG_PRINTF(" %s(): found level %lu that has " UINT64PF - " distinct records for n_prefix=%lu\n", + DEBUG_PRINTF(" %s(): found level " ULINTPF + " that has " UINT64PF + " distinct records for n_prefix=" ULINTPF "\n", __func__, level, n_diff_on_level[n_prefix - 1], n_prefix); /* here we are either on level 1 or the level that we are on @@ -2535,20 +2544,19 @@ dict_stats_save( ut_ad(!dict_index_is_ibuf(index)); - for (ulint i = 0; i < index->n_uniq; i++) { + for (unsigned i = 0; i < index->n_uniq; i++) { char stat_name[16]; char stat_description[1024]; - ulint j; ut_snprintf(stat_name, sizeof(stat_name), - "n_diff_pfx%02lu", i + 1); + "n_diff_pfx%02u", i + 1); /* craft a string that contains the column names */ ut_snprintf(stat_description, sizeof(stat_description), "%s", index->fields[0].name()); - for (j = 1; j <= i; j++) { + for (unsigned j = 1; j <= i; j++) { size_t len; len = strlen(stat_description); diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc index 4ffee160c9f..876d1bcb342 100644 --- a/storage/innobase/dict/dict0stats_bg.cc +++ b/storage/innobase/dict/dict0stats_bg.cc @@ -1,7 +1,7 @@ /***************************************************************************** -Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2012, 2017, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -31,6 +31,7 @@ Created Apr 25, 2012 Vasil Dimov #include "row0mysql.h" #include "srv0start.h" #include "ut0new.h" +#include "fil0fil.h" #include <vector> @@ -318,8 +319,9 @@ dict_stats_process_entry_from_recalc_pool() return; } - /* Check whether table is corrupted */ - if (table->corrupted) { + ut_ad(!dict_table_is_temporary(table)); + + if (!fil_table_accessible(table)) { dict_table_close(table, TRUE, FALSE); mutex_exit(&dict_sys->mutex); return; diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index db7efe89d37..b031a77baa8 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -1,6 +1,6 @@ /***************************************************************************** Copyright (C) 2013, 2015, Google Inc. All Rights Reserved. -Copyright (c) 2014, 2017, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2014, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -629,7 +629,7 @@ fil_space_encrypt( fil_space_crypt_t* crypt_data = space->crypt_data; const page_size_t page_size(space->flags); - ut_ad(space->n_pending_ops); + ut_ad(space->n_pending_ios > 0); byte* tmp = fil_encrypt_buf(crypt_data, space->id, offset, lsn, src_frame, page_size, dst_frame); @@ -647,7 +647,8 @@ fil_space_encrypt( comp_mem = (byte *)malloc(UNIV_PAGE_SIZE); uncomp_mem = (byte *)malloc(UNIV_PAGE_SIZE); memcpy(comp_mem, src_frame, UNIV_PAGE_SIZE); - fil_decompress_page(uncomp_mem, comp_mem, page_size.physical(), NULL); + fil_decompress_page(uncomp_mem, comp_mem, + srv_page_size, NULL); src = uncomp_mem; } @@ -657,7 +658,8 @@ fil_space_encrypt( /* Need to decompress the page if it was also compressed */ if (page_compressed_encrypted) { memcpy(comp_mem, tmp_mem, UNIV_PAGE_SIZE); - fil_decompress_page(tmp_mem, comp_mem, page_size.physical(), NULL); + fil_decompress_page(tmp_mem, comp_mem, + srv_page_size, NULL); } bool corrupted = buf_page_is_corrupted(true, tmp_mem, page_size, space); @@ -731,7 +733,8 @@ fil_space_decrypt( << " carries key_version " << key_version << " (should be undefined)"); - mach_write_to_4(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 0); + memset(src_frame + + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 0, 4); } return false; @@ -818,7 +821,7 @@ fil_space_decrypt( *decrypted = false; ut_ad(space->crypt_data != NULL && space->crypt_data->is_encrypted()); - ut_ad(space->n_pending_ops > 0); + ut_ad(space->n_pending_ios > 0); bool encrypted = fil_space_decrypt(space->crypt_data, tmp_frame, page_size, src_frame, &err); @@ -1305,26 +1308,28 @@ fil_crypt_realloc_iops( if (10 * state->cnt_waited > state->batch) { /* if we waited more than 10% re-estimate max_iops */ - uint avg_wait_time_us = + ulint avg_wait_time_us = state->sum_waited_us / state->cnt_waited; + if (avg_wait_time_us == 0) { + avg_wait_time_us = 1; // prevent division by zero + } + DBUG_PRINT("ib_crypt", - ("thr_no: %u - update estimated_max_iops from %u to %u.", + ("thr_no: %u - update estimated_max_iops from %u to " + ULINTPF ".", state->thread_no, state->estimated_max_iops, 1000000 / avg_wait_time_us)); - if (avg_wait_time_us == 0) { - avg_wait_time_us = 1; // prevent division by zero - } - - state->estimated_max_iops = 1000000 / avg_wait_time_us; + state->estimated_max_iops = uint(1000000 / avg_wait_time_us); state->cnt_waited = 0; state->sum_waited_us = 0; } else { DBUG_PRINT("ib_crypt", - ("thr_no: %u only waited %lu%% skip re-estimate.", + ("thr_no: %u only waited " ULINTPF + "%% skip re-estimate.", state->thread_no, (100 * state->cnt_waited) / state->batch)); } @@ -1552,33 +1557,27 @@ fil_crypt_find_page_to_rotate( fil_space_crypt_t *crypt_data = space->crypt_data; - /* Space might already be dropped */ - if (crypt_data) { - mutex_enter(&crypt_data->mutex); - ut_ad(key_state->key_id == crypt_data->key_id); + mutex_enter(&crypt_data->mutex); + ut_ad(key_state->key_id == crypt_data->key_id); - if (crypt_data->rotate_state.next_offset < - crypt_data->rotate_state.max_offset) { + bool found = crypt_data->rotate_state.max_offset >= + crypt_data->rotate_state.next_offset; - state->offset = crypt_data->rotate_state.next_offset; - ulint remaining = crypt_data->rotate_state.max_offset - - crypt_data->rotate_state.next_offset; + if (found) { + state->offset = crypt_data->rotate_state.next_offset; + ulint remaining = crypt_data->rotate_state.max_offset - + crypt_data->rotate_state.next_offset; - if (batch <= remaining) { - state->batch = batch; - } else { - state->batch = remaining; - } - - crypt_data->rotate_state.next_offset += batch; - mutex_exit(&crypt_data->mutex); - return true; + if (batch <= remaining) { + state->batch = batch; + } else { + state->batch = remaining; } - - mutex_exit(&crypt_data->mutex); } - return false; + crypt_data->rotate_state.next_offset += batch; + mutex_exit(&crypt_data->mutex); + return found; } /*********************************************************************** @@ -2160,7 +2159,7 @@ DECLARE_THREAD(fil_crypt_thread)( fil_crypt_start_rotate_space(&new_state, &thr); /* iterate all pages (cooperativly with other threads) */ - while (!thr.should_shutdown() && thr.space && + while (!thr.should_shutdown() && fil_crypt_find_page_to_rotate(&new_state, &thr)) { /* rotate a (set) of pages */ @@ -2169,6 +2168,8 @@ DECLARE_THREAD(fil_crypt_thread)( /* If space is marked as stopping, release space and stop rotation. */ if (thr.space->is_stopping()) { + fil_crypt_complete_rotate_space( + &new_state, &thr); fil_space_release(thr.space); thr.space = NULL; break; @@ -2491,10 +2492,6 @@ bool fil_space_verify_crypt_checksum( byte* page, const page_size_t& page_size, -#ifdef UNIV_INNOCHECKSUM - bool strict_check, /*!< --strict-check */ - FILE* log_file, /*!< --log */ -#endif /* UNIV_INNOCHECKSUM */ ulint space, ulint offset) { @@ -2540,14 +2537,7 @@ fil_space_verify_crypt_checksum( mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, checksum); bool valid = page_zip_verify_checksum(page, - page_size.physical() -#ifdef UNIV_INNOCHECKSUM - , offset, - strict_check, - log_file != NULL, - log_file -#endif - ); + page_size.physical()); mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, old); @@ -2593,19 +2583,11 @@ fil_space_verify_crypt_checksum( ulint checksum2 = mach_read_from_4( page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM); -#ifdef UNIV_INNOCHECKSUM -# define CKARGS page, checksum1, checksum2, \ - offset, log_file != NULL, log_file, algorithm -#else -# define CKARGS page, checksum1, checksum2 -#endif - bool valid = buf_page_is_checksum_valid_crc32( - CKARGS, false + page, checksum1, checksum2, false /* FIXME: also try the original crc32 that was buggy on big-endian architectures? */) - || buf_page_is_checksum_valid_innodb(CKARGS); -#undef CKARGS + || buf_page_is_checksum_valid_innodb(page, checksum1, checksum2); if (encrypted && valid) { /* If page is encrypted and traditional checksums match, diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 06ec31a7ed4..7a169c0bf2c 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2014, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -30,6 +30,7 @@ Created 10/25/1995 Heikki Tuuri #include "fil0crypt.h" #include "btr0btr.h" +#include "btr0sea.h" #include "buf0buf.h" #include "dict0boot.h" #include "dict0dict.h" @@ -39,6 +40,7 @@ Created 10/25/1995 Heikki Tuuri #include "fsp0space.h" #include "fsp0sysspace.h" #include "hash0hash.h" +#include "log0log.h" #include "log0recv.h" #include "mach0data.h" #include "mem0mem.h" @@ -55,9 +57,6 @@ Created 10/25/1995 Heikki Tuuri #include "os0event.h" #include "sync0sync.h" #include "buf0flu.h" -#include "srv0start.h" -#include "trx0purge.h" -#include "ut0new.h" #include "os0api.h" /** Tries to close a file in the LRU list. The caller must hold the fil_sys @@ -1507,6 +1506,13 @@ fil_space_free_low( ut_ad(srv_fast_shutdown == 2 || !srv_was_started || space->max_lsn == 0); + /* Wait for fil_space_release_for_io(); after + fil_space_detach(), the tablespace cannot be found, so + fil_space_acquire_for_io() would return NULL */ + while (space->n_pending_ios) { + os_thread_sleep(100); + } + for (fil_node_t* node = UT_LIST_GET_FIRST(space->chain); node != NULL; ) { ut_d(space->size -= node->size); @@ -2268,13 +2274,11 @@ Used by background threads that do not necessarily hold proper locks for concurrency control. @param[in] id tablespace ID @param[in] silent whether to silently ignore missing tablespaces -@param[in] for_io whether to look up the tablespace while performing I/O - (possibly executing TRUNCATE) @return the tablespace @retval NULL if missing or being deleted or truncated */ inline fil_space_t* -fil_space_acquire_low(ulint id, bool silent, bool for_io = false) +fil_space_acquire_low(ulint id, bool silent) { fil_space_t* space; @@ -2287,7 +2291,7 @@ fil_space_acquire_low(ulint id, bool silent, bool for_io = false) ib::warn() << "Trying to access missing" " tablespace " << id; } - } else if (!for_io && space->is_stopping()) { + } else if (space->is_stopping()) { space = NULL; } else { space->n_pending_ops++; @@ -2302,14 +2306,12 @@ fil_space_acquire_low(ulint id, bool silent, bool for_io = false) Used by background threads that do not necessarily hold proper locks for concurrency control. @param[in] id tablespace ID -@param[in] for_io whether to look up the tablespace while performing I/O - (possibly executing TRUNCATE) @return the tablespace @retval NULL if missing or being deleted or truncated */ fil_space_t* -fil_space_acquire(ulint id, bool for_io) +fil_space_acquire(ulint id) { - return(fil_space_acquire_low(id, false, for_io)); + return(fil_space_acquire_low(id, false)); } /** Acquire a tablespace that may not exist. @@ -2336,6 +2338,39 @@ fil_space_release(fil_space_t* space) mutex_exit(&fil_system->mutex); } +/** Acquire a tablespace for reading or writing a block, +when it could be dropped concurrently. +@param[in] id tablespace ID +@return the tablespace +@retval NULL if missing */ +fil_space_t* +fil_space_acquire_for_io(ulint id) +{ + mutex_enter(&fil_system->mutex); + + fil_space_t* space = fil_space_get_by_id(id); + + if (space) { + space->n_pending_ios++; + } + + mutex_exit(&fil_system->mutex); + + return(space); +} + +/** Release a tablespace acquired with fil_space_acquire_for_io(). +@param[in,out] space tablespace to release */ +void +fil_space_release_for_io(fil_space_t* space) +{ + mutex_enter(&fil_system->mutex); + ut_ad(space->magic_n == FIL_SPACE_MAGIC_N); + ut_ad(space->n_pending_ios > 0); + space->n_pending_ios--; + mutex_exit(&fil_system->mutex); +} + /********************************************************//** Creates the database directory for a table if it does not exist yet. */ void @@ -2837,15 +2872,15 @@ enum fil_operation_t { @return 0 if no operations else count + 1. */ static ulint -fil_check_pending_ops( - fil_space_t* space, - ulint count) +fil_check_pending_ops(const fil_space_t* space, ulint count) { ut_ad(mutex_own(&fil_system->mutex)); - const ulint n_pending_ops = space ? space->n_pending_ops : 0; + if (space == NULL) { + return 0; + } - if (n_pending_ops) { + if (ulint n_pending_ops = space->n_pending_ops) { if (count > 5000) { ib::warn() << "Trying to close/delete/truncate" @@ -3057,6 +3092,32 @@ fil_close_tablespace( return(err); } +/** Determine whether a table can be accessed in operations that are +not (necessarily) protected by meta-data locks. +(Rollback would generally be protected, but rollback of +FOREIGN KEY CASCADE/SET NULL is not protected by meta-data locks +but only by InnoDB table locks, which may be broken by TRUNCATE TABLE.) +@param[in] table persistent table +checked @return whether the table is accessible */ +bool +fil_table_accessible(const dict_table_t* table) +{ + if (UNIV_UNLIKELY(table->ibd_file_missing || table->corrupted)) { + return(false); + } + + if (fil_space_t* space = fil_space_acquire(table->space)) { + bool accessible = !space->is_stopping(); + fil_space_release(space); + ut_ad(accessible || dict_table_is_file_per_table(table)); + return(accessible); + } else { + /* The tablespace may momentarily be missing during + TRUNCATE TABLE. */ + return(false); + } +} + /** Deletes an IBD tablespace, either general or single-table. The tablespace must be cached in the memory cache. This will delete the datafile, fil_space_t & fil_node_t entries from the file_system_t cache. @@ -3266,20 +3327,34 @@ fil_prepare_for_truncate( return(err); } -/**********************************************************************//** -Reinitialize the original tablespace header with the same space id -for single tablespace */ +/** Reinitialize the original tablespace header with the same space id +for single tablespace +@param[in] id space id of the tablespace +@param[in] size size in blocks +@param[in] trx Transaction covering truncate */ void fil_reinit_space_header( -/*====================*/ - ulint id, /*!< in: space id */ - ulint size) /*!< in: size in blocks */ + ulint id, + ulint size, + trx_t* trx) { ut_a(!is_system_tablespace(id)); /* Invalidate in the buffer pool all pages belonging - to the tablespace */ + to the tablespace. The buffer pool scan may take long + time to complete, therefore we release dict_sys->mutex + and the dict operation lock during the scan and aquire + it again after the buffer pool scan.*/ + + row_mysql_unlock_data_dictionary(trx); + + /* Lock the search latch in shared mode to prevent user + from disabling AHI during the scan */ + btr_search_s_lock_all(); + DEBUG_SYNC_C("buffer_pool_scan"); buf_LRU_flush_or_remove_pages(id, BUF_REMOVE_ALL_NO_WRITE, 0); + btr_search_s_unlock_all(); + row_mysql_lock_data_dictionary(trx); /* Remove all insert buffer entries for the tablespace */ ibuf_delete_for_discarded_space(id); @@ -3859,8 +3934,6 @@ fil_ibd_create( return(DB_OUT_OF_FILE_SPACE); } - /* printf("Creating tablespace %s id %lu\n", path, space_id); */ - /* We have to write the space id to the file immediately and flush the file to disk. This is because in crash recovery we must be aware what tablespaces exist and what are their space id's, so that we can apply @@ -5489,6 +5562,24 @@ fil_flush( mutex_exit(&fil_system->mutex); } +/** Flush a tablespace. +@param[in,out] space tablespace to flush */ +void +fil_flush(fil_space_t* space) +{ + ut_ad(space->n_pending_ios > 0); + ut_ad(space->purpose == FIL_TYPE_TABLESPACE + || space->purpose == FIL_TYPE_IMPORT); + + if (!space->is_stopping()) { + mutex_enter(&fil_system->mutex); + if (!space->is_stopping()) { + fil_flush_low(space); + } + mutex_exit(&fil_system->mutex); + } +} + /** Flush to disk the writes in file spaces of the given type possibly cached by the OS. @param[in] purpose FIL_TYPE_TABLESPACE or FIL_TYPE_LOG */ @@ -5894,7 +5985,8 @@ fil_iterate( /* If the original page is page_compressed, we need to decompress page before we can update it. */ if (page_compressed) { - fil_decompress_page(NULL, dst, size, NULL); + fil_decompress_page(NULL, dst, ulong(size), + NULL); updated = true; } @@ -5956,12 +6048,13 @@ fil_iterate( if (page_compressed) { ulint len = 0; - byte * res = fil_compress_page(space_id, + byte * res = fil_compress_page( + NULL, src, NULL, size, dict_table_page_compression_level(iter.table), - fil_space_get_block_size(space_id, offset, size), + 512,/* FIXME: use proper block size */ encrypted, &len, NULL); @@ -5976,6 +6069,8 @@ fil_iterate( /* If tablespace is encrypted, encrypt page before we write it back. Note that we should not encrypt the buffer that is in buffer pool. */ + /* NOTE: At this stage of IMPORT the + buffer pool is not being used at all! */ if (decrypted && encrypted) { byte *dest = writeptr + (i * size); ulint space = mach_read_from_4( @@ -6478,6 +6573,12 @@ fil_names_clear( bool do_write) { mtr_t mtr; + ulint mtr_checkpoint_size = LOG_CHECKPOINT_FREE_PER_THREAD; + + DBUG_EXECUTE_IF( + "increase_mtr_checkpoint_size", + mtr_checkpoint_size = 75 * 1024; + ); ut_ad(log_mutex_own()); @@ -6511,11 +6612,24 @@ fil_names_clear( fil_names_write(space, &mtr); do_write = true; + const mtr_buf_t* mtr_log = mtr_get_log(&mtr); + + /** If the mtr buffer size exceeds the size of + LOG_CHECKPOINT_FREE_PER_THREAD then commit the multi record + mini-transaction, start the new mini-transaction to + avoid the parsing buffer overflow error during recovery. */ + + if (mtr_log->size() > mtr_checkpoint_size) { + ut_ad(mtr_log->size() < (RECV_PARSING_BUF_SIZE / 2)); + mtr.commit_checkpoint(lsn, false); + mtr.start(); + } + space = next; } if (do_write) { - mtr.commit_checkpoint(lsn); + mtr.commit_checkpoint(lsn, true); } else { ut_ad(!mtr.has_modifications()); } @@ -6823,73 +6937,24 @@ fil_space_keyrotate_next( return(space); } -/********************************************************************//** -Find correct node from file space -@return node */ -static -fil_node_t* -fil_space_get_node( - fil_space_t* space, /*!< in: file spage */ - ulint space_id, /*!< in: space id */ - os_offset_t* block_offset, /*!< in/out: offset in number of blocks */ - ulint byte_offset, /*!< in: remainder of offset in bytes; in - aio this must be divisible by the OS block - size */ - ulint len) /*!< in: how many bytes to read or write; this - must not cross a file boundary; in aio this - must be a block size multiple */ -{ - fil_node_t* node; - ut_ad(mutex_own(&fil_system->mutex)); - - node = UT_LIST_GET_FIRST(space->chain); - - for (;;) { - if (node == NULL) { - return(NULL); - } else if (fil_is_user_tablespace_id(space->id) - && node->size == 0) { - - /* We do not know the size of a single-table tablespace - before we open the file */ - break; - } else if (node->size > *block_offset) { - /* Found! */ - break; - } else { - *block_offset -= node->size; - node = UT_LIST_GET_NEXT(chain, node); - } - } - - return (node); -} - -/********************************************************************//** -Return block size of node in file space -@param[in] space_id space id -@param[in] block_offset page offset -@param[in] len page len -@return file block size */ +/** Determine the block size of the data file. +@param[in] space tablespace +@param[in] offset page number +@return block size */ UNIV_INTERN ulint -fil_space_get_block_size( - ulint space_id, - os_offset_t block_offset, - ulint len) +fil_space_get_block_size(const fil_space_t* space, unsigned offset) { ulint block_size = 512; - ut_ad(!mutex_own(&fil_system->mutex)); - - mutex_enter(&fil_system->mutex); - fil_space_t* space = fil_space_get_space(space_id); - - if (space) { - fil_node_t* node = fil_space_get_node(space, space_id, &block_offset, 0, len); - if (node) { - block_size = node->block_size; + for (fil_node_t* node = UT_LIST_GET_FIRST(space->chain); + node != NULL; + node = UT_LIST_GET_NEXT(chain, node)) { + block_size = node->block_size; + if (node->size > offset) { + break; } + offset -= node->size; } /* Currently supporting block size up to 4K, @@ -6898,8 +6963,6 @@ fil_space_get_block_size( block_size = 512; } - mutex_exit(&fil_system->mutex); - return block_size; } diff --git a/storage/innobase/fil/fil0pagecompress.cc b/storage/innobase/fil/fil0pagecompress.cc index 39a02aa40df..cb3e50745a7 100644 --- a/storage/innobase/fil/fil0pagecompress.cc +++ b/storage/innobase/fil/fil0pagecompress.cc @@ -85,8 +85,7 @@ UNIV_INTERN byte* fil_compress_page( /*==============*/ - ulint space_id, /*!< in: tablespace id of the - table. */ + fil_space_t* space, /*!< in,out: tablespace (NULL during IMPORT) */ byte* buf, /*!< in: buffer from which to write; in aio this must be appropriately aligned */ byte* out_buf, /*!< out: compressed buffer */ @@ -104,9 +103,12 @@ fil_compress_page( ulint write_size=0; /* Cache to avoid change during function execution */ ulint comp_method = innodb_compression_algorithm; - ulint orig_page_type; bool allocated=false; + /* page_compression does not apply to tables or tablespaces + that use ROW_FORMAT=COMPRESSED */ + ut_ad(!space || !FSP_FLAGS_GET_ZIP_SSIZE(space->flags)); + if (encrypted) { header_len += FIL_PAGE_COMPRESSION_METHOD_SIZE; } @@ -127,21 +129,14 @@ fil_compress_page( ut_ad(len); ut_ad(out_len); - /* read original page type */ - orig_page_type = mach_read_from_2(buf + FIL_PAGE_TYPE); - - fil_system_enter(); - fil_space_t* space = fil_space_get_by_id(space_id); - fil_system_exit(); - /* Let's not compress file space header or extent descriptor */ - if (orig_page_type == 0 || - orig_page_type == FIL_PAGE_TYPE_FSP_HDR || - orig_page_type == FIL_PAGE_TYPE_XDES || - orig_page_type == FIL_PAGE_PAGE_COMPRESSED) { + switch (fil_page_get_type(buf)) { + case 0: + case FIL_PAGE_TYPE_FSP_HDR: + case FIL_PAGE_TYPE_XDES: + case FIL_PAGE_PAGE_COMPRESSED: *out_len = len; - goto err_exit; } @@ -151,11 +146,9 @@ fil_compress_page( comp_level = page_zip_level; } -#ifdef UNIV_PAGECOMPRESS_DEBUG - ib_logf(IB_LOG_LEVEL_INFO, - "Preparing for compress for space %lu name %s len %lu.", - space_id, fil_space_name(space), len); -#endif /* UNIV_PAGECOMPRESS_DEBUG */ + DBUG_LOG("compress", "Preparing for space " + << (space ? space->id : 0) << " '" + << (space ? space->name : "(import)") << "' len " << len); write_size = UNIV_PAGE_SIZE - header_len; @@ -252,7 +245,8 @@ fil_compress_page( #endif /* HAVE_SNAPPY */ case PAGE_ZLIB_ALGORITHM: - err = compress2(out_buf+header_len, (ulong*)&write_size, buf, len, comp_level); + err = compress2(out_buf+header_len, (ulong*)&write_size, buf, + uLong(len), comp_level); if (err != Z_OK) { goto err_exit; @@ -304,13 +298,12 @@ fil_compress_page( comp_page = static_cast<byte *>(ut_malloc_nokey(UNIV_PAGE_SIZE)); uncomp_page = static_cast<byte *>(ut_malloc_nokey(UNIV_PAGE_SIZE)); memcpy(comp_page, out_buf, UNIV_PAGE_SIZE); - bool tsfound; - const page_size_t page_size = fil_space_get_page_size(space_id, &tsfound); - fil_decompress_page(uncomp_page, comp_page, len, NULL); + fil_decompress_page(uncomp_page, comp_page, ulong(len), NULL); - if (buf_page_is_corrupted(false, uncomp_page, page_size, space)) { - buf_page_print(uncomp_page, page_size, 0); + if (buf_page_is_corrupted(false, uncomp_page, univ_page_size, + space)) { + buf_page_print(uncomp_page, univ_page_size, 0); } ut_free(comp_page); @@ -329,7 +322,6 @@ fil_compress_page( /* Actual write needs to be alligned on block size */ if (write_size % block_size) { size_t tmp = write_size; - write_size = (size_t)ut_uint64_align_up((ib_uint64_t)write_size, block_size); /* Clean up the end of buffer */ memset(out_buf+tmp, 0, write_size - tmp); @@ -339,11 +331,10 @@ fil_compress_page( #endif } -#ifdef UNIV_PAGECOMPRESS_DEBUG - ib_logf(IB_LOG_LEVEL_INFO, - "Compression succeeded for space %lu name %s len %lu out_len %lu.", - space_id, fil_space_name(space), len, write_size); -#endif /* UNIV_PAGECOMPRESS_DEBUG */ + DBUG_LOG("compress", "Succeeded for space " + << (space ? space->id : 0) << " '" + << (space ? space->name : "(import)") + << "' len " << len << " out_len " << write_size); srv_stats.page_compression_saved.add((len - write_size)); srv_stats.pages_page_compressed.inc(); @@ -369,17 +360,17 @@ err_exit: /* If error we leave the actual page as it was */ #ifndef UNIV_PAGECOMPRESS_DEBUG - if (space && space->printed_compression_failure == false) { + if (space && !space->printed_compression_failure) { + space->printed_compression_failure = true; #endif ib::warn() << "Compression failed for space: " - << space_id << " name: " - << fil_space_name(space) << " len: " + << space->id << " name: " + << space->name << " len: " << len << " err: " << err << " write_size: " << write_size << " compression method: " << fil_get_compression_alg_name(comp_method) << "."; - space->printed_compression_failure = true; #ifndef UNIV_PAGECOMPRESS_DEBUG } #endif @@ -640,21 +631,17 @@ err_exit: /* Note that as we have found the page is corrupted, so all this could be incorrect. */ ulint space_id = mach_read_from_4(buf+FIL_PAGE_SPACE_ID); - fil_system_enter(); - fil_space_t* space = fil_space_get_by_id(space_id); - fil_system_exit(); - - bool tsfound; - const page_size_t page_size = fil_space_get_page_size(space_id, &tsfound); + fil_space_t* space = fil_space_acquire_for_io(space_id); ib::error() << "Corruption: Page is marked as compressed" << " space: " << space_id << " name: " - << (space ? fil_space_name(space) : "NULL") + << (space ? space->name : "NULL") << " but uncompress failed with error: " << err << " size: " << actual_size << " len: " << len << " compression method: " << fil_get_compression_alg_name(compression_alg) << "."; - buf_page_print(buf, page_size, 0); + buf_page_print(buf, univ_page_size, 0); + fil_space_release_for_io(space); } diff --git a/storage/innobase/fts/fts0config.cc b/storage/innobase/fts/fts0config.cc index cca3d5fcd87..4d41df1abf9 100644 --- a/storage/innobase/fts/fts0config.cc +++ b/storage/innobase/fts/fts0config.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -349,7 +350,7 @@ fts_config_set_index_ulint( ut_a(FTS_MAX_INT_LEN < FTS_MAX_CONFIG_VALUE_LEN); value.f_len = ut_snprintf( - (char*) value.f_str, FTS_MAX_INT_LEN, "%lu", int_value); + (char*) value.f_str, FTS_MAX_INT_LEN, ULINTPF, int_value); error = fts_config_set_index_value(trx, index, name, &value); @@ -422,7 +423,7 @@ fts_config_set_ulint( ut_a(FTS_MAX_INT_LEN < FTS_MAX_CONFIG_VALUE_LEN); value.f_len = my_snprintf( - (char*) value.f_str, FTS_MAX_INT_LEN, "%lu", int_value); + (char*) value.f_str, FTS_MAX_INT_LEN, ULINTPF, int_value); error = fts_config_set_value(trx, fts_table, name, &value); @@ -435,4 +436,3 @@ fts_config_set_ulint( return(error); } - diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index a7d09b5dd47..79020fb4442 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, MariaDB Corporation. All Rights reserved. +Copyright (c) 2016, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -93,6 +93,7 @@ static const ulint FTS_DEADLOCK_RETRY_WAIT = 100000; /** variable to record innodb_fts_internal_tbl_name for information schema table INNODB_FTS_INSERTED etc. */ char* fts_internal_tbl_name = NULL; +char* fts_internal_tbl_name2 = NULL; /** InnoDB default stopword list: There are different versions of stopwords, the stop words listed @@ -2542,7 +2543,7 @@ fts_get_max_cache_size( { dberr_t error; fts_string_t value; - ulint cache_size_in_mb; + ulong cache_size_in_mb; /* Set to the default value. */ cache_size_in_mb = FTS_CACHE_SIZE_LOWER_LIMIT_IN_MB; @@ -6496,6 +6497,36 @@ fts_check_corrupt_index( return(0); } +/* Get parent table name if it's a fts aux table +@param[in] aux_table_name aux table name +@param[in] aux_table_len aux table length +@return parent table name, or NULL */ +char* +fts_get_parent_table_name( + const char* aux_table_name, + ulint aux_table_len) +{ + fts_aux_table_t aux_table; + char* parent_table_name = NULL; + + if (fts_is_aux_table_name(&aux_table, aux_table_name, aux_table_len)) { + dict_table_t* parent_table; + + parent_table = dict_table_open_on_id( + aux_table.parent_id, TRUE, DICT_TABLE_OP_NORMAL); + + if (parent_table != NULL) { + parent_table_name = mem_strdupl( + parent_table->name.m_name, + strlen(parent_table->name.m_name)); + + dict_table_close(parent_table, TRUE, FALSE); + } + } + + return(parent_table_name); +} + /** Check the validity of the parent table. @param[in] aux_table auxiliary table @return true if it is a valid table or false if it is not */ diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc index f1e717c353a..820e82dc600 100644 --- a/storage/innobase/fts/fts0opt.cc +++ b/storage/innobase/fts/fts0opt.cc @@ -578,9 +578,6 @@ fts_zip_read_word( fts_zip_t* zip, /*!< in: Zip state + data */ fts_string_t* word) /*!< out: uncompressed word */ { -#ifdef UNIV_DEBUG - ulint i; -#endif short len = 0; void* null = NULL; byte* ptr = word->f_str; @@ -656,10 +653,9 @@ fts_zip_read_word( } } -#ifdef UNIV_DEBUG /* All blocks must be freed at end of inflate. */ if (zip->status != Z_OK) { - for (i = 0; i < ib_vector_size(zip->blocks); ++i) { + for (ulint i = 0; i < ib_vector_size(zip->blocks); ++i) { if (ib_vector_getp(zip->blocks, i)) { ut_free(ib_vector_getp(zip->blocks, i)); ib_vector_set(zip->blocks, i, &null); @@ -670,7 +666,6 @@ fts_zip_read_word( if (ptr != NULL) { ut_ad(word->f_len == strlen((char*) ptr)); } -#endif /* UNIV_DEBUG */ return(zip->status == Z_OK || zip->status == Z_STREAM_END ? ptr : NULL); } diff --git a/storage/innobase/fts/fts0que.cc b/storage/innobase/fts/fts0que.cc index beef71aa178..bc1d173cc29 100644 --- a/storage/innobase/fts/fts0que.cc +++ b/storage/innobase/fts/fts0que.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -487,7 +488,7 @@ fts_query_lcs( len = FTS_ELEM(table, c, 0, 0); fts_print_lcs_table(table, r, c); - printf("\nLen=%lu\n", len); + printf("\nLen=" ULINTPF "\n", len); ut_free(table); diff --git a/storage/innobase/gis/gis0rtree.cc b/storage/innobase/gis/gis0rtree.cc index a558ce3f54d..d14bafff72b 100644 --- a/storage/innobase/gis/gis0rtree.cc +++ b/storage/innobase/gis/gis0rtree.cc @@ -837,6 +837,9 @@ rtr_split_page_move_rec_list( ulint max_to_move = 0; rtr_rec_move_t* rec_move = NULL; + ut_ad(!dict_index_is_ibuf(index)); + ut_ad(dict_index_is_spatial(index)); + rec_offs_init(offsets_); page_cur_set_before_first(block, &page_cursor); @@ -907,8 +910,7 @@ rtr_split_page_move_rec_list( same temp-table in parallel. max_trx_id is ignored for temp tables because it not required for MVCC. */ - if (dict_index_is_sec_or_ibuf(index) - && page_is_leaf(page) + if (page_is_leaf(page) && !dict_table_is_temporary(index->table)) { page_update_max_trx_id(new_block, NULL, page_get_max_trx_id(page), diff --git a/storage/innobase/ha/ha0ha.cc b/storage/innobase/ha/ha0ha.cc index 5822bd6755c..f620db6f62e 100644 --- a/storage/innobase/ha/ha0ha.cc +++ b/storage/innobase/ha/ha0ha.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -189,6 +190,12 @@ ha_clear( } #ifdef BTR_CUR_HASH_ADAPT +# if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG +/** Maximum number of records in a page */ +static const lint MAX_N_POINTERS + = UNIV_PAGE_SIZE_MAX / REC_N_NEW_EXTRA_BYTES; +# endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ + /*************************************************************//** 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 @@ -235,9 +242,11 @@ ha_insert_for_fold_func( buf_block_t* prev_block = prev_node->block; ut_a(prev_block->frame == page_align(prev_node->data)); - ut_a(prev_block->n_pointers > 0); - prev_block->n_pointers--; - block->n_pointers++; + ut_a(my_atomic_addlint( + &prev_block->n_pointers, -1) + < MAX_N_POINTERS); + ut_a(my_atomic_addlint(&block->n_pointers, 1) + < MAX_N_POINTERS); } prev_node->block = block; @@ -268,7 +277,8 @@ ha_insert_for_fold_func( #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG if (table->adaptive) { - block->n_pointers++; + ut_a(my_atomic_addlint(&block->n_pointers, 1) + < MAX_N_POINTERS); } #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ @@ -329,8 +339,8 @@ ha_delete_hash_node( #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG if (table->adaptive) { ut_a(del_node->block->frame = page_align(del_node->data)); - ut_a(del_node->block->n_pointers > 0); - del_node->block->n_pointers--; + ut_a(my_atomic_addlint(&del_node->block->n_pointers, -1) + < MAX_N_POINTERS); } #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ @@ -372,9 +382,10 @@ ha_search_and_update_if_found_func( if (node) { #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG if (table->adaptive) { - ut_a(node->block->n_pointers > 0); - node->block->n_pointers--; - new_block->n_pointers++; + ut_a(my_atomic_addlint(&node->block->n_pointers, -1) + < MAX_N_POINTERS); + ut_a(my_atomic_addlint(&new_block->n_pointers, 1) + < MAX_N_POINTERS); } node->block = new_block; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 2022ae4a4c1..37c4c09e553 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -215,46 +215,46 @@ static uint innobase_old_blocks_pct; /* The default values for the following char* start-up parameters are determined in innobase_init below: */ -static char* innobase_data_home_dir = NULL; -static char* innobase_data_file_path = NULL; -static char* innobase_temp_data_file_path = NULL; -static char* innobase_file_format_name = NULL; -static char* innobase_change_buffering = NULL; -static char* innobase_enable_monitor_counter = NULL; -static char* innobase_disable_monitor_counter = NULL; -static char* innobase_reset_monitor_counter = NULL; -static char* innobase_reset_all_monitor_counter = NULL; +static char* innobase_data_home_dir; +static char* innobase_data_file_path; +static char* innobase_temp_data_file_path; +static char* innobase_file_format_name; +static char* innobase_change_buffering; +static char* innobase_enable_monitor_counter; +static char* innobase_disable_monitor_counter; +static char* innobase_reset_monitor_counter; +static char* innobase_reset_all_monitor_counter; /* The highest file format being used in the database. The value can be set by user, however, it will be adjusted to the newer file format if a table of such format is created/opened. */ -char* innobase_file_format_max = NULL; +char* innobase_file_format_max; /** Default value of innodb_file_format */ static const char* innodb_file_format_default = "Barracuda"; /** Default value of innodb_file_format_max */ static const char* innodb_file_format_max_default = "Antelope"; -static char* innobase_file_flush_method = NULL; +static char* innobase_file_flush_method; /* This variable can be set in the server configure file, specifying stopword table to be used */ -static char* innobase_server_stopword_table = NULL; +static char* innobase_server_stopword_table; /* Below we have boolean-valued start-up parameters, and their default values */ -static my_bool innobase_file_format_check = TRUE; -static my_bool innobase_use_atomic_writes = TRUE; +static my_bool innobase_file_format_check; +static my_bool innobase_use_atomic_writes; static my_bool innobase_use_fallocate; -static my_bool innobase_use_doublewrite = TRUE; -static my_bool innobase_use_checksums = TRUE; -static my_bool innobase_locks_unsafe_for_binlog = FALSE; -static my_bool innobase_rollback_on_timeout = FALSE; -static my_bool innobase_create_status_file = FALSE; -my_bool innobase_stats_on_metadata = TRUE; -static my_bool innobase_large_prefix = FALSE; -static my_bool innodb_optimize_fulltext_only = FALSE; +static my_bool innobase_use_doublewrite; +static my_bool innobase_use_checksums; +static my_bool innobase_locks_unsafe_for_binlog; +static my_bool innobase_rollback_on_timeout; +static my_bool innobase_create_status_file; +my_bool innobase_stats_on_metadata; +static my_bool innobase_large_prefix; +static my_bool innodb_optimize_fulltext_only; static char* innodb_version_str = (char*) INNODB_VERSION_STR; @@ -1359,15 +1359,11 @@ void innobase_commit_concurrency_init_default(); /*=======================================*/ -/** @brief Initialize the default and max value of innodb_undo_logs. - -Once InnoDB is running, the default value and the max value of -innodb_undo_logs must be equal to the available undo logs, -given by srv_available_undo_logs. */ +/** @brief Adjust some InnoDB startup parameters based on file contents +or innodb_page_size. */ static void -innobase_undo_logs_init_default_max(); -/*==================================*/ +innodb_params_adjust(); /************************************************************//** Validate the file format name and return its corresponding id. @@ -2334,7 +2330,8 @@ innobase_get_cset_width( if (cset != 0) { sql_print_warning( - "Unknown collation #%lu.", cset); + "Unknown collation #" ULINTPF ".", + cset); } } else { @@ -4270,9 +4267,8 @@ innobase_change_buffering_inited_ok: } else if (srv_max_io_capacity < srv_io_capacity) { sql_print_warning("InnoDB: innodb_io_capacity" " cannot be set higher than" - " innodb_io_capacity_max.\n" - "InnoDB: Setting" - " innodb_io_capacity to %lu\n", + " innodb_io_capacity_max." + "Setting innodb_io_capacity=%lu", srv_max_io_capacity); srv_io_capacity = srv_max_io_capacity; @@ -4293,6 +4289,11 @@ innobase_change_buffering_inited_ok: if (UNIV_PAGE_SIZE_DEF != srv_page_size) { ib::info() << "innodb_page_size=" << srv_page_size; + + srv_max_undo_log_size = std::max( + srv_max_undo_log_size, + ulonglong(SRV_UNDO_TABLESPACE_SIZE_IN_PAGES) + * srv_page_size); } if (srv_log_write_ahead_size > srv_page_size) { @@ -4459,12 +4460,6 @@ innobase_change_buffering_inited_ok: } */ - /* Since we in this module access directly the fields of a trx - struct, and due to different headers and flags it might happen that - ib_mutex_t has a different size in this module and in InnoDB - modules, we check at run time that the size is the same in - these compilation modules. */ - err = innobase_start_or_create_for_mysql(); if (srv_buf_pool_size_org != 0) { @@ -4489,9 +4484,8 @@ innobase_change_buffering_inited_ok: os_thread_sleep(20); } - srv_was_started = TRUE; - /* Adjust the innodb_undo_logs config object */ - innobase_undo_logs_init_default_max(); + srv_was_started = true; + innodb_params_adjust(); innobase_old_blocks_pct = static_cast<uint>( buf_LRU_old_ratio_update(innobase_old_blocks_pct, TRUE)); @@ -6337,9 +6331,10 @@ innobase_build_index_translation( if (index_mapping == NULL) { /* Report an error if index_mapping continues to be NULL and mysql_num_index is a non-zero value */ - sql_print_error("InnoDB: fail to allocate memory for" - " index translation table. Number of" - " Index:%lu, array size:%lu", + sql_print_error("InnoDB: fail to allocate memory for " + "index translation table. Number of " + "Index: " ULINTPF + ", array size:" ULINTPF, mysql_num_index, share->idx_trans_tbl.array_size); ret = false; @@ -6848,9 +6843,9 @@ ha_innobase::open( if (key_used_on_scan != MAX_KEY) { sql_print_warning( - "Table %s key_used_on_scan is %lu even" - " though there is no primary key inside" - " InnoDB.", name, (ulong) key_used_on_scan); + "Table %s key_used_on_scan is %u even " + "though there is no primary key inside " + "InnoDB.", name, key_used_on_scan); } } @@ -10478,13 +10473,7 @@ ha_innobase::rnd_init( bool scan) /*!< in: true if table/index scan FALSE otherwise */ { TrxInInnoDB trx_in_innodb(m_prebuilt->trx); - - if (trx_in_innodb.is_aborted()) { - - return(innobase_rollback(ht, m_user_thd, false)); - } - - int err; + int err; /* Store the active index value so that we can restore the original value after a scan */ @@ -11094,7 +11083,8 @@ wsrep_append_foreign_key( if (rcode != DB_SUCCESS) { WSREP_ERROR( - "FK key set failed: %lu (%lu %lu), index: %s %s, %s", + "FK key set failed: " ULINTPF + " (" ULINTPF " " ULINTPF "), index: %s %s, %s", rcode, referenced, shared, (index) ? index->name() : "void index", (index && index->table) ? index->table->name.m_name : @@ -11156,8 +11146,9 @@ wsrep_append_foreign_key( copy); if (rcode) { - DBUG_PRINT("wsrep", ("row key failed: %lu", rcode)); - WSREP_ERROR("Appending cascaded fk row key failed: %s, %lu", + DBUG_PRINT("wsrep", ("row key failed: " ULINTPF, rcode)); + WSREP_ERROR("Appending cascaded fk row key failed: %s, " + ULINTPF, (wsrep_thd_query(thd)) ? wsrep_thd_query(thd) : "void", rcode); return DB_ERROR; @@ -11436,13 +11427,7 @@ ha_innobase::position( len = key_info->key_length; } - /* We assume that the 'ref' value len is always fixed for the same - table. */ - - if (len != ref_length) { - sql_print_error("Stored ref len is %lu, but table ref len is" - " %lu", (ulong) len, (ulong) ref_length); - } + ut_ad(len == ref_length); } /*****************************************************************//** @@ -11778,8 +11763,8 @@ create_table_info_t::create_table_def() ER_CANT_CREATE_TABLE, "In InnoDB, charset-collation codes" " must be below 256." - " Unsupported code %lu.", - (ulong) charset_no); + " Unsupported code " ULINTPF ".", + charset_no); mem_heap_free(heap); dict_mem_table_free(table); @@ -12300,7 +12285,7 @@ create_table_info_t::create_options_are_invalid() push_warning_printf( m_thd, Sql_condition::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: invalid KEY_BLOCK_SIZE = %lu." + "InnoDB: invalid KEY_BLOCK_SIZE = %u." " Valid values are [1, 2, 4, 8, 16]", m_create_info->key_block_size); ret = "KEY_BLOCK_SIZE"; @@ -12791,7 +12776,7 @@ index_bad: push_warning_printf( m_thd, Sql_condition::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: ignoring KEY_BLOCK_SIZE=%lu.", + "InnoDB: ignoring KEY_BLOCK_SIZE=%u.", m_create_info->key_block_size); } } @@ -12813,7 +12798,7 @@ index_bad: push_warning_printf( m_thd, Sql_condition::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: ignoring KEY_BLOCK_SIZE=%lu" + "InnoDB: ignoring KEY_BLOCK_SIZE=%u" " unless ROW_FORMAT=COMPRESSED.", m_create_info->key_block_size); zip_allowed = false; @@ -13822,7 +13807,8 @@ ha_innobase::delete_table( extension, in contrast to ::create */ normalize_table_name(norm_name, name); - if (srv_read_only_mode) { + if (srv_read_only_mode + || srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN) { DBUG_RETURN(HA_ERR_TABLE_READONLY); } @@ -14255,116 +14241,6 @@ ha_innobase::rename_table( } /*********************************************************************//** -Returns the exact number of records that this client can see using this -handler object. -@return Error code in case something goes wrong. -These errors will abort the current query: - case HA_ERR_LOCK_DEADLOCK: - case HA_ERR_LOCK_TABLE_FULL: - case HA_ERR_LOCK_WAIT_TIMEOUT: - case HA_ERR_QUERY_INTERRUPTED: -For other error codes, the server will fall back to counting records. */ - -#ifdef MYSQL_57_SELECT_COUNT_OPTIMIZATION -int -ha_innobase::records( -/*==================*/ - ha_rows* num_rows) /*!< out: number of rows */ -{ - DBUG_ENTER("ha_innobase::records()"); - - dberr_t ret; - ulint n_rows = 0; /* Record count in this view */ - - update_thd(); - - if (dict_table_is_discarded(m_prebuilt->table)) { - ib_senderrf( - m_user_thd, - IB_LOG_LEVEL_ERROR, - ER_TABLESPACE_DISCARDED, - table->s->table_name.str); - - *num_rows = HA_POS_ERROR; - DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); - - } else if (m_prebuilt->table->ibd_file_missing) { - ib_senderrf( - m_user_thd, IB_LOG_LEVEL_ERROR, - ER_TABLESPACE_MISSING, - table->s->table_name.str); - - *num_rows = HA_POS_ERROR; - DBUG_RETURN(HA_ERR_TABLESPACE_MISSING); - - } else if (m_prebuilt->table->corrupted) { - ib_errf(m_user_thd, IB_LOG_LEVEL_WARN, - ER_INNODB_INDEX_CORRUPT, - "Table '%s' is corrupt.", - table->s->table_name.str); - - *num_rows = HA_POS_ERROR; - DBUG_RETURN(HA_ERR_INDEX_CORRUPT); - } - - TrxInInnoDB trx_in_innodb(m_prebuilt->trx); - - m_prebuilt->trx->op_info = "counting records"; - - dict_index_t* index = dict_table_get_first_index(m_prebuilt->table); - - ut_ad(dict_index_is_clust(index)); - - m_prebuilt->index_usable = row_merge_is_index_usable( - m_prebuilt->trx, index); - - if (!m_prebuilt->index_usable) { - *num_rows = HA_POS_ERROR; - DBUG_RETURN(HA_ERR_TABLE_DEF_CHANGED); - } - - /* (Re)Build the m_prebuilt->mysql_template if it is null to use - the clustered index and just the key, no off-record data. */ - m_prebuilt->index = index; - dtuple_set_n_fields(m_prebuilt->search_tuple, 0); - m_prebuilt->read_just_key = 1; - build_template(false); - - /* Count the records in the clustered index */ - ret = row_scan_index_for_mysql(m_prebuilt, index, false, &n_rows); - reset_template(); - switch (ret) { - case DB_SUCCESS: - break; - case DB_DEADLOCK: - case DB_LOCK_TABLE_FULL: - case DB_LOCK_WAIT_TIMEOUT: - *num_rows = HA_POS_ERROR; - DBUG_RETURN(convert_error_code_to_mysql(ret, 0, m_user_thd)); - case DB_INTERRUPTED: - *num_rows = HA_POS_ERROR; - DBUG_RETURN(HA_ERR_QUERY_INTERRUPTED); - default: - /* No other error besides the three below is returned from - row_scan_index_for_mysql(). Make a debug catch. */ - *num_rows = HA_POS_ERROR; - ut_ad(0); - DBUG_RETURN(-1); - } - - m_prebuilt->trx->op_info = ""; - - if (thd_killed(m_user_thd)) { - *num_rows = HA_POS_ERROR; - DBUG_RETURN(HA_ERR_QUERY_INTERRUPTED); - } - - *num_rows= n_rows; - DBUG_RETURN(0); -} -#endif /* MYSQL_57_SELECT_COUNT_OPTIMIZATION */ - -/*********************************************************************//** Estimates the number of index records in a range. @return estimated number of rows */ @@ -15108,15 +14984,14 @@ ha_innobase::info_low( if (j + 1 > index->n_uniq) { sql_print_error( - "Index %s of %s has %lu columns" - " unique inside InnoDB, but" - " MariaDB is asking statistics for" - " %lu columns. Have you mixed" - " up .frm files from different" + "Index %s of %s has %u columns" + " unique inside InnoDB, but " + "MySQL is asking statistics for" + " %lu columns. Have you mixed " + "up .frm files from different " " installations? %s", index->name(), ib_table->name.m_name, - (unsigned long) index->n_uniq, j + 1, TROUBLESHOOTING_MSG); break; @@ -15611,7 +15486,7 @@ ha_innobase::check( ret = row_count_rtree_recs(m_prebuilt, &n_rows); } else { ret = row_scan_index_for_mysql( - m_prebuilt, index, true, &n_rows); + m_prebuilt, index, &n_rows); } DBUG_EXECUTE_IF( @@ -15646,11 +15521,9 @@ ha_innobase::check( push_warning_printf( thd, Sql_condition::WARN_LEVEL_WARN, ER_NOT_KEYFILE, - "InnoDB: Index '%-.200s' contains %lu" - " entries, should be %lu.", - index->name(), - (ulong) n_rows, - (ulong) n_rows_in_table); + "InnoDB: Index '%-.200s' contains " ULINTPF + " entries, should be " ULINTPF ".", + index->name(), n_rows, n_rows_in_table); is_ok = false; dict_set_corrupted( index, m_prebuilt->trx, @@ -15891,6 +15764,28 @@ get_foreign_key_info( f_key_info.update_method = FK_OPTION_RESTRICT; } + /* Load referenced table to update FK referenced key name. */ + if (foreign->referenced_table == NULL) { + + dict_table_t* ref_table; + + ut_ad(mutex_own(&dict_sys->mutex)); + ref_table = dict_table_open_on_name( + foreign->referenced_table_name_lookup, + TRUE, FALSE, DICT_ERR_IGNORE_NONE); + + if (ref_table == NULL) { + + ib::info() << "Foreign Key referenced table " + << foreign->referenced_table_name + << " not found for foreign table " + << foreign->foreign_table_name; + } else { + + dict_table_close(ref_table, TRUE, FALSE); + } + } + if (foreign->referenced_index && foreign->referenced_index->name != NULL) { referenced_key_name = thd_make_lex_string( @@ -17095,16 +16990,16 @@ innodb_show_rwlock_status( } buf1len = ut_snprintf( - buf1, sizeof buf1, "rwlock: %s:%lu", + buf1, sizeof buf1, "rwlock: %s:%u", innobase_basename(rw_lock->cfile_name), - static_cast<ulong>(rw_lock->cline)); + rw_lock->cline); int buf2len; char buf2[IO_SIZE]; buf2len = ut_snprintf( - buf2, sizeof buf2, "waits=%lu", - static_cast<ulong>(rw_lock->count_os_wait)); + buf2, sizeof buf2, "waits=%u", + rw_lock->count_os_wait); if (stat_print(thd, innobase_hton_name, hton_name_len, @@ -17123,16 +17018,16 @@ innodb_show_rwlock_status( char buf1[IO_SIZE]; buf1len = ut_snprintf( - buf1, sizeof buf1, "sum rwlock: %s:%lu", + buf1, sizeof buf1, "sum rwlock: %s:%u", innobase_basename(block_rwlock->cfile_name), - static_cast<ulong>(block_rwlock->cline)); + block_rwlock->cline); int buf2len; char buf2[IO_SIZE]; buf2len = ut_snprintf( - buf2, sizeof buf2, "waits=%lu", - static_cast<ulong>(block_rwlock_oswait_count)); + buf2, sizeof buf2, "waits=" ULINTPF, + block_rwlock_oswait_count); if (stat_print(thd, innobase_hton_name, hton_name_len, @@ -17687,6 +17582,37 @@ ha_innobase::get_auto_increment( whether we update the table autoinc counter or not. */ ulonglong col_max_value = innobase_get_int_col_max_value(table->next_number_field); + /** The following logic is needed to avoid duplicate key error + for autoincrement column. + + (1) InnoDB gives the current autoincrement value with respect + to increment and offset value. + + (2) Basically it does compute_next_insert_id() logic inside InnoDB + to avoid the current auto increment value changed by handler layer. + + (3) It is restricted only for insert operations. */ + + if (increment > 1 && thd_sql_command(m_user_thd) != SQLCOM_ALTER_TABLE + && autoinc < col_max_value) { + + ulonglong prev_auto_inc = autoinc; + + autoinc = ((autoinc - 1) + increment - offset)/ increment; + + autoinc = autoinc * increment + offset; + + /* If autoinc exceeds the col_max_value then reset + to old autoinc value. Because in case of non-strict + sql mode, boundary value is not considered as error. */ + + if (autoinc >= col_max_value) { + autoinc = prev_auto_inc; + } + + ut_ad(autoinc > 0); + } + /* Called for the first time ? */ if (trx->n_autoinc_rows == 0) { @@ -18792,6 +18718,41 @@ innodb_internal_table_validate( return(ret); } +/****************************************************************//** +Update global variable "fts_internal_tbl_name" with the "saved" +stopword table name value. This function is registered as a callback +with MySQL. */ +static +void +innodb_internal_table_update( +/*=========================*/ + THD* thd, /*!< in: thread handle */ + struct st_mysql_sys_var* var, /*!< in: pointer to + system variable */ + void* var_ptr,/*!< out: where the + formal string goes */ + const void* save) /*!< in: immediate result + from check function */ +{ + const char* table_name; + char* old; + + ut_a(save != NULL); + ut_a(var_ptr != NULL); + + table_name = *static_cast<const char*const*>(save); + old = *(char**) var_ptr; + *(char**) var_ptr = table_name ? my_strdup(table_name, MYF(0)) : NULL; + my_free(old); + + fts_internal_tbl_name2 = *(char**) var_ptr; + if (fts_internal_tbl_name2 == NULL) { + fts_internal_tbl_name = const_cast<char*>("default"); + } else { + fts_internal_tbl_name = fts_internal_tbl_name2; + } +} + #ifdef BTR_CUR_HASH_ADAPT /****************************************************************//** Update the system variable innodb_adaptive_hash_index using the "saved" @@ -20346,9 +20307,9 @@ wsrep_innobase_kill_one_trx( WSREP_LOG_CONFLICT(bf_thd, thd, TRUE); - WSREP_DEBUG("BF kill (%lu, seqno: %lld), victim: (%lu) trx: " - TRX_ID_FMT, - signal, (long long)bf_seqno, + WSREP_DEBUG("BF kill (" ULINTPF ", seqno: " INT64PF + "), victim: (%lu) trx: " TRX_ID_FMT, + signal, bf_seqno, thd_get_thread_id(thd), victim_trx->id); @@ -20723,6 +20684,12 @@ static MYSQL_SYSVAR_BOOL(use_fallocate, innobase_use_fallocate, "Use posix_fallocate() to allocate files. DEPRECATED, has no effect.", NULL, NULL, FALSE); +static MYSQL_SYSVAR_BOOL(stats_include_delete_marked, + srv_stats_include_delete_marked, + PLUGIN_VAR_OPCMDARG, + "Include delete marked records when calculating persistent statistics", + NULL, NULL, FALSE); + static MYSQL_SYSVAR_ULONG(io_capacity, srv_io_capacity, PLUGIN_VAR_RQCMDARG, "Number of IOPs the server can do. Tunes the background IO rate", @@ -21231,6 +21198,13 @@ static MYSQL_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter, "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket", NULL, NULL, 5000L, 1L, ~0UL, 0); +static MYSQL_SYSVAR_BOOL(deadlock_detect, innobase_deadlock_detect, + PLUGIN_VAR_NOCMDARG, + "Enable/disable InnoDB deadlock detector (default ON)." + " if set to OFF, deadlock detection is skipped," + " and we rely on innodb_lock_wait_timeout in case of deadlock.", + NULL, NULL, TRUE); + static MYSQL_SYSVAR_LONG(fill_factor, innobase_fill_factor, PLUGIN_VAR_RQCMDARG, "Percentage of B-tree page filled during bulk insert", @@ -21246,11 +21220,11 @@ static MYSQL_SYSVAR_BOOL(disable_sort_file_cache, srv_disable_sort_file_cache, "Whether to disable OS system file cache for sort I/O", NULL, NULL, FALSE); -static MYSQL_SYSVAR_STR(ft_aux_table, fts_internal_tbl_name, - PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC, +static MYSQL_SYSVAR_STR(ft_aux_table, fts_internal_tbl_name2, + PLUGIN_VAR_RQCMDARG, "FTS internal auxiliary table to be checked", innodb_internal_table_validate, - NULL, NULL); + innodb_internal_table_update, NULL); static MYSQL_SYSVAR_ULONG(ft_cache_size, fts_max_cache_size, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, @@ -21418,11 +21392,11 @@ static MYSQL_SYSVAR_STR(undo_directory, srv_undo_dir, static MYSQL_SYSVAR_ULONG(undo_tablespaces, srv_undo_tablespaces, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, - "Number of undo tablespaces to use. ", + "Number of undo tablespaces to use.", NULL, NULL, 0L, /* Default seting */ 0L, /* Minimum value */ - 95L, 0); /* Maximum value */ + TRX_SYS_MAX_UNDO_SPACES, 0); /* Maximum value */ static MYSQL_SYSVAR_ULONG(undo_logs, srv_undo_logs, PLUGIN_VAR_OPCMDARG, @@ -21434,12 +21408,10 @@ static MYSQL_SYSVAR_ULONG(undo_logs, srv_undo_logs, static MYSQL_SYSVAR_ULONGLONG(max_undo_log_size, srv_max_undo_log_size, PLUGIN_VAR_OPCMDARG, - "Maximum size of UNDO tablespace in MB (If UNDO tablespace grows" - " beyond this size it will be truncated in due course). ", + "Desired maximum UNDO tablespace size in bytes", NULL, NULL, - 1024 * 1024 * 1024L, - 10 * 1024 * 1024L, - ~0ULL, 0); + 10 << 20, 10 << 20, + 1ULL << (32 + UNIV_PAGE_SIZE_SHIFT_MAX), 0); static MYSQL_SYSVAR_ULONG(purge_rseg_truncate_frequency, srv_purge_rseg_truncate_frequency, @@ -21912,6 +21884,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(temp_data_file_path), MYSQL_SYSVAR(data_home_dir), MYSQL_SYSVAR(doublewrite), + MYSQL_SYSVAR(stats_include_delete_marked), MYSQL_SYSVAR(use_atomic_writes), MYSQL_SYSVAR(use_fallocate), MYSQL_SYSVAR(fast_shutdown), @@ -21939,6 +21912,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(lock_schedule_algorithm), MYSQL_SYSVAR(locks_unsafe_for_binlog), MYSQL_SYSVAR(lock_wait_timeout), + MYSQL_SYSVAR(deadlock_detect), MYSQL_SYSVAR(page_size), MYSQL_SYSVAR(log_buffer_size), MYSQL_SYSVAR(log_file_size), @@ -22161,19 +22135,25 @@ innobase_commit_concurrency_init_default() = innobase_commit_concurrency; } -/** @brief Initialize the default and max value of innodb_undo_logs. - -Once InnoDB is running, the default value and the max value of -innodb_undo_logs must be equal to the available undo logs, -given by srv_available_undo_logs. */ +/** @brief Adjust some InnoDB startup parameters based on file contents +or innodb_page_size. */ static void -innobase_undo_logs_init_default_max() -/*=================================*/ +innodb_params_adjust() { + /* The default value and the max value of + innodb_undo_logs must be equal to the available undo logs. */ MYSQL_SYSVAR_NAME(undo_logs).max_val = MYSQL_SYSVAR_NAME(undo_logs).def_val = srv_available_undo_logs; + MYSQL_SYSVAR_NAME(max_undo_log_size).max_val + = 1ULL << (32 + UNIV_PAGE_SIZE_SHIFT); + MYSQL_SYSVAR_NAME(max_undo_log_size).min_val + = MYSQL_SYSVAR_NAME(max_undo_log_size).def_val + = ulonglong(SRV_UNDO_TABLESPACE_SIZE_IN_PAGES) + * srv_page_size; + MYSQL_SYSVAR_NAME(max_undo_log_size).max_val + = 1ULL << (32 + UNIV_PAGE_SIZE_SHIFT); } /**************************************************************************** @@ -22846,7 +22826,8 @@ ib_warn_row_too_big(const dict_table_t* table) push_warning_printf( thd, Sql_condition::WARN_LEVEL_WARN, HA_ERR_TO_BIG_ROW, - "Row size too large (> %lu). Changing some columns to TEXT" + "Row size too large (> " ULINTPF ")." + " Changing some columns to TEXT" " or BLOB %smay help. In current row format, BLOB prefix of" " %d bytes is stored inline.", free_space , prefix ? "or using ROW_FORMAT=DYNAMIC or" @@ -23191,7 +23172,7 @@ ib_push_frm_error( break; case DICT_FRM_INCONSISTENT_KEYS: - sql_print_error("InnoDB: Table %s contains %lu " + sql_print_error("InnoDB: Table %s contains " ULINTPF " " "indexes inside InnoDB, which " "is different from the number of " "indexes %u defined in the MariaDB " @@ -23206,7 +23187,7 @@ ib_push_frm_error( if (push_warning) { push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_NO_SUCH_INDEX, - "InnoDB: Table %s contains %lu " + "InnoDB: Table %s contains " ULINTPF " " "indexes inside InnoDB, which " "is different from the number of " "indexes %u defined in the MariaDB ", diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index 297b73ed02f..64147291338 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2000, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2013, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -219,9 +219,6 @@ public: ha_rows estimate_rows_upper_bound(); - // JAN: TODO: MySQL 5.7 - // int records(ha_rows* num_rows); - void update_create_info(HA_CREATE_INFO* create_info); int create( diff --git a/storage/innobase/handler/ha_innopart.cc b/storage/innobase/handler/ha_innopart.cc index 7abc1f29b60..1041871805e 100644 --- a/storage/innobase/handler/ha_innopart.cc +++ b/storage/innobase/handler/ha_innopart.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. +Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2016, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -3004,41 +3004,6 @@ ha_innopart::truncate() DBUG_RETURN(error); } -/** Total number of rows in all used partitions. -Returns the exact number of records that this client can see using this -handler object. -@param[out] num_rows Number of rows. -@return 0 or error number. */ -int -ha_innopart::records( - ha_rows* num_rows) -{ - ha_rows n_rows; - int err; - DBUG_ENTER("ha_innopart::records()"); - - *num_rows = 0; - - /* The index scan is probably so expensive, so the overhead - of the rest of the function is neglectable for each partition. - So no current reason for optimizing this further. */ - - for (uint i = m_part_info->get_first_used_partition(); - i < m_tot_parts; - i = m_part_info->get_next_used_partition(i)) { - - set_partition(i); - err = ha_innobase::records(&n_rows); - update_partition(i); - if (err != 0) { - *num_rows = HA_POS_ERROR; - DBUG_RETURN(err); - } - *num_rows += n_rows; - } - DBUG_RETURN(0); -} - /** Estimates the number of index records in a range. @param[in] keynr Index number. @param[in] min_key Start key value (or NULL). diff --git a/storage/innobase/handler/ha_innopart.h b/storage/innobase/handler/ha_innopart.h index 5f3f8eaa318..67db9e07150 100644 --- a/storage/innobase/handler/ha_innopart.h +++ b/storage/innobase/handler/ha_innopart.h @@ -1222,10 +1222,6 @@ protected: uchar* pos); int - records( - ha_rows* num_rows); - - int index_next( uchar* record) { diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index f9791f5fa97..153484c9941 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -400,7 +400,10 @@ innobase_need_rebuild( const Alter_inplace_info* ha_alter_info, const TABLE* altered_table) { - if (ha_alter_info->handler_flags + Alter_inplace_info::HA_ALTER_FLAGS alter_inplace_flags = + ha_alter_info->handler_flags & ~(INNOBASE_INPLACE_IGNORE); + + if (alter_inplace_flags == Alter_inplace_info::CHANGE_CREATE_OPTION && !(ha_alter_info->create_info->used_fields & (HA_CREATE_USED_ROW_FORMAT @@ -1293,7 +1296,6 @@ innobase_find_fk_index( while (index != NULL) { if (!(index->type & DICT_FTS) - && !dict_index_has_virtual(index) && dict_foreign_qualify_index( table, col_names, columns, n_cols, index, NULL, true, 0, @@ -2466,6 +2468,7 @@ innobase_fts_check_doc_id_index_in_def( return(FTS_NOT_EXIST_DOC_ID_INDEX); } + /*******************************************************************//** Create an index table where indexes are ordered as follows: @@ -2534,35 +2537,16 @@ innobase_create_key_defs( (only prefix/part of the column is indexed), MySQL will treat the index as a PRIMARY KEY unless the table already has one. */ - if (n_add > 0 && !new_primary && got_default_clust - && (key_info[*add].flags & HA_NOSAME) - && !(key_info[*add].flags & HA_KEY_HAS_PART_KEY_SEG)) { - uint key_part = key_info[*add].user_defined_key_parts; - - new_primary = true; - - while (key_part--) { - const uint maybe_null - = key_info[*add].key_part[key_part].key_type - & FIELDFLAG_MAYBE_NULL; - bool is_v - = innobase_is_v_fld( - key_info[*add].key_part[key_part].field); - DBUG_ASSERT(!maybe_null - == !key_info[*add].key_part[key_part]. - field->real_maybe_null()); - - if (maybe_null || is_v) { - new_primary = false; - break; - } - } + ut_ad(altered_table->s->primary_key == 0 + || altered_table->s->primary_key == MAX_KEY); + + if (got_default_clust && !new_primary) { + new_primary = (altered_table->s->primary_key != MAX_KEY); } const bool rebuild = new_primary || add_fts_doc_id || innobase_need_rebuild(ha_alter_info, table); - /* Reserve one more space if new_primary is true, and we might need to add the FTS_DOC_ID_INDEX */ indexdef = indexdefs = static_cast<index_def_t*>( @@ -2576,8 +2560,14 @@ innobase_create_key_defs( ulint primary_key_number; if (new_primary) { - DBUG_ASSERT(n_add > 0); - primary_key_number = *add; + if (n_add == 0) { + DBUG_ASSERT(got_default_clust); + DBUG_ASSERT(altered_table->s->primary_key + == 0); + primary_key_number = 0; + } else { + primary_key_number = *add; + } } else if (got_default_clust) { /* Create the GEN_CLUST_INDEX */ index_def_t* index = indexdef++; @@ -4782,6 +4772,8 @@ new_clustered_failed: ctx->add_cols = add_cols; } else { DBUG_ASSERT(!innobase_need_rebuild(ha_alter_info, old_table)); + DBUG_ASSERT(old_table->s->primary_key + == altered_table->s->primary_key); for (dict_index_t* index = dict_table_get_first_index(user_table); @@ -6082,7 +6074,7 @@ err_exit: } if (!(ha_alter_info->handler_flags & INNOBASE_ALTER_DATA) - || (ha_alter_info->handler_flags + || ((ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE) == Alter_inplace_info::CHANGE_CREATE_OPTION && !innobase_need_rebuild(ha_alter_info, table))) { @@ -6306,6 +6298,26 @@ alter_templ_needs_rebuild( return(false); } +/** Get the name of an erroneous key. +@param[in] error_key_num InnoDB number of the erroneus key +@param[in] ha_alter_info changes that were being performed +@param[in] table InnoDB table +@return the name of the erroneous key */ +static +const char* +get_error_key_name( + ulint error_key_num, + const Alter_inplace_info* ha_alter_info, + const dict_table_t* table) +{ + if (error_key_num == ULINT_UNDEFINED) { + return(FTS_DOC_ID_INDEX_NAME); + } else if (ha_alter_info->key_count == 0) { + return(dict_table_get_first_index(table)->name); + } else { + return(ha_alter_info->key_info_buffer[error_key_num].name); + } +} /** Alter the table structure in-place with operations specified using Alter_inplace_info. @@ -6346,7 +6358,7 @@ ok_exit: DBUG_RETURN(false); } - if (ha_alter_info->handler_flags + if ((ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE) == Alter_inplace_info::CHANGE_CREATE_OPTION && !innobase_need_rebuild(ha_alter_info, table)) { goto ok_exit; @@ -6443,15 +6455,6 @@ ok_exit: ctx->add_autoinc, ctx->sequence, ctx->skip_pk_sort, ctx->m_stage, add_v, eval_table); - if (s_templ) { - ut_ad(ctx->need_rebuild() || ctx->num_to_add_vcol > 0 - || rebuild_templ); - dict_free_vc_templ(s_templ); - UT_DELETE(s_templ); - - ctx->new_table->vc_templ = old_templ; - } - #ifndef DBUG_OFF oom: #endif /* !DBUG_OFF */ @@ -6467,6 +6470,15 @@ oom: onlineddl_rowlog_pct_used = 0; onlineddl_pct_progress = 0; + if (s_templ) { + ut_ad(ctx->need_rebuild() || ctx->num_to_add_vcol > 0 + || rebuild_templ); + dict_free_vc_templ(s_templ); + UT_DELETE(s_templ); + + ctx->new_table->vc_templ = old_templ; + } + DEBUG_SYNC_C("inplace_after_index_build"); DBUG_EXECUTE_IF("create_index_fail", @@ -6506,17 +6518,13 @@ oom: case DB_ONLINE_LOG_TOO_BIG: DBUG_ASSERT(ctx->online); my_error(ER_INNODB_ONLINE_LOG_TOO_BIG, MYF(0), - (m_prebuilt->trx->error_key_num == ULINT_UNDEFINED) - ? FTS_DOC_ID_INDEX_NAME - : ha_alter_info->key_info_buffer[ - m_prebuilt->trx->error_key_num].name); + get_error_key_name(m_prebuilt->trx->error_key_num, + ha_alter_info, m_prebuilt->table)); break; case DB_INDEX_CORRUPT: my_error(ER_INDEX_CORRUPT, MYF(0), - (m_prebuilt->trx->error_key_num == ULINT_UNDEFINED) - ? FTS_DOC_ID_INDEX_NAME - : ha_alter_info->key_info_buffer[ - m_prebuilt->trx->error_key_num].name); + get_error_key_name(m_prebuilt->trx->error_key_num, + ha_alter_info, m_prebuilt->table)); break; case DB_DECRYPTION_FAILED: { String str; @@ -7724,11 +7732,31 @@ commit_try_rebuild( if (ctx->online) { DEBUG_SYNC_C("row_log_table_apply2_before"); + dict_vcol_templ_t* s_templ = NULL; + + if (ctx->new_table->n_v_cols > 0) { + s_templ = UT_NEW_NOKEY( + dict_vcol_templ_t()); + s_templ->vtempl = NULL; + + innobase_build_v_templ( + altered_table, ctx->new_table, s_templ, + NULL, true); + ctx->new_table->vc_templ = s_templ; + } + error = row_log_table_apply( ctx->thr, user_table, altered_table, static_cast<ha_innobase_inplace_ctx*>( ha_alter_info->handler_ctx)->m_stage); + if (s_templ) { + ut_ad(ctx->need_rebuild()); + dict_free_vc_templ(s_templ); + UT_DELETE(s_templ); + ctx->new_table->vc_templ = NULL; + } + ulint err_key = thr_get_trx(ctx->thr)->error_key_num; switch (error) { @@ -7750,14 +7778,13 @@ commit_try_rebuild( DBUG_RETURN(true); case DB_ONLINE_LOG_TOO_BIG: my_error(ER_INNODB_ONLINE_LOG_TOO_BIG, MYF(0), - ha_alter_info->key_info_buffer[0].name); + get_error_key_name(err_key, ha_alter_info, + rebuilt_table)); DBUG_RETURN(true); case DB_INDEX_CORRUPT: my_error(ER_INDEX_CORRUPT, MYF(0), - (err_key == ULINT_UNDEFINED) - ? FTS_DOC_ID_INDEX_NAME - : ha_alter_info->key_info_buffer[err_key] - .name); + get_error_key_name(err_key, ha_alter_info, + rebuilt_table)); DBUG_RETURN(true); default: my_error_innodb(error, table_name, user_table->flags); diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 6bf16573efd..3d764ef6e7a 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -3955,6 +3955,8 @@ i_s_fts_config_fill( DBUG_RETURN(0); } + DEBUG_SYNC_C("i_s_fts_config_fille_check"); + fields = table->field; /* Prevent DDL to drop fts aux tables. */ @@ -5147,6 +5149,10 @@ i_s_innodb_buffer_page_get_info( block = reinterpret_cast<const buf_block_t*>(bpage); frame = block->frame; #ifdef BTR_CUR_HASH_ADAPT + /* Note: this may be a false positive, that + is, block->index will not always be set to + NULL when the last adaptive hash index + reference is dropped. */ page_info->hashed = (block->index != NULL); #endif /* BTR_CUR_HASH_ADAPT */ } else { diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc index 2fde0cb23b9..c7ffecd00c1 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.cc +++ b/storage/innobase/ibuf/ibuf0ibuf.cc @@ -1472,8 +1472,8 @@ ibuf_print_ops( ut_a(UT_ARR_SIZE(op_names) == IBUF_OP_COUNT); for (i = 0; i < IBUF_OP_COUNT; i++) { - fprintf(file, "%s %lu%s", op_names[i], - (ulong) ops[i], (i < (IBUF_OP_COUNT - 1)) ? ", " : ""); + fprintf(file, "%s " ULINTPF "%s", op_names[i], + ops[i], (i < (IBUF_OP_COUNT - 1)) ? ", " : ""); } putc('\n', file); @@ -3953,7 +3953,11 @@ ibuf_insert_to_index_page( ut_ad(ibuf_inside(mtr)); ut_ad(dtuple_check_typed(entry)); #ifdef BTR_CUR_HASH_ADAPT + /* A change buffer merge must occur before users are granted + any access to the page. No adaptive hash index entries may + point to a freshly read page. */ ut_ad(!block->index); + assert_block_ahi_empty(block); #endif /* BTR_CUR_HASH_ADAPT */ ut_ad(mtr->is_named_space(block->page.id.space())); @@ -4928,12 +4932,12 @@ ibuf_print( mutex_enter(&ibuf_mutex); fprintf(file, - "Ibuf: size %lu, free list len %lu," - " seg size %lu, %lu merges\n", - (ulong) ibuf->size, - (ulong) ibuf->free_list_len, - (ulong) ibuf->seg_size, - (ulong) ibuf->n_merges); + "Ibuf: size " ULINTPF ", free list len " ULINTPF "," + " seg size " ULINTPF ", " ULINTPF " merges\n", + ibuf->size, + ibuf->free_list_len, + ibuf->seg_size, + ibuf->n_merges); fputs("merged operations:\n ", file); ibuf_print_ops(ibuf->n_merged_ops, file); @@ -4948,9 +4952,10 @@ ibuf_print( if (count > 0) { fprintf(stderr, - "Ibuf count for space/page %lu/%lu" - " is %lu\n", - (ulong) i, (ulong) j, (ulong) count); + "Ibuf count for page " + ULINTPF ":" ULINTPF "" + " is " ULINTPF "\n", + i, j, count); } } } diff --git a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h index 8887a3f81ad..fad0dac93c4 100644 --- a/storage/innobase/include/btr0sea.h +++ b/storage/innobase/include/btr0sea.h @@ -247,6 +247,8 @@ btr_get_search_table(const dict_index_t* index); # define btr_search_drop_page_hash_index(block) # define btr_search_s_lock(index) # define btr_search_s_unlock(index) +# define btr_search_s_lock_all(index) +# define btr_search_s_unlock_all(index) # define btr_search_x_lock(index) # define btr_search_x_unlock(index) # define btr_search_info_update(index, cursor) diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index 3aab242606d..7dee52d8f74 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -769,10 +769,6 @@ buf_block_unfix( @param[in] read_buf database page @param[in] checksum_field1 new checksum field @param[in] checksum_field2 old checksum field -@param[in] page_no page number of given read_buf -@param[in] is_log_enabled true if log option is enabled -@param[in] log_file file pointer to log_file -@param[in] curr_algo current checksum algorithm @param[in] use_legacy_big_endian use legacy big endian algorithm @return true if the page is in crc32 checksum format. */ bool @@ -780,12 +776,6 @@ buf_page_is_checksum_valid_crc32( const byte* read_buf, ulint checksum_field1, ulint checksum_field2, -#ifdef UNIV_INNOCHECKSUM - uintmax_t page_no, - bool is_log_enabled, - FILE* log_file, - const srv_checksum_algorithm_t curr_algo, -#endif /* UNIV_INNOCHECKSUM */ bool use_legacy_big_endian) MY_ATTRIBUTE((nonnull(1), warn_unused_result)); @@ -793,59 +783,26 @@ buf_page_is_checksum_valid_crc32( @param[in] read_buf database page @param[in] checksum_field1 new checksum field @param[in] checksum_field2 old checksum field -@param[in] page_no page number of given read_buf -@param[in] is_log_enabled true if log option is enabled -@param[in] log_file file pointer to log_file -@param[in] curr_algo current checksum algorithm @return true if the page is in innodb checksum format. */ bool buf_page_is_checksum_valid_innodb( const byte* read_buf, ulint checksum_field1, - ulint checksum_field2 -#ifdef UNIV_INNOCHECKSUM - ,uintmax_t page_no, - bool is_log_enabled, - FILE* log_file, - const srv_checksum_algorithm_t curr_algo -#endif /* UNIV_INNOCHECKSUM */ - ) + ulint checksum_field2) MY_ATTRIBUTE((nonnull(1), warn_unused_result)); /** Checks if the page is in none checksum format. @param[in] read_buf database page @param[in] checksum_field1 new checksum field @param[in] checksum_field2 old checksum field -@param[in] page_no page number of given read_buf -@param[in] is_log_enabled true if log option is enabled -@param[in] log_file file pointer to log_file -@param[in] curr_algo current checksum algorithm @return true if the page is in none checksum format. */ bool buf_page_is_checksum_valid_none( const byte* read_buf, ulint checksum_field1, - ulint checksum_field2 -#ifdef UNIV_INNOCHECKSUM - ,uintmax_t page_no, - bool is_log_enabled, - FILE* log_file, - const srv_checksum_algorithm_t curr_algo -#endif /* UNIV_INNOCHECKSUM */ - ) + ulint checksum_field2) MY_ATTRIBUTE((nonnull(1), warn_unused_result)); -/********************************************************************//** -Check if page is maybe compressed, encrypted or both when we encounter -corrupted page. Note that we can't be 100% sure if page is corrupted -or decrypt/decompress just failed. -@param[in] bpage Page -@return true if page corrupted, false if not */ -bool -buf_page_check_corrupt( - buf_page_t* bpage) /*!< in/out: buffer page read from disk */ - MY_ATTRIBUTE((nonnull, warn_unused_result)); - /** Checks if a page contains only zeroes. @param[in] read_buf database page @param[in] page_size page size @@ -861,10 +818,6 @@ the LSN @param[in] read_buf database page @param[in] page_size page size @param[in] space tablespace -@param[in] page_no page number of given read_buf -@param[in] strict_check true if strict-check option is enabled -@param[in] is_log_enabled true if log option is enabled -@param[in] log_file file pointer to log_file @return whether the page is corrupted */ bool buf_page_is_corrupted( @@ -872,12 +825,6 @@ buf_page_is_corrupted( const byte* read_buf, const page_size_t& page_size, const fil_space_t* space = NULL -#ifdef UNIV_INNOCHECKSUM - ,uintmax_t page_no = 0, - bool strict_check = false, - bool is_log_enabled = false, - FILE* log_file = NULL -#endif /* UNIV_INNOCHECKSUM */ ) MY_ATTRIBUTE((warn_unused_result)); #ifndef UNIV_INNOCHECKSUM /**********************************************************************//** @@ -1544,17 +1491,19 @@ buf_flush_update_zip_checksum( ulint size, lsn_t lsn); -/********************************************************************//** -The hook that is called just before a page is written to disk. -The function encrypts the content of the page and returns a pointer -to a frame that will be written instead of the real frame. */ +/** Encryption and page_compression hook that is called just before +a page is written to disk. +@param[in,out] space tablespace +@param[in,out] bpage buffer page +@param[in] src_frame physical page frame that is being encrypted +@return page frame to be written to file +(may be src_frame or an encrypted/compressed copy of it) */ UNIV_INTERN byte* buf_page_encrypt_before_write( -/*==========================*/ - buf_page_t* page, /*!< in/out: buffer page to be flushed */ - byte* frame, /*!< in: src frame */ - ulint space_id); /*!< in: space id */ + fil_space_t* space, + buf_page_t* bpage, + byte* src_frame); /** @brief The temporary memory structure. @@ -1834,23 +1783,58 @@ struct buf_block_t{ /* @} */ /** @name Hash search fields - These 5 fields may only be modified when we have - an x-latch on search system AND - - we are holding an s-latch or x-latch on buf_block_t::lock or - - we know that buf_block_t::buf_fix_count == 0. + These 5 fields may only be modified when: + we are holding the appropriate x-latch in btr_search_latches[], and + one of the following holds: + (1) the block state is BUF_BLOCK_FILE_PAGE, and + we are holding an s-latch or x-latch on buf_block_t::lock, or + (2) buf_block_t::buf_fix_count == 0, or + (3) the block state is BUF_BLOCK_REMOVE_HASH. An exception to this is when we init or create a page in the buffer pool in buf0buf.cc. - Another exception is that assigning block->index = NULL - is allowed whenever holding an x-latch on search system. */ + Another exception for buf_pool_clear_hash_index() is that + assigning block->index = NULL (and block->n_pointers = 0) + is allowed whenever btr_search_own_all(RW_LOCK_X). + + Another exception is that ha_insert_for_fold_func() may + decrement n_pointers without holding the appropriate latch + in btr_search_latches[]. Thus, n_pointers must be + protected by atomic memory access. + + This implies that the fields may be read without race + condition whenever any of the following hold: + - the btr_search_latches[] s-latch or x-latch is being held, or + - the block state is not BUF_BLOCK_FILE_PAGE or BUF_BLOCK_REMOVE_HASH, + and holding some latch prevents the state from changing to that. + + Some use of assert_block_ahi_empty() or assert_block_ahi_valid() + is prone to race conditions while buf_pool_clear_hash_index() is + executing (the adaptive hash index is being disabled). Such use + is explicitly commented. */ /* @{ */ # if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG ulint n_pointers; /*!< used in debugging: the number of pointers in the adaptive hash index - pointing to this frame */ + pointing to this frame; + protected by atomic memory access + or btr_search_own_all(). */ +# define assert_block_ahi_empty(block) \ + ut_a(my_atomic_addlint(&(block)->n_pointers, 0) == 0) +# define assert_block_ahi_empty_on_init(block) do { \ + UNIV_MEM_VALID(&(block)->n_pointers, sizeof (block)->n_pointers); \ + assert_block_ahi_empty(block); \ +} while (0) +# define assert_block_ahi_valid(block) \ + ut_a((block)->index \ + || my_atomic_addlint(&(block)->n_pointers, 0) == 0) +# else /* UNIV_AHI_DEBUG || UNIV_DEBUG */ +# define assert_block_ahi_empty(block) /* nothing */ +# define assert_block_ahi_empty_on_init(block) /* nothing */ +# define assert_block_ahi_valid(block) /* nothing */ # endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ unsigned curr_n_fields:10;/*!< prefix length for hash indexing: number of full fields */ @@ -1866,11 +1850,15 @@ struct buf_block_t{ complete, though: there may have been hash collisions, record deletions, etc. */ + /* @} */ +#else /* BTR_CUR_HASH_ADAPT */ +# define assert_block_ahi_empty(block) /* nothing */ +# define assert_block_ahi_empty_on_init(block) /* nothing */ +# define assert_block_ahi_valid(block) /* nothing */ #endif /* BTR_CUR_HASH_ADAPT */ bool skip_flush_check; /*!< Skip check in buf_dblwr_check_block during bulk load, protected by lock.*/ - /* @} */ # ifdef UNIV_DEBUG /** @name Debug fields */ /* @{ */ diff --git a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic index 429c7fd3ba6..f22dcc48a01 100644 --- a/storage/innobase/include/buf0buf.ic +++ b/storage/innobase/include/buf0buf.ic @@ -920,6 +920,7 @@ buf_block_modify_clock_inc( RW_LOCK_FLAG_X | RW_LOCK_FLAG_SX)); } #endif /* UNIV_DEBUG */ + assert_block_ahi_valid(block); block->modify_clock++; } diff --git a/storage/innobase/include/buf0dblwr.h b/storage/innobase/include/buf0dblwr.h index bf2bf6ab32b..e1ecb6baf56 100644 --- a/storage/innobase/include/buf0dblwr.h +++ b/storage/innobase/include/buf0dblwr.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -44,8 +44,7 @@ doublewrite buffer is placed on the trx system header page. @return true if successful, false if not. */ MY_ATTRIBUTE((warn_unused_result)) bool -buf_dblwr_create(void); -/*==================*/ +buf_dblwr_create(); /****************************************************************//** At a database startup initializes the doublewrite buffer memory structure if @@ -61,13 +60,13 @@ buf_dblwr_init_or_load_pages( /** Process and remove the double write buffer pages for all tablespaces. */ void -buf_dblwr_process(void); +buf_dblwr_process(); /****************************************************************//** frees doublewrite buffer. */ void -buf_dblwr_free(void); -/*================*/ +buf_dblwr_free(); + /********************************************************************//** Updates the doublewrite buffer when an IO request is completed. */ void @@ -105,8 +104,8 @@ important to call this function after a batch of writes has been posted, and also when we may have to wait for a page latch! Otherwise a deadlock of threads can occur. */ void -buf_dblwr_flush_buffered_writes(void); -/*=================================*/ +buf_dblwr_flush_buffered_writes(); + /********************************************************************//** Writes a page to the doublewrite buffer on disk, sync it, then write the page to the datafile and sync the datafile. This function is used diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic index 580118f2fdd..8849be1206d 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -393,13 +393,9 @@ dict_index_is_sec_or_ibuf( /*======================*/ const dict_index_t* index) /*!< in: index */ { - ulint type; - ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - type = index->type; - - return(!(type & DICT_CLUSTERED) || (type & DICT_IBUF)); + return((index->type & (DICT_CLUSTERED | DICT_IBUF)) != DICT_CLUSTERED); } /********************************************************************//** @@ -797,7 +793,8 @@ dict_sys_tables_type_validate( } else if (zip_ssize) { /* Antelope does not support COMPRESSED format. */ ib::error() - << "SYS_TABLES::TYPE=" << type << "zip_ssize:" << zip_ssize; + << "SYS_TABLES::TYPE=" << type + << ", zip_ssize:" << zip_ssize; return(ULINT_UNDEFINED); } @@ -809,16 +806,16 @@ dict_sys_tables_type_validate( low_order_bit and DICT_N_COLS_COMPACT flags. */ if (!atomic_blobs) { ib::error() << "SYS_TABLES::TYPE=" << type - << " zip_ssize:" << zip_ssize - << " atomic_blobs:" << atomic_blobs; + << ", zip_ssize:" << zip_ssize + << ", atomic_blobs:" << atomic_blobs; return(ULINT_UNDEFINED); } /* Validate that the number is within allowed range. */ if (zip_ssize > PAGE_ZIP_SSIZE_MAX) { ib::error() << "SYS_TABLES::TYPE=" << type - << " zip_ssize:" << zip_ssize - << " max:" << PAGE_ZIP_SSIZE_MAX; + << ", zip_ssize:" << zip_ssize + << " > " << PAGE_ZIP_SSIZE_MAX; return(ULINT_UNDEFINED); } } diff --git a/storage/innobase/include/fil0crypt.h b/storage/innobase/include/fil0crypt.h index 831d61445d8..ca65df21402 100644 --- a/storage/innobase/include/fil0crypt.h +++ b/storage/innobase/include/fil0crypt.h @@ -116,10 +116,10 @@ struct fil_space_crypt_t : st_encryption_scheme min_key_version(new_min_key_version), page0_offset(0), encryption(new_encryption), - key_found(), + mutex(), + key_found(new_min_key_version), rotate_state() { - key_found = new_min_key_version; key_id = new_key_id; my_random_bytes(iv, sizeof(iv)); mutex_create(LATCH_ID_FIL_CRYPT_DATA_MUTEX, &mutex); @@ -492,10 +492,6 @@ bool fil_space_verify_crypt_checksum( byte* page, const page_size_t& page_size, -#ifdef UNIV_INNOCHECKSUM - bool strict_check, /*!< --strict-check */ - FILE* log_file, /*!< --log */ -#endif /* UNIV_INNOCHECKSUM */ ulint space, ulint offset) MY_ATTRIBUTE((warn_unused_result)); diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index e63550f26ff..cef5b578a4a 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2013, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -142,14 +142,21 @@ struct fil_space_t { ulint n_pending_flushes; /*!< this is positive when flushing the tablespace to disk; dropping of the tablespace is forbidden if this is positive */ - ulint n_pending_ops;/*!< this is positive when we - have pending operations against this - tablespace. The pending operations can - be ibuf merges or lock validation code - trying to read a block. - Dropping of the tablespace is forbidden - if this is positive. - Protected by fil_system->mutex. */ + /** Number of pending buffer pool operations accessing the tablespace + without holding a table lock or dict_operation_lock S-latch + that would prevent the table (and tablespace) from being + dropped. An example is change buffer merge. + The tablespace cannot be dropped while this is nonzero, + or while fil_node_t::n_pending is nonzero. + Protected by fil_system->mutex. */ + ulint n_pending_ops; + /** Number of pending block read or write operations + (when a write is imminent or a read has recently completed). + The tablespace object cannot be freed while this is nonzero, + but it can be detached from fil_system. + Note that fil_node_t::n_pending tracks actual pending I/O requests. + Protected by fil_system->mutex. */ + ulint n_pending_ios; hash_node_t hash; /*!< hash chain node */ hash_node_t name_hash;/*!< hash chain the name_hash table */ rw_lock_t latch; /*!< latch protecting the file space storage @@ -552,15 +559,6 @@ void fil_space_set_imported( ulint id); -#ifdef UNIV_DEBUG -/** Determine if a tablespace is temporary. -@param[in] id tablespace identifier -@return whether it is a temporary tablespace */ -bool -fsp_is_temporary(ulint id) -MY_ATTRIBUTE((warn_unused_result, pure)); -#endif /* UNIV_DEBUG */ - /** Append a file to the chain of files of a space. @param[in] name file name of a file that is not open @param[in] size file size in entire database blocks @@ -735,12 +733,10 @@ MY_ATTRIBUTE((warn_unused_result)); Used by background threads that do not necessarily hold proper locks for concurrency control. @param[in] id tablespace ID -@param[in] for_io whether to look up the tablespace while performing I/O - (possibly executing TRUNCATE) @return the tablespace @retval NULL if missing or being deleted or truncated */ fil_space_t* -fil_space_acquire(ulint id, bool for_io = false) +fil_space_acquire(ulint id) MY_ATTRIBUTE((warn_unused_result)); /** Acquire a tablespace that may not exist. @@ -758,6 +754,19 @@ fil_space_acquire_silent(ulint id) void fil_space_release(fil_space_t* space); +/** Acquire a tablespace for reading or writing a block, +when it could be dropped concurrently. +@param[in] id tablespace ID +@return the tablespace +@retval NULL if missing */ +fil_space_t* +fil_space_acquire_for_io(ulint id); + +/** Release a tablespace acquired with fil_space_acquire_for_io(). +@param[in,out] space tablespace to release */ +void +fil_space_release_for_io(fil_space_t* space); + /** Return the next fil_space_t. Once started, the caller must keep calling this until it returns NULL. fil_space_acquire() and fil_space_release() are invoked here which @@ -794,12 +803,9 @@ public: /** Constructor: Look up the tablespace and increment the reference count if found. - @param[in] space_id tablespace ID - @param[in] for_io whether to look up the tablespace - while performing I/O - (possibly executing TRUNCATE) */ - explicit FilSpace(ulint space_id, bool for_io = false) - : m_space(fil_space_acquire(space_id, for_io)) {} + @param[in] space_id tablespace ID */ + explicit FilSpace(ulint space_id) + : m_space(fil_space_acquire(space_id)) {} /** Assignment operator: This assumes that fil_space_acquire() has already been done for the fil_space_t. The caller must @@ -892,6 +898,17 @@ fil_op_replay_rename( const char* new_name) MY_ATTRIBUTE((warn_unused_result)); +/** Determine whether a table can be accessed in operations that are +not (necessarily) protected by meta-data locks. +(Rollback would generally be protected, but rollback of +FOREIGN KEY CASCADE/SET NULL is not protected by meta-data locks +but only by InnoDB table locks, which may be broken by TRUNCATE TABLE.) +@param[in] table persistent table +checked @return whether the table is accessible */ +bool +fil_table_accessible(const dict_table_t* table) + MY_ATTRIBUTE((warn_unused_result, nonnull)); + /** Deletes an IBD tablespace, either general or single-table. The tablespace must be cached in the memory cache. This will delete the datafile, fil_space_t & fil_node_t entries from the file_system_t cache. @@ -923,14 +940,18 @@ dberr_t fil_prepare_for_truncate( /*=====================*/ ulint id); /*!< in: space id */ -/**********************************************************************//** -Reinitialize the original tablespace header with the same space id -for single tablespace */ + +/** Reinitialize the original tablespace header with the same space id +for single tablespace +@param[in] id space id of the tablespace +@param[in] size size in blocks +@param[in] trx Transaction covering truncate */ void fil_reinit_space_header( -/*====================*/ - ulint id, /*!< in: space id */ - ulint size); /*!< in: size in blocks */ + ulint id, + ulint size, + trx_t* trx); + /*******************************************************************//** Closes a single-table tablespace. The tablespace must be cached in the memory cache. Free all pages used by the tablespace. @@ -1216,6 +1237,11 @@ fil_flush( /*======*/ ulint space_id); /*!< in: file space id (this can be a group of log files or a tablespace of the database) */ +/** Flush a tablespace. +@param[in,out] space tablespace to flush */ +void +fil_flush(fil_space_t* space); + /** Flush to disk the writes in file spaces of the given type possibly cached by the OS. @param[in] purpose FIL_TYPE_TABLESPACE or FIL_TYPE_LOG */ @@ -1474,7 +1500,7 @@ fil_mtr_rename_log( const dict_table_t* new_table, const char* tmp_name, mtr_t* mtr) - MY_ATTRIBUTE((warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /** Acquire the fil_system mutex. */ #define fil_system_enter() mutex_enter(&fil_system->mutex) @@ -1581,35 +1607,13 @@ fil_names_clear( void test_make_filepath(); #endif /* UNIV_ENABLE_UNIT_TEST_MAKE_FILEPATH */ - -/*******************************************************************//** -Returns the block size of the file space -@param[in] space_id space id -@param[in] offset page offset -@param[in] len page len +/** Determine the block size of the data file. +@param[in] space tablespace +@param[in] offset page number @return block size */ UNIV_INTERN ulint -fil_space_get_block_size( - ulint id, - os_offset_t offset, - ulint len); -/*******************************************************************//** -Increments the count of pending operation, if space is not being deleted. -@return TRUE if being deleted, and operation should be skipped */ -UNIV_INTERN -ibool -fil_inc_pending_ops( -/*================*/ - ulint id, /*!< in: space id */ - ibool print_err); /*!< in: need to print error or not */ -/*******************************************************************//** -Decrements the count of pending operations. */ -UNIV_INTERN -void -fil_decr_pending_ops( -/*=================*/ - ulint id); /*!< in: space id */ +fil_space_get_block_size(const fil_space_t* space, unsigned offset); #include "fil0fil.ic" #endif /* UNIV_INNOCHECKSUM */ diff --git a/storage/innobase/include/fil0fil.ic b/storage/innobase/include/fil0fil.ic index 01fa1093e5e..e3d4fd4d88b 100644 --- a/storage/innobase/include/fil0fil.ic +++ b/storage/innobase/include/fil0fil.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2015, 2017 MariaDB Corporation. +Copyright (c) 2015, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -27,28 +27,6 @@ Created 31/03/2015 Jan Lindström #define fil0fil_ic /*******************************************************************//** -Return space name */ -UNIV_INLINE -char* -fil_space_name( -/*===========*/ - fil_space_t* space) /*!< in: space */ -{ - return (space->name); -} - -/*******************************************************************//** -Return space flags */ -UNIV_INLINE -ulint -fil_space_flags( -/*===========*/ - fil_space_t* space) /*!< in: space */ -{ - return (space->flags); -} - -/*******************************************************************//** Return page type name */ UNIV_INLINE const char* diff --git a/storage/innobase/include/fil0pagecompress.h b/storage/innobase/include/fil0pagecompress.h index 0bf6aa75f19..cd754151d80 100644 --- a/storage/innobase/include/fil0pagecompress.h +++ b/storage/innobase/include/fil0pagecompress.h @@ -30,34 +30,6 @@ atomic writes information to table space. Created 11/12/2013 Jan Lindström jan.lindstrom@skysql.com ***********************************************************************/ -/*******************************************************************//** -Returns the page compression level flag of the space, or 0 if the space -is not compressed. The tablespace must be cached in the memory cache. -@return page compression level if page compressed, ULINT_UNDEFINED if space not found */ -UNIV_INLINE -ulint -fil_space_get_page_compression_level( -/*=================================*/ - ulint id); /*!< in: space id */ -/*******************************************************************//** -Returns the page compression flag of the space, or false if the space -is not compressed. The tablespace must be cached in the memory cache. -@return true if page compressed, false if not or space not found */ -UNIV_INLINE -bool -fil_space_is_page_compressed( -/*=========================*/ - ulint id); /*!< in: space id */ -/*******************************************************************//** -Returns the atomic writes flag of the space, or false if the space -is not using atomic writes. The tablespace must be cached in the memory cache. -@return atomic write table option value */ -UNIV_INLINE -bool -fil_space_get_atomic_writes( -/*=========================*/ - ulint id); /*!< in: space id */ - /****************************************************************//** For page compressed pages compress the page before actual write operation. @@ -66,8 +38,7 @@ UNIV_INTERN byte* fil_compress_page( /*==============*/ - ulint space_id, /*!< in: tablespace id of the - table. */ + fil_space_t* space, /*!< in,out: tablespace (NULL during IMPORT) */ byte* buf, /*!< in: buffer from which to write; in aio this must be appropriately aligned */ byte* out_buf, /*!< out: compressed buffer */ diff --git a/storage/innobase/include/fsp0pagecompress.ic b/storage/innobase/include/fsp0pagecompress.ic index bb11371d712..f4b95162b2a 100644 --- a/storage/innobase/include/fsp0pagecompress.ic +++ b/storage/innobase/include/fsp0pagecompress.ic @@ -74,47 +74,6 @@ fil_page_is_compressed_encrypted( return(mach_read_from_2(buf+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED); } -#ifndef UNIV_INNOCHECKSUM -/*******************************************************************//** -Returns the page compression level of the space, or 0 if the space -is not compressed. The tablespace must be cached in the memory cache. -@return page compression level, 0 if space not found */ -UNIV_INLINE -ulint -fil_space_get_page_compression_level( -/*=================================*/ - ulint id) /*!< in: space id */ -{ - ulint flags; - - flags = fil_space_get_flags(id); - - if (flags && flags != ULINT_UNDEFINED) { - - return(fsp_flags_get_page_compression_level(flags)); - } - - return(0); -} - -/*******************************************************************//** -Extract the page compression from space. -@return true if space is page compressed, false if space is not found -or space is not page compressed. */ -UNIV_INLINE -bool -fil_space_is_page_compressed( -/*=========================*/ - ulint id) /*!< in: space id */ -{ - ulint flags = fil_space_get_flags(id); - - return(flags != ULINT_UNDEFINED - && FSP_FLAGS_HAS_PAGE_COMPRESSION(flags)); -} - -#endif /* UNIV_INNOCHECKSUM */ - /****************************************************************//** Get the name of the compression algorithm used for page compression. @@ -155,31 +114,6 @@ fil_get_compression_alg_name( #ifndef UNIV_INNOCHECKSUM /*******************************************************************//** -Returns the atomic writes flag of the space, or false if the space -is not using atomic writes. The tablespace must be cached in the memory cache. -@return 1 if atomic writes can be used for the file */ -UNIV_INLINE -bool -fil_space_get_atomic_writes( -/*========================*/ - ulint id) /*!< in: space id */ -{ - struct fil_space_t* space; - bool ret= 0; - - ut_ad(fil_system); - - mutex_enter(&fil_system->mutex); - - if ((space = fil_space_get_by_id(id))) - ret= space->atomic_write_supported; - - mutex_exit(&fil_system->mutex); - return(ret); -} - - -/*******************************************************************//** Find out wheather the page is page compressed with lzo method @return true if page is page compressed with lzo method, false if not */ UNIV_INLINE diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h index 21354b1b605..f1d53165cdd 100644 --- a/storage/innobase/include/fts0fts.h +++ b/storage/innobase/include/fts0fts.h @@ -409,6 +409,7 @@ extern bool fts_need_sync; /** Variable specifying the table that has Fulltext index to display its content through information schema table */ extern char* fts_internal_tbl_name; +extern char* fts_internal_tbl_name2; #define fts_que_graph_free(graph) \ do { \ @@ -842,6 +843,15 @@ fts_init_doc_id( /*============*/ const dict_table_t* table); /*!< in: table */ +/* Get parent table name if it's a fts aux table +@param[in] aux_table_name aux table name +@param[in] aux_table_len aux table length +@return parent table name, or NULL */ +char* +fts_get_parent_table_name( + const char* aux_table_name, + ulint aux_table_len); + /******************************************************************//** compare two character string according to their charset. */ extern diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h index 6992f4a6689..7b3726b1fef 100644 --- a/storage/innobase/include/ha_prototypes.h +++ b/storage/innobase/include/ha_prototypes.h @@ -38,7 +38,6 @@ simple headers. class THD; // JAN: TODO missing features: -#undef MYSQL_57_SELECT_COUNT_OPTIMIZATION #undef MYSQL_FT_INIT_EXT #undef MYSQL_INNODB_PARTITIONING #undef MYSQL_PFS diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index ca6a5286cde..e718189062d 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -55,6 +55,9 @@ extern ulong innodb_lock_schedule_algorithm; // Forward declaration class ReadView; +/** The value of innodb_deadlock_detect */ +extern my_bool innobase_deadlock_detect; + /*********************************************************************//** Gets the size of a lock struct. @return size in bytes */ diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h index 35a94513632..d1aae64227e 100644 --- a/storage/innobase/include/log0log.h +++ b/storage/innobase/include/log0log.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved. +Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2009, Google Inc. Copyright (c) 2017, MariaDB Corporation. All Rights Reserved. @@ -46,6 +46,12 @@ struct log_group_t; /** Magic value to use instead of log checksums when they are disabled */ #define LOG_NO_CHECKSUM_MAGIC 0xDEADBEEFUL +/* Margin for the free space in the smallest log group, before a new query +step which modifies the database, is started */ + +#define LOG_CHECKPOINT_FREE_PER_THREAD (4 * UNIV_PAGE_SIZE) +#define LOG_CHECKPOINT_EXTRA_FREE (8 * UNIV_PAGE_SIZE) + typedef ulint (*log_checksum_func_t)(const byte* log_block); /** Pointer to the log checksum calculation function. Protected with diff --git a/storage/innobase/include/mtr0log.ic b/storage/innobase/include/mtr0log.ic index 701f1482e64..972fdc81518 100644 --- a/storage/innobase/include/mtr0log.ic +++ b/storage/innobase/include/mtr0log.ic @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -227,20 +228,11 @@ mlog_write_initial_log_record_fast( if (space == TRX_SYS_SPACE && offset >= FSP_EXTENT_SIZE && offset < 3 * FSP_EXTENT_SIZE) { - if (buf_dblwr_being_created) { - /* Do nothing: we only come to this branch in an - InnoDB database creation. We do not redo log - anything for the doublewrite buffer pages. */ - return(log_ptr); - } else { - ib::error() << "Trying to redo log a record of type " - << type << " on page " - << page_id_t(space, offset) << "in the" - " doublewrite buffer, continuing anyway." - " Please post a bug report to" - " bugs.mysql.com."; - ut_ad(0); - } + ut_ad(buf_dblwr_being_created); + /* Do nothing: we only come to this branch in an + InnoDB database creation. We do not redo log + anything for the doublewrite buffer pages. */ + return(log_ptr); } return(mlog_write_initial_log_record_low(type, space, offset, diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h index a02333109cc..045a14221a3 100644 --- a/storage/innobase/include/mtr0mtr.h +++ b/storage/innobase/include/mtr0mtr.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. Copyright (c) 2013, 2017, MariaDB Corporation @@ -269,8 +269,12 @@ struct mtr_t { MLOG_FILE_NAME records and a MLOG_CHECKPOINT marker. The caller must invoke log_mutex_enter() and log_mutex_exit(). This is to be used at log_checkpoint(). - @param[in] checkpoint_lsn the LSN of the log checkpoint */ - void commit_checkpoint(lsn_t checkpoint_lsn); + @param[in] checkpoint_lsn the LSN of the log checkpoint + @param[in] write_mlog_checkpoint Write MLOG_CHECKPOINT marker + if it is enabled. */ + void commit_checkpoint( + lsn_t checkpoint_lsn, + bool write_mlog_checkpoint); /** Return current size of the buffer. @return savepoint */ diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h index 6a82c06e3ed..e3396a4b7f7 100644 --- a/storage/innobase/include/os0file.h +++ b/storage/innobase/include/os0file.h @@ -52,24 +52,11 @@ struct fil_space_t; extern bool os_has_said_disk_full; extern my_bool srv_use_trim; -/** Number of pending read operations */ -extern ulint os_n_pending_reads; -/** Number of pending write operations */ -extern ulint os_n_pending_writes; - /** File offset in bytes */ typedef ib_uint64_t os_offset_t; #ifdef _WIN32 -/** -Gets the operating system version. Currently works only on Windows. -@return OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000, OS_WINXP, OS_WINVISTA, -OS_WIN7. */ - -ulint -os_get_os_version(); - typedef HANDLE os_file_dir_t; /*!< directory stream */ /** We define always WIN_ASYNC_IO, and check at run-time whether diff --git a/storage/innobase/include/os0thread.h b/storage/innobase/include/os0thread.h index 7aea976a37e..6f521b5a2ec 100644 --- a/storage/innobase/include/os0thread.h +++ b/storage/innobase/include/os0thread.h @@ -118,9 +118,19 @@ os_thread_create_func( os_thread_id_t* thread_id); /*!< out: id of the created thread, or NULL */ -/** Exits the current thread. */ +/** Waits until the specified thread completes and joins it. +Its return value is ignored. +@param[in,out] thread thread to join */ void -os_thread_exit() +os_thread_join( + os_thread_id_t thread); + +/** Exits the current thread. +@param[in] detach if true, the thread will be detached right before +exiting. If false, another thread is responsible for joining this thread */ +void +os_thread_exit( + bool detach = true) UNIV_COLD MY_ATTRIBUTE((noreturn)); /*****************************************************************//** diff --git a/storage/innobase/include/page0page.ic b/storage/innobase/include/page0page.ic index 7250a96bb5d..1c680ce7cc4 100644 --- a/storage/innobase/include/page0page.ic +++ b/storage/innobase/include/page0page.ic @@ -295,7 +295,7 @@ page_is_comp( /*=========*/ const page_t* page) /*!< in: index page */ { - return(page_header_get_field(page, PAGE_N_HEAP) & 0x8000); + return(page[PAGE_HEADER + PAGE_N_HEAP] & 0x80); } /************************************************************//** diff --git a/storage/innobase/include/page0zip.h b/storage/innobase/include/page0zip.h index e1062c00a6f..c1d5443d9e5 100644 --- a/storage/innobase/include/page0zip.h +++ b/storage/innobase/include/page0zip.h @@ -512,19 +512,7 @@ ibool page_zip_verify_checksum( /*=====================*/ const void* data, /*!< in: compressed page */ - ulint size /*!< in: size of compressed page */ -#ifdef UNIV_INNOCHECKSUM - /* these variables are used only for innochecksum tool. */ - ,uintmax_t page_no, /*!< in: page number of - given read_buf */ - bool strict_check, /*!< in: true if strict-check - option is enable */ - bool is_log_enabled, /*!< in: true if log option is - enable */ - FILE* log_file /*!< in: file pointer to - log_file */ -#endif /* UNIV_INNOCHECKSUM */ -); + ulint size); /*!< in: size of compressed page */ #ifndef UNIV_INNOCHECKSUM /**********************************************************************//** diff --git a/storage/innobase/include/pars0grm.h b/storage/innobase/include/pars0grm.h index 788090a2e74..90a7468bc9a 100644 --- a/storage/innobase/include/pars0grm.h +++ b/storage/innobase/include/pars0grm.h @@ -48,104 +48,101 @@ extern int yydebug; PARS_INT_LIT = 258, PARS_FLOAT_LIT = 259, PARS_STR_LIT = 260, - PARS_FIXBINARY_LIT = 261, - PARS_BLOB_LIT = 262, - PARS_NULL_LIT = 263, - PARS_ID_TOKEN = 264, - PARS_AND_TOKEN = 265, - PARS_OR_TOKEN = 266, - PARS_NOT_TOKEN = 267, - PARS_GE_TOKEN = 268, - PARS_LE_TOKEN = 269, - PARS_NE_TOKEN = 270, - PARS_PROCEDURE_TOKEN = 271, - PARS_IN_TOKEN = 272, - PARS_OUT_TOKEN = 273, - PARS_BINARY_TOKEN = 274, - PARS_BLOB_TOKEN = 275, - PARS_INT_TOKEN = 276, - PARS_INTEGER_TOKEN = 277, - PARS_FLOAT_TOKEN = 278, - PARS_CHAR_TOKEN = 279, - PARS_IS_TOKEN = 280, - PARS_BEGIN_TOKEN = 281, - PARS_END_TOKEN = 282, - PARS_IF_TOKEN = 283, - PARS_THEN_TOKEN = 284, - PARS_ELSE_TOKEN = 285, - PARS_ELSIF_TOKEN = 286, - PARS_LOOP_TOKEN = 287, - PARS_WHILE_TOKEN = 288, - PARS_RETURN_TOKEN = 289, - PARS_SELECT_TOKEN = 290, - PARS_SUM_TOKEN = 291, - PARS_COUNT_TOKEN = 292, - PARS_DISTINCT_TOKEN = 293, - PARS_FROM_TOKEN = 294, - PARS_WHERE_TOKEN = 295, - PARS_FOR_TOKEN = 296, - PARS_DDOT_TOKEN = 297, - PARS_READ_TOKEN = 298, - PARS_ORDER_TOKEN = 299, - PARS_BY_TOKEN = 300, - PARS_ASC_TOKEN = 301, - PARS_DESC_TOKEN = 302, - PARS_INSERT_TOKEN = 303, - PARS_INTO_TOKEN = 304, - PARS_VALUES_TOKEN = 305, - PARS_UPDATE_TOKEN = 306, - PARS_SET_TOKEN = 307, - PARS_DELETE_TOKEN = 308, - PARS_CURRENT_TOKEN = 309, - PARS_OF_TOKEN = 310, - PARS_CREATE_TOKEN = 311, - PARS_TABLE_TOKEN = 312, - PARS_INDEX_TOKEN = 313, - PARS_UNIQUE_TOKEN = 314, - PARS_CLUSTERED_TOKEN = 315, - PARS_ON_TOKEN = 316, - PARS_ASSIGN_TOKEN = 317, - PARS_DECLARE_TOKEN = 318, - PARS_CURSOR_TOKEN = 319, - PARS_SQL_TOKEN = 320, - PARS_OPEN_TOKEN = 321, - PARS_FETCH_TOKEN = 322, - PARS_CLOSE_TOKEN = 323, - PARS_NOTFOUND_TOKEN = 324, - PARS_TO_CHAR_TOKEN = 325, - PARS_TO_NUMBER_TOKEN = 326, - PARS_TO_BINARY_TOKEN = 327, - PARS_BINARY_TO_NUMBER_TOKEN = 328, - PARS_SUBSTR_TOKEN = 329, - PARS_REPLSTR_TOKEN = 330, - PARS_CONCAT_TOKEN = 331, - PARS_INSTR_TOKEN = 332, - PARS_LENGTH_TOKEN = 333, - PARS_SYSDATE_TOKEN = 334, - PARS_PRINTF_TOKEN = 335, - PARS_ASSERT_TOKEN = 336, - PARS_RND_TOKEN = 337, - PARS_RND_STR_TOKEN = 338, - PARS_ROW_PRINTF_TOKEN = 339, - PARS_COMMIT_TOKEN = 340, - PARS_ROLLBACK_TOKEN = 341, - PARS_WORK_TOKEN = 342, - PARS_UNSIGNED_TOKEN = 343, - PARS_EXIT_TOKEN = 344, - PARS_FUNCTION_TOKEN = 345, - PARS_LOCK_TOKEN = 346, - PARS_SHARE_TOKEN = 347, - PARS_MODE_TOKEN = 348, - PARS_LIKE_TOKEN = 349, - PARS_LIKE_TOKEN_EXACT = 350, - PARS_LIKE_TOKEN_PREFIX = 351, - PARS_LIKE_TOKEN_SUFFIX = 352, - PARS_LIKE_TOKEN_SUBSTR = 353, - PARS_TABLE_NAME_TOKEN = 354, - PARS_COMPACT_TOKEN = 355, - PARS_BLOCK_SIZE_TOKEN = 356, - PARS_BIGINT_TOKEN = 357, - NEG = 358 + PARS_NULL_LIT = 261, + PARS_ID_TOKEN = 262, + PARS_AND_TOKEN = 263, + PARS_OR_TOKEN = 264, + PARS_NOT_TOKEN = 265, + PARS_GE_TOKEN = 266, + PARS_LE_TOKEN = 267, + PARS_NE_TOKEN = 268, + PARS_PROCEDURE_TOKEN = 269, + PARS_IN_TOKEN = 270, + PARS_OUT_TOKEN = 271, + PARS_BINARY_TOKEN = 272, + PARS_BLOB_TOKEN = 273, + PARS_INT_TOKEN = 274, + PARS_FLOAT_TOKEN = 275, + PARS_CHAR_TOKEN = 276, + PARS_IS_TOKEN = 277, + PARS_BEGIN_TOKEN = 278, + PARS_END_TOKEN = 279, + PARS_IF_TOKEN = 280, + PARS_THEN_TOKEN = 281, + PARS_ELSE_TOKEN = 282, + PARS_ELSIF_TOKEN = 283, + PARS_LOOP_TOKEN = 284, + PARS_WHILE_TOKEN = 285, + PARS_RETURN_TOKEN = 286, + PARS_SELECT_TOKEN = 287, + PARS_SUM_TOKEN = 288, + PARS_COUNT_TOKEN = 289, + PARS_DISTINCT_TOKEN = 290, + PARS_FROM_TOKEN = 291, + PARS_WHERE_TOKEN = 292, + PARS_FOR_TOKEN = 293, + PARS_DDOT_TOKEN = 294, + PARS_READ_TOKEN = 295, + PARS_ORDER_TOKEN = 296, + PARS_BY_TOKEN = 297, + PARS_ASC_TOKEN = 298, + PARS_DESC_TOKEN = 299, + PARS_INSERT_TOKEN = 300, + PARS_INTO_TOKEN = 301, + PARS_VALUES_TOKEN = 302, + PARS_UPDATE_TOKEN = 303, + PARS_SET_TOKEN = 304, + PARS_DELETE_TOKEN = 305, + PARS_CURRENT_TOKEN = 306, + PARS_OF_TOKEN = 307, + PARS_CREATE_TOKEN = 308, + PARS_TABLE_TOKEN = 309, + PARS_INDEX_TOKEN = 310, + PARS_UNIQUE_TOKEN = 311, + PARS_CLUSTERED_TOKEN = 312, + PARS_ON_TOKEN = 313, + PARS_ASSIGN_TOKEN = 314, + PARS_DECLARE_TOKEN = 315, + PARS_CURSOR_TOKEN = 316, + PARS_SQL_TOKEN = 317, + PARS_OPEN_TOKEN = 318, + PARS_FETCH_TOKEN = 319, + PARS_CLOSE_TOKEN = 320, + PARS_NOTFOUND_TOKEN = 321, + PARS_TO_CHAR_TOKEN = 322, + PARS_TO_NUMBER_TOKEN = 323, + PARS_TO_BINARY_TOKEN = 324, + PARS_BINARY_TO_NUMBER_TOKEN = 325, + PARS_SUBSTR_TOKEN = 326, + PARS_REPLSTR_TOKEN = 327, + PARS_CONCAT_TOKEN = 328, + PARS_INSTR_TOKEN = 329, + PARS_LENGTH_TOKEN = 330, + PARS_SYSDATE_TOKEN = 331, + PARS_PRINTF_TOKEN = 332, + PARS_ASSERT_TOKEN = 333, + PARS_RND_TOKEN = 334, + PARS_RND_STR_TOKEN = 335, + PARS_ROW_PRINTF_TOKEN = 336, + PARS_COMMIT_TOKEN = 337, + PARS_ROLLBACK_TOKEN = 338, + PARS_WORK_TOKEN = 339, + PARS_UNSIGNED_TOKEN = 340, + PARS_EXIT_TOKEN = 341, + PARS_FUNCTION_TOKEN = 342, + PARS_LOCK_TOKEN = 343, + PARS_SHARE_TOKEN = 344, + PARS_MODE_TOKEN = 345, + PARS_LIKE_TOKEN = 346, + PARS_LIKE_TOKEN_EXACT = 347, + PARS_LIKE_TOKEN_PREFIX = 348, + PARS_LIKE_TOKEN_SUFFIX = 349, + PARS_LIKE_TOKEN_SUBSTR = 350, + PARS_TABLE_NAME_TOKEN = 351, + PARS_COMPACT_TOKEN = 352, + PARS_BLOCK_SIZE_TOKEN = 353, + PARS_BIGINT_TOKEN = 354, + NEG = 355 }; #endif diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 59bd786d25c..0557b585ae1 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2000, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -540,9 +540,6 @@ row_scan_index_for_mysql( row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in MySQL handle */ const dict_index_t* index, /*!< in: index */ - bool check_keys, /*!< in: true=check for mis- - ordered or duplicate records, - false=count the rows only */ ulint* n_rows) /*!< out: number of entries seen in the consistent read */ MY_ATTRIBUTE((warn_unused_result)); diff --git a/storage/innobase/include/srv0mon.h b/storage/innobase/include/srv0mon.h index 1b1597d0fba..e4034f3a6ff 100644 --- a/storage/innobase/include/srv0mon.h +++ b/storage/innobase/include/srv0mon.h @@ -2,7 +2,7 @@ Copyright (c) 2010, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2016, MariaDB Corporation. +Copyright (c) 2013, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -603,9 +603,10 @@ on the counters */ /** Atomically increment a monitor counter. Use MONITOR_INC if appropriate mutex protection exists. -@param monitor monitor to be incremented by 1 */ -# define MONITOR_ATOMIC_INC(monitor) \ - if (MONITOR_IS_ON(monitor)) { \ +@param monitor monitor to be incremented by 1 +@param enabled whether the monitor is enabled */ +#define MONITOR_ATOMIC_INC_LOW(monitor, enabled) \ + if (enabled) { \ ib_uint64_t value; \ value = my_atomic_add64( \ (int64*) &MONITOR_VALUE(monitor), 1) + 1; \ @@ -618,9 +619,10 @@ Use MONITOR_INC if appropriate mutex protection exists. /** Atomically decrement a monitor counter. Use MONITOR_DEC if appropriate mutex protection exists. -@param monitor monitor to be decremented by 1 */ -# define MONITOR_ATOMIC_DEC(monitor) \ - if (MONITOR_IS_ON(monitor)) { \ +@param monitor monitor to be decremented by 1 +@param enabled whether the monitor is enabled */ +#define MONITOR_ATOMIC_DEC_LOW(monitor, enabled) \ + if (enabled) { \ ib_uint64_t value; \ value = my_atomic_add64( \ (int64*) &MONITOR_VALUE(monitor), -1) - 1; \ @@ -631,6 +633,17 @@ Use MONITOR_DEC if appropriate mutex protection exists. } \ } +/** Atomically increment a monitor counter if it is enabled. +Use MONITOR_INC if appropriate mutex protection exists. +@param monitor monitor to be incremented by 1 */ +#define MONITOR_ATOMIC_INC(monitor) \ + MONITOR_ATOMIC_INC_LOW(monitor, MONITOR_IS_ON(monitor)) +/** Atomically decrement a monitor counter if it is enabled. +Use MONITOR_DEC if appropriate mutex protection exists. +@param monitor monitor to be decremented by 1 */ +#define MONITOR_ATOMIC_DEC(monitor) \ + MONITOR_ATOMIC_DEC_LOW(monitor, MONITOR_IS_ON(monitor)) + #define MONITOR_DEC(monitor) \ if (MONITOR_IS_ON(monitor)) { \ MONITOR_VALUE(monitor)--; \ diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index eb08c478965..230d7b7effe 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -301,6 +301,9 @@ extern long srv_mtflush_threads; /* If this flag is TRUE, then we will use multi threaded flush. */ extern my_bool srv_use_mtflush; +/** TRUE if the server was successfully started */ +extern bool srv_was_started; + /** Server undo tablespaces directory, can be absolute path. */ extern char* srv_undo_dir; @@ -472,6 +475,7 @@ extern unsigned long long srv_stats_transient_sample_pages; extern my_bool srv_stats_persistent; extern unsigned long long srv_stats_persistent_sample_pages; extern my_bool srv_stats_auto_recalc; +extern my_bool srv_stats_include_delete_marked; extern unsigned long long srv_stats_modified_counter; extern my_bool srv_stats_sample_traditional; @@ -512,7 +516,6 @@ extern ulong srv_n_spin_wait_rounds; extern ulong srv_n_free_tickets_to_enter; extern ulong srv_thread_sleep_delay; extern uint srv_spin_wait_delay; -extern ibool srv_priority_boost; extern ulint srv_truncated_status_writes; /** Number of initialized rollback segments for persistent undo log */ @@ -746,36 +749,24 @@ srv_set_io_thread_op_info( Resets the info describing an i/o thread current state. */ void srv_reset_io_thread_op_info(); -/*=========================*/ -/*******************************************************************//** -Tells the purge thread that there has been activity in the database -and wakes up the purge thread if it is suspended (not sleeping). Note -that there is a small chance that the purge thread stays suspended -(we do not protect our operation with the srv_sys_t:mutex, for -performance reasons). */ + +/** Wake up the purge threads if there is work to do. */ void -srv_wake_purge_thread_if_not_active(void); -/*=====================================*/ -/*******************************************************************//** -Tells the Innobase server that there has been activity in the database -and wakes up the master thread if it is suspended (not sleeping). Used -in the MySQL interface. Note that there is a small chance that the master -thread stays suspended (we do not protect our operation with the kernel -mutex, for performace reasons). */ +srv_wake_purge_thread_if_not_active(); +/** Wake up the InnoDB master thread if it was suspended (not sleeping). */ void -srv_active_wake_master_thread_low(void); -/*===================================*/ +srv_active_wake_master_thread_low(); + #define srv_active_wake_master_thread() \ do { \ if (!srv_read_only_mode) { \ srv_active_wake_master_thread_low(); \ } \ } while (0) -/*******************************************************************//** -Wakes up the master thread if it is suspended or being suspended. */ +/** Wake up the master thread if it is suspended or being suspended. */ void -srv_wake_master_thread(void); -/*========================*/ +srv_wake_master_thread(); + /******************************************************************//** Outputs to a file the output of the InnoDB Monitor. @return FALSE if not all information printed diff --git a/storage/innobase/include/srv0start.h b/storage/innobase/include/srv0start.h index d7a5922c954..4f2f4a312ff 100644 --- a/storage/innobase/include/srv0start.h +++ b/storage/innobase/include/srv0start.h @@ -121,8 +121,6 @@ extern lsn_t srv_start_lsn; extern bool srv_is_being_started; /** TRUE if SYS_TABLESPACES is available for lookups */ extern bool srv_sys_tablespaces_open; -/** TRUE if the server was successfully started */ -extern ibool srv_was_started; /** TRUE if the server is being started, before rolling back any incomplete transactions */ extern bool srv_startup_is_before_trx_rollback_phase; diff --git a/storage/innobase/include/sync0types.h b/storage/innobase/include/sync0types.h index 736c5454711..1d11bfa7811 100644 --- a/storage/innobase/include/sync0types.h +++ b/storage/innobase/include/sync0types.h @@ -505,14 +505,32 @@ private: }; #ifdef UNIV_PFS_MUTEX -/** Latch element +/** Latch element. +Used for mutexes which have PFS keys defined under UNIV_PFS_MUTEX. @param[in] id Latch id @param[in] level Latch level @param[in] key PFS key */ -# define LATCH_ADD(id, level, key) latch_meta[LATCH_ID_ ## id] = \ +# define LATCH_ADD_MUTEX(id, level, key) latch_meta[LATCH_ID_ ## id] =\ + UT_NEW_NOKEY(latch_meta_t(LATCH_ID_ ## id, #id, level, #level, key)) + +#ifdef UNIV_PFS_RWLOCK +/** Latch element. +Used for rwlocks which have PFS keys defined under UNIV_PFS_RWLOCK. +@param[in] id Latch id +@param[in] level Latch level +@param[in] key PFS key */ +# define LATCH_ADD_RWLOCK(id, level, key) latch_meta[LATCH_ID_ ## id] =\ UT_NEW_NOKEY(latch_meta_t(LATCH_ID_ ## id, #id, level, #level, key)) #else -# define LATCH_ADD(id, level, key) latch_meta[LATCH_ID_ ## id] = \ +# define LATCH_ADD_RWLOCK(id, level, key) latch_meta[LATCH_ID_ ## id] =\ + UT_NEW_NOKEY(latch_meta_t(LATCH_ID_ ## id, #id, level, #level, \ + PSI_NOT_INSTRUMENTED)) +#endif /* UNIV_PFS_RWLOCK */ + +#else +# define LATCH_ADD_MUTEX(id, level, key) latch_meta[LATCH_ID_ ## id] =\ + UT_NEW_NOKEY(latch_meta_t(LATCH_ID_ ## id, #id, level, #level)) +# define LATCH_ADD_RWLOCK(id, level, key) latch_meta[LATCH_ID_ ## id] =\ UT_NEW_NOKEY(latch_meta_t(LATCH_ID_ ## id, #id, level, #level)) #endif /* UNIV_PFS_MUTEX */ @@ -919,7 +937,7 @@ sync_latch_get_level(latch_id_t id) return(meta.get_level()); } -#ifdef HAVE_PSI_INTERFACE +#ifdef UNIV_PFS_MUTEX /** Get the latch PFS key from the latch ID @param[in] id Latch ID @return the PFS key */ diff --git a/storage/innobase/include/trx0rseg.h b/storage/innobase/include/trx0rseg.h index 95774cbf476..4c162526384 100644 --- a/storage/innobase/include/trx0rseg.h +++ b/storage/innobase/include/trx0rseg.h @@ -200,7 +200,10 @@ struct trx_rseg_t { bool is_persistent() const { ut_ad(space == SRV_TMP_SPACE_ID - || space <= srv_undo_tablespaces); + || space <= TRX_SYS_MAX_UNDO_SPACES); + ut_ad(space == SRV_TMP_SPACE_ID + || space <= srv_undo_tablespaces_active + || !srv_was_started); return(space != SRV_TMP_SPACE_ID); } }; diff --git a/storage/innobase/include/trx0rseg.ic b/storage/innobase/include/trx0rseg.ic index 0a33c747668..45ee3ef8d66 100644 --- a/storage/innobase/include/trx0rseg.ic +++ b/storage/innobase/include/trx0rseg.ic @@ -42,7 +42,9 @@ trx_rsegf_get( buf_block_t* block; trx_rsegf_t* header; - ut_ad(space <= srv_undo_tablespaces || space == SRV_TMP_SPACE_ID); + ut_ad(space <= srv_undo_tablespaces_active || space == SRV_TMP_SPACE_ID + || !srv_was_started); + ut_ad(space <= TRX_SYS_MAX_UNDO_SPACES || space == SRV_TMP_SPACE_ID); block = buf_page_get( page_id_t(space, page_no), univ_page_size, RW_X_LATCH, mtr); @@ -69,7 +71,9 @@ trx_rsegf_get_new( buf_block_t* block; trx_rsegf_t* header; - ut_ad(space <= srv_undo_tablespaces || space == SRV_TMP_SPACE_ID); + ut_ad(space <= srv_undo_tablespaces_active || space == SRV_TMP_SPACE_ID + || !srv_was_started); + ut_ad(space <= TRX_SYS_MAX_UNDO_SPACES || space == SRV_TMP_SPACE_ID); block = buf_page_get( page_id_t(space, page_no), univ_page_size, RW_X_LATCH, mtr); diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h index b867600653d..bf8cf2481eb 100644 --- a/storage/innobase/include/trx0sys.h +++ b/storage/innobase/include/trx0sys.h @@ -403,10 +403,8 @@ byte, therefore 128; each slot is currently 8 bytes in size. If you want to raise the level to 256 then you will need to fix some assertions that impose the 7 bit restriction. e.g., mach_write_to_3() */ #define TRX_SYS_N_RSEGS 128 -/* Originally, InnoDB defined TRX_SYS_N_RSEGS as 256 but created only one -rollback segment. It initialized some arrays with this number of entries. -We must remember this limit in order to keep file compatibility. */ -#define TRX_SYS_OLD_N_RSEGS 256 +/** Maximum number of undo tablespaces (not counting the system tablespace) */ +#define TRX_SYS_MAX_UNDO_SPACES (TRX_SYS_N_RSEGS - 1) /** Maximum length of MySQL binlog file name, in bytes. */ #define TRX_SYS_MYSQL_LOG_NAME_LEN 512 diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index b08148578dc..446e619abb9 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -386,6 +386,22 @@ trx_print_latched( ulint max_query_len); /*!< in: max query length to print, or 0 to use the default max length */ +#ifdef WITH_WSREP +/**********************************************************************//** +Prints info about a transaction. +Transaction information may be retrieved without having trx_sys->mutex acquired +so it may not be completely accurate. The caller must own lock_sys->mutex +and the trx must have some locks to make sure that it does not escape +without locking lock_sys->mutex. */ +UNIV_INTERN +void +wsrep_trx_print_locking( + FILE* f, /*!< in: output stream */ + const trx_t* trx, /*!< in: transaction */ + ulint max_query_len) /*!< in: max query length to print, + or 0 to use the default max length */ + MY_ATTRIBUTE((nonnull)); +#endif /* WITH_WSREP */ /**********************************************************************//** Prints info about a transaction. Acquires and releases lock_sys->mutex and trx_sys->mutex. */ @@ -1468,10 +1484,30 @@ private: return; } - /* Avoid excessive mutex acquire/release */ - ut_ad(!is_async_rollback(trx)); + /* If it hasn't already been marked for async rollback. + and it will be committed/rolled back. */ + if (disable) { + + trx_mutex_enter(trx); + if (!is_forced_rollback(trx) + && is_started(trx) + && !trx_is_autocommit_non_locking(trx)) { + + ut_ad(trx->killed_by == 0); + + /* This transaction has crossed the point of + no return and cannot be rolled back + asynchronously now. It must commit or rollback + synhronously. */ + + trx->in_innodb |= TRX_FORCE_ROLLBACK_DISABLE; + } + trx_mutex_exit(trx); + } + + /* Avoid excessive mutex acquire/release */ ++trx->in_depth; /* If trx->in_depth is greater than 1 then @@ -1489,25 +1525,7 @@ private: wait(trx); - ut_ad((trx->in_innodb & TRX_FORCE_ROLLBACK_MASK) - < (TRX_FORCE_ROLLBACK_MASK - 1)); - - /* If it hasn't already been marked for async rollback. - and it will be committed/rolled back. */ - - if (!is_forced_rollback(trx) - && disable - && is_started(trx) - && !trx_is_autocommit_non_locking(trx)) { - - ut_ad(trx->killed_by == 0); - - /* This transaction has crossed the point of no - return and cannot be rolled back asynchronously - now. It must commit or rollback synhronously. */ - - trx->in_innodb |= TRX_FORCE_ROLLBACK_DISABLE; - } + ut_ad((trx->in_innodb & TRX_FORCE_ROLLBACK_MASK) == 0); ++trx->in_innodb; diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index cb2674ebddf..ee759534301 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -102,11 +102,18 @@ support cross-platform development and expose comonly used SQL names. */ #endif #include <stdint.h> +#define __STDC_FORMAT_MACROS /* Enable C99 printf format macros */ #include <inttypes.h> #ifdef HAVE_UNISTD_H #include <unistd.h> #endif +#ifdef UNIV_INNOCHECKSUM +extern bool strict_verify; +extern FILE* log_file; +extern uintmax_t cur_page_num; +#endif /* UNIV_INNOCHECKSUM */ + #include "my_pthread.h" /* Following defines are to enable performance schema instrumentation in each of five InnoDB modules if @@ -282,16 +289,7 @@ rarely invoked function for size instead for speed. */ #define UNIV_INLINE static inline -#ifdef _WIN32 -# ifdef _WIN64 -# define UNIV_WORD_SIZE 8 -# else -# define UNIV_WORD_SIZE 4 -# endif -#else /* !_WIN32 */ -/** MySQL config.h generated by CMake will define SIZEOF_LONG in Posix */ -#define UNIV_WORD_SIZE SIZEOF_LONG -#endif /* _WIN32 */ +#define UNIV_WORD_SIZE SIZEOF_SIZE_T /** The following alignment is used in memory allocations in memory heap management to ensure correct alignment for doubles etc. */ @@ -463,52 +461,48 @@ mysql_com.h if you are to use this macro. */ ========================== */ -/* Note that inside MySQL 'byte' is defined as char on Linux! */ -#define byte unsigned char +/** Unsigned octet of bits */ +typedef unsigned char byte; +/** Machine-word-width unsigned integer */ +typedef size_t ulint; +/** Machine-word-width signed integer */ +typedef ssize_t lint; -/* Another basic type we use is unsigned long integer which should be equal to -the word size of the machine, that is on a 32-bit platform 32 bits, and on a -64-bit platform 64 bits. We also give the printf format for the type as a -macro ULINTPF. */ +/** ulint format for the printf() family of functions */ +#define ULINTPF "%zu" +/** ulint hexadecimal format for the printf() family of functions */ +#define ULINTPFx "%zx" #ifdef _WIN32 /* Use the integer types and formatting strings defined in Visual Studio. */ # define UINT32PF "%u" -# define UINT64PF "%llu" -# define UINT64PFx "%016llx" +# define INT64PF "%lld" # define UINT64scan "llu" -typedef unsigned __int64 ib_uint64_t; -typedef unsigned __int32 ib_uint32_t; -#else -# define UINT32PF "%u" -#if SIZEOF_LONG == 8 -# define UINT64PF "%lu" -# define UINT64PFx "%016lx" -# define UINT64scan "lu" -#else -# define UINT64PF "%llu" # define UINT64PFx "%016llx" +#elif defined __APPLE__ +/* Apple prefers to call the 64-bit types 'long long' +in both 32-bit and 64-bit environments. */ +# define UINT32PF "%" PRIu32 +# define INT64PF "%lld" # define UINT64scan "llu" +# define UINT64PFx "%016llx" +#else +/* Use the integer types and formatting strings defined in the C99 standard. */ +# define UINT32PF "%" PRIu32 +# define INT64PF "%" PRId64 +# define UINT64scan PRIu64 +# define UINT64PFx "%016" PRIx64 #endif + +typedef int64_t ib_int64_t; typedef uint64_t ib_uint64_t; typedef uint32_t ib_uint32_t; -#endif /* _WIN32 */ -#ifdef _WIN64 -typedef unsigned __int64 ulint; -typedef __int64 lint; -# define ULINTPF UINT64PF -#else -typedef unsigned long int ulint; -typedef long int lint; -# define ULINTPF "%lu" -#endif /* _WIN64 */ +#define UINT64PF "%" UINT64scan +#define IB_ID_FMT UINT64PF -#ifndef _WIN32 -#if SIZEOF_LONG != SIZEOF_VOIDP -#error "Error: InnoDB's ulint must be of the same size as void*" -#endif -#endif +/** Log sequence number (also used for redo log byte arithmetics) */ +typedef ib_uint64_t lsn_t; /** The 'undefined' value for a ulint */ #define ULINT_UNDEFINED ((ulint)(-1)) diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 134853dd0d7..1860cd51362 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -56,6 +56,9 @@ Created 5/7/1996 Heikki Tuuri /** Lock scheduling algorithm */ ulong innodb_lock_schedule_algorithm = INNODB_LOCK_SCHEDULE_ALGORITHM_FCFS; +/** The value of innodb_deadlock_detect */ +my_bool innobase_deadlock_detect; + /** Total number of cached record locks */ static const ulint REC_LOCK_CACHE = 8; @@ -124,7 +127,7 @@ public: @return id of transaction chosen as victim or 0 */ static const trx_t* check_and_resolve( const lock_t* lock, - const trx_t* trx); + trx_t* trx); private: /** Do a shallow copy. Default destructor OK. @@ -1378,24 +1381,20 @@ wsrep_kill_victim( is in the queue*/ } else if (lock->trx != trx) { if (wsrep_log_conflicts) { - mutex_enter(&trx_sys->mutex); if (bf_this) { ib::info() << "*** Priority TRANSACTION:"; } else { ib::info() << "*** Victim TRANSACTION:"; } - trx_print_latched(stderr, trx, 3000); + wsrep_trx_print_locking(stderr, trx, 3000); if (bf_other) { ib::info() << "*** Priority TRANSACTION:"; } else { ib::info() << "*** Victim TRANSACTION:"; } - - trx_print_latched(stderr, lock->trx, 3000); - - mutex_exit(&trx_sys->mutex); + wsrep_trx_print_locking(stderr, lock->trx, 3000); ib::info() << "*** WAITING FOR THIS LOCK TO BE GRANTED:"; @@ -2136,25 +2135,8 @@ RecLock::deadlock_check(lock_t* lock) ut_ad(lock->trx == m_trx); ut_ad(trx_mutex_own(m_trx)); - bool async_rollback = m_trx->in_innodb & TRX_FORCE_ROLLBACK_ASYNC; - - /* This is safe, because DeadlockChecker::check_and_resolve() - is invoked when a lock wait is enqueued for the currently - running transaction. Because m_trx is a running transaction - (it is not currently suspended because of a lock wait), - its state can only be changed by this thread, which is - currently associated with the transaction. */ - - trx_mutex_exit(m_trx); - - /* If transaction is marked for ASYNC rollback then we should - not allow it to wait for another lock causing possible deadlock. - We return current transaction as deadlock victim here. */ - - const trx_t* victim_trx = async_rollback ? m_trx - : DeadlockChecker::check_and_resolve(lock, m_trx); - - trx_mutex_enter(m_trx); + const trx_t* victim_trx = + DeadlockChecker::check_and_resolve(lock, m_trx); /* Check the outcome of the deadlock test. It is possible that the transaction that blocked our lock was rolled back and we @@ -3613,18 +3595,7 @@ lock_move_reorganize_page( } } -#ifdef UNIV_DEBUG - { - ulint i = lock_rec_find_set_bit(lock); - - /* Check that all locks were moved. */ - if (i != ULINT_UNDEFINED) { - ib::fatal() << "lock_move_reorganize_page(): " - << i << " not moved in " - << (void*) lock; - } - } -#endif /* UNIV_DEBUG */ + ut_ad(lock_rec_find_set_bit(lock) == ULINT_UNDEFINED); } lock_mutex_exit(); @@ -4664,25 +4635,8 @@ lock_table_enqueue_waiting( /* Enqueue the lock request that will wait to be granted */ lock = lock_table_create(c_lock, table, mode | LOCK_WAIT, trx); - bool async_rollback = trx->in_innodb & TRX_FORCE_ROLLBACK_ASYNC; - /* Release the mutex to obey the latching order. - This is safe, because DeadlockChecker::check_and_resolve() - is invoked when a lock wait is enqueued for the currently - running transaction. Because trx is a running transaction - (it is not currently suspended because of a lock wait), - its state can only be changed by this thread, which is - currently associated with the transaction. */ - - trx_mutex_exit(trx); - - /* If transaction is marked for ASYNC rollback then we should - not allow it to wait for another lock causing possible deadlock. - We return current transaction as deadlock victim here. */ - - const trx_t* victim_trx = async_rollback ? trx - : DeadlockChecker::check_and_resolve(lock, trx); - - trx_mutex_enter(trx); + const trx_t* victim_trx = + DeadlockChecker::check_and_resolve(lock, trx); if (victim_trx != 0) { ut_ad(victim_trx == trx); @@ -6606,7 +6560,7 @@ lock_rec_block_validate( if (err != DB_SUCCESS) { ib::error() << "Lock rec block validate failed for tablespace " - << ((space && space->name) ? space->name : " system ") + << space->name << " space_id " << space_id << " page_no " << page_no << " err " << err; } @@ -8452,17 +8406,37 @@ and rolling it back. It will attempt to resolve all deadlocks. The returned transaction id will be the joining transaction instance or NULL if some other transaction was chosen as a victim and rolled back or no deadlock found. -@param lock lock the transaction is requesting -@param trx transaction requesting the lock +@param[in] lock lock the transaction is requesting +@param[in,out] trx transaction requesting the lock @return transaction instanace chosen as victim or 0 */ const trx_t* -DeadlockChecker::check_and_resolve(const lock_t* lock, const trx_t* trx) +DeadlockChecker::check_and_resolve(const lock_t* lock, trx_t* trx) { ut_ad(lock_mutex_own()); + ut_ad(trx_mutex_own(trx)); check_trx_state(trx); ut_ad(!srv_read_only_mode); + /* If transaction is marked for ASYNC rollback then we should + not allow it to wait for another lock causing possible deadlock. + We return current transaction as deadlock victim here. */ + if (trx->in_innodb & TRX_FORCE_ROLLBACK_ASYNC) { + return(trx); + } else if (!innobase_deadlock_detect) { + return(NULL); + } + + /* Release the mutex to obey the latching order. + This is safe, because DeadlockChecker::check_and_resolve() + is invoked when a lock wait is enqueued for the currently + running transaction. Because m_trx is a running transaction + (it is not currently suspended because of a lock wait), + its state can only be changed by this thread, which is + currently associated with the transaction. */ + + trx_mutex_exit(trx); + const trx_t* victim_trx; THD* start_mysql_thd; bool report_waits = false; @@ -8502,7 +8476,7 @@ DeadlockChecker::check_and_resolve(const lock_t* lock, const trx_t* trx) break; - } else if (victim_trx != 0 && victim_trx != trx) { + } else if (victim_trx != NULL && victim_trx != trx) { ut_ad(victim_trx == checker.m_wait_lock->trx); @@ -8523,6 +8497,8 @@ DeadlockChecker::check_and_resolve(const lock_t* lock, const trx_t* trx) lock_deadlock_found = true; } + trx_mutex_enter(trx); + return(victim_trx); } diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index d26886e45f9..7d4e0459610 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2009, Google Inc. Copyright (c) 2014, 2017, MariaDB Corporation. @@ -106,12 +106,6 @@ static time_t log_last_margine_warning_time; #define LOG_BUF_FLUSH_RATIO 2 #define LOG_BUF_FLUSH_MARGIN (LOG_BUF_WRITE_MARGIN + 4 * UNIV_PAGE_SIZE) -/* Margin for the free space in the smallest log group, before a new query -step which modifies the database, is started */ - -#define LOG_CHECKPOINT_FREE_PER_THREAD (4 * UNIV_PAGE_SIZE) -#define LOG_CHECKPOINT_EXTRA_FREE (8 * UNIV_PAGE_SIZE) - /* This parameter controls asynchronous making of a new checkpoint; the value should be bigger than LOG_POOL_PREFLUSH_RATIO_SYNC */ @@ -742,14 +736,11 @@ failure: if (!success) { ib::error() << "Cannot continue operation. ib_logfiles are too" - " small for innodb_thread_concurrency " + " small for innodb_thread_concurrency=" << srv_thread_concurrency << ". The combined size of" " ib_logfiles should be bigger than" - " 200 kB * innodb_thread_concurrency. To get mysqld" - " to start up, set innodb_thread_concurrency in" - " my.cnf to a lower value, for example, to 8. After" - " an ERROR-FREE shutdown of mysqld you can adjust" - " the size of ib_logfiles. " << INNODB_PARAMETERS_MSG; + " 200 kB * innodb_thread_concurrency. " + << INNODB_PARAMETERS_MSG; } return(success); @@ -2181,7 +2172,8 @@ wait_suspend_loop: bool freed = buf_all_freed(); ut_a(freed); - ut_a(lsn == log_sys->lsn); + ut_a(lsn == log_sys->lsn + || srv_force_recovery == SRV_FORCE_NO_LOG_REDO); if (lsn < srv_start_lsn) { ib::error() << "Shutdown LSN=" << lsn @@ -2207,7 +2199,8 @@ wait_suspend_loop: freed = buf_all_freed(); ut_a(freed); - ut_a(lsn == log_sys->lsn); + ut_a(lsn == log_sys->lsn + || srv_force_recovery == SRV_FORCE_NO_LOG_REDO); } /******************************************************//** diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index adf2d3aca0a..0b46c92f00a 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. Copyright (c) 2013, 2017, MariaDB Corporation. @@ -532,6 +532,7 @@ DECLARE_THREAD(recv_writer_thread)( /*!< in: a dummy parameter required by os_thread_create */ { + my_thread_init(); ut_ad(!srv_read_only_mode); #ifdef UNIV_PFS_THREAD @@ -568,6 +569,7 @@ DECLARE_THREAD(recv_writer_thread)( recv_writer_thread_active = false; + my_thread_end(); /* We count the number of threads in os_thread_exit(). A created thread should always use that to exit and not use return() to exit. */ @@ -2480,6 +2482,8 @@ loop: ulint total_len = 0; ulint n_recs = 0; + bool only_mlog_file = true; + ulint mlog_rec_len = 0; for (;;) { len = recv_parse_log_rec( @@ -2508,6 +2512,22 @@ loop: = recv_sys->recovered_offset + total_len; recv_previous_parsed_rec_is_multi = 1; + /* MLOG_FILE_NAME redo log records doesn't make changes + to persistent data. If only MLOG_FILE_NAME redo + log record exists then reset the parsing buffer pointer + by changing recovered_lsn and recovered_offset. */ + if (type != MLOG_FILE_NAME && only_mlog_file == true) { + only_mlog_file = false; + } + + if (only_mlog_file) { + new_recovered_lsn = recv_calc_lsn_on_data_add( + recv_sys->recovered_lsn, len); + mlog_rec_len += len; + recv_sys->recovered_offset += len; + recv_sys->recovered_lsn = new_recovered_lsn; + } + total_len += len; n_recs++; @@ -2521,6 +2541,7 @@ loop: " n=" ULINTPF, recv_sys->recovered_lsn, total_len, n_recs)); + total_len -= mlog_rec_len; break; } @@ -2740,6 +2761,7 @@ recv_scan_log_recs( ulint data_len; bool more_data = false; bool apply = recv_sys->mlog_checkpoint_lsn != 0; + ulint recv_parsing_buf_size = RECV_PARSING_BUF_SIZE; ut_ad(start_lsn % OS_FILE_LOG_BLOCK_SIZE == 0); ut_ad(end_lsn % OS_FILE_LOG_BLOCK_SIZE == 0); @@ -2812,8 +2834,14 @@ recv_scan_log_recs( parsing buffer if parse_start_lsn is already non-zero */ + DBUG_EXECUTE_IF( + "reduce_recv_parsing_buf", + recv_parsing_buf_size + = (70 * 1024); + ); + if (recv_sys->len + 4 * OS_FILE_LOG_BLOCK_SIZE - >= RECV_PARSING_BUF_SIZE) { + >= recv_parsing_buf_size) { ib::error() << "Log parsing buffer overflow." " Recovery may have failed!"; @@ -2863,7 +2891,7 @@ recv_scan_log_recs( *store_to_hash = STORE_NO; } - if (recv_sys->recovered_offset > RECV_PARSING_BUF_SIZE / 4) { + if (recv_sys->recovered_offset > recv_parsing_buf_size / 4) { /* Move parsing buffer data to the buffer start */ recv_sys_justify_left_parsing_buf(); @@ -2986,7 +3014,7 @@ recv_init_missing_space(dberr_t err, const recv_spaces_t::const_iterator& i) @return error code or DB_SUCCESS */ static MY_ATTRIBUTE((warn_unused_result)) dberr_t -recv_init_crash_recovery_spaces(void) +recv_init_crash_recovery_spaces() { typedef std::set<ulint> space_set_t; bool flag_deleted = false; diff --git a/storage/innobase/mach/mach0data.cc b/storage/innobase/mach/mach0data.cc index b22da00c0f1..6cb33715898 100644 --- a/storage/innobase/mach/mach0data.cc +++ b/storage/innobase/mach/mach0data.cc @@ -49,7 +49,22 @@ mach_parse_compressed( /* 0nnnnnnn (7 bits) */ ++*ptr; return(static_cast<ib_uint32_t>(val)); - } else if (val < 0xC0) { + } + + /* Workaround GCC bug + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77673: + the compiler moves mach_read_from_4 right to the beginning of the + function, causing and out-of-bounds read if we are reading a short + integer close to the end of buffer. */ +#if defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__clang__) +#define DEPLOY_FENCE +#endif + +#ifdef DEPLOY_FENCE + __atomic_thread_fence(__ATOMIC_ACQUIRE); +#endif + + if (val < 0xC0) { /* 10nnnnnn nnnnnnnn (14 bits) */ if (end_ptr >= *ptr + 2) { val = mach_read_from_2(*ptr) & 0x3FFF; @@ -57,7 +72,15 @@ mach_parse_compressed( *ptr += 2; return(static_cast<ib_uint32_t>(val)); } - } else if (val < 0xE0) { + *ptr = NULL; + return(0); + } + +#ifdef DEPLOY_FENCE + __atomic_thread_fence(__ATOMIC_ACQUIRE); +#endif + + if (val < 0xE0) { /* 110nnnnn nnnnnnnn nnnnnnnn (21 bits) */ if (end_ptr >= *ptr + 3) { val = mach_read_from_3(*ptr) & 0x1FFFFF; @@ -65,7 +88,15 @@ mach_parse_compressed( *ptr += 3; return(static_cast<ib_uint32_t>(val)); } - } else if (val < 0xF0) { + *ptr = NULL; + return(0); + } + +#ifdef DEPLOY_FENCE + __atomic_thread_fence(__ATOMIC_ACQUIRE); +#endif + + if (val < 0xF0) { /* 1110nnnn nnnnnnnn nnnnnnnn nnnnnnnn (28 bits) */ if (end_ptr >= *ptr + 4) { val = mach_read_from_4(*ptr) & 0xFFFFFFF; @@ -73,16 +104,24 @@ mach_parse_compressed( *ptr += 4; return(static_cast<ib_uint32_t>(val)); } - } else { - ut_ad(val == 0xF0); - - /* 11110000 nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn (32 bits) */ - if (end_ptr >= *ptr + 5) { - val = mach_read_from_4(*ptr + 1); - ut_ad(val > 0xFFFFFFF); - *ptr += 5; - return(static_cast<ib_uint32_t>(val)); - } + *ptr = NULL; + return(0); + } + +#ifdef DEPLOY_FENCE + __atomic_thread_fence(__ATOMIC_ACQUIRE); +#endif + +#undef DEPLOY_FENCE + + ut_ad(val == 0xF0); + + /* 11110000 nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn (32 bits) */ + if (end_ptr >= *ptr + 5) { + val = mach_read_from_4(*ptr + 1); + ut_ad(val > 0xFFFFFFF); + *ptr += 5; + return(static_cast<ib_uint32_t>(val)); } *ptr = NULL; diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index c626937b0d8..d8c7d59fe27 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -580,9 +580,13 @@ but generated some redo log on a higher level, such as MLOG_FILE_NAME records and a MLOG_CHECKPOINT marker. The caller must invoke log_mutex_enter() and log_mutex_exit(). This is to be used at log_checkpoint(). -@param[in] checkpoint_lsn the LSN of the log checkpoint */ +@param[in] checkpoint_lsn the LSN of the log checkpoint +@param[in] write_mlog_checkpoint Write MLOG_CHECKPOINT marker + if it is enabled. */ void -mtr_t::commit_checkpoint(lsn_t checkpoint_lsn) +mtr_t::commit_checkpoint( + lsn_t checkpoint_lsn, + bool write_mlog_checkpoint) { ut_ad(log_mutex_own()); ut_ad(is_active()); @@ -593,6 +597,7 @@ mtr_t::commit_checkpoint(lsn_t checkpoint_lsn) ut_ad(m_impl.m_memo.size() == 0); ut_ad(!srv_read_only_mode); ut_d(m_impl.m_state = MTR_STATE_COMMITTING); + ut_ad(write_mlog_checkpoint || m_impl.m_n_log_recs > 1); /* This is a dirty read, for debugging. */ ut_ad(!recv_no_log_write); @@ -608,20 +613,24 @@ mtr_t::commit_checkpoint(lsn_t checkpoint_lsn) &m_impl.m_log, MLOG_MULTI_REC_END, MLOG_1BYTE); } - byte* ptr = m_impl.m_log.push<byte*>(SIZE_OF_MLOG_CHECKPOINT); + if (write_mlog_checkpoint) { + byte* ptr = m_impl.m_log.push<byte*>(SIZE_OF_MLOG_CHECKPOINT); #if SIZE_OF_MLOG_CHECKPOINT != 9 # error SIZE_OF_MLOG_CHECKPOINT != 9 #endif - *ptr = MLOG_CHECKPOINT; - mach_write_to_8(ptr + 1, checkpoint_lsn); + *ptr = MLOG_CHECKPOINT; + mach_write_to_8(ptr + 1, checkpoint_lsn); + } Command cmd(this); cmd.finish_write(m_impl.m_log.size()); cmd.release_resources(); - DBUG_PRINT("ib_log", - ("MLOG_CHECKPOINT(" LSN_PF ") written at " LSN_PF, - checkpoint_lsn, log_sys->lsn)); + if (write_mlog_checkpoint) { + DBUG_PRINT("ib_log", + ("MLOG_CHECKPOINT(" LSN_PF ") written at " LSN_PF, + checkpoint_lsn, log_sys->lsn)); + } } #ifdef UNIV_DEBUG diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 43f04186f0e..110ac6f40f1 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -2,7 +2,7 @@ Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2009, Percona Inc. -Copyright (c) 2012, 2017, MariaDB Corporation. +Copyright (c) 2013, 2017, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Percona Inc.. Those modifications are @@ -687,10 +687,6 @@ ulint os_n_fsyncs; static ulint os_n_file_reads_old; static ulint os_n_file_writes_old; static ulint os_n_fsyncs_old; -/** Number of pending write operations */ -ulint os_n_pending_writes; -/** Number of pending read operations */ -ulint os_n_pending_reads; static time_t os_last_printout; bool os_has_said_disk_full; @@ -3500,7 +3496,8 @@ SyncFileIO::execute(Slot* slot) /* Wait for async io to complete */ ret = GetOverlappedResult(slot->file, &slot->control, &slot->n_bytes, TRUE); } - return(ret ? slot->n_bytes : -1); + + return(ret ? static_cast<ssize_t>(slot->n_bytes) : -1); } /* Startup/shutdown */ @@ -4945,14 +4942,11 @@ os_file_pwrite( ++os_n_file_writes; - (void) my_atomic_addlint(&os_n_pending_writes, 1); - MONITOR_ATOMIC_INC(MONITOR_OS_PENDING_WRITES); - + const bool monitor = MONITOR_IS_ON(MONITOR_OS_PENDING_WRITES); + MONITOR_ATOMIC_INC_LOW(MONITOR_OS_PENDING_WRITES, monitor); ssize_t n_bytes = os_file_io(type, file, const_cast<byte*>(buf), n, offset, err); - - (void) my_atomic_addlint(&os_n_pending_writes, -1); - MONITOR_ATOMIC_DEC(MONITOR_OS_PENDING_WRITES); + MONITOR_ATOMIC_DEC_LOW(MONITOR_OS_PENDING_WRITES, monitor); return(n_bytes); } @@ -5032,13 +5026,10 @@ os_file_pread( { ++os_n_file_reads; - (void) my_atomic_addlint(&os_n_pending_reads, 1); - MONITOR_ATOMIC_INC(MONITOR_OS_PENDING_READS); - + const bool monitor = MONITOR_IS_ON(MONITOR_OS_PENDING_READS); + MONITOR_ATOMIC_INC_LOW(MONITOR_OS_PENDING_READS, monitor); ssize_t n_bytes = os_file_io(type, file, buf, n, offset, err); - - (void) my_atomic_addlint(&os_n_pending_reads, -1); - MONITOR_ATOMIC_DEC(MONITOR_OS_PENDING_READS); + MONITOR_ATOMIC_DEC_LOW(MONITOR_OS_PENDING_READS, monitor); return(n_bytes); } @@ -7362,7 +7353,7 @@ AIO::print_segment_info( fprintf(file, ", "); } - fprintf(file, "%lu", *segments); + fprintf(file, ULINTPF, *segments); } fprintf(file, "] "); @@ -7443,8 +7434,8 @@ os_aio_print(FILE* file) double avg_bytes_read; for (ulint i = 0; i < srv_n_file_io_threads; ++i) { - fprintf(file, "I/O thread %lu state: %s (%s)", - (ulint) i, + fprintf(file, "I/O thread " ULINTPF " state: %s (%s)", + i, srv_io_thread_op_info[i], srv_io_thread_function[i]); @@ -7467,19 +7458,24 @@ os_aio_print(FILE* file) time_elapsed = 0.001 + difftime(current_time, os_last_printout); fprintf(file, - "Pending flushes (fsync) log: %lu; buffer pool: %lu\n" - "%lu OS file reads, %lu OS file writes, %lu OS fsyncs\n", - (ulint) fil_n_pending_log_flushes, - (ulint) fil_n_pending_tablespace_flushes, - (ulint) os_n_file_reads, - (ulint) os_n_file_writes, - (ulint) os_n_fsyncs); - - if (os_n_pending_writes != 0 || os_n_pending_reads != 0) { + "Pending flushes (fsync) log: " ULINTPF + "; buffer pool: " ULINTPF "\n" + ULINTPF " OS file reads, " + ULINTPF " OS file writes, " + ULINTPF " OS fsyncs\n", + fil_n_pending_log_flushes, + fil_n_pending_tablespace_flushes, + os_n_file_reads, + os_n_file_writes, + os_n_fsyncs); + + const ulint n_reads = ulint(MONITOR_VALUE(MONITOR_OS_PENDING_READS)); + const ulint n_writes = ulint(MONITOR_VALUE(MONITOR_OS_PENDING_WRITES)); + + if (n_reads != 0 || n_writes != 0) { fprintf(file, - "%lu pending preads, %lu pending pwrites\n", - (ulint) os_n_pending_reads, - (ulint) os_n_pending_writes); + ULINTPF " pending reads, " ULINTPF " pending writes\n", + n_reads, n_writes); } if (os_n_file_reads == os_n_file_reads_old) { @@ -7490,7 +7486,7 @@ os_aio_print(FILE* file) } fprintf(file, - "%.2f reads/s, %lu avg bytes/read," + "%.2f reads/s, " ULINTPF " avg bytes/read," " %.2f writes/s, %.2f fsyncs/s\n", (os_n_file_reads - os_n_file_reads_old) / time_elapsed, @@ -7545,7 +7541,7 @@ AIO::to_file(FILE* file) const { acquire(); - fprintf(file, " %lu\n", static_cast<ulint>(m_n_reserved)); + fprintf(file, " " ULINTPF "\n", m_n_reserved); for (ulint i = 0; i < m_slots.size(); ++i) { diff --git a/storage/innobase/os/os0thread.cc b/storage/innobase/os/os0thread.cc index 4012c281f8d..72199b4cf0b 100644 --- a/storage/innobase/os/os0thread.cc +++ b/storage/innobase/os/os0thread.cc @@ -161,9 +161,32 @@ os_thread_create_func( return((os_thread_t)new_thread_id); } -/** Exits the current thread. */ +/** Waits until the specified thread completes and joins it. +Its return value is ignored. +@param[in,out] thread thread to join */ void -os_thread_exit() +os_thread_join( + os_thread_id_t thread) +{ +#ifdef _WIN32 + /* Do nothing. */ +#else +#ifdef UNIV_DEBUG + const int ret = +#endif /* UNIV_DEBUG */ + pthread_join(thread, NULL); + + /* Waiting on already-quit threads is allowed. */ + ut_ad(ret == 0 || ret == ESRCH); +#endif /* _WIN32 */ +} + +/** Exits the current thread. +@param[in] detach if true, the thread will be detached right before +exiting. If false, another thread is responsible for joining this thread */ +void +os_thread_exit( + bool detach) { #ifdef UNIV_DEBUG_THREAD_CREATION ib::info() << "Thread exits, id " @@ -184,7 +207,9 @@ os_thread_exit() ExitThread(0); #else mutex_exit(&thread_mutex); - pthread_detach(pthread_self()); + if (detach) { + pthread_detach(pthread_self()); + } pthread_exit(NULL); #endif } diff --git a/storage/innobase/page/page0cur.cc b/storage/innobase/page/page0cur.cc index f2ba1c64229..df7d26c63e8 100644 --- a/storage/innobase/page/page0cur.cc +++ b/storage/innobase/page/page0cur.cc @@ -1324,7 +1324,8 @@ use_heap: data_len = rec_offs_data_size(offsets); fprintf(stderr, "InnoDB: Error: current_rec == insert_rec " - " extra_len %lu data_len %lu insert_buf %p rec %p\n", + " extra_len " ULINTPF + " data_len " ULINTPF " insert_buf %p rec %p\n", extra_len, data_len, insert_buf, rec); fprintf(stderr, "InnoDB; Physical record: \n"); rec_print(stderr, rec, index); diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc index 11b8838ce2d..e718081ed63 100644 --- a/storage/innobase/page/page0zip.cc +++ b/storage/innobase/page/page0zip.cc @@ -2,7 +2,7 @@ Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2014, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -4973,19 +4973,7 @@ ibool page_zip_verify_checksum( /*=====================*/ const void* data, /*!< in: compressed page */ - ulint size /*!< in: size of compressed page */ -#ifdef UNIV_INNOCHECKSUM - /* these variables are used only for innochecksum tool. */ - ,uintmax_t page_no, /*!< in: page number of - given read_buf */ - bool strict_check, /*!< in: true if strict-check - option is enable */ - bool is_log_enabled, /*!< in: true if log option is - enabled */ - FILE* log_file /*!< in: file pointer to - log_file */ -#endif /* UNIV_INNOCHECKSUM */ -) + ulint size) /*!< in: size of compressed page */ { const unsigned char* p = static_cast<const unsigned char*>(data) + FIL_PAGE_SPACE_OR_CHKSUM; @@ -5023,9 +5011,9 @@ page_zip_verify_checksum( break; } if (i >= size) { - if (is_log_enabled) { + if (log_file) { fprintf(log_file, "Page::%lu is empty and" - " uncorrupted\n", page_no); + " uncorrupted\n", cur_page_num); } return(TRUE); @@ -5061,28 +5049,28 @@ page_zip_verify_checksum( const uint32_t calc = page_zip_calc_checksum(data, size, curr_algo); #ifdef UNIV_INNOCHECKSUM - if (is_log_enabled) { + if (log_file) { fprintf(log_file, "page::%lu;" " %s checksum: calculated = %u;" - " recorded = %u\n", page_no, + " recorded = %u\n", cur_page_num, buf_checksum_algorithm_name( static_cast<srv_checksum_algorithm_t>( srv_checksum_algorithm)), calc, stored); } - if (!strict_check) { + if (!strict_verify) { const uint32_t crc32 = page_zip_calc_checksum( data, size, SRV_CHECKSUM_ALGORITHM_CRC32); - if (is_log_enabled) { + if (log_file) { fprintf(log_file, "page::%lu: crc32 checksum:" " calculated = %u; recorded = %u\n", - page_no, crc32, stored); + cur_page_num, crc32, stored); fprintf(log_file, "page::%lu: none checksum:" " calculated = %lu; recorded = %u\n", - page_no, BUF_NO_CHECKSUM_MAGIC, stored); + cur_page_num, BUF_NO_CHECKSUM_MAGIC, stored); } } #endif /* UNIV_INNOCHECKSUM */ diff --git a/storage/innobase/pars/pars0grm.cc b/storage/innobase/pars/pars0grm.cc index ef732209978..a0a09771106 100644 --- a/storage/innobase/pars/pars0grm.cc +++ b/storage/innobase/pars/pars0grm.cc @@ -119,104 +119,101 @@ extern int yydebug; PARS_INT_LIT = 258, PARS_FLOAT_LIT = 259, PARS_STR_LIT = 260, - PARS_FIXBINARY_LIT = 261, - PARS_BLOB_LIT = 262, - PARS_NULL_LIT = 263, - PARS_ID_TOKEN = 264, - PARS_AND_TOKEN = 265, - PARS_OR_TOKEN = 266, - PARS_NOT_TOKEN = 267, - PARS_GE_TOKEN = 268, - PARS_LE_TOKEN = 269, - PARS_NE_TOKEN = 270, - PARS_PROCEDURE_TOKEN = 271, - PARS_IN_TOKEN = 272, - PARS_OUT_TOKEN = 273, - PARS_BINARY_TOKEN = 274, - PARS_BLOB_TOKEN = 275, - PARS_INT_TOKEN = 276, - PARS_INTEGER_TOKEN = 277, - PARS_FLOAT_TOKEN = 278, - PARS_CHAR_TOKEN = 279, - PARS_IS_TOKEN = 280, - PARS_BEGIN_TOKEN = 281, - PARS_END_TOKEN = 282, - PARS_IF_TOKEN = 283, - PARS_THEN_TOKEN = 284, - PARS_ELSE_TOKEN = 285, - PARS_ELSIF_TOKEN = 286, - PARS_LOOP_TOKEN = 287, - PARS_WHILE_TOKEN = 288, - PARS_RETURN_TOKEN = 289, - PARS_SELECT_TOKEN = 290, - PARS_SUM_TOKEN = 291, - PARS_COUNT_TOKEN = 292, - PARS_DISTINCT_TOKEN = 293, - PARS_FROM_TOKEN = 294, - PARS_WHERE_TOKEN = 295, - PARS_FOR_TOKEN = 296, - PARS_DDOT_TOKEN = 297, - PARS_READ_TOKEN = 298, - PARS_ORDER_TOKEN = 299, - PARS_BY_TOKEN = 300, - PARS_ASC_TOKEN = 301, - PARS_DESC_TOKEN = 302, - PARS_INSERT_TOKEN = 303, - PARS_INTO_TOKEN = 304, - PARS_VALUES_TOKEN = 305, - PARS_UPDATE_TOKEN = 306, - PARS_SET_TOKEN = 307, - PARS_DELETE_TOKEN = 308, - PARS_CURRENT_TOKEN = 309, - PARS_OF_TOKEN = 310, - PARS_CREATE_TOKEN = 311, - PARS_TABLE_TOKEN = 312, - PARS_INDEX_TOKEN = 313, - PARS_UNIQUE_TOKEN = 314, - PARS_CLUSTERED_TOKEN = 315, - PARS_ON_TOKEN = 316, - PARS_ASSIGN_TOKEN = 317, - PARS_DECLARE_TOKEN = 318, - PARS_CURSOR_TOKEN = 319, - PARS_SQL_TOKEN = 320, - PARS_OPEN_TOKEN = 321, - PARS_FETCH_TOKEN = 322, - PARS_CLOSE_TOKEN = 323, - PARS_NOTFOUND_TOKEN = 324, - PARS_TO_CHAR_TOKEN = 325, - PARS_TO_NUMBER_TOKEN = 326, - PARS_TO_BINARY_TOKEN = 327, - PARS_BINARY_TO_NUMBER_TOKEN = 328, - PARS_SUBSTR_TOKEN = 329, - PARS_REPLSTR_TOKEN = 330, - PARS_CONCAT_TOKEN = 331, - PARS_INSTR_TOKEN = 332, - PARS_LENGTH_TOKEN = 333, - PARS_SYSDATE_TOKEN = 334, - PARS_PRINTF_TOKEN = 335, - PARS_ASSERT_TOKEN = 336, - PARS_RND_TOKEN = 337, - PARS_RND_STR_TOKEN = 338, - PARS_ROW_PRINTF_TOKEN = 339, - PARS_COMMIT_TOKEN = 340, - PARS_ROLLBACK_TOKEN = 341, - PARS_WORK_TOKEN = 342, - PARS_UNSIGNED_TOKEN = 343, - PARS_EXIT_TOKEN = 344, - PARS_FUNCTION_TOKEN = 345, - PARS_LOCK_TOKEN = 346, - PARS_SHARE_TOKEN = 347, - PARS_MODE_TOKEN = 348, - PARS_LIKE_TOKEN = 349, - PARS_LIKE_TOKEN_EXACT = 350, - PARS_LIKE_TOKEN_PREFIX = 351, - PARS_LIKE_TOKEN_SUFFIX = 352, - PARS_LIKE_TOKEN_SUBSTR = 353, - PARS_TABLE_NAME_TOKEN = 354, - PARS_COMPACT_TOKEN = 355, - PARS_BLOCK_SIZE_TOKEN = 356, - PARS_BIGINT_TOKEN = 357, - NEG = 358 + PARS_NULL_LIT = 261, + PARS_ID_TOKEN = 262, + PARS_AND_TOKEN = 263, + PARS_OR_TOKEN = 264, + PARS_NOT_TOKEN = 265, + PARS_GE_TOKEN = 266, + PARS_LE_TOKEN = 267, + PARS_NE_TOKEN = 268, + PARS_PROCEDURE_TOKEN = 269, + PARS_IN_TOKEN = 270, + PARS_OUT_TOKEN = 271, + PARS_BINARY_TOKEN = 272, + PARS_BLOB_TOKEN = 273, + PARS_INT_TOKEN = 274, + PARS_FLOAT_TOKEN = 275, + PARS_CHAR_TOKEN = 276, + PARS_IS_TOKEN = 277, + PARS_BEGIN_TOKEN = 278, + PARS_END_TOKEN = 279, + PARS_IF_TOKEN = 280, + PARS_THEN_TOKEN = 281, + PARS_ELSE_TOKEN = 282, + PARS_ELSIF_TOKEN = 283, + PARS_LOOP_TOKEN = 284, + PARS_WHILE_TOKEN = 285, + PARS_RETURN_TOKEN = 286, + PARS_SELECT_TOKEN = 287, + PARS_SUM_TOKEN = 288, + PARS_COUNT_TOKEN = 289, + PARS_DISTINCT_TOKEN = 290, + PARS_FROM_TOKEN = 291, + PARS_WHERE_TOKEN = 292, + PARS_FOR_TOKEN = 293, + PARS_DDOT_TOKEN = 294, + PARS_READ_TOKEN = 295, + PARS_ORDER_TOKEN = 296, + PARS_BY_TOKEN = 297, + PARS_ASC_TOKEN = 298, + PARS_DESC_TOKEN = 299, + PARS_INSERT_TOKEN = 300, + PARS_INTO_TOKEN = 301, + PARS_VALUES_TOKEN = 302, + PARS_UPDATE_TOKEN = 303, + PARS_SET_TOKEN = 304, + PARS_DELETE_TOKEN = 305, + PARS_CURRENT_TOKEN = 306, + PARS_OF_TOKEN = 307, + PARS_CREATE_TOKEN = 308, + PARS_TABLE_TOKEN = 309, + PARS_INDEX_TOKEN = 310, + PARS_UNIQUE_TOKEN = 311, + PARS_CLUSTERED_TOKEN = 312, + PARS_ON_TOKEN = 313, + PARS_ASSIGN_TOKEN = 314, + PARS_DECLARE_TOKEN = 315, + PARS_CURSOR_TOKEN = 316, + PARS_SQL_TOKEN = 317, + PARS_OPEN_TOKEN = 318, + PARS_FETCH_TOKEN = 319, + PARS_CLOSE_TOKEN = 320, + PARS_NOTFOUND_TOKEN = 321, + PARS_TO_CHAR_TOKEN = 322, + PARS_TO_NUMBER_TOKEN = 323, + PARS_TO_BINARY_TOKEN = 324, + PARS_BINARY_TO_NUMBER_TOKEN = 325, + PARS_SUBSTR_TOKEN = 326, + PARS_REPLSTR_TOKEN = 327, + PARS_CONCAT_TOKEN = 328, + PARS_INSTR_TOKEN = 329, + PARS_LENGTH_TOKEN = 330, + PARS_SYSDATE_TOKEN = 331, + PARS_PRINTF_TOKEN = 332, + PARS_ASSERT_TOKEN = 333, + PARS_RND_TOKEN = 334, + PARS_RND_STR_TOKEN = 335, + PARS_ROW_PRINTF_TOKEN = 336, + PARS_COMMIT_TOKEN = 337, + PARS_ROLLBACK_TOKEN = 338, + PARS_WORK_TOKEN = 339, + PARS_UNSIGNED_TOKEN = 340, + PARS_EXIT_TOKEN = 341, + PARS_FUNCTION_TOKEN = 342, + PARS_LOCK_TOKEN = 343, + PARS_SHARE_TOKEN = 344, + PARS_MODE_TOKEN = 345, + PARS_LIKE_TOKEN = 346, + PARS_LIKE_TOKEN_EXACT = 347, + PARS_LIKE_TOKEN_PREFIX = 348, + PARS_LIKE_TOKEN_SUFFIX = 349, + PARS_LIKE_TOKEN_SUBSTR = 350, + PARS_TABLE_NAME_TOKEN = 351, + PARS_COMPACT_TOKEN = 352, + PARS_BLOCK_SIZE_TOKEN = 353, + PARS_BIGINT_TOKEN = 354, + NEG = 355 }; #endif @@ -236,7 +233,7 @@ int yyparse (void); /* Copy the second part of user declarations. */ -#line 240 "pars0grm.cc" /* yacc.c:358 */ +#line 237 "pars0grm.cc" /* yacc.c:358 */ #ifdef short # undef short @@ -478,21 +475,21 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 5 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 824 +#define YYLAST 780 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 119 +#define YYNTOKENS 116 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 72 /* YYNRULES -- Number of rules. */ -#define YYNRULES 181 +#define YYNRULES 178 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 348 +#define YYNSTATES 345 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 358 +#define YYMAXUTOK 355 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -504,16 +501,16 @@ static const yytype_uint8 yytranslate[] = 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 111, 2, 2, - 113, 114, 108, 107, 116, 106, 2, 109, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 112, - 104, 103, 105, 115, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 108, 2, 2, + 110, 111, 105, 104, 113, 103, 2, 106, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 109, + 101, 100, 102, 112, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 117, 2, 118, 2, 2, 2, 2, + 2, 2, 2, 114, 2, 115, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -536,32 +533,31 @@ static const yytype_uint8 yytranslate[] = 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 110 + 95, 96, 97, 98, 99, 107 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 163, 163, 166, 167, 168, 169, 170, 171, 172, - 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, 187, 191, 192, 197, 198, 200, - 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, - 211, 212, 213, 214, 216, 217, 218, 219, 220, 221, - 222, 223, 224, 226, 231, 232, 233, 234, 236, 237, - 238, 239, 240, 241, 242, 245, 247, 248, 252, 258, - 263, 264, 265, 269, 273, 274, 279, 280, 281, 286, - 287, 288, 292, 293, 298, 304, 311, 312, 313, 318, - 320, 323, 327, 328, 332, 333, 338, 339, 344, 345, - 346, 350, 351, 358, 373, 378, 381, 389, 395, 396, - 401, 407, 416, 424, 432, 439, 447, 455, 461, 468, - 474, 475, 480, 481, 483, 487, 494, 500, 510, 514, - 518, 525, 532, 536, 544, 553, 554, 559, 560, 565, - 566, 572, 573, 579, 580, 585, 586, 591, 602, 603, - 608, 609, 613, 614, 618, 632, 633, 637, 642, 647, - 648, 649, 650, 651, 652, 656, 661, 669, 670, 671, - 676, 682, 684, 685, 689, 697, 703, 704, 707, 709, - 710, 714 + 0, 160, 160, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 188, 189, 194, 195, 197, + 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 221, 226, 227, 228, 229, 231, 232, 233, 234, + 235, 236, 237, 240, 242, 243, 247, 253, 258, 259, + 260, 264, 268, 269, 274, 275, 276, 281, 282, 283, + 287, 288, 293, 299, 306, 307, 308, 313, 315, 318, + 322, 323, 327, 328, 333, 334, 339, 340, 341, 345, + 346, 353, 368, 373, 376, 384, 390, 391, 396, 402, + 411, 419, 427, 434, 442, 450, 456, 463, 469, 470, + 475, 476, 478, 482, 489, 495, 505, 509, 513, 520, + 527, 531, 539, 548, 549, 554, 555, 560, 561, 567, + 568, 574, 575, 580, 581, 586, 597, 598, 603, 604, + 608, 609, 613, 627, 628, 632, 637, 642, 643, 644, + 645, 646, 650, 655, 663, 664, 665, 670, 676, 678, + 679, 683, 691, 697, 698, 701, 703, 704, 708 }; #endif @@ -571,19 +567,18 @@ static const yytype_uint16 yyrline[] = static const char *const yytname[] = { "$end", "error", "$undefined", "PARS_INT_LIT", "PARS_FLOAT_LIT", - "PARS_STR_LIT", "PARS_FIXBINARY_LIT", "PARS_BLOB_LIT", "PARS_NULL_LIT", - "PARS_ID_TOKEN", "PARS_AND_TOKEN", "PARS_OR_TOKEN", "PARS_NOT_TOKEN", - "PARS_GE_TOKEN", "PARS_LE_TOKEN", "PARS_NE_TOKEN", - "PARS_PROCEDURE_TOKEN", "PARS_IN_TOKEN", "PARS_OUT_TOKEN", - "PARS_BINARY_TOKEN", "PARS_BLOB_TOKEN", "PARS_INT_TOKEN", - "PARS_INTEGER_TOKEN", "PARS_FLOAT_TOKEN", "PARS_CHAR_TOKEN", - "PARS_IS_TOKEN", "PARS_BEGIN_TOKEN", "PARS_END_TOKEN", "PARS_IF_TOKEN", - "PARS_THEN_TOKEN", "PARS_ELSE_TOKEN", "PARS_ELSIF_TOKEN", - "PARS_LOOP_TOKEN", "PARS_WHILE_TOKEN", "PARS_RETURN_TOKEN", - "PARS_SELECT_TOKEN", "PARS_SUM_TOKEN", "PARS_COUNT_TOKEN", - "PARS_DISTINCT_TOKEN", "PARS_FROM_TOKEN", "PARS_WHERE_TOKEN", - "PARS_FOR_TOKEN", "PARS_DDOT_TOKEN", "PARS_READ_TOKEN", - "PARS_ORDER_TOKEN", "PARS_BY_TOKEN", "PARS_ASC_TOKEN", "PARS_DESC_TOKEN", + "PARS_STR_LIT", "PARS_NULL_LIT", "PARS_ID_TOKEN", "PARS_AND_TOKEN", + "PARS_OR_TOKEN", "PARS_NOT_TOKEN", "PARS_GE_TOKEN", "PARS_LE_TOKEN", + "PARS_NE_TOKEN", "PARS_PROCEDURE_TOKEN", "PARS_IN_TOKEN", + "PARS_OUT_TOKEN", "PARS_BINARY_TOKEN", "PARS_BLOB_TOKEN", + "PARS_INT_TOKEN", "PARS_FLOAT_TOKEN", "PARS_CHAR_TOKEN", "PARS_IS_TOKEN", + "PARS_BEGIN_TOKEN", "PARS_END_TOKEN", "PARS_IF_TOKEN", "PARS_THEN_TOKEN", + "PARS_ELSE_TOKEN", "PARS_ELSIF_TOKEN", "PARS_LOOP_TOKEN", + "PARS_WHILE_TOKEN", "PARS_RETURN_TOKEN", "PARS_SELECT_TOKEN", + "PARS_SUM_TOKEN", "PARS_COUNT_TOKEN", "PARS_DISTINCT_TOKEN", + "PARS_FROM_TOKEN", "PARS_WHERE_TOKEN", "PARS_FOR_TOKEN", + "PARS_DDOT_TOKEN", "PARS_READ_TOKEN", "PARS_ORDER_TOKEN", + "PARS_BY_TOKEN", "PARS_ASC_TOKEN", "PARS_DESC_TOKEN", "PARS_INSERT_TOKEN", "PARS_INTO_TOKEN", "PARS_VALUES_TOKEN", "PARS_UPDATE_TOKEN", "PARS_SET_TOKEN", "PARS_DELETE_TOKEN", "PARS_CURRENT_TOKEN", "PARS_OF_TOKEN", "PARS_CREATE_TOKEN", @@ -646,15 +641,15 @@ static const yytype_uint16 yytoknum[] = 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 61, 60, 62, 45, 43, 42, 47, - 358, 37, 59, 40, 41, 63, 44, 123, 125 + 61, 60, 62, 45, 43, 42, 47, 355, 37, 59, + 40, 41, 63, 44, 123, 125 }; # endif -#define YYPACT_NINF -179 +#define YYPACT_NINF -176 #define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-179))) + (!!((Yystate) == (-176))) #define YYTABLE_NINF -1 @@ -665,41 +660,41 @@ static const yytype_uint16 yytoknum[] = STATE-NUM. */ static const yytype_int16 yypact[] = { - 35, 50, 72, -37, -36, -179, -179, 67, 49, -179, - -78, 13, 13, 53, 67, -179, -179, -179, -179, -179, - -179, -179, -179, 76, -179, 13, -179, 7, -31, -34, - -179, -179, -179, -179, -14, -179, 77, 83, 583, -179, - 78, -10, 42, 284, 284, -179, 17, 96, 58, 2, - 69, -16, 105, 107, 108, -179, -179, -179, 84, 31, - 37, -179, 113, -179, 403, -179, 14, 15, 19, -4, - 21, 89, 23, 24, 89, 25, 26, 32, 33, 44, - 45, 47, 51, 52, 54, 55, 56, 57, 60, 62, - 63, 84, -179, 284, -179, -179, -179, -179, -179, -179, - 43, 284, 59, -179, -179, -179, -179, -179, -179, -179, - -179, -179, -179, -179, 284, 284, 571, 70, 612, 73, - 74, -179, 699, -179, -45, 95, 145, 2, -179, -179, - 136, 2, 2, -179, 129, -179, 116, -179, -179, -179, - -179, 79, -179, -179, -179, 284, -179, 80, -179, -179, - 194, -179, -179, -179, -179, -179, -179, -179, -179, -179, - -179, -179, -179, -179, -179, -179, -179, -179, -179, -179, - -179, -179, -179, 82, 699, 121, 715, 122, 3, 210, - 284, 284, 284, 284, 284, 583, 190, 284, 284, 284, - 284, 284, 284, 284, 284, 583, 284, -29, 187, 173, - 2, 284, -179, 195, -179, 92, -179, 149, 199, 97, - 699, -72, 284, 156, 699, -179, -179, -179, -179, 715, - 715, 4, 4, 699, 343, -179, 4, 4, 4, 12, - 12, 3, 3, -69, 463, 226, 204, 101, -179, 100, - -179, -32, -179, 642, 114, -179, 103, 217, 218, 117, - -179, 100, -179, -66, -179, 284, -59, 220, 583, 284, - -179, 202, 207, -179, 203, -179, 128, -179, 244, 284, - 2, 216, 284, 284, 195, 13, -179, -52, 200, 146, - 144, 154, 699, -179, -179, 583, 672, -179, 246, -179, - -179, -179, -179, 224, 189, 679, 699, -179, 165, 181, - 217, 2, -179, -179, -179, 583, -179, -179, 265, 239, - 583, 281, 197, -179, 193, -179, 182, 583, 205, 253, - -179, 523, 185, -179, 289, 206, -179, 293, 212, 294, - 274, -179, 300, -179, 307, -179, -51, -179, 22, -179, - -179, -179, -179, 302, -179, -179, -179, -179 + 20, 21, 41, -64, -59, -176, -176, 48, 54, -176, + -74, 12, 12, 45, 48, -176, -176, -176, -176, -176, + -176, -176, 69, -176, 12, -176, 8, -32, -43, -176, + -176, -176, -176, -13, -176, 72, 81, 445, -176, 75, + -11, 42, 530, 530, -176, 16, 99, 67, -3, 78, + -14, 108, 109, 110, -176, -176, -176, 86, 36, 44, + -176, 122, -176, 216, -176, 22, 23, 25, 6, 26, + 93, 27, 33, 93, 46, 51, 53, 56, 61, 63, + 64, 66, 68, 70, 71, 76, 79, 89, 94, 95, + 86, -176, 530, -176, -176, -176, -176, 43, 530, 49, + -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, + -176, 530, 530, 570, 77, 603, 80, 96, -176, 674, + -176, -38, 118, 161, -3, -176, -176, 129, -3, -3, + -176, 148, -176, 163, -176, -176, -176, -176, 97, -176, + -176, -176, 530, -176, 100, -176, -176, 481, -176, -176, + -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, + -176, -176, -176, -176, -176, -176, -176, -176, -176, -176, + 102, 674, 149, 220, 155, 14, 91, 530, 530, 530, + 530, 530, 445, 219, 530, 530, 530, 530, 530, 530, + 530, 530, 445, 530, -24, 218, 267, -3, 530, -176, + 221, -176, 117, -176, 179, 228, 124, 674, -65, 530, + 185, 674, -176, -176, -176, -176, 220, 220, 19, 19, + 674, 136, -176, 19, 19, 19, 3, 3, 14, 14, + -57, 326, 554, 231, 128, -176, 130, -176, -1, -176, + 610, 142, -176, 131, 238, 242, 141, -176, 130, -176, + -52, -176, 530, -51, 246, 445, 530, -176, 227, 233, + -176, 229, -176, 151, -176, 252, 530, -3, 225, 530, + 530, 221, 12, -176, -48, 207, 156, 153, 164, 674, + -176, -176, 445, 626, -176, 250, -176, -176, -176, -176, + 230, 194, 655, 674, -176, 173, 187, 238, -3, -176, + -176, -176, 445, -176, -176, 270, 245, 445, 284, 204, + -176, 192, -176, 181, 445, 203, 253, -176, 386, 193, + -176, 286, 205, -176, 296, 217, 299, 279, -176, 303, + -176, 307, -176, -47, -176, 30, -176, -176, -176, -176, + 305, -176, -176, -176, -176 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -707,67 +702,67 @@ static const yytype_int16 yypact[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 0, 0, 0, 0, 0, 1, 2, 167, 0, 168, - 0, 0, 0, 0, 0, 163, 164, 159, 160, 162, - 161, 165, 166, 171, 169, 0, 172, 178, 0, 0, - 173, 176, 177, 179, 0, 170, 0, 0, 0, 180, - 0, 0, 0, 0, 0, 129, 86, 0, 0, 0, - 0, 150, 0, 0, 0, 70, 71, 72, 0, 0, - 0, 128, 0, 25, 0, 3, 0, 0, 0, 0, - 0, 92, 0, 0, 92, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 2, 164, 0, 165, + 0, 0, 0, 0, 0, 160, 161, 157, 159, 158, + 162, 163, 168, 166, 0, 169, 175, 0, 0, 170, + 173, 174, 176, 0, 167, 0, 0, 0, 177, 0, + 0, 0, 0, 0, 127, 84, 0, 0, 0, 0, + 148, 0, 0, 0, 68, 69, 70, 0, 0, 0, + 126, 0, 25, 0, 3, 0, 0, 0, 0, 0, + 90, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 175, 0, 29, 30, 31, 32, 33, 34, - 27, 0, 35, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 0, 0, 0, 0, 0, 0, - 0, 89, 82, 87, 91, 0, 0, 0, 155, 156, - 0, 0, 0, 151, 152, 130, 0, 131, 117, 157, - 158, 0, 181, 26, 4, 79, 11, 0, 106, 12, - 0, 112, 113, 16, 17, 115, 116, 14, 15, 13, - 10, 8, 5, 6, 7, 9, 18, 20, 19, 23, - 24, 21, 22, 0, 118, 0, 51, 0, 40, 0, + 0, 172, 0, 29, 30, 31, 32, 27, 0, 33, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 0, 0, 0, 0, 0, 0, 0, 87, 80, + 85, 89, 0, 0, 0, 153, 154, 0, 0, 0, + 149, 150, 128, 0, 129, 115, 155, 156, 0, 178, + 26, 4, 77, 11, 0, 104, 12, 0, 110, 111, + 16, 17, 113, 114, 14, 15, 13, 10, 8, 5, + 6, 7, 9, 18, 20, 19, 23, 24, 21, 22, + 0, 116, 0, 49, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 79, 0, 0, 0, 76, 0, - 0, 0, 104, 0, 114, 0, 153, 0, 76, 65, - 80, 0, 79, 0, 93, 174, 52, 53, 41, 49, - 50, 46, 47, 48, 122, 43, 42, 44, 45, 37, - 36, 38, 39, 0, 0, 0, 0, 0, 77, 90, - 88, 92, 74, 0, 0, 108, 111, 0, 0, 77, - 133, 132, 66, 0, 69, 0, 0, 0, 0, 0, - 120, 124, 0, 28, 0, 85, 0, 83, 0, 0, - 0, 94, 0, 0, 0, 0, 135, 0, 0, 0, - 0, 0, 81, 105, 110, 123, 0, 121, 0, 126, - 84, 78, 75, 0, 96, 0, 107, 109, 137, 143, - 0, 0, 73, 68, 67, 0, 125, 95, 0, 101, - 0, 0, 139, 144, 145, 136, 0, 119, 0, 0, - 103, 0, 0, 140, 141, 0, 147, 0, 0, 0, - 0, 138, 0, 134, 0, 148, 0, 97, 98, 127, - 142, 146, 154, 0, 99, 100, 102, 149 + 0, 77, 0, 0, 0, 74, 0, 0, 0, 102, + 0, 112, 0, 151, 0, 74, 63, 78, 0, 77, + 0, 91, 171, 50, 51, 39, 47, 48, 44, 45, + 46, 120, 41, 40, 42, 43, 35, 34, 36, 37, + 0, 0, 0, 0, 0, 75, 88, 86, 90, 72, + 0, 0, 106, 109, 0, 0, 75, 131, 130, 64, + 0, 67, 0, 0, 0, 0, 0, 118, 122, 0, + 28, 0, 83, 0, 81, 0, 0, 0, 92, 0, + 0, 0, 0, 133, 0, 0, 0, 0, 0, 79, + 103, 108, 121, 0, 119, 0, 124, 82, 76, 73, + 0, 94, 0, 105, 107, 135, 141, 0, 0, 71, + 66, 65, 0, 123, 93, 0, 99, 0, 0, 137, + 142, 143, 134, 0, 117, 0, 0, 101, 0, 0, + 138, 139, 0, 145, 0, 0, 0, 0, 136, 0, + 132, 0, 146, 0, 95, 96, 125, 140, 144, 152, + 0, 97, 98, 100, 147 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -179, -179, -63, -178, -41, -179, -179, -179, -179, -179, - -179, -179, 104, -154, 123, -179, -179, -68, -179, -179, - -179, -179, -30, -179, -179, 64, -179, 247, -179, -179, - -179, -179, -179, -179, -179, -179, 65, -179, -179, -179, - -179, -179, -179, -179, -179, -179, -179, 27, -179, -179, - -179, -179, -179, -179, -179, -179, -179, -179, -179, -117, - -179, -179, -12, 309, -179, 298, -179, -179, -179, 303, - -179, -179 + -176, -176, -62, -175, -40, -176, -176, -176, -176, -176, + -176, -176, 111, -166, 119, -176, -176, -67, -176, -176, + -176, -176, -33, -176, -176, 47, -176, 240, -176, -176, + -176, -176, -176, -176, -176, -176, 59, -176, -176, -176, + -176, -176, -176, -176, -176, -176, -176, 17, -176, -176, + -176, -176, -176, -176, -176, -176, -176, -176, -176, -115, + -176, -176, -12, 313, -176, 293, -176, -176, -176, 295, + -176, -176 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 2, 63, 64, 210, 117, 253, 65, 66, 67, - 250, 241, 239, 211, 123, 124, 125, 151, 294, 309, - 346, 320, 68, 69, 70, 245, 246, 152, 71, 72, - 73, 74, 75, 76, 77, 78, 260, 261, 262, 79, - 80, 81, 82, 83, 84, 85, 86, 276, 277, 312, - 324, 333, 314, 326, 87, 336, 134, 207, 88, 130, - 89, 90, 21, 9, 10, 26, 27, 31, 32, 33, - 34, 3 + -1, 2, 62, 63, 207, 114, 250, 64, 65, 66, + 247, 238, 236, 208, 120, 121, 122, 148, 291, 306, + 343, 317, 67, 68, 69, 242, 243, 149, 70, 71, + 72, 73, 74, 75, 76, 77, 257, 258, 259, 78, + 79, 80, 81, 82, 83, 84, 85, 273, 274, 309, + 321, 330, 311, 323, 86, 333, 131, 204, 87, 127, + 88, 89, 20, 9, 10, 25, 26, 30, 31, 32, + 33, 3 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -775,241 +770,232 @@ static const yytype_int16 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_uint16 yytable[] = { - 22, 143, 116, 118, 198, 122, 155, 224, 269, 236, - 202, 128, 38, 28, 204, 205, 25, 234, 184, 184, - 94, 95, 96, 97, 98, 99, 100, 184, 138, 101, - 36, 46, 15, 16, 17, 18, 13, 19, 14, 148, - 233, 132, 254, 133, 255, 263, 147, 255, 280, 29, - 281, 1, 174, 119, 120, 283, 37, 255, 256, 4, - 176, 173, 299, 342, 300, 343, 11, 12, 344, 345, - 29, 199, 5, 178, 179, 6, 8, 7, 23, 237, - 285, 35, 102, 242, 270, 25, 40, 103, 104, 105, - 106, 107, 41, 108, 109, 110, 111, 186, 186, 112, - 113, 129, 92, 91, 93, 126, 186, 127, 131, 214, - 190, 191, 192, 193, 135, 20, 136, 137, 139, 46, - 192, 193, 141, 114, 140, 121, 144, 317, 145, 150, - 115, 146, 321, 149, 200, 153, 154, 157, 158, 219, - 220, 221, 222, 223, 159, 160, 226, 227, 228, 229, - 230, 231, 232, 292, 175, 235, 161, 162, 122, 163, - 243, 143, 201, 164, 165, 208, 166, 167, 168, 169, - 177, 143, 170, 271, 171, 172, 94, 95, 96, 97, - 98, 99, 100, 194, 316, 101, 196, 197, 203, 206, - 216, 217, 209, 212, 215, 225, 238, 94, 95, 96, - 97, 98, 99, 100, 244, 247, 101, 248, 249, 119, - 120, 257, 252, 266, 282, 267, 268, 273, 286, 274, - 180, 181, 143, 182, 183, 184, 275, 278, 214, 284, - 279, 295, 296, 259, 288, 289, 180, 181, 102, 182, - 183, 184, 290, 103, 104, 105, 106, 107, 213, 108, - 109, 110, 111, 291, 143, 112, 113, 293, 143, 102, - 302, 301, 303, 298, 103, 104, 105, 106, 107, 304, - 108, 109, 110, 111, 306, 307, 112, 113, 311, 114, - 308, 313, 318, 319, 322, 323, 115, 94, 95, 96, - 97, 98, 99, 100, 325, 327, 101, 328, 329, 331, - 114, 332, 335, 338, 186, 337, 339, 115, 340, 334, - 341, 347, 251, 187, 188, 189, 190, 191, 192, 193, - 186, 156, 240, 24, 218, 30, 287, 315, 0, 187, - 188, 189, 190, 191, 192, 193, 0, 39, 297, 0, - 265, 0, 0, 0, 0, 0, 0, 0, 0, 102, - 0, 0, 42, 0, 103, 104, 105, 106, 107, 0, - 108, 109, 110, 111, 0, 0, 112, 113, 0, 0, - 0, 43, 0, 258, 259, 0, 44, 45, 46, 0, - 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, - 114, 48, 0, 0, 49, 0, 50, 115, 0, 51, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, - 53, 54, 42, 0, 0, 0, 0, 0, 55, 0, - 0, 0, 0, 56, 57, 0, 0, 58, 59, 60, - 142, 43, 61, 0, 0, 0, 44, 45, 46, 0, - 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, - 0, 48, 0, 0, 49, 0, 50, 0, 0, 51, - 62, 0, 0, 0, 0, 0, 0, 0, 0, 52, - 53, 54, 42, 0, 0, 0, 0, 0, 55, 0, - 0, 0, 0, 56, 57, 0, 0, 58, 59, 60, - 264, 43, 61, 0, 0, 0, 44, 45, 46, 0, - 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, - 0, 48, 0, 0, 49, 0, 50, 0, 0, 51, - 62, 0, 0, 0, 0, 0, 0, 0, 0, 52, - 53, 54, 42, 0, 0, 0, 0, 0, 55, 0, - 0, 0, 0, 56, 57, 0, 0, 58, 59, 60, - 330, 43, 61, 0, 0, 0, 44, 45, 46, 0, - 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, - 0, 48, 0, 0, 49, 0, 50, 0, 0, 51, - 62, 180, 181, 0, 182, 183, 184, 0, 0, 52, - 53, 54, 42, 0, 0, 0, 0, 0, 55, 0, - 185, 0, 0, 56, 57, 0, 0, 58, 59, 60, - 0, 43, 61, 0, 0, 0, 44, 45, 46, 0, - 0, 0, 180, 181, 47, 182, 183, 184, 0, 0, - 0, 48, 0, 0, 49, 0, 50, 0, 0, 51, - 62, 0, 0, 0, 195, 0, 0, 0, 0, 52, - 53, 54, 180, 181, 0, 182, 183, 184, 55, 0, - 0, 0, 0, 56, 57, 186, 0, 58, 59, 60, - 0, 0, 61, 0, 187, 188, 189, 190, 191, 192, - 193, 0, 180, 181, 272, 182, 183, 184, 0, 180, - 181, 0, 182, 183, 184, 0, 0, 0, 0, 0, - 62, 305, 0, 0, 0, 0, 186, 0, 0, 180, - 181, 310, 182, 183, 184, 187, 188, 189, 190, 191, - 192, 193, 0, 0, 0, 0, 0, 0, 182, 183, - 184, 0, 0, 0, 0, 0, 186, 0, 0, 0, - 0, 0, 0, 0, 0, 187, 188, 189, 190, 191, - 192, 193, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, - 0, 0, 0, 186, 0, 187, 188, 189, 190, 191, - 192, 193, 187, 188, 189, 190, 191, 192, 193, 0, - 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, - 0, 0, 187, 188, 189, 190, 191, 192, 193, 186, - 0, 0, 0, 0, 0, 0, 0, 0, 187, 188, - 189, 190, 191, 192, 193 + 21, 140, 113, 115, 125, 119, 152, 221, 195, 199, + 37, 233, 27, 201, 202, 24, 181, 231, 35, 93, + 94, 95, 96, 97, 135, 230, 98, 181, 4, 15, + 16, 17, 181, 18, 1, 145, 266, 13, 45, 14, + 129, 5, 130, 253, 36, 6, 251, 28, 252, 116, + 117, 7, 171, 144, 260, 8, 252, 170, 173, 277, + 280, 278, 252, 296, 339, 297, 340, 22, 28, 11, + 12, 175, 176, 341, 342, 196, 24, 34, 99, 39, + 282, 234, 239, 100, 101, 102, 103, 104, 40, 105, + 106, 107, 108, 126, 183, 109, 110, 90, 91, 177, + 178, 92, 179, 180, 181, 183, 123, 211, 189, 190, + 183, 19, 267, 124, 128, 132, 133, 134, 45, 111, + 136, 118, 187, 188, 189, 190, 112, 314, 137, 138, + 147, 141, 318, 142, 143, 146, 150, 216, 217, 218, + 219, 220, 151, 41, 223, 224, 225, 226, 227, 228, + 229, 172, 289, 232, 197, 154, 119, 174, 240, 140, + 155, 42, 156, 255, 256, 157, 43, 44, 45, 140, + 158, 268, 159, 160, 46, 161, 198, 162, 200, 163, + 164, 47, 183, 313, 48, 165, 49, 191, 166, 50, + 193, 184, 185, 186, 187, 188, 189, 190, 167, 51, + 52, 53, 215, 168, 169, 203, 194, 206, 54, 205, + 209, 212, 279, 55, 56, 213, 283, 57, 58, 59, + 140, 214, 60, 41, 222, 235, 211, 244, 241, 292, + 293, 179, 180, 181, 245, 246, 249, 254, 263, 264, + 139, 42, 270, 265, 271, 272, 43, 44, 45, 275, + 61, 276, 140, 281, 46, 256, 140, 285, 286, 288, + 295, 47, 287, 290, 48, 298, 49, 299, 300, 50, + 93, 94, 95, 96, 97, 303, 301, 98, 304, 51, + 52, 53, 305, 308, 310, 315, 316, 319, 54, 320, + 322, 324, 325, 55, 56, 326, 329, 57, 58, 59, + 116, 117, 60, 332, 328, 331, 335, 334, 336, 337, + 338, 183, 344, 153, 312, 237, 248, 284, 294, 29, + 184, 185, 186, 187, 188, 189, 190, 23, 38, 99, + 61, 0, 0, 41, 100, 101, 102, 103, 104, 0, + 105, 106, 107, 108, 0, 0, 109, 110, 0, 0, + 261, 42, 0, 0, 0, 0, 43, 44, 45, 0, + 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, + 111, 47, 0, 0, 48, 0, 49, 112, 0, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, + 52, 53, 0, 41, 0, 0, 0, 0, 54, 0, + 0, 0, 0, 55, 56, 0, 0, 57, 58, 59, + 327, 42, 60, 0, 0, 0, 43, 44, 45, 0, + 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, + 0, 47, 0, 0, 48, 0, 49, 0, 0, 50, + 61, 0, 0, 0, 0, 0, 0, 0, 0, 51, + 52, 53, 41, 0, 0, 0, 0, 0, 54, 0, + 0, 0, 0, 55, 56, 0, 0, 57, 58, 59, + 42, 0, 60, 0, 0, 43, 44, 45, 0, 0, + 0, 0, 0, 46, 93, 94, 95, 96, 97, 0, + 47, 98, 0, 48, 0, 49, 0, 0, 50, 0, + 61, 0, 0, 0, 0, 0, 0, 0, 51, 52, + 53, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 0, 0, 55, 56, 0, 0, 57, 58, 59, 0, + 0, 60, 210, 93, 94, 95, 96, 97, 0, 0, + 98, 0, 0, 99, 0, 0, 0, 0, 100, 101, + 102, 103, 104, 0, 105, 106, 107, 108, 0, 61, + 109, 110, 177, 178, 0, 179, 180, 181, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 177, 178, + 0, 179, 180, 181, 111, 0, 0, 0, 0, 0, + 0, 112, 99, 0, 0, 0, 182, 100, 101, 102, + 103, 104, 0, 105, 106, 107, 108, 0, 0, 109, + 110, 177, 178, 0, 179, 180, 181, 0, 177, 178, + 0, 179, 180, 181, 0, 0, 0, 0, 0, 0, + 0, 0, 192, 111, 177, 178, 0, 179, 180, 181, + 112, 0, 0, 0, 0, 183, 0, 0, 0, 269, + 0, 0, 302, 0, 184, 185, 186, 187, 188, 189, + 190, 183, 0, 177, 178, 262, 179, 180, 181, 0, + 184, 185, 186, 187, 188, 189, 190, 0, 0, 0, + 0, 0, 177, 178, 307, 179, 180, 181, 0, 0, + 0, 0, 0, 0, 183, 0, 0, 0, 0, 0, + 0, 183, 0, 184, 185, 186, 187, 188, 189, 190, + 184, 185, 186, 187, 188, 189, 190, 183, 0, 0, + 0, 0, 0, 0, 0, 0, 184, 185, 186, 187, + 188, 189, 190, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 183, 0, 0, 0, + 0, 0, 0, 0, 0, 184, 185, 186, 187, 188, + 189, 190, 0, 0, 0, 183, 0, 0, 0, 0, + 0, 0, 0, 0, 184, 185, 186, 187, 188, 189, + 190 }; static const yytype_int16 yycheck[] = { - 12, 64, 43, 44, 49, 46, 74, 185, 40, 38, - 127, 9, 26, 25, 131, 132, 9, 195, 15, 15, - 3, 4, 5, 6, 7, 8, 9, 15, 58, 12, - 64, 35, 19, 20, 21, 22, 114, 24, 116, 69, - 194, 57, 114, 59, 116, 114, 50, 116, 114, 63, - 116, 16, 93, 36, 37, 114, 90, 116, 212, 9, - 101, 91, 114, 114, 116, 116, 17, 18, 46, 47, - 63, 116, 0, 114, 115, 112, 9, 113, 25, 108, - 258, 112, 65, 200, 116, 9, 9, 70, 71, 72, - 73, 74, 9, 76, 77, 78, 79, 94, 94, 82, - 83, 99, 112, 25, 62, 9, 94, 49, 39, 150, - 106, 107, 108, 109, 9, 102, 9, 9, 87, 35, - 108, 109, 9, 106, 87, 108, 112, 305, 113, 40, - 113, 112, 310, 112, 39, 112, 112, 112, 112, 180, - 181, 182, 183, 184, 112, 112, 187, 188, 189, 190, - 191, 192, 193, 270, 111, 196, 112, 112, 199, 112, - 201, 224, 17, 112, 112, 49, 112, 112, 112, 112, - 111, 234, 112, 241, 112, 112, 3, 4, 5, 6, - 7, 8, 9, 113, 301, 12, 113, 113, 52, 60, - 69, 69, 113, 113, 112, 5, 9, 3, 4, 5, - 6, 7, 8, 9, 9, 113, 12, 58, 9, 36, - 37, 55, 115, 9, 255, 114, 116, 103, 259, 116, - 10, 11, 285, 13, 14, 15, 9, 9, 269, 9, - 113, 272, 273, 31, 27, 32, 10, 11, 65, 13, - 14, 15, 114, 70, 71, 72, 73, 74, 54, 76, - 77, 78, 79, 9, 317, 82, 83, 41, 321, 65, - 114, 61, 118, 275, 70, 71, 72, 73, 74, 115, - 76, 77, 78, 79, 28, 51, 82, 83, 113, 106, - 91, 100, 17, 44, 3, 88, 113, 3, 4, 5, - 6, 7, 8, 9, 101, 113, 12, 92, 45, 114, - 106, 12, 9, 9, 94, 93, 32, 113, 8, 103, - 3, 9, 208, 103, 104, 105, 106, 107, 108, 109, - 94, 74, 199, 14, 114, 27, 261, 300, -1, 103, - 104, 105, 106, 107, 108, 109, -1, 34, 274, -1, - 114, -1, -1, -1, -1, -1, -1, -1, -1, 65, - -1, -1, 9, -1, 70, 71, 72, 73, 74, -1, - 76, 77, 78, 79, -1, -1, 82, 83, -1, -1, - -1, 28, -1, 30, 31, -1, 33, 34, 35, -1, - -1, -1, -1, -1, 41, -1, -1, -1, -1, -1, - 106, 48, -1, -1, 51, -1, 53, 113, -1, 56, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 66, - 67, 68, 9, -1, -1, -1, -1, -1, 75, -1, - -1, -1, -1, 80, 81, -1, -1, 84, 85, 86, - 27, 28, 89, -1, -1, -1, 33, 34, 35, -1, - -1, -1, -1, -1, 41, -1, -1, -1, -1, -1, - -1, 48, -1, -1, 51, -1, 53, -1, -1, 56, - 117, -1, -1, -1, -1, -1, -1, -1, -1, 66, - 67, 68, 9, -1, -1, -1, -1, -1, 75, -1, - -1, -1, -1, 80, 81, -1, -1, 84, 85, 86, - 27, 28, 89, -1, -1, -1, 33, 34, 35, -1, - -1, -1, -1, -1, 41, -1, -1, -1, -1, -1, - -1, 48, -1, -1, 51, -1, 53, -1, -1, 56, - 117, -1, -1, -1, -1, -1, -1, -1, -1, 66, - 67, 68, 9, -1, -1, -1, -1, -1, 75, -1, - -1, -1, -1, 80, 81, -1, -1, 84, 85, 86, - 27, 28, 89, -1, -1, -1, 33, 34, 35, -1, - -1, -1, -1, -1, 41, -1, -1, -1, -1, -1, - -1, 48, -1, -1, 51, -1, 53, -1, -1, 56, - 117, 10, 11, -1, 13, 14, 15, -1, -1, 66, - 67, 68, 9, -1, -1, -1, -1, -1, 75, -1, - 29, -1, -1, 80, 81, -1, -1, 84, 85, 86, - -1, 28, 89, -1, -1, -1, 33, 34, 35, -1, - -1, -1, 10, 11, 41, 13, 14, 15, -1, -1, - -1, 48, -1, -1, 51, -1, 53, -1, -1, 56, - 117, -1, -1, -1, 32, -1, -1, -1, -1, 66, - 67, 68, 10, 11, -1, 13, 14, 15, 75, -1, - -1, -1, -1, 80, 81, 94, -1, 84, 85, 86, - -1, -1, 89, -1, 103, 104, 105, 106, 107, 108, - 109, -1, 10, 11, 42, 13, 14, 15, -1, 10, - 11, -1, 13, 14, 15, -1, -1, -1, -1, -1, - 117, 29, -1, -1, -1, -1, 94, -1, -1, 10, - 11, 32, 13, 14, 15, 103, 104, 105, 106, 107, - 108, 109, -1, -1, -1, -1, -1, -1, 13, 14, - 15, -1, -1, -1, -1, -1, 94, -1, -1, -1, - -1, -1, -1, -1, -1, 103, 104, 105, 106, 107, - 108, 109, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 94, -1, -1, -1, - -1, -1, -1, 94, -1, 103, 104, 105, 106, 107, - 108, 109, 103, 104, 105, 106, 107, 108, 109, -1, - -1, -1, -1, 94, -1, -1, -1, -1, -1, -1, - -1, -1, 103, 104, 105, 106, 107, 108, 109, 94, - -1, -1, -1, -1, -1, -1, -1, -1, 103, 104, - 105, 106, 107, 108, 109 + 12, 63, 42, 43, 7, 45, 73, 182, 46, 124, + 23, 35, 24, 128, 129, 7, 13, 192, 61, 3, + 4, 5, 6, 7, 57, 191, 10, 13, 7, 17, + 18, 19, 13, 21, 14, 68, 37, 111, 32, 113, + 54, 0, 56, 209, 87, 109, 111, 60, 113, 33, + 34, 110, 92, 47, 111, 7, 113, 90, 98, 111, + 111, 113, 113, 111, 111, 113, 113, 22, 60, 15, + 16, 111, 112, 43, 44, 113, 7, 109, 62, 7, + 255, 105, 197, 67, 68, 69, 70, 71, 7, 73, + 74, 75, 76, 96, 91, 79, 80, 22, 109, 8, + 9, 59, 11, 12, 13, 91, 7, 147, 105, 106, + 91, 99, 113, 46, 36, 7, 7, 7, 32, 103, + 84, 105, 103, 104, 105, 106, 110, 302, 84, 7, + 37, 109, 307, 110, 109, 109, 109, 177, 178, 179, + 180, 181, 109, 7, 184, 185, 186, 187, 188, 189, + 190, 108, 267, 193, 36, 109, 196, 108, 198, 221, + 109, 25, 109, 27, 28, 109, 30, 31, 32, 231, + 109, 238, 109, 109, 38, 109, 15, 109, 49, 109, + 109, 45, 91, 298, 48, 109, 50, 110, 109, 53, + 110, 100, 101, 102, 103, 104, 105, 106, 109, 63, + 64, 65, 111, 109, 109, 57, 110, 110, 72, 46, + 110, 109, 252, 77, 78, 66, 256, 81, 82, 83, + 282, 66, 86, 7, 5, 7, 266, 110, 7, 269, + 270, 11, 12, 13, 55, 7, 112, 52, 7, 111, + 24, 25, 100, 113, 113, 7, 30, 31, 32, 7, + 114, 110, 314, 7, 38, 28, 318, 24, 29, 7, + 272, 45, 111, 38, 48, 58, 50, 111, 115, 53, + 3, 4, 5, 6, 7, 25, 112, 10, 48, 63, + 64, 65, 88, 110, 97, 15, 41, 3, 72, 85, + 98, 110, 89, 77, 78, 42, 10, 81, 82, 83, + 33, 34, 86, 7, 111, 100, 7, 90, 29, 6, + 3, 91, 7, 73, 297, 196, 205, 258, 271, 26, + 100, 101, 102, 103, 104, 105, 106, 14, 33, 62, + 114, -1, -1, 7, 67, 68, 69, 70, 71, -1, + 73, 74, 75, 76, -1, -1, 79, 80, -1, -1, + 24, 25, -1, -1, -1, -1, 30, 31, 32, -1, + -1, -1, -1, -1, 38, -1, -1, -1, -1, -1, + 103, 45, -1, -1, 48, -1, 50, 110, -1, 53, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 63, + 64, 65, -1, 7, -1, -1, -1, -1, 72, -1, + -1, -1, -1, 77, 78, -1, -1, 81, 82, 83, + 24, 25, 86, -1, -1, -1, 30, 31, 32, -1, + -1, -1, -1, -1, 38, -1, -1, -1, -1, -1, + -1, 45, -1, -1, 48, -1, 50, -1, -1, 53, + 114, -1, -1, -1, -1, -1, -1, -1, -1, 63, + 64, 65, 7, -1, -1, -1, -1, -1, 72, -1, + -1, -1, -1, 77, 78, -1, -1, 81, 82, 83, + 25, -1, 86, -1, -1, 30, 31, 32, -1, -1, + -1, -1, -1, 38, 3, 4, 5, 6, 7, -1, + 45, 10, -1, 48, -1, 50, -1, -1, 53, -1, + 114, -1, -1, -1, -1, -1, -1, -1, 63, 64, + 65, -1, -1, -1, -1, -1, -1, 72, -1, -1, + -1, -1, 77, 78, -1, -1, 81, 82, 83, -1, + -1, 86, 51, 3, 4, 5, 6, 7, -1, -1, + 10, -1, -1, 62, -1, -1, -1, -1, 67, 68, + 69, 70, 71, -1, 73, 74, 75, 76, -1, 114, + 79, 80, 8, 9, -1, 11, 12, 13, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 8, 9, + -1, 11, 12, 13, 103, -1, -1, -1, -1, -1, + -1, 110, 62, -1, -1, -1, 26, 67, 68, 69, + 70, 71, -1, 73, 74, 75, 76, -1, -1, 79, + 80, 8, 9, -1, 11, 12, 13, -1, 8, 9, + -1, 11, 12, 13, -1, -1, -1, -1, -1, -1, + -1, -1, 29, 103, 8, 9, -1, 11, 12, 13, + 110, -1, -1, -1, -1, 91, -1, -1, -1, 39, + -1, -1, 26, -1, 100, 101, 102, 103, 104, 105, + 106, 91, -1, 8, 9, 111, 11, 12, 13, -1, + 100, 101, 102, 103, 104, 105, 106, -1, -1, -1, + -1, -1, 8, 9, 29, 11, 12, 13, -1, -1, + -1, -1, -1, -1, 91, -1, -1, -1, -1, -1, + -1, 91, -1, 100, 101, 102, 103, 104, 105, 106, + 100, 101, 102, 103, 104, 105, 106, 91, -1, -1, + -1, -1, -1, -1, -1, -1, 100, 101, 102, 103, + 104, 105, 106, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 91, -1, -1, -1, + -1, -1, -1, -1, -1, 100, 101, 102, 103, 104, + 105, 106, -1, -1, -1, 91, -1, -1, -1, -1, + -1, -1, -1, -1, 100, 101, 102, 103, 104, 105, + 106 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 16, 120, 190, 9, 0, 112, 113, 9, 182, - 183, 17, 18, 114, 116, 19, 20, 21, 22, 24, - 102, 181, 181, 25, 182, 9, 184, 185, 181, 63, - 184, 186, 187, 188, 189, 112, 64, 90, 26, 188, - 9, 9, 9, 28, 33, 34, 35, 41, 48, 51, - 53, 56, 66, 67, 68, 75, 80, 81, 84, 85, - 86, 89, 117, 121, 122, 126, 127, 128, 141, 142, - 143, 147, 148, 149, 150, 151, 152, 153, 154, 158, - 159, 160, 161, 162, 163, 164, 165, 173, 177, 179, - 180, 25, 112, 62, 3, 4, 5, 6, 7, 8, - 9, 12, 65, 70, 71, 72, 73, 74, 76, 77, - 78, 79, 82, 83, 106, 113, 123, 124, 123, 36, - 37, 108, 123, 133, 134, 135, 9, 49, 9, 99, - 178, 39, 57, 59, 175, 9, 9, 9, 141, 87, - 87, 9, 27, 121, 112, 113, 112, 50, 141, 112, - 40, 136, 146, 112, 112, 136, 146, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 141, 123, 111, 123, 111, 123, 123, - 10, 11, 13, 14, 15, 29, 94, 103, 104, 105, - 106, 107, 108, 109, 113, 32, 113, 113, 49, 116, - 39, 17, 178, 52, 178, 178, 60, 176, 49, 113, - 123, 132, 113, 54, 123, 112, 69, 69, 114, 123, - 123, 123, 123, 123, 122, 5, 123, 123, 123, 123, - 123, 123, 123, 132, 122, 123, 38, 108, 9, 131, - 133, 130, 178, 123, 9, 144, 145, 113, 58, 9, - 129, 131, 115, 125, 114, 116, 132, 55, 30, 31, - 155, 156, 157, 114, 27, 114, 9, 114, 116, 40, - 116, 136, 42, 103, 116, 9, 166, 167, 9, 113, - 114, 116, 123, 114, 9, 122, 123, 155, 27, 32, - 114, 9, 178, 41, 137, 123, 123, 144, 181, 114, - 116, 61, 114, 118, 115, 29, 28, 51, 91, 138, - 32, 113, 168, 100, 171, 166, 178, 122, 17, 44, - 140, 122, 3, 88, 169, 101, 172, 113, 92, 45, - 27, 114, 12, 170, 103, 9, 174, 93, 9, 32, - 8, 3, 114, 116, 46, 47, 139, 9 + 0, 14, 117, 187, 7, 0, 109, 110, 7, 179, + 180, 15, 16, 111, 113, 17, 18, 19, 21, 99, + 178, 178, 22, 179, 7, 181, 182, 178, 60, 181, + 183, 184, 185, 186, 109, 61, 87, 23, 185, 7, + 7, 7, 25, 30, 31, 32, 38, 45, 48, 50, + 53, 63, 64, 65, 72, 77, 78, 81, 82, 83, + 86, 114, 118, 119, 123, 124, 125, 138, 139, 140, + 144, 145, 146, 147, 148, 149, 150, 151, 155, 156, + 157, 158, 159, 160, 161, 162, 170, 174, 176, 177, + 22, 109, 59, 3, 4, 5, 6, 7, 10, 62, + 67, 68, 69, 70, 71, 73, 74, 75, 76, 79, + 80, 103, 110, 120, 121, 120, 33, 34, 105, 120, + 130, 131, 132, 7, 46, 7, 96, 175, 36, 54, + 56, 172, 7, 7, 7, 138, 84, 84, 7, 24, + 118, 109, 110, 109, 47, 138, 109, 37, 133, 143, + 109, 109, 133, 143, 109, 109, 109, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, + 138, 120, 108, 120, 108, 120, 120, 8, 9, 11, + 12, 13, 26, 91, 100, 101, 102, 103, 104, 105, + 106, 110, 29, 110, 110, 46, 113, 36, 15, 175, + 49, 175, 175, 57, 173, 46, 110, 120, 129, 110, + 51, 120, 109, 66, 66, 111, 120, 120, 120, 120, + 120, 119, 5, 120, 120, 120, 120, 120, 120, 120, + 129, 119, 120, 35, 105, 7, 128, 130, 127, 175, + 120, 7, 141, 142, 110, 55, 7, 126, 128, 112, + 122, 111, 113, 129, 52, 27, 28, 152, 153, 154, + 111, 24, 111, 7, 111, 113, 37, 113, 133, 39, + 100, 113, 7, 163, 164, 7, 110, 111, 113, 120, + 111, 7, 119, 120, 152, 24, 29, 111, 7, 175, + 38, 134, 120, 120, 141, 178, 111, 113, 58, 111, + 115, 112, 26, 25, 48, 88, 135, 29, 110, 165, + 97, 168, 163, 175, 119, 15, 41, 137, 119, 3, + 85, 166, 98, 169, 110, 89, 42, 24, 111, 10, + 167, 100, 7, 171, 90, 7, 29, 6, 3, 111, + 113, 43, 44, 136, 7 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 119, 120, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 122, 122, 123, 123, 123, - 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 123, 123, 123, 124, 124, 124, 124, 124, 124, - 124, 124, 124, 124, 124, 125, 125, 125, 126, 127, - 128, 128, 128, 129, 130, 130, 131, 131, 131, 132, - 132, 132, 133, 133, 133, 133, 134, 134, 134, 135, - 135, 135, 136, 136, 137, 137, 138, 138, 139, 139, - 139, 140, 140, 141, 142, 143, 143, 144, 145, 145, - 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 156, 157, 157, 157, 158, 159, 160, 161, 162, - 163, 164, 165, 165, 166, 167, 167, 168, 168, 169, - 169, 170, 170, 171, 171, 172, 172, 173, 174, 174, - 175, 175, 176, 176, 177, 178, 178, 179, 180, 181, - 181, 181, 181, 181, 181, 182, 182, 183, 183, 183, - 184, 185, 185, 185, 186, 187, 188, 188, 189, 189, - 189, 190 + 0, 116, 117, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 119, 119, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 122, 122, 122, 123, 124, 125, 125, + 125, 126, 127, 127, 128, 128, 128, 129, 129, 129, + 130, 130, 130, 130, 131, 131, 131, 132, 132, 132, + 133, 133, 134, 134, 135, 135, 136, 136, 136, 137, + 137, 138, 139, 140, 140, 141, 142, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 153, + 154, 154, 154, 155, 156, 157, 158, 159, 160, 161, + 162, 162, 163, 164, 164, 165, 165, 166, 166, 167, + 167, 168, 168, 169, 169, 170, 171, 171, 172, 172, + 173, 173, 174, 175, 175, 176, 177, 178, 178, 178, + 178, 178, 179, 179, 180, 180, 180, 181, 182, 182, + 182, 183, 184, 185, 185, 186, 186, 186, 187 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ @@ -1018,22 +1004,21 @@ static const yytype_uint8 yyr2[] = 0, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 4, 1, - 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, - 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 2, 3, 3, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 0, 1, 3, 6, 4, - 1, 1, 1, 3, 1, 3, 0, 1, 3, 0, - 1, 3, 1, 4, 5, 4, 0, 1, 3, 1, - 3, 1, 0, 2, 0, 2, 0, 4, 0, 1, - 1, 0, 4, 8, 3, 5, 2, 3, 1, 3, - 4, 4, 2, 2, 3, 2, 2, 2, 3, 4, - 1, 2, 0, 2, 1, 7, 6, 10, 1, 1, - 2, 2, 4, 4, 5, 1, 3, 0, 3, 0, - 1, 0, 2, 0, 1, 0, 3, 8, 1, 3, - 0, 1, 0, 1, 10, 1, 1, 2, 2, 1, - 1, 1, 1, 1, 1, 3, 3, 0, 1, 3, - 3, 0, 1, 2, 6, 4, 1, 1, 0, 1, - 2, 11 + 1, 1, 1, 1, 3, 3, 3, 3, 2, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, + 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 1, 3, 6, 4, 1, 1, + 1, 3, 1, 3, 0, 1, 3, 0, 1, 3, + 1, 4, 5, 4, 0, 1, 3, 1, 3, 1, + 0, 2, 0, 2, 0, 4, 0, 1, 1, 0, + 4, 8, 3, 5, 2, 3, 1, 3, 4, 4, + 2, 2, 3, 2, 2, 2, 3, 4, 1, 2, + 0, 2, 1, 7, 6, 10, 1, 1, 2, 2, + 4, 4, 5, 1, 3, 0, 3, 0, 1, 0, + 2, 0, 1, 0, 3, 8, 1, 3, 0, 1, + 0, 1, 10, 1, 1, 2, 2, 1, 1, 1, + 1, 1, 3, 3, 0, 1, 3, 3, 0, 1, + 2, 6, 4, 1, 1, 0, 1, 2, 11 }; @@ -1710,471 +1695,459 @@ yyreduce: switch (yyn) { case 25: -#line 191 "pars0grm.y" /* yacc.c:1646 */ +#line 188 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = que_node_list_add_last(NULL, (yyvsp[0])); } -#line 1716 "pars0grm.cc" /* yacc.c:1646 */ +#line 1701 "pars0grm.cc" /* yacc.c:1646 */ break; case 26: -#line 193 "pars0grm.y" /* yacc.c:1646 */ +#line 190 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = que_node_list_add_last((yyvsp[-1]), (yyvsp[0])); } -#line 1722 "pars0grm.cc" /* yacc.c:1646 */ +#line 1707 "pars0grm.cc" /* yacc.c:1646 */ break; case 27: -#line 197 "pars0grm.y" /* yacc.c:1646 */ +#line 194 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]);} -#line 1728 "pars0grm.cc" /* yacc.c:1646 */ +#line 1713 "pars0grm.cc" /* yacc.c:1646 */ break; case 28: -#line 199 "pars0grm.y" /* yacc.c:1646 */ +#line 196 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_func((yyvsp[-3]), (yyvsp[-1])); } -#line 1734 "pars0grm.cc" /* yacc.c:1646 */ +#line 1719 "pars0grm.cc" /* yacc.c:1646 */ break; case 29: -#line 200 "pars0grm.y" /* yacc.c:1646 */ +#line 197 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]);} -#line 1740 "pars0grm.cc" /* yacc.c:1646 */ +#line 1725 "pars0grm.cc" /* yacc.c:1646 */ break; case 30: -#line 201 "pars0grm.y" /* yacc.c:1646 */ +#line 198 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]);} -#line 1746 "pars0grm.cc" /* yacc.c:1646 */ +#line 1731 "pars0grm.cc" /* yacc.c:1646 */ break; case 31: -#line 202 "pars0grm.y" /* yacc.c:1646 */ +#line 199 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]);} -#line 1752 "pars0grm.cc" /* yacc.c:1646 */ +#line 1737 "pars0grm.cc" /* yacc.c:1646 */ break; case 32: -#line 203 "pars0grm.y" /* yacc.c:1646 */ +#line 200 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]);} -#line 1758 "pars0grm.cc" /* yacc.c:1646 */ +#line 1743 "pars0grm.cc" /* yacc.c:1646 */ break; case 33: -#line 204 "pars0grm.y" /* yacc.c:1646 */ +#line 201 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]);} -#line 1764 "pars0grm.cc" /* yacc.c:1646 */ +#line 1749 "pars0grm.cc" /* yacc.c:1646 */ break; case 34: -#line 205 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[0]);} -#line 1770 "pars0grm.cc" /* yacc.c:1646 */ +#line 202 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = pars_op('+', (yyvsp[-2]), (yyvsp[0])); } +#line 1755 "pars0grm.cc" /* yacc.c:1646 */ break; case 35: -#line 206 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[0]);} -#line 1776 "pars0grm.cc" /* yacc.c:1646 */ +#line 203 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = pars_op('-', (yyvsp[-2]), (yyvsp[0])); } +#line 1761 "pars0grm.cc" /* yacc.c:1646 */ break; case 36: -#line 207 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = pars_op('+', (yyvsp[-2]), (yyvsp[0])); } -#line 1782 "pars0grm.cc" /* yacc.c:1646 */ +#line 204 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = pars_op('*', (yyvsp[-2]), (yyvsp[0])); } +#line 1767 "pars0grm.cc" /* yacc.c:1646 */ break; case 37: -#line 208 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = pars_op('-', (yyvsp[-2]), (yyvsp[0])); } -#line 1788 "pars0grm.cc" /* yacc.c:1646 */ +#line 205 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = pars_op('/', (yyvsp[-2]), (yyvsp[0])); } +#line 1773 "pars0grm.cc" /* yacc.c:1646 */ break; case 38: -#line 209 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = pars_op('*', (yyvsp[-2]), (yyvsp[0])); } -#line 1794 "pars0grm.cc" /* yacc.c:1646 */ +#line 206 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = pars_op('-', (yyvsp[0]), NULL); } +#line 1779 "pars0grm.cc" /* yacc.c:1646 */ break; case 39: -#line 210 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = pars_op('/', (yyvsp[-2]), (yyvsp[0])); } -#line 1800 "pars0grm.cc" /* yacc.c:1646 */ +#line 207 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = (yyvsp[-1]); } +#line 1785 "pars0grm.cc" /* yacc.c:1646 */ break; case 40: -#line 211 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = pars_op('-', (yyvsp[0]), NULL); } -#line 1806 "pars0grm.cc" /* yacc.c:1646 */ +#line 208 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = pars_op('=', (yyvsp[-2]), (yyvsp[0])); } +#line 1791 "pars0grm.cc" /* yacc.c:1646 */ break; case 41: -#line 212 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[-1]); } -#line 1812 "pars0grm.cc" /* yacc.c:1646 */ +#line 210 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = pars_op(PARS_LIKE_TOKEN, (yyvsp[-2]), (yyvsp[0])); } +#line 1797 "pars0grm.cc" /* yacc.c:1646 */ break; case 42: -#line 213 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = pars_op('=', (yyvsp[-2]), (yyvsp[0])); } -#line 1818 "pars0grm.cc" /* yacc.c:1646 */ +#line 211 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = pars_op('<', (yyvsp[-2]), (yyvsp[0])); } +#line 1803 "pars0grm.cc" /* yacc.c:1646 */ break; case 43: -#line 215 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = pars_op(PARS_LIKE_TOKEN, (yyvsp[-2]), (yyvsp[0])); } -#line 1824 "pars0grm.cc" /* yacc.c:1646 */ +#line 212 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = pars_op('>', (yyvsp[-2]), (yyvsp[0])); } +#line 1809 "pars0grm.cc" /* yacc.c:1646 */ break; case 44: -#line 216 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = pars_op('<', (yyvsp[-2]), (yyvsp[0])); } -#line 1830 "pars0grm.cc" /* yacc.c:1646 */ +#line 213 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = pars_op(PARS_GE_TOKEN, (yyvsp[-2]), (yyvsp[0])); } +#line 1815 "pars0grm.cc" /* yacc.c:1646 */ break; case 45: -#line 217 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = pars_op('>', (yyvsp[-2]), (yyvsp[0])); } -#line 1836 "pars0grm.cc" /* yacc.c:1646 */ +#line 214 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = pars_op(PARS_LE_TOKEN, (yyvsp[-2]), (yyvsp[0])); } +#line 1821 "pars0grm.cc" /* yacc.c:1646 */ break; case 46: -#line 218 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = pars_op(PARS_GE_TOKEN, (yyvsp[-2]), (yyvsp[0])); } -#line 1842 "pars0grm.cc" /* yacc.c:1646 */ +#line 215 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = pars_op(PARS_NE_TOKEN, (yyvsp[-2]), (yyvsp[0])); } +#line 1827 "pars0grm.cc" /* yacc.c:1646 */ break; case 47: -#line 219 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = pars_op(PARS_LE_TOKEN, (yyvsp[-2]), (yyvsp[0])); } -#line 1848 "pars0grm.cc" /* yacc.c:1646 */ +#line 216 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = pars_op(PARS_AND_TOKEN, (yyvsp[-2]), (yyvsp[0])); } +#line 1833 "pars0grm.cc" /* yacc.c:1646 */ break; case 48: -#line 220 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = pars_op(PARS_NE_TOKEN, (yyvsp[-2]), (yyvsp[0])); } -#line 1854 "pars0grm.cc" /* yacc.c:1646 */ +#line 217 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = pars_op(PARS_OR_TOKEN, (yyvsp[-2]), (yyvsp[0])); } +#line 1839 "pars0grm.cc" /* yacc.c:1646 */ break; case 49: -#line 221 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = pars_op(PARS_AND_TOKEN, (yyvsp[-2]), (yyvsp[0])); } -#line 1860 "pars0grm.cc" /* yacc.c:1646 */ +#line 218 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = pars_op(PARS_NOT_TOKEN, (yyvsp[0]), NULL); } +#line 1845 "pars0grm.cc" /* yacc.c:1646 */ break; case 50: -#line 222 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = pars_op(PARS_OR_TOKEN, (yyvsp[-2]), (yyvsp[0])); } -#line 1866 "pars0grm.cc" /* yacc.c:1646 */ +#line 220 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = pars_op(PARS_NOTFOUND_TOKEN, (yyvsp[-2]), NULL); } +#line 1851 "pars0grm.cc" /* yacc.c:1646 */ break; case 51: -#line 223 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = pars_op(PARS_NOT_TOKEN, (yyvsp[0]), NULL); } -#line 1872 "pars0grm.cc" /* yacc.c:1646 */ +#line 222 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = pars_op(PARS_NOTFOUND_TOKEN, (yyvsp[-2]), NULL); } +#line 1857 "pars0grm.cc" /* yacc.c:1646 */ break; case 52: -#line 225 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = pars_op(PARS_NOTFOUND_TOKEN, (yyvsp[-2]), NULL); } -#line 1878 "pars0grm.cc" /* yacc.c:1646 */ +#line 226 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = &pars_to_char_token; } +#line 1863 "pars0grm.cc" /* yacc.c:1646 */ break; case 53: #line 227 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = pars_op(PARS_NOTFOUND_TOKEN, (yyvsp[-2]), NULL); } -#line 1884 "pars0grm.cc" /* yacc.c:1646 */ + { (yyval) = &pars_to_number_token; } +#line 1869 "pars0grm.cc" /* yacc.c:1646 */ break; case 54: -#line 231 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = &pars_to_char_token; } -#line 1890 "pars0grm.cc" /* yacc.c:1646 */ +#line 228 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = &pars_to_binary_token; } +#line 1875 "pars0grm.cc" /* yacc.c:1646 */ break; case 55: -#line 232 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = &pars_to_number_token; } -#line 1896 "pars0grm.cc" /* yacc.c:1646 */ +#line 230 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = &pars_binary_to_number_token; } +#line 1881 "pars0grm.cc" /* yacc.c:1646 */ break; case 56: -#line 233 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = &pars_to_binary_token; } -#line 1902 "pars0grm.cc" /* yacc.c:1646 */ +#line 231 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = &pars_substr_token; } +#line 1887 "pars0grm.cc" /* yacc.c:1646 */ break; case 57: -#line 235 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = &pars_binary_to_number_token; } -#line 1908 "pars0grm.cc" /* yacc.c:1646 */ +#line 232 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = &pars_concat_token; } +#line 1893 "pars0grm.cc" /* yacc.c:1646 */ break; case 58: -#line 236 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = &pars_substr_token; } -#line 1914 "pars0grm.cc" /* yacc.c:1646 */ +#line 233 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = &pars_instr_token; } +#line 1899 "pars0grm.cc" /* yacc.c:1646 */ break; case 59: -#line 237 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = &pars_concat_token; } -#line 1920 "pars0grm.cc" /* yacc.c:1646 */ +#line 234 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = &pars_length_token; } +#line 1905 "pars0grm.cc" /* yacc.c:1646 */ break; case 60: -#line 238 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = &pars_instr_token; } -#line 1926 "pars0grm.cc" /* yacc.c:1646 */ +#line 235 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = &pars_sysdate_token; } +#line 1911 "pars0grm.cc" /* yacc.c:1646 */ break; case 61: -#line 239 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = &pars_length_token; } -#line 1932 "pars0grm.cc" /* yacc.c:1646 */ +#line 236 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = &pars_rnd_token; } +#line 1917 "pars0grm.cc" /* yacc.c:1646 */ break; case 62: -#line 240 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = &pars_sysdate_token; } -#line 1938 "pars0grm.cc" /* yacc.c:1646 */ +#line 237 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = &pars_rnd_str_token; } +#line 1923 "pars0grm.cc" /* yacc.c:1646 */ break; - case 63: -#line 241 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = &pars_rnd_token; } -#line 1944 "pars0grm.cc" /* yacc.c:1646 */ + case 66: +#line 248 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = pars_stored_procedure_call( + static_cast<sym_node_t*>((yyvsp[-4]))); } +#line 1930 "pars0grm.cc" /* yacc.c:1646 */ break; - case 64: -#line 242 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = &pars_rnd_str_token; } -#line 1950 "pars0grm.cc" /* yacc.c:1646 */ + case 67: +#line 254 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = pars_procedure_call((yyvsp[-3]), (yyvsp[-1])); } +#line 1936 "pars0grm.cc" /* yacc.c:1646 */ break; case 68: -#line 253 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = pars_stored_procedure_call( - static_cast<sym_node_t*>((yyvsp[-4]))); } -#line 1957 "pars0grm.cc" /* yacc.c:1646 */ +#line 258 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = &pars_replstr_token; } +#line 1942 "pars0grm.cc" /* yacc.c:1646 */ break; case 69: #line 259 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = pars_procedure_call((yyvsp[-3]), (yyvsp[-1])); } -#line 1963 "pars0grm.cc" /* yacc.c:1646 */ + { (yyval) = &pars_printf_token; } +#line 1948 "pars0grm.cc" /* yacc.c:1646 */ break; case 70: -#line 263 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = &pars_replstr_token; } -#line 1969 "pars0grm.cc" /* yacc.c:1646 */ +#line 260 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = &pars_assert_token; } +#line 1954 "pars0grm.cc" /* yacc.c:1646 */ break; case 71: #line 264 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = &pars_printf_token; } -#line 1975 "pars0grm.cc" /* yacc.c:1646 */ + { (yyval) = (yyvsp[-2]); } +#line 1960 "pars0grm.cc" /* yacc.c:1646 */ break; case 72: -#line 265 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = &pars_assert_token; } -#line 1981 "pars0grm.cc" /* yacc.c:1646 */ +#line 268 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = que_node_list_add_last(NULL, (yyvsp[0])); } +#line 1966 "pars0grm.cc" /* yacc.c:1646 */ break; case 73: -#line 269 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[-2]); } -#line 1987 "pars0grm.cc" /* yacc.c:1646 */ +#line 270 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = que_node_list_add_last((yyvsp[-2]), (yyvsp[0])); } +#line 1972 "pars0grm.cc" /* yacc.c:1646 */ break; case 74: -#line 273 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = que_node_list_add_last(NULL, (yyvsp[0])); } -#line 1993 "pars0grm.cc" /* yacc.c:1646 */ +#line 274 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = NULL; } +#line 1978 "pars0grm.cc" /* yacc.c:1646 */ break; case 75: #line 275 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = que_node_list_add_last((yyvsp[-2]), (yyvsp[0])); } -#line 1999 "pars0grm.cc" /* yacc.c:1646 */ + { (yyval) = que_node_list_add_last(NULL, (yyvsp[0])); } +#line 1984 "pars0grm.cc" /* yacc.c:1646 */ break; case 76: -#line 279 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = NULL; } -#line 2005 "pars0grm.cc" /* yacc.c:1646 */ +#line 277 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = que_node_list_add_last((yyvsp[-2]), (yyvsp[0])); } +#line 1990 "pars0grm.cc" /* yacc.c:1646 */ break; case 77: -#line 280 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = que_node_list_add_last(NULL, (yyvsp[0])); } -#line 2011 "pars0grm.cc" /* yacc.c:1646 */ +#line 281 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = NULL; } +#line 1996 "pars0grm.cc" /* yacc.c:1646 */ break; case 78: #line 282 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = que_node_list_add_last((yyvsp[-2]), (yyvsp[0])); } -#line 2017 "pars0grm.cc" /* yacc.c:1646 */ + { (yyval) = que_node_list_add_last(NULL, (yyvsp[0]));} +#line 2002 "pars0grm.cc" /* yacc.c:1646 */ break; case 79: -#line 286 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = NULL; } -#line 2023 "pars0grm.cc" /* yacc.c:1646 */ +#line 283 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = que_node_list_add_last((yyvsp[-2]), (yyvsp[0])); } +#line 2008 "pars0grm.cc" /* yacc.c:1646 */ break; case 80: #line 287 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = que_node_list_add_last(NULL, (yyvsp[0]));} -#line 2029 "pars0grm.cc" /* yacc.c:1646 */ - break; - - case 81: -#line 288 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = que_node_list_add_last((yyvsp[-2]), (yyvsp[0])); } -#line 2035 "pars0grm.cc" /* yacc.c:1646 */ - break; - - case 82: -#line 292 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 2041 "pars0grm.cc" /* yacc.c:1646 */ +#line 2014 "pars0grm.cc" /* yacc.c:1646 */ break; - case 83: -#line 294 "pars0grm.y" /* yacc.c:1646 */ + case 81: +#line 289 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_func(&pars_count_token, que_node_list_add_last(NULL, sym_tab_add_int_lit( pars_sym_tab_global, 1))); } -#line 2050 "pars0grm.cc" /* yacc.c:1646 */ +#line 2023 "pars0grm.cc" /* yacc.c:1646 */ break; - case 84: -#line 299 "pars0grm.y" /* yacc.c:1646 */ + case 82: +#line 294 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_func(&pars_count_token, que_node_list_add_last(NULL, pars_func(&pars_distinct_token, que_node_list_add_last( NULL, (yyvsp[-1]))))); } -#line 2060 "pars0grm.cc" /* yacc.c:1646 */ +#line 2033 "pars0grm.cc" /* yacc.c:1646 */ break; - case 85: -#line 305 "pars0grm.y" /* yacc.c:1646 */ + case 83: +#line 300 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_func(&pars_sum_token, que_node_list_add_last(NULL, (yyvsp[-1]))); } -#line 2068 "pars0grm.cc" /* yacc.c:1646 */ +#line 2041 "pars0grm.cc" /* yacc.c:1646 */ break; - case 86: -#line 311 "pars0grm.y" /* yacc.c:1646 */ + case 84: +#line 306 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 2074 "pars0grm.cc" /* yacc.c:1646 */ +#line 2047 "pars0grm.cc" /* yacc.c:1646 */ break; - case 87: -#line 312 "pars0grm.y" /* yacc.c:1646 */ + case 85: +#line 307 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = que_node_list_add_last(NULL, (yyvsp[0])); } -#line 2080 "pars0grm.cc" /* yacc.c:1646 */ +#line 2053 "pars0grm.cc" /* yacc.c:1646 */ break; - case 88: -#line 314 "pars0grm.y" /* yacc.c:1646 */ + case 86: +#line 309 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = que_node_list_add_last((yyvsp[-2]), (yyvsp[0])); } -#line 2086 "pars0grm.cc" /* yacc.c:1646 */ +#line 2059 "pars0grm.cc" /* yacc.c:1646 */ break; - case 89: -#line 318 "pars0grm.y" /* yacc.c:1646 */ + case 87: +#line 313 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_select_list(&pars_star_denoter, NULL); } -#line 2093 "pars0grm.cc" /* yacc.c:1646 */ +#line 2066 "pars0grm.cc" /* yacc.c:1646 */ break; - case 90: -#line 321 "pars0grm.y" /* yacc.c:1646 */ + case 88: +#line 316 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_select_list( (yyvsp[-2]), static_cast<sym_node_t*>((yyvsp[0]))); } -#line 2100 "pars0grm.cc" /* yacc.c:1646 */ +#line 2073 "pars0grm.cc" /* yacc.c:1646 */ + break; + + case 89: +#line 318 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = pars_select_list((yyvsp[0]), NULL); } +#line 2079 "pars0grm.cc" /* yacc.c:1646 */ + break; + + case 90: +#line 322 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = NULL; } +#line 2085 "pars0grm.cc" /* yacc.c:1646 */ break; case 91: #line 323 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = pars_select_list((yyvsp[0]), NULL); } -#line 2106 "pars0grm.cc" /* yacc.c:1646 */ + { (yyval) = (yyvsp[0]); } +#line 2091 "pars0grm.cc" /* yacc.c:1646 */ break; case 92: #line 327 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 2112 "pars0grm.cc" /* yacc.c:1646 */ +#line 2097 "pars0grm.cc" /* yacc.c:1646 */ break; case 93: -#line 328 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = (yyvsp[0]); } -#line 2118 "pars0grm.cc" /* yacc.c:1646 */ +#line 329 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = &pars_update_token; } +#line 2103 "pars0grm.cc" /* yacc.c:1646 */ break; case 94: -#line 332 "pars0grm.y" /* yacc.c:1646 */ +#line 333 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 2124 "pars0grm.cc" /* yacc.c:1646 */ +#line 2109 "pars0grm.cc" /* yacc.c:1646 */ break; case 95: -#line 334 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = &pars_update_token; } -#line 2130 "pars0grm.cc" /* yacc.c:1646 */ +#line 335 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = &pars_share_token; } +#line 2115 "pars0grm.cc" /* yacc.c:1646 */ break; case 96: -#line 338 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = NULL; } -#line 2136 "pars0grm.cc" /* yacc.c:1646 */ +#line 339 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = &pars_asc_token; } +#line 2121 "pars0grm.cc" /* yacc.c:1646 */ break; case 97: #line 340 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = &pars_share_token; } -#line 2142 "pars0grm.cc" /* yacc.c:1646 */ + { (yyval) = &pars_asc_token; } +#line 2127 "pars0grm.cc" /* yacc.c:1646 */ break; case 98: -#line 344 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = &pars_asc_token; } -#line 2148 "pars0grm.cc" /* yacc.c:1646 */ +#line 341 "pars0grm.y" /* yacc.c:1646 */ + { (yyval) = &pars_desc_token; } +#line 2133 "pars0grm.cc" /* yacc.c:1646 */ break; case 99: #line 345 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = &pars_asc_token; } -#line 2154 "pars0grm.cc" /* yacc.c:1646 */ - break; - - case 100: -#line 346 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = &pars_desc_token; } -#line 2160 "pars0grm.cc" /* yacc.c:1646 */ - break; - - case 101: -#line 350 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 2166 "pars0grm.cc" /* yacc.c:1646 */ +#line 2139 "pars0grm.cc" /* yacc.c:1646 */ break; - case 102: -#line 352 "pars0grm.y" /* yacc.c:1646 */ + case 100: +#line 347 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_order_by( static_cast<sym_node_t*>((yyvsp[-1])), static_cast<pars_res_word_t*>((yyvsp[0]))); } -#line 2174 "pars0grm.cc" /* yacc.c:1646 */ +#line 2147 "pars0grm.cc" /* yacc.c:1646 */ break; - case 103: -#line 363 "pars0grm.y" /* yacc.c:1646 */ + case 101: +#line 358 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_select_statement( static_cast<sel_node_t*>((yyvsp[-6])), static_cast<sym_node_t*>((yyvsp[-4])), @@ -2182,498 +2155,492 @@ yyreduce: static_cast<pars_res_word_t*>((yyvsp[-2])), static_cast<pars_res_word_t*>((yyvsp[-1])), static_cast<order_node_t*>((yyvsp[0]))); } -#line 2186 "pars0grm.cc" /* yacc.c:1646 */ +#line 2159 "pars0grm.cc" /* yacc.c:1646 */ break; - case 104: -#line 374 "pars0grm.y" /* yacc.c:1646 */ + case 102: +#line 369 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 2192 "pars0grm.cc" /* yacc.c:1646 */ +#line 2165 "pars0grm.cc" /* yacc.c:1646 */ break; - case 105: -#line 379 "pars0grm.y" /* yacc.c:1646 */ + case 103: +#line 374 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_insert_statement( static_cast<sym_node_t*>((yyvsp[-4])), (yyvsp[-1]), NULL); } -#line 2199 "pars0grm.cc" /* yacc.c:1646 */ +#line 2172 "pars0grm.cc" /* yacc.c:1646 */ break; - case 106: -#line 382 "pars0grm.y" /* yacc.c:1646 */ + case 104: +#line 377 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_insert_statement( static_cast<sym_node_t*>((yyvsp[-1])), NULL, static_cast<sel_node_t*>((yyvsp[0]))); } -#line 2208 "pars0grm.cc" /* yacc.c:1646 */ +#line 2181 "pars0grm.cc" /* yacc.c:1646 */ break; - case 107: -#line 389 "pars0grm.y" /* yacc.c:1646 */ + case 105: +#line 384 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_column_assignment( static_cast<sym_node_t*>((yyvsp[-2])), static_cast<que_node_t*>((yyvsp[0]))); } -#line 2216 "pars0grm.cc" /* yacc.c:1646 */ +#line 2189 "pars0grm.cc" /* yacc.c:1646 */ break; - case 108: -#line 395 "pars0grm.y" /* yacc.c:1646 */ + case 106: +#line 390 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = que_node_list_add_last(NULL, (yyvsp[0])); } -#line 2222 "pars0grm.cc" /* yacc.c:1646 */ +#line 2195 "pars0grm.cc" /* yacc.c:1646 */ break; - case 109: -#line 397 "pars0grm.y" /* yacc.c:1646 */ + case 107: +#line 392 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = que_node_list_add_last((yyvsp[-2]), (yyvsp[0])); } -#line 2228 "pars0grm.cc" /* yacc.c:1646 */ +#line 2201 "pars0grm.cc" /* yacc.c:1646 */ break; - case 110: -#line 403 "pars0grm.y" /* yacc.c:1646 */ + case 108: +#line 398 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 2234 "pars0grm.cc" /* yacc.c:1646 */ +#line 2207 "pars0grm.cc" /* yacc.c:1646 */ break; - case 111: -#line 409 "pars0grm.y" /* yacc.c:1646 */ + case 109: +#line 404 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_update_statement_start( FALSE, static_cast<sym_node_t*>((yyvsp[-2])), static_cast<col_assign_node_t*>((yyvsp[0]))); } -#line 2243 "pars0grm.cc" /* yacc.c:1646 */ +#line 2216 "pars0grm.cc" /* yacc.c:1646 */ break; - case 112: -#line 417 "pars0grm.y" /* yacc.c:1646 */ + case 110: +#line 412 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_update_statement( static_cast<upd_node_t*>((yyvsp[-1])), NULL, static_cast<que_node_t*>((yyvsp[0]))); } -#line 2252 "pars0grm.cc" /* yacc.c:1646 */ +#line 2225 "pars0grm.cc" /* yacc.c:1646 */ break; - case 113: -#line 425 "pars0grm.y" /* yacc.c:1646 */ + case 111: +#line 420 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_update_statement( static_cast<upd_node_t*>((yyvsp[-1])), static_cast<sym_node_t*>((yyvsp[0])), NULL); } -#line 2261 "pars0grm.cc" /* yacc.c:1646 */ +#line 2234 "pars0grm.cc" /* yacc.c:1646 */ break; - case 114: -#line 433 "pars0grm.y" /* yacc.c:1646 */ + case 112: +#line 428 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_update_statement_start( TRUE, static_cast<sym_node_t*>((yyvsp[0])), NULL); } -#line 2269 "pars0grm.cc" /* yacc.c:1646 */ +#line 2242 "pars0grm.cc" /* yacc.c:1646 */ break; - case 115: -#line 440 "pars0grm.y" /* yacc.c:1646 */ + case 113: +#line 435 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_update_statement( static_cast<upd_node_t*>((yyvsp[-1])), NULL, static_cast<que_node_t*>((yyvsp[0]))); } -#line 2278 "pars0grm.cc" /* yacc.c:1646 */ +#line 2251 "pars0grm.cc" /* yacc.c:1646 */ break; - case 116: -#line 448 "pars0grm.y" /* yacc.c:1646 */ + case 114: +#line 443 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_update_statement( static_cast<upd_node_t*>((yyvsp[-1])), static_cast<sym_node_t*>((yyvsp[0])), NULL); } -#line 2287 "pars0grm.cc" /* yacc.c:1646 */ +#line 2260 "pars0grm.cc" /* yacc.c:1646 */ break; - case 117: -#line 456 "pars0grm.y" /* yacc.c:1646 */ + case 115: +#line 451 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_row_printf_statement( static_cast<sel_node_t*>((yyvsp[0]))); } -#line 2294 "pars0grm.cc" /* yacc.c:1646 */ +#line 2267 "pars0grm.cc" /* yacc.c:1646 */ break; - case 118: -#line 462 "pars0grm.y" /* yacc.c:1646 */ + case 116: +#line 457 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_assignment_statement( static_cast<sym_node_t*>((yyvsp[-2])), static_cast<que_node_t*>((yyvsp[0]))); } -#line 2302 "pars0grm.cc" /* yacc.c:1646 */ +#line 2275 "pars0grm.cc" /* yacc.c:1646 */ break; - case 119: -#line 470 "pars0grm.y" /* yacc.c:1646 */ + case 117: +#line 465 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_elsif_element((yyvsp[-2]), (yyvsp[0])); } -#line 2308 "pars0grm.cc" /* yacc.c:1646 */ +#line 2281 "pars0grm.cc" /* yacc.c:1646 */ break; - case 120: -#line 474 "pars0grm.y" /* yacc.c:1646 */ + case 118: +#line 469 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = que_node_list_add_last(NULL, (yyvsp[0])); } -#line 2314 "pars0grm.cc" /* yacc.c:1646 */ +#line 2287 "pars0grm.cc" /* yacc.c:1646 */ break; - case 121: -#line 476 "pars0grm.y" /* yacc.c:1646 */ + case 119: +#line 471 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = que_node_list_add_last((yyvsp[-1]), (yyvsp[0])); } -#line 2320 "pars0grm.cc" /* yacc.c:1646 */ +#line 2293 "pars0grm.cc" /* yacc.c:1646 */ break; - case 122: -#line 480 "pars0grm.y" /* yacc.c:1646 */ + case 120: +#line 475 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 2326 "pars0grm.cc" /* yacc.c:1646 */ +#line 2299 "pars0grm.cc" /* yacc.c:1646 */ break; - case 123: -#line 482 "pars0grm.y" /* yacc.c:1646 */ + case 121: +#line 477 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 2332 "pars0grm.cc" /* yacc.c:1646 */ +#line 2305 "pars0grm.cc" /* yacc.c:1646 */ break; - case 124: -#line 483 "pars0grm.y" /* yacc.c:1646 */ + case 122: +#line 478 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 2338 "pars0grm.cc" /* yacc.c:1646 */ +#line 2311 "pars0grm.cc" /* yacc.c:1646 */ break; - case 125: -#line 490 "pars0grm.y" /* yacc.c:1646 */ + case 123: +#line 485 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_if_statement((yyvsp[-5]), (yyvsp[-3]), (yyvsp[-2])); } -#line 2344 "pars0grm.cc" /* yacc.c:1646 */ +#line 2317 "pars0grm.cc" /* yacc.c:1646 */ break; - case 126: -#line 496 "pars0grm.y" /* yacc.c:1646 */ + case 124: +#line 491 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_while_statement((yyvsp[-4]), (yyvsp[-2])); } -#line 2350 "pars0grm.cc" /* yacc.c:1646 */ +#line 2323 "pars0grm.cc" /* yacc.c:1646 */ break; - case 127: -#line 504 "pars0grm.y" /* yacc.c:1646 */ + case 125: +#line 499 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_for_statement( static_cast<sym_node_t*>((yyvsp[-8])), (yyvsp[-6]), (yyvsp[-4]), (yyvsp[-2])); } -#line 2358 "pars0grm.cc" /* yacc.c:1646 */ +#line 2331 "pars0grm.cc" /* yacc.c:1646 */ break; - case 128: -#line 510 "pars0grm.y" /* yacc.c:1646 */ + case 126: +#line 505 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_exit_statement(); } -#line 2364 "pars0grm.cc" /* yacc.c:1646 */ +#line 2337 "pars0grm.cc" /* yacc.c:1646 */ break; - case 129: -#line 514 "pars0grm.y" /* yacc.c:1646 */ + case 127: +#line 509 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_return_statement(); } -#line 2370 "pars0grm.cc" /* yacc.c:1646 */ +#line 2343 "pars0grm.cc" /* yacc.c:1646 */ break; - case 130: -#line 519 "pars0grm.y" /* yacc.c:1646 */ + case 128: +#line 514 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_open_statement( ROW_SEL_OPEN_CURSOR, static_cast<sym_node_t*>((yyvsp[0]))); } -#line 2378 "pars0grm.cc" /* yacc.c:1646 */ +#line 2351 "pars0grm.cc" /* yacc.c:1646 */ break; - case 131: -#line 526 "pars0grm.y" /* yacc.c:1646 */ + case 129: +#line 521 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_open_statement( ROW_SEL_CLOSE_CURSOR, static_cast<sym_node_t*>((yyvsp[0]))); } -#line 2386 "pars0grm.cc" /* yacc.c:1646 */ +#line 2359 "pars0grm.cc" /* yacc.c:1646 */ break; - case 132: -#line 533 "pars0grm.y" /* yacc.c:1646 */ + case 130: +#line 528 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_fetch_statement( static_cast<sym_node_t*>((yyvsp[-2])), static_cast<sym_node_t*>((yyvsp[0])), NULL); } -#line 2394 "pars0grm.cc" /* yacc.c:1646 */ +#line 2367 "pars0grm.cc" /* yacc.c:1646 */ break; - case 133: -#line 537 "pars0grm.y" /* yacc.c:1646 */ + case 131: +#line 532 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_fetch_statement( static_cast<sym_node_t*>((yyvsp[-2])), NULL, static_cast<sym_node_t*>((yyvsp[0]))); } -#line 2403 "pars0grm.cc" /* yacc.c:1646 */ +#line 2376 "pars0grm.cc" /* yacc.c:1646 */ break; - case 134: -#line 545 "pars0grm.y" /* yacc.c:1646 */ + case 132: +#line 540 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_column_def( static_cast<sym_node_t*>((yyvsp[-4])), static_cast<pars_res_word_t*>((yyvsp[-3])), static_cast<sym_node_t*>((yyvsp[-2])), (yyvsp[-1]), (yyvsp[0])); } -#line 2413 "pars0grm.cc" /* yacc.c:1646 */ +#line 2386 "pars0grm.cc" /* yacc.c:1646 */ break; - case 135: -#line 553 "pars0grm.y" /* yacc.c:1646 */ + case 133: +#line 548 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = que_node_list_add_last(NULL, (yyvsp[0])); } -#line 2419 "pars0grm.cc" /* yacc.c:1646 */ +#line 2392 "pars0grm.cc" /* yacc.c:1646 */ break; - case 136: -#line 555 "pars0grm.y" /* yacc.c:1646 */ + case 134: +#line 550 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = que_node_list_add_last((yyvsp[-2]), (yyvsp[0])); } -#line 2425 "pars0grm.cc" /* yacc.c:1646 */ +#line 2398 "pars0grm.cc" /* yacc.c:1646 */ break; - case 137: -#line 559 "pars0grm.y" /* yacc.c:1646 */ + case 135: +#line 554 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 2431 "pars0grm.cc" /* yacc.c:1646 */ +#line 2404 "pars0grm.cc" /* yacc.c:1646 */ break; - case 138: -#line 561 "pars0grm.y" /* yacc.c:1646 */ + case 136: +#line 556 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[-1]); } -#line 2437 "pars0grm.cc" /* yacc.c:1646 */ +#line 2410 "pars0grm.cc" /* yacc.c:1646 */ break; - case 139: -#line 565 "pars0grm.y" /* yacc.c:1646 */ + case 137: +#line 560 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 2443 "pars0grm.cc" /* yacc.c:1646 */ +#line 2416 "pars0grm.cc" /* yacc.c:1646 */ break; - case 140: -#line 567 "pars0grm.y" /* yacc.c:1646 */ + case 138: +#line 562 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = &pars_int_token; /* pass any non-NULL pointer */ } -#line 2450 "pars0grm.cc" /* yacc.c:1646 */ +#line 2423 "pars0grm.cc" /* yacc.c:1646 */ break; - case 141: -#line 572 "pars0grm.y" /* yacc.c:1646 */ + case 139: +#line 567 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 2456 "pars0grm.cc" /* yacc.c:1646 */ +#line 2429 "pars0grm.cc" /* yacc.c:1646 */ break; - case 142: -#line 574 "pars0grm.y" /* yacc.c:1646 */ + case 140: +#line 569 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = &pars_int_token; /* pass any non-NULL pointer */ } -#line 2463 "pars0grm.cc" /* yacc.c:1646 */ +#line 2436 "pars0grm.cc" /* yacc.c:1646 */ break; - case 143: -#line 579 "pars0grm.y" /* yacc.c:1646 */ + case 141: +#line 574 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 2469 "pars0grm.cc" /* yacc.c:1646 */ +#line 2442 "pars0grm.cc" /* yacc.c:1646 */ break; - case 144: -#line 580 "pars0grm.y" /* yacc.c:1646 */ + case 142: +#line 575 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = &pars_int_token; /* pass any non-NULL pointer */ } -#line 2476 "pars0grm.cc" /* yacc.c:1646 */ +#line 2449 "pars0grm.cc" /* yacc.c:1646 */ break; - case 145: -#line 585 "pars0grm.y" /* yacc.c:1646 */ + case 143: +#line 580 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 2482 "pars0grm.cc" /* yacc.c:1646 */ +#line 2455 "pars0grm.cc" /* yacc.c:1646 */ break; - case 146: -#line 587 "pars0grm.y" /* yacc.c:1646 */ + case 144: +#line 582 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 2488 "pars0grm.cc" /* yacc.c:1646 */ +#line 2461 "pars0grm.cc" /* yacc.c:1646 */ break; - case 147: -#line 594 "pars0grm.y" /* yacc.c:1646 */ + case 145: +#line 589 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_create_table( static_cast<sym_node_t*>((yyvsp[-5])), static_cast<sym_node_t*>((yyvsp[-3])), static_cast<sym_node_t*>((yyvsp[-1])), static_cast<sym_node_t*>((yyvsp[0]))); } -#line 2498 "pars0grm.cc" /* yacc.c:1646 */ +#line 2471 "pars0grm.cc" /* yacc.c:1646 */ break; - case 148: -#line 602 "pars0grm.y" /* yacc.c:1646 */ + case 146: +#line 597 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = que_node_list_add_last(NULL, (yyvsp[0])); } -#line 2504 "pars0grm.cc" /* yacc.c:1646 */ +#line 2477 "pars0grm.cc" /* yacc.c:1646 */ break; - case 149: -#line 604 "pars0grm.y" /* yacc.c:1646 */ + case 147: +#line 599 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = que_node_list_add_last((yyvsp[-2]), (yyvsp[0])); } -#line 2510 "pars0grm.cc" /* yacc.c:1646 */ +#line 2483 "pars0grm.cc" /* yacc.c:1646 */ break; - case 150: -#line 608 "pars0grm.y" /* yacc.c:1646 */ + case 148: +#line 603 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 2516 "pars0grm.cc" /* yacc.c:1646 */ +#line 2489 "pars0grm.cc" /* yacc.c:1646 */ break; - case 151: -#line 609 "pars0grm.y" /* yacc.c:1646 */ + case 149: +#line 604 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = &pars_unique_token; } -#line 2522 "pars0grm.cc" /* yacc.c:1646 */ +#line 2495 "pars0grm.cc" /* yacc.c:1646 */ break; - case 152: -#line 613 "pars0grm.y" /* yacc.c:1646 */ + case 150: +#line 608 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 2528 "pars0grm.cc" /* yacc.c:1646 */ +#line 2501 "pars0grm.cc" /* yacc.c:1646 */ break; - case 153: -#line 614 "pars0grm.y" /* yacc.c:1646 */ + case 151: +#line 609 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = &pars_clustered_token; } -#line 2534 "pars0grm.cc" /* yacc.c:1646 */ +#line 2507 "pars0grm.cc" /* yacc.c:1646 */ break; - case 154: -#line 623 "pars0grm.y" /* yacc.c:1646 */ + case 152: +#line 618 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_create_index( static_cast<pars_res_word_t*>((yyvsp[-8])), static_cast<pars_res_word_t*>((yyvsp[-7])), static_cast<sym_node_t*>((yyvsp[-5])), static_cast<sym_node_t*>((yyvsp[-3])), static_cast<sym_node_t*>((yyvsp[-1]))); } -#line 2545 "pars0grm.cc" /* yacc.c:1646 */ +#line 2518 "pars0grm.cc" /* yacc.c:1646 */ break; - case 155: -#line 632 "pars0grm.y" /* yacc.c:1646 */ + case 153: +#line 627 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 2551 "pars0grm.cc" /* yacc.c:1646 */ +#line 2524 "pars0grm.cc" /* yacc.c:1646 */ break; - case 156: -#line 633 "pars0grm.y" /* yacc.c:1646 */ + case 154: +#line 628 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = (yyvsp[0]); } -#line 2557 "pars0grm.cc" /* yacc.c:1646 */ +#line 2530 "pars0grm.cc" /* yacc.c:1646 */ break; - case 157: -#line 638 "pars0grm.y" /* yacc.c:1646 */ + case 155: +#line 633 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_commit_statement(); } -#line 2563 "pars0grm.cc" /* yacc.c:1646 */ +#line 2536 "pars0grm.cc" /* yacc.c:1646 */ break; - case 158: -#line 643 "pars0grm.y" /* yacc.c:1646 */ + case 156: +#line 638 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_rollback_statement(); } -#line 2569 "pars0grm.cc" /* yacc.c:1646 */ +#line 2542 "pars0grm.cc" /* yacc.c:1646 */ break; - case 159: -#line 647 "pars0grm.y" /* yacc.c:1646 */ - { (yyval) = &pars_int_token; } -#line 2575 "pars0grm.cc" /* yacc.c:1646 */ - break; - - case 160: -#line 648 "pars0grm.y" /* yacc.c:1646 */ + case 157: +#line 642 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = &pars_int_token; } -#line 2581 "pars0grm.cc" /* yacc.c:1646 */ +#line 2548 "pars0grm.cc" /* yacc.c:1646 */ break; - case 161: -#line 649 "pars0grm.y" /* yacc.c:1646 */ + case 158: +#line 643 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = &pars_bigint_token; } -#line 2587 "pars0grm.cc" /* yacc.c:1646 */ +#line 2554 "pars0grm.cc" /* yacc.c:1646 */ break; - case 162: -#line 650 "pars0grm.y" /* yacc.c:1646 */ + case 159: +#line 644 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = &pars_char_token; } -#line 2593 "pars0grm.cc" /* yacc.c:1646 */ +#line 2560 "pars0grm.cc" /* yacc.c:1646 */ break; - case 163: -#line 651 "pars0grm.y" /* yacc.c:1646 */ + case 160: +#line 645 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = &pars_binary_token; } -#line 2599 "pars0grm.cc" /* yacc.c:1646 */ +#line 2566 "pars0grm.cc" /* yacc.c:1646 */ break; - case 164: -#line 652 "pars0grm.y" /* yacc.c:1646 */ + case 161: +#line 646 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = &pars_blob_token; } -#line 2605 "pars0grm.cc" /* yacc.c:1646 */ +#line 2572 "pars0grm.cc" /* yacc.c:1646 */ break; - case 165: -#line 657 "pars0grm.y" /* yacc.c:1646 */ + case 162: +#line 651 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_parameter_declaration( static_cast<sym_node_t*>((yyvsp[-2])), PARS_INPUT, static_cast<pars_res_word_t*>((yyvsp[0]))); } -#line 2614 "pars0grm.cc" /* yacc.c:1646 */ +#line 2581 "pars0grm.cc" /* yacc.c:1646 */ break; - case 166: -#line 662 "pars0grm.y" /* yacc.c:1646 */ + case 163: +#line 656 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_parameter_declaration( static_cast<sym_node_t*>((yyvsp[-2])), PARS_OUTPUT, static_cast<pars_res_word_t*>((yyvsp[0]))); } -#line 2623 "pars0grm.cc" /* yacc.c:1646 */ +#line 2590 "pars0grm.cc" /* yacc.c:1646 */ break; - case 167: -#line 669 "pars0grm.y" /* yacc.c:1646 */ + case 164: +#line 663 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = NULL; } -#line 2629 "pars0grm.cc" /* yacc.c:1646 */ +#line 2596 "pars0grm.cc" /* yacc.c:1646 */ break; - case 168: -#line 670 "pars0grm.y" /* yacc.c:1646 */ + case 165: +#line 664 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = que_node_list_add_last(NULL, (yyvsp[0])); } -#line 2635 "pars0grm.cc" /* yacc.c:1646 */ +#line 2602 "pars0grm.cc" /* yacc.c:1646 */ break; - case 169: -#line 672 "pars0grm.y" /* yacc.c:1646 */ + case 166: +#line 666 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = que_node_list_add_last((yyvsp[-2]), (yyvsp[0])); } -#line 2641 "pars0grm.cc" /* yacc.c:1646 */ +#line 2608 "pars0grm.cc" /* yacc.c:1646 */ break; - case 170: -#line 677 "pars0grm.y" /* yacc.c:1646 */ + case 167: +#line 671 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_variable_declaration( static_cast<sym_node_t*>((yyvsp[-2])), static_cast<pars_res_word_t*>((yyvsp[-1]))); } -#line 2649 "pars0grm.cc" /* yacc.c:1646 */ +#line 2616 "pars0grm.cc" /* yacc.c:1646 */ break; - case 174: -#line 691 "pars0grm.y" /* yacc.c:1646 */ + case 171: +#line 685 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_cursor_declaration( static_cast<sym_node_t*>((yyvsp[-3])), static_cast<sel_node_t*>((yyvsp[-1]))); } -#line 2657 "pars0grm.cc" /* yacc.c:1646 */ +#line 2624 "pars0grm.cc" /* yacc.c:1646 */ break; - case 175: -#line 698 "pars0grm.y" /* yacc.c:1646 */ + case 172: +#line 692 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_function_declaration( static_cast<sym_node_t*>((yyvsp[-1]))); } -#line 2664 "pars0grm.cc" /* yacc.c:1646 */ +#line 2631 "pars0grm.cc" /* yacc.c:1646 */ break; - case 181: -#line 720 "pars0grm.y" /* yacc.c:1646 */ + case 178: +#line 714 "pars0grm.y" /* yacc.c:1646 */ { (yyval) = pars_procedure_definition( static_cast<sym_node_t*>((yyvsp[-9])), static_cast<sym_node_t*>((yyvsp[-7])), (yyvsp[-1])); } -#line 2673 "pars0grm.cc" /* yacc.c:1646 */ +#line 2640 "pars0grm.cc" /* yacc.c:1646 */ break; -#line 2677 "pars0grm.cc" /* yacc.c:1646 */ +#line 2644 "pars0grm.cc" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -2901,5 +2868,5 @@ yyreturn: #endif return yyresult; } -#line 726 "pars0grm.y" /* yacc.c:1906 */ +#line 720 "pars0grm.y" /* yacc.c:1906 */ diff --git a/storage/innobase/pars/pars0grm.y b/storage/innobase/pars/pars0grm.y index 5f3cb41310f..9b0a6766c3e 100644 --- a/storage/innobase/pars/pars0grm.y +++ b/storage/innobase/pars/pars0grm.y @@ -48,8 +48,6 @@ yylex(void); %token PARS_INT_LIT %token PARS_FLOAT_LIT %token PARS_STR_LIT -%token PARS_FIXBINARY_LIT -%token PARS_BLOB_LIT %token PARS_NULL_LIT %token PARS_ID_TOKEN %token PARS_AND_TOKEN @@ -64,7 +62,6 @@ yylex(void); %token PARS_BINARY_TOKEN %token PARS_BLOB_TOKEN %token PARS_INT_TOKEN -%token PARS_INTEGER_TOKEN %token PARS_FLOAT_TOKEN %token PARS_CHAR_TOKEN %token PARS_IS_TOKEN @@ -200,8 +197,6 @@ exp: | PARS_INT_LIT { $$ = $1;} | PARS_FLOAT_LIT { $$ = $1;} | PARS_STR_LIT { $$ = $1;} - | PARS_FIXBINARY_LIT { $$ = $1;} - | PARS_BLOB_LIT { $$ = $1;} | PARS_NULL_LIT { $$ = $1;} | PARS_SQL_TOKEN { $$ = $1;} | exp '+' exp { $$ = pars_op('+', $1, $3); } @@ -645,7 +640,6 @@ rollback_statement: type_name: PARS_INT_TOKEN { $$ = &pars_int_token; } - | PARS_INTEGER_TOKEN { $$ = &pars_int_token; } | PARS_BIGINT_TOKEN { $$ = &pars_bigint_token; } | PARS_CHAR_TOKEN { $$ = &pars_char_token; } | PARS_BINARY_TOKEN { $$ = &pars_binary_token; } diff --git a/storage/innobase/pars/pars0sym.cc b/storage/innobase/pars/pars0sym.cc index ed49500dd94..8249af53b39 100644 --- a/storage/innobase/pars/pars0sym.cc +++ b/storage/innobase/pars/pars0sym.cc @@ -223,25 +223,15 @@ sym_tab_add_bound_lit( switch (blit->type) { case DATA_FIXBINARY: + case DATA_CHAR: + ut_ad(blit->length > 0); len = blit->length; - *lit_type = PARS_FIXBINARY_LIT; - break; - + /* fall through */ case DATA_BLOB: - *lit_type = PARS_BLOB_LIT; - break; - case DATA_VARCHAR: *lit_type = PARS_STR_LIT; break; - case DATA_CHAR: - ut_a(blit->length > 0); - - len = blit->length; - *lit_type = PARS_STR_LIT; - break; - case DATA_INT: ut_a(blit->length > 0); ut_a(blit->length <= 8); diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc index cc611725095..26bb12e8a03 100644 --- a/storage/innobase/rem/rem0rec.cc +++ b/storage/innobase/rem/rem0rec.cc @@ -1652,6 +1652,7 @@ rec_copy_prefix_to_buf( ulint prefix_len; ulint null_mask; ulint status; + bool is_rtr_node_ptr = false; UNIV_PREFETCH_RW(*buf); @@ -1673,6 +1674,7 @@ rec_copy_prefix_to_buf( /* For R-tree, we need to copy the child page number field. */ if (dict_index_is_spatial(index)) { ut_ad(n_fields == DICT_INDEX_SPATIAL_NODEPTR_SIZE + 1); + is_rtr_node_ptr = true; } else { /* it doesn't make sense to copy the child page number field */ @@ -1717,7 +1719,11 @@ rec_copy_prefix_to_buf( null_mask <<= 1; } - if (field->fixed_len) { + if (is_rtr_node_ptr && i == 1) { + /* For rtree node ptr rec, we need to + copy the page no field with 4 bytes len. */ + prefix_len += 4; + } else if (field->fixed_len) { prefix_len += field->fixed_len; } else { ulint len = *lens--; @@ -1871,17 +1877,17 @@ rec_print_old( n = rec_get_n_fields_old(rec); - fprintf(file, "PHYSICAL RECORD: n_fields %lu;" - " %u-byte offsets; info bits %lu\n", - (ulong) n, + fprintf(file, "PHYSICAL RECORD: n_fields " ULINTPF ";" + " %u-byte offsets; info bits " ULINTPF "\n", + n, rec_get_1byte_offs_flag(rec) ? 1 : 2, - (ulong) rec_get_info_bits(rec, FALSE)); + rec_get_info_bits(rec, FALSE)); for (i = 0; i < n; i++) { data = rec_get_nth_field_old(rec, i, &len); - fprintf(file, " %lu:", (ulong) i); + fprintf(file, " " ULINTPF ":", i); if (len != UNIV_SQL_NULL) { if (len <= 30) { @@ -1890,8 +1896,8 @@ rec_print_old( } else { ut_print_buf(file, data, 30); - fprintf(file, " (total %lu bytes)", - (ulong) len); + fprintf(file, " (total " ULINTPF " bytes)", + len); } } else { fprintf(file, " SQL NULL, size " ULINTPF " ", @@ -1924,7 +1930,7 @@ rec_print_comp( data = rec_get_nth_field(rec, offsets, i, &len); - fprintf(file, " %lu:", (ulong) i); + fprintf(file, " " ULINTPF ":", i); if (len != UNIV_SQL_NULL) { if (len <= 30) { @@ -1932,16 +1938,17 @@ rec_print_comp( ut_print_buf(file, data, len); } else if (rec_offs_nth_extern(offsets, i)) { ut_print_buf(file, data, 30); - fprintf(file, " (total %lu bytes, external)", - (ulong) len); + fprintf(file, + " (total " ULINTPF " bytes, external)", + len); ut_print_buf(file, data + len - BTR_EXTERN_FIELD_REF_SIZE, BTR_EXTERN_FIELD_REF_SIZE); } else { ut_print_buf(file, data, 30); - fprintf(file, " (total %lu bytes)", - (ulong) len); + fprintf(file, " (total " ULINTPF " bytes)", + len); } } else { fputs(" SQL NULL", file); @@ -2007,7 +2014,7 @@ rec_print_mbr_old( } } } else { - fprintf(file, " SQL NULL, size %lu ", + fprintf(file, " SQL NULL, size " ULINTPF " ", rec_get_nth_field_size(rec, i)); } @@ -2123,10 +2130,10 @@ rec_print_new( return; } - fprintf(file, "PHYSICAL RECORD: n_fields %lu;" - " compact format; info bits %lu\n", - (ulong) rec_offs_n_fields(offsets), - (ulong) rec_get_info_bits(rec, TRUE)); + fprintf(file, "PHYSICAL RECORD: n_fields " ULINTPF ";" + " compact format; info bits " ULINTPF "\n", + rec_offs_n_fields(offsets), + rec_get_info_bits(rec, TRUE)); rec_print_comp(file, rec, offsets); rec_validate(rec, offsets); @@ -2342,9 +2349,10 @@ wsrep_rec_get_foreign_key( data = rec_get_nth_field(rec, offsets, i, &len); if (key_len + ((len != UNIV_SQL_NULL) ? len + 1 : 1) > *buf_len) { - fprintf (stderr, - "WSREP: FK key len exceeded %lu %lu %lu\n", - key_len, len, *buf_len); + fprintf(stderr, + "WSREP: FK key len exceeded " + ULINTPF " " ULINTPF " " ULINTPF "\n", + key_len, len, *buf_len); goto err_out; } diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc index 19e1ba926d0..fca6ae5a1bf 100644 --- a/storage/innobase/row/row0ftsort.cc +++ b/storage/innobase/row/row0ftsort.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2010, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, 2016, MariaDB Corporation. +Copyright (c) 2015, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -946,7 +946,7 @@ loop: goto exit; } else if (retried > 10000) { ut_ad(!doc_item); - /* retied too many times and cannot get new record */ + /* retried too many times and cannot get new record */ ib::error() << "FTS parallel sort processed " << num_doc_processed << " records, the sort queue has " @@ -1144,7 +1144,7 @@ fts_parallel_merge( os_event_set(psort_info->psort_common->merge_event); psort_info->child_status = FTS_CHILD_EXITING; - os_thread_exit(); + os_thread_exit(false); OS_THREAD_DUMMY_RETURN; } @@ -1157,15 +1157,16 @@ row_fts_start_parallel_merge( fts_psort_t* merge_info) /*!< in: parallel sort info */ { int i = 0; - os_thread_id_t thd_id; /* Kick off merge/insert threads */ for (i = 0; i < FTS_NUM_AUX_INDEX; i++) { merge_info[i].psort_id = i; merge_info[i].child_status = 0; - merge_info[i].thread_hdl = os_thread_create(fts_parallel_merge, - (void*) &merge_info[i], &thd_id); + merge_info[i].thread_hdl = os_thread_create( + fts_parallel_merge, + (void*) &merge_info[i], + &merge_info[i].thread_hdl); } } @@ -1480,10 +1481,9 @@ row_fts_build_sel_tree_level( int child_left; int child_right; ulint i; - ulint num_item; + ulint num_item = ulint(1) << level; - start = static_cast<ulint>((1 << level) - 1); - num_item = static_cast<ulint>(1 << level); + start = num_item - 1; for (i = 0; i < num_item; i++) { child_left = sel_tree[(start + i) * 2 + 1]; @@ -1552,7 +1552,7 @@ row_fts_build_sel_tree( treelevel++; } - start = (1 << treelevel) - 1; + start = (ulint(1) << treelevel) - 1; for (i = 0; i < (int) fts_sort_pll_degree; i++) { sel_tree[i + start] = i; @@ -1673,7 +1673,7 @@ row_fts_merge_insert( } if (fts_enable_diag_print) { - ib::info() << "InnoDB_FTS: to inserted " << count_diag + ib::info() << "InnoDB_FTS: to insert " << count_diag << " records"; } diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index b70a1952f97..01a55d0dc61 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -468,16 +468,6 @@ protected: return(DB_SUCCESS); } - /** - @return true if it is a root page */ - bool is_root_page(const page_t* page) const UNIV_NOTHROW - { - ut_ad(fil_page_index_page_check(page)); - - return(mach_read_from_4(page + FIL_PAGE_NEXT) == FIL_NULL - && mach_read_from_4(page + FIL_PAGE_PREV) == FIL_NULL); - } - /** Check if the page is marked as free in the extent descriptor. @param page_no page number to check in the extent descriptor. @return true if the page is marked as free */ @@ -669,7 +659,7 @@ FetchIndexRootPages::operator() ( err = set_current_xdes(block->page.id.page_no(), page); } else if (fil_page_index_page_check(page) && !is_free(block->page.id.page_no()) - && is_root_page(page)) { + && page_is_root(page)) { index_id_t id = btr_page_get_index_id(page); @@ -1088,10 +1078,9 @@ row_import::match_index_columns( ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH, - "Index field count %lu doesn't match" - " tablespace metadata file value %lu", - (ulong) index->n_fields, - (ulong) cfg_index->m_n_fields); + "Index field count %u doesn't match" + " tablespace metadata file value " ULINTPF, + index->n_fields, cfg_index->m_n_fields); return(DB_ERROR); } @@ -1108,8 +1097,8 @@ row_import::match_index_columns( ER_TABLE_SCHEMA_MISMATCH, "Index field name %s doesn't match" " tablespace metadata field name %s" - " for field position %lu", - field->name(), cfg_field->name(), (ulong) i); + " for field position " ULINTPF, + field->name(), cfg_field->name(), i); err = DB_ERROR; } @@ -1117,12 +1106,10 @@ row_import::match_index_columns( if (cfg_field->prefix_len != field->prefix_len) { ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH, - "Index %s field %s prefix len %lu" - " doesn't match metadata file value" - " %lu", + "Index %s field %s prefix len %u" + " doesn't match metadata file value %u", index->name(), field->name(), - (ulong) field->prefix_len, - (ulong) cfg_field->prefix_len); + field->prefix_len, cfg_field->prefix_len); err = DB_ERROR; } @@ -1130,12 +1117,11 @@ row_import::match_index_columns( if (cfg_field->fixed_len != field->fixed_len) { ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH, - "Index %s field %s fixed len %lu" - " doesn't match metadata file value" - " %lu", + "Index %s field %s fixed len %u" + " doesn't match metadata file value %u", index->name(), field->name(), - (ulong) field->fixed_len, - (ulong) cfg_field->fixed_len); + field->fixed_len, + cfg_field->fixed_len); err = DB_ERROR; } @@ -1176,12 +1162,11 @@ row_import::match_table_columns( } else if (cfg_col_index != col->ind) { ib_errf(thd, IB_LOG_LEVEL_ERROR, - ER_TABLE_SCHEMA_MISMATCH, - "Column %s ordinal value mismatch, it's at" - " %lu in the table and %lu in the tablespace" - " meta-data file", - col_name, - (ulong) col->ind, (ulong) cfg_col_index); + ER_TABLE_SCHEMA_MISMATCH, + "Column %s ordinal value mismatch, it's at %u" + " in the table and " ULINTPF + " in the tablespace meta-data file", + col_name, col->ind, cfg_col_index); err = DB_ERROR; } else { @@ -1263,19 +1248,19 @@ row_import::match_schema( { /* Do some simple checks. */ - if (m_flags != m_table->flags) { + if ((m_table->flags ^ m_flags) & ~DICT_TF_MASK_DATA_DIR) { ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH, - "Table flags don't match, server table has 0x%lx" - " and the meta-data file has 0x%lx", - (ulong) m_table->n_cols, (ulong) m_flags); + "Table flags don't match, server table has 0x%x" + " and the meta-data file has 0x" ULINTPFx, + m_table->flags, m_flags); return(DB_ERROR); } else if (m_table->n_cols != m_n_cols) { ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH, - "Number of columns don't match, table has %lu" - " columns but the tablespace meta-data file has" - " %lu columns", - (ulong) m_table->n_cols, (ulong) m_n_cols); + "Number of columns don't match, table has %u" + " columns but the tablespace meta-data file has " + ULINTPF " columns", + m_table->n_cols, m_n_cols); return(DB_ERROR); } else if (UT_LIST_GET_LEN(m_table->indexes) != m_n_indexes) { @@ -1285,11 +1270,10 @@ row_import::match_schema( table matching the IMPORT definition. */ ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH, - "Number of indexes don't match, table has %lu" - " indexes but the tablespace meta-data file has" - " %lu indexes", - (ulong) UT_LIST_GET_LEN(m_table->indexes), - (ulong) m_n_indexes); + "Number of indexes don't match, table has " ULINTPF + " indexes but the tablespace meta-data file has " + ULINTPF " indexes", + UT_LIST_GET_LEN(m_table->indexes), m_n_indexes); return(DB_ERROR); } @@ -1590,9 +1574,10 @@ PageConverter::adjust_cluster_index_blob_column( ib_errf(m_trx->mysql_thd, IB_LOG_LEVEL_ERROR, ER_INNODB_INDEX_CORRUPT, - "Externally stored column(%lu) has a reference" - " length of %lu in the cluster index %s", - (ulong) i, (ulong) len, m_cluster_index->name()); + "Externally stored column(" ULINTPF + ") has a reference length of " ULINTPF + " in the cluster index %s", + i, len, m_cluster_index->name()); return(DB_CORRUPTION); } @@ -1831,12 +1816,28 @@ PageConverter::update_index_page( btr_page_set_index_id( page, m_page_zip_ptr, m_index->m_srv_index->id, 0); - page_set_max_trx_id(block, m_page_zip_ptr, m_trx->id, 0); + if (dict_index_is_clust(m_index->m_srv_index)) { + if (page_is_root(page)) { + /* Preserve the PAGE_ROOT_AUTO_INC. */ + } else { + /* Clear PAGE_MAX_TRX_ID so that it can be + used for other purposes in the future. IMPORT + in MySQL 5.6, 5.7 and MariaDB 10.0 and 10.1 + would set the field to the transaction ID even + on clustered index pages. */ + page_set_max_trx_id(block, m_page_zip_ptr, 0, NULL); + } + } else { + /* Set PAGE_MAX_TRX_ID on secondary index leaf pages, + and clear it on non-leaf pages. */ + page_set_max_trx_id(block, m_page_zip_ptr, + page_is_leaf(page) ? m_trx->id : 0, NULL); + } - if (page_is_empty(block->frame)) { + if (page_is_empty(page)) { /* Only a root page can be empty. */ - if (!is_root_page(block->frame)) { + if (!page_is_root(page)) { // TODO: We should relax this and skip secondary // indexes. Mark them as corrupt because they can // always be rebuilt. @@ -2259,11 +2260,10 @@ row_import_adjust_root_pages_of_secondary_indexes( ib_errf(trx->mysql_thd, IB_LOG_LEVEL_WARN, ER_INNODB_INDEX_CORRUPT, - "Index %s contains %lu entries," - " should be %lu, you should recreate" - " this index.", index->name(), - (ulong) purge.get_n_rows(), - (ulong) n_rows_in_table); + "Index '%s' contains " ULINTPF " entries, " + "should be " ULINTPF ", you should recreate " + "this index.", index->name(), + purge.get_n_rows(), n_rows_in_table); index->type |= DICT_CORRUPT; @@ -2564,10 +2564,10 @@ row_import_read_index_data( char msg[BUFSIZ]; ut_snprintf(msg, sizeof(msg), - "while reading index meta-data, expected" - " to read %lu bytes but read only %lu" - " bytes", - (ulong) sizeof(row), (ulong) n_bytes); + "while reading index meta-data, expected " + "to read " ULINTPF + " bytes but read only " ULINTPF " bytes", + sizeof(row), n_bytes); ib_senderrf( thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR, @@ -2619,8 +2619,8 @@ row_import_read_index_data( if (len > OS_FILE_MAX_PATH) { ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_INNODB_INDEX_CORRUPT, - "Index name length (%lu) is too long," - " the meta-data is corrupt", len); + "Index name length (" ULINTPF ") is too long, " + "the meta-data is corrupt", len); return(DB_CORRUPTION); } @@ -2702,8 +2702,8 @@ row_import_read_indexes( } else if (cfg->m_n_indexes > 1024) { // FIXME: What is the upper limit? */ ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR, - "Number of indexes in meta-data file is too high: %lu", - (ulong) cfg->m_n_indexes); + "Number of indexes in meta-data file is too high: " + ULINTPF, cfg->m_n_indexes); cfg->m_n_indexes = 0; return(DB_CORRUPTION); @@ -2807,8 +2807,8 @@ row_import_read_columns( if (len == 0 || len > 128) { ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR, - "Column name length %lu, is invalid", - (ulong) len); + "Column name length " ULINTPF ", is invalid", + len); return(DB_CORRUPTION); } @@ -3058,8 +3058,8 @@ row_import_read_meta_data( return(row_import_read_v1(file, thd, &cfg)); default: ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR, - "Unsupported meta-data version number (%lu)," - " file ignored", (ulong) cfg.m_version); + "Unsupported meta-data version number (" ULINTPF "), " + "file ignored", cfg.m_version); } return(DB_ERROR); diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index f596f3d8f27..5152d499bad 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -1596,6 +1596,10 @@ row_ins_check_foreign_constraint( ulint offsets_[REC_OFFS_NORMAL_SIZE]; ulint* offsets = offsets_; + bool skip_gap_lock; + + skip_gap_lock = (trx->isolation_level <= TRX_ISO_READ_COMMITTED); + DBUG_ENTER("row_ins_check_foreign_constraint"); rec_offs_init(offsets_); @@ -1725,6 +1729,11 @@ row_ins_check_foreign_constraint( if (page_rec_is_supremum(rec)) { + if (skip_gap_lock) { + + continue; + } + err = row_ins_set_shared_rec_lock(LOCK_ORDINARY, block, rec, check_index, offsets, thr); @@ -1740,10 +1749,17 @@ row_ins_check_foreign_constraint( cmp = cmp_dtuple_rec(entry, rec, offsets); if (cmp == 0) { + + ulint lock_type; + + lock_type = skip_gap_lock + ? LOCK_REC_NOT_GAP + : LOCK_ORDINARY; + if (rec_get_deleted_flag(rec, rec_offs_comp(offsets))) { err = row_ins_set_shared_rec_lock( - LOCK_ORDINARY, block, + lock_type, block, rec, check_index, offsets, thr); switch (err) { case DB_SUCCESS_LOCKED_REC: @@ -1824,9 +1840,13 @@ row_ins_check_foreign_constraint( } else { ut_a(cmp < 0); - err = row_ins_set_shared_rec_lock( - LOCK_GAP, block, - rec, check_index, offsets, thr); + err = DB_SUCCESS; + + if (!skip_gap_lock) { + err = row_ins_set_shared_rec_lock( + LOCK_GAP, block, + rec, check_index, offsets, thr); + } switch (err) { case DB_SUCCESS_LOCKED_REC: @@ -1878,6 +1898,8 @@ do_possible_lock_wait: my_atomic_addlint( &check_table->n_foreign_key_checks_running, 1); + trx_kill_blocking(trx); + lock_wait_suspend_thread(thr); thr->lock_state = QUE_THR_LOCK_NOLOCK; diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index 7e6975a67f1..36ad6cdd3d9 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -649,7 +649,7 @@ row_log_table_delete( &old_pk_extra_size); ut_ad(old_pk_extra_size < 0x100); - mrec_size = 4 + old_pk_size; + mrec_size = 6 + old_pk_size; /* Log enough prefix of the BLOB unless both the old and new table are in COMPACT or REDUNDANT format, @@ -686,8 +686,8 @@ row_log_table_delete( *b++ = static_cast<byte>(old_pk_extra_size); /* Log the size of external prefix we saved */ - mach_write_to_2(b, ext_size); - b += 2; + mach_write_to_4(b, ext_size); + b += 4; rec_convert_dtuple_to_temp( b + old_pk_extra_size, new_index, @@ -820,12 +820,9 @@ row_log_table_low_redundant( mrec_size = ROW_LOG_HEADER_SIZE + size + (extra_size >= 0x80); - if (ventry && ventry->n_v_fields > 0) { - ulint v_extra = 0; - mrec_size += rec_get_converted_size_temp( - index, NULL, 0, ventry, &v_extra); - + if (num_v) { if (o_ventry) { + ulint v_extra = 0; mrec_size += rec_get_converted_size_temp( index, NULL, 0, o_ventry, &v_extra); } @@ -878,11 +875,7 @@ row_log_table_low_redundant( ventry); b += size; - if (ventry && ventry->n_v_fields > 0) { - rec_convert_dtuple_to_temp( - b, new_index, NULL, 0, ventry); - b += mach_read_from_2(b); - + if (num_v) { if (o_ventry) { rec_convert_dtuple_to_temp( b, new_index, NULL, 0, o_ventry); @@ -943,6 +936,13 @@ row_log_table_low( ut_ad(fil_page_get_type(page_align(rec)) == FIL_PAGE_INDEX); ut_ad(page_is_leaf(page_align(rec))); ut_ad(!page_is_comp(page_align(rec)) == !rec_offs_comp(offsets)); + /* old_pk=row_log_table_get_pk() [not needed in INSERT] is a prefix + of the clustered index record (PRIMARY KEY,DB_TRX_ID,DB_ROLL_PTR), + with no information on virtual columns */ + ut_ad(!old_pk || !insert); + ut_ad(!old_pk || old_pk->n_v_fields == 0); + ut_ad(!o_ventry || !insert); + ut_ad(!o_ventry || ventry); if (dict_index_is_corrupted(index) || !dict_index_is_online_ddl(index) @@ -996,7 +996,7 @@ row_log_table_low( old_pk_size = rec_get_converted_size_temp( new_index, old_pk->fields, old_pk->n_fields, - old_pk, &old_pk_extra_size); + NULL, &old_pk_extra_size); ut_ad(old_pk_extra_size < 0x100); mrec_size += 1/*old_pk_extra_size*/ + old_pk_size; } @@ -2195,8 +2195,9 @@ func_exit_committed: goto func_exit_committed; } - dtuple_t* entry = row_build_index_entry( - row, NULL, index, heap); + /** It allows to create tuple with virtual column information. */ + dtuple_t* entry = row_build_index_entry_low( + row, NULL, index, heap, ROW_BUILD_FOR_INSERT); upd_t* update = row_upd_build_difference_binary( index, entry, btr_pcur_get_rec(&pcur), cur_offsets, false, NULL, heap, dup->table); @@ -2441,14 +2442,14 @@ row_log_table_apply_op( break; case ROW_T_DELETE: - /* 1 (extra_size) + 2 (ext_size) + at least 1 (payload) */ - if (mrec + 4 >= mrec_end) { + /* 1 (extra_size) + 4 (ext_size) + at least 1 (payload) */ + if (mrec + 6 >= mrec_end) { return(NULL); } extra_size = *mrec++; - ext_size = mach_read_from_2(mrec); - mrec += 2; + ext_size = mach_read_from_4(mrec); + mrec += 4; ut_ad(mrec < mrec_end); /* We assume extra_size < 0x100 for the PRIMARY KEY prefix. @@ -2459,6 +2460,10 @@ row_log_table_apply_op( rec_init_offsets_temp(mrec, new_index, offsets); next_mrec = mrec + rec_offs_data_size(offsets) + ext_size; if (log->table->n_v_cols) { + if (next_mrec + 2 >= mrec_end) { + return(NULL); + } + next_mrec += mach_read_from_2(next_mrec); } diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 85f0ce2c9e6..aeff27c31eb 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2014, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -26,6 +26,7 @@ Completed by Sunny Bains and Marko Makela *******************************************************/ #include <my_config.h> #include <log.h> +#include <sql_class.h> #include <math.h> @@ -3300,7 +3301,11 @@ row_merge_sort( } #endif /* UNIV_SOLARIS */ - sql_print_information("InnoDB: Online DDL : merge-sorting has estimated %lu runs", num_runs); + if (global_system_variables.log_warnings > 2) { + sql_print_information("InnoDB: Online DDL : merge-sorting" + " has estimated " ULINTPF " runs", + num_runs); + } /* Merge the runs until we have one big run */ do { @@ -4765,9 +4770,11 @@ row_merge_build_indexes( duplicate keys. */ innobase_rec_reset(table); - sql_print_information("InnoDB: Online DDL : Start"); - sql_print_information("InnoDB: Online DDL : Start reading clustered " - "index of the table and create temporary files"); + if (global_system_variables.log_warnings > 2) { + sql_print_information("InnoDB: Online DDL : Start reading" + " clustered index of the table" + " and create temporary files"); + } pct_cost = COST_READ_CLUSTERED_INDEX * 100 / (total_static_cost + total_dynamic_cost); @@ -4795,8 +4802,11 @@ row_merge_build_indexes( pct_progress += pct_cost; - sql_print_information("InnoDB: Online DDL : End of reading " - "clustered index of the table and create temporary files"); + if (global_system_variables.log_warnings > 2) { + sql_print_information("InnoDB: Online DDL : End of reading " + "clustered index of the table" + " and create temporary files"); + } for (i = 0; i < n_indexes; i++) { total_index_blocks += merge_files[i].offset; @@ -4875,6 +4885,13 @@ wait_again: " threads exited when creating" " FTS index '" << indexes[i]->name << "'"; + } else { + for (j = 0; j < FTS_NUM_AUX_INDEX; + j++) { + + os_thread_join(merge_info[j] + .thread_hdl); + } } } else { /* This cannot report duplicates; an @@ -4888,8 +4905,7 @@ wait_again: DEBUG_FTS_SORT_PRINT("FTS_SORT: Complete Insert\n"); #endif } else if (merge_files[i].fd >= 0) { - char buf[3 * NAME_LEN]; - char *bufend; + char buf[NAME_LEN + 1]; row_merge_dup_t dup = { sort_idx, table, col_map, 0}; @@ -4898,17 +4914,24 @@ wait_again: total_index_blocks)) / (total_static_cost + total_dynamic_cost) * PCT_COST_MERGESORT_INDEX * 100; - - bufend = innobase_convert_name( + char* bufend = innobase_convert_name( buf, sizeof buf, - indexes[i]->name, strlen(indexes[i]->name), + indexes[i]->name, + strlen(indexes[i]->name), trx->mysql_thd); - buf[bufend - buf]='\0'; - sql_print_information("InnoDB: Online DDL : Start merge-sorting" - " index %s (%lu / %lu), estimated cost : %2.4f", - buf, (i+1), n_indexes, pct_cost); + if (global_system_variables.log_warnings > 2) { + sql_print_information("InnoDB: Online DDL :" + " Start merge-sorting" + " index %s" + " (" ULINTPF + " / " ULINTPF ")," + " estimated cost :" + " %2.4f", + buf, i + 1, n_indexes, + pct_cost); + } error = row_merge_sort( trx, &dup, &merge_files[i], @@ -4918,9 +4941,14 @@ wait_again: pct_progress += pct_cost; - sql_print_information("InnoDB: Online DDL : End of " - " merge-sorting index %s (%lu / %lu)", - buf, (i+1), n_indexes); + if (global_system_variables.log_warnings > 2) { + sql_print_information("InnoDB: Online DDL :" + " End of " + " merge-sorting index %s" + " (" ULINTPF + " / " ULINTPF ")", + buf, i + 1, n_indexes); + } DBUG_EXECUTE_IF( "ib_merge_wait_after_sort", @@ -4937,10 +4965,15 @@ wait_again: (total_static_cost + total_dynamic_cost) * PCT_COST_INSERT_INDEX * 100; - sql_print_information("InnoDB: Online DDL : Start " - "building index %s (%lu / %lu), estimated " - "cost : %2.4f", buf, (i+1), - n_indexes, pct_cost); + if (global_system_variables.log_warnings > 2) { + sql_print_information( + "InnoDB: Online DDL : Start " + "building index %s" + " (" ULINTPF + " / " ULINTPF "), estimated " + "cost : %2.4f", buf, i + 1, + n_indexes, pct_cost); + } error = row_merge_insert_index_tuples( trx->id, sort_idx, old_table, @@ -4953,9 +4986,13 @@ wait_again: pct_progress += pct_cost; - sql_print_information("InnoDB: Online DDL : " - "End of building index %s (%lu / %lu)", - buf, (i+1), n_indexes); + if (global_system_variables.log_warnings > 2) { + sql_print_information( + "InnoDB: Online DDL : " + "End of building index %s" + " (" ULINTPF " / " ULINTPF ")", + buf, i + 1, n_indexes); + } } } @@ -4973,19 +5010,19 @@ wait_again: == ONLINE_INDEX_COMPLETE); } else { ut_ad(need_flush_observer); - sql_print_information("InnoDB: Online DDL : Start applying row log"); - + if (global_system_variables.log_warnings > 2) { + sql_print_information( + "InnoDB: Online DDL : Applying" + " log to index"); + } flush_observer->flush(); row_merge_write_redo(indexes[i]); DEBUG_SYNC_C("row_log_apply_before"); error = row_log_apply(trx, sort_idx, table, stage); DEBUG_SYNC_C("row_log_apply_after"); - sql_print_information("InnoDB: Online DDL : End of applying row log"); } - sql_print_information("InnoDB: Online DDL : Completed"); - if (error != DB_SUCCESS) { trx->error_key_num = key_numbers[i]; goto func_exit; diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 03d7ac628a7..aed59070396 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2000, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -1440,7 +1440,7 @@ row_insert_for_mysql( return(DB_TABLESPACE_NOT_FOUND); } else if (prebuilt->table->is_encrypted) { ib_push_warning(trx, DB_DECRYPTION_FAILED, - "Table %s in tablespace %lu encrypted." + "Table %s in tablespace " ULINTPF " encrypted." "However key management plugin or used key_id is not found or" " used encryption algorithm or method does not match.", prebuilt->table->name, prebuilt->table->space); @@ -1505,6 +1505,8 @@ run_again: row_ins_step(thr); + DEBUG_SYNC_C("ib_after_row_insert_step"); + err = trx->error_state; if (err != DB_SUCCESS) { @@ -1866,7 +1868,7 @@ row_update_for_mysql_using_upd_graph( DBUG_RETURN(DB_ERROR); } else if (prebuilt->table->is_encrypted) { ib_push_warning(trx, DB_DECRYPTION_FAILED, - "Table %s in tablespace %lu encrypted." + "Table %s in tablespace " ULINTPF " encrypted." "However key management plugin or used key_id is not found or" " used encryption algorithm or method does not match.", prebuilt->table->name, prebuilt->table->space); @@ -2888,6 +2890,10 @@ loop: return(n_tables + n_tables_dropped); } + DBUG_EXECUTE_IF("row_drop_tables_in_background_sleep", + os_thread_sleep(5000000); + ); + table = dict_table_open_on_name(drop->table_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE); @@ -2898,6 +2904,16 @@ loop: goto already_dropped; } + if (!table->to_be_dropped) { + /* There is a scenario: the old table is dropped + just after it's added into drop list, and new + table with the same name is created, then we try + to drop the new table in background. */ + dict_table_close(table, FALSE, FALSE); + + goto already_dropped; + } + ut_a(!table->can_be_evicted); dict_table_close(table, FALSE, FALSE); @@ -3766,6 +3782,13 @@ row_drop_table_for_mysql( } } + + DBUG_EXECUTE_IF("row_drop_table_add_to_background", + row_add_table_to_background_drop_list(table->name.m_name); + err = DB_SUCCESS; + goto funct_exit; + ); + /* TODO: could we replace the counter n_foreign_key_checks_running with lock checks on the table? Acquire here an exclusive lock on the table, and rewrite lock0lock.cc and the lock wait in srv0srv.cc so that @@ -4272,6 +4295,19 @@ loop: row_mysql_lock_data_dictionary(trx); while ((table_name = dict_get_first_table_name_in_db(name))) { + /* Drop parent table if it is a fts aux table, to + avoid accessing dropped fts aux tables in information + scheam when parent table still exists. + Note: Drop parent table will drop fts aux tables. */ + char* parent_table_name; + parent_table_name = fts_get_parent_table_name( + table_name, strlen(table_name)); + + if (parent_table_name != NULL) { + ut_free(table_name); + table_name = parent_table_name; + } + ut_a(memcmp(table_name, name, namelen) == 0); table = dict_table_open_on_name( @@ -5010,9 +5046,6 @@ row_scan_index_for_mysql( row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in MySQL handle */ const dict_index_t* index, /*!< in: index */ - bool check_keys, /*!< in: true=check for mis- - ordered or duplicate records, - false=count the rows only */ ulint* n_rows) /*!< out: number of entries seen in the consistent read */ { @@ -5079,7 +5112,7 @@ loop: goto func_exit; default: { - const char* doing = check_keys? "CHECK TABLE" : "COUNT(*)"; + const char* doing = "CHECK TABLE"; ib::warn() << doing << " on index " << index->name << " of" " table " << index->table->name << " returned " << ret; /* fall through (this error is ignored by CHECK TABLE) */ @@ -5095,9 +5128,6 @@ func_exit: *n_rows = *n_rows + 1; - if (!check_keys) { - goto next_rec; - } /* else this code is doing handler::check() for CHECK TABLE */ /* row_search... returns the index record in buf, record origin offset @@ -5179,7 +5209,6 @@ not_ok: } } -next_rec: ret = row_search_for_mysql( buf, PAGE_CUR_G, prebuilt, 0, ROW_SEL_NEXT); diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc index 2a13203b747..492d864ec96 100644 --- a/storage/innobase/row/row0purge.cc +++ b/storage/innobase/row/row0purge.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -43,6 +43,7 @@ Created 3/14/1997 Heikki Tuuri #include "srv0start.h" #include "handler.h" #include "ha_innodb.h" +#include "fil0fil.h" /************************************************************************* IMPORTANT NOTE: Any operation that generates redo MUST check that there @@ -852,8 +853,15 @@ try_again: /* The table has been dropped: no need to do purge */ goto err_exit; } + ut_ad(!dict_table_is_temporary(node->table)); + if (!fil_table_accessible(node->table)) { + dict_table_close(node->table, FALSE, FALSE); + node->table = NULL; + goto err_exit; + } + if (node->table->n_v_cols && !node->table->vc_templ && dict_table_has_indexed_v_cols(node->table)) { /* Need server fully up for virtual column computation */ @@ -872,16 +880,6 @@ try_again: innobase_init_vc_templ(node->table); } - if (node->table->ibd_file_missing) { - /* We skip purge of missing .ibd files */ - - dict_table_close(node->table, FALSE, FALSE); - - node->table = NULL; - - goto err_exit; - } - clust_index = dict_table_get_first_index(node->table); if (clust_index == NULL diff --git a/storage/innobase/row/row0trunc.cc b/storage/innobase/row/row0trunc.cc index 46cff288059..1fc30e714f4 100644 --- a/storage/innobase/row/row0trunc.cc +++ b/storage/innobase/row/row0trunc.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2013, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2013, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -2000,9 +2000,22 @@ row_truncate_table_for_mysql( } if (is_file_per_table && fsp_flags != ULINT_UNDEFINED) { - fil_reinit_space_header( - table->space, - table->indexes.count + FIL_IBD_FILE_INITIAL_SIZE + 1); + /* A single-table tablespace has initially + FIL_IBD_FILE_INITIAL_SIZE number of pages allocated and an + extra page is allocated for each of the indexes present. But in + the case of clust index 2 pages are allocated and as one is + covered in the calculation as part of table->indexes.count we + take care of the other page by adding 1. */ + ulint space_size = table->indexes.count + + FIL_IBD_FILE_INITIAL_SIZE + 1; + + if (has_internal_doc_id) { + /* Since aux tables are created for fts indexes and + they use seperate tablespaces. */ + space_size -= ib_vector_size(table->fts->indexes); + } + + fil_reinit_space_header(table->space, space_size, trx); } DBUG_EXECUTE_IF("ib_trunc_crash_with_intermediate_log_checkpoint", diff --git a/storage/innobase/row/row0uins.cc b/storage/innobase/row/row0uins.cc index 25504e32087..9288adb21a4 100644 --- a/storage/innobase/row/row0uins.cc +++ b/storage/innobase/row/row0uins.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -41,6 +41,7 @@ Created 2/25/1997 Heikki Tuuri #include "que0que.h" #include "ibuf0ibuf.h" #include "log0log.h" +#include "fil0fil.h" /************************************************************************* IMPORTANT NOTE: Any operation that generates redo MUST check that there @@ -345,8 +346,20 @@ row_undo_ins_parse_undo_rec( /* Skip the UNDO if we can't find the table or the .ibd file. */ if (UNIV_UNLIKELY(node->table == NULL)) { - } else if (UNIV_UNLIKELY(node->table->ibd_file_missing)) { + return; + } + + if (UNIV_UNLIKELY(!fil_table_accessible(node->table))) { close_table: + /* Normally, tables should not disappear or become + unaccessible during ROLLBACK, because they should be + protected by InnoDB table locks. TRUNCATE TABLE + or table corruption could be valid exceptions. + + FIXME: When running out of temporary tablespace, it + would probably be better to just drop all temporary + tables (and temporary undo log records) of the current + connection, instead of doing this rollback. */ dict_table_close(node->table, dict_locked, FALSE); node->table = NULL; } else { @@ -357,6 +370,9 @@ close_table: ptr, clust_index, &node->ref, node->heap); if (!row_undo_search_clust_to_pcur(node)) { + /* An error probably occurred during + an insert into the clustered index, + after we wrote the undo log record. */ goto close_table; } if (node->table->n_v_cols) { diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc index 378cad00b93..ba072a72aa1 100644 --- a/storage/innobase/row/row0umod.cc +++ b/storage/innobase/row/row0umod.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1139,12 +1139,19 @@ row_undo_mod_parse_undo_rec( return; } - if (node->table->ibd_file_missing) { + if (UNIV_UNLIKELY(!fil_table_accessible(node->table))) { +close_table: + /* Normally, tables should not disappear or become + unaccessible during ROLLBACK, because they should be + protected by InnoDB table locks. TRUNCATE TABLE + or table corruption could be valid exceptions. + + FIXME: When running out of temporary tablespace, it + would probably be better to just drop all temporary + tables (and temporary undo log records) of the current + connection, instead of doing this rollback. */ dict_table_close(node->table, dict_locked, FALSE); - - /* We skip undo operations to missing .ibd files */ node->table = NULL; - return; } @@ -1162,15 +1169,21 @@ row_undo_mod_parse_undo_rec( node->new_trx_id = trx_id; node->cmpl_info = cmpl_info; - if (!row_undo_search_clust_to_pcur(node)) { - - dict_table_close(node->table, dict_locked, FALSE); - - node->table = NULL; + if (UNIV_UNLIKELY(!row_undo_search_clust_to_pcur(node))) { + /* This should never occur. As long as this + rolling-back transaction exists, the PRIMARY KEY value + pointed to by the undo log record must exist. + btr_cur_upd_lock_and_undo() only writes the undo log + record after successfully acquiring an exclusive lock + on the the clustered index record. That lock will not + be released before the transaction is committed or + fully rolled back. */ + ut_ad(0); + goto close_table; } /* Extract indexed virtual columns from undo log */ - if (node->table && node->table->n_v_cols) { + if (node->table->n_v_cols) { row_upd_replace_vcol(node->row, node->table, node->update, false, node->undo_row, (node->cmpl_info & UPD_NODE_NO_ORD_CHANGE) diff --git a/storage/innobase/srv/srv0mon.cc b/storage/innobase/srv/srv0mon.cc index 5a3e1a2c930..f6c388f2dcf 100644 --- a/storage/innobase/srv/srv0mon.cc +++ b/storage/innobase/srv/srv0mon.cc @@ -2,7 +2,7 @@ Copyright (c) 2010, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2016, MariaDB Corporation +Copyright (c) 2013, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -739,11 +739,11 @@ static monitor_info_t innodb_counter_info[] = MONITOR_DEFAULT_START, MONITOR_OVLD_OS_FSYNC}, {"os_pending_reads", "os", "Number of reads pending", - MONITOR_NONE, + MONITOR_DEFAULT_ON, MONITOR_DEFAULT_START, MONITOR_OS_PENDING_READS}, {"os_pending_writes", "os", "Number of writes pending", - MONITOR_NONE, + MONITOR_DEFAULT_ON, MONITOR_DEFAULT_START, MONITOR_OS_PENDING_WRITES}, {"os_log_bytes_written", "os", diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index a05bb5300a3..6e010fadc6d 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -87,7 +87,7 @@ UNIV_INTERN ulong srv_fatal_semaphore_wait_threshold = DEFAULT_SRV_FATAL_SEMAPH /* How much data manipulation language (DML) statements need to be delayed, in microseconds, in order to reduce the lagging of the purge thread. */ -ulint srv_dml_needed_delay = 0; +ulint srv_dml_needed_delay; bool srv_monitor_active; bool srv_error_monitor_active; @@ -107,34 +107,34 @@ const char srv_mysql50_table_name_prefix[10] = "#mysql50#"; /* The following three are dir paths which are catenated before file names, where the file name itself may also contain a path */ -char* srv_data_home = NULL; +char* srv_data_home; /** Rollback files directory, can be absolute. */ -char* srv_undo_dir = NULL; +char* srv_undo_dir; /** The number of tablespaces to use for rollback segments. */ -ulong srv_undo_tablespaces = 0; +ulong srv_undo_tablespaces; /** The number of UNDO tablespaces that are open and ready to use. */ -ulint srv_undo_tablespaces_open = 0; +ulint srv_undo_tablespaces_open; /** The number of UNDO tablespaces that are active (hosting some rollback segment). It is quite possible that some of the tablespaces doesn't host any of the rollback-segment based on configuration used. */ -ulint srv_undo_tablespaces_active = 0; +ulint srv_undo_tablespaces_active; /* The number of rollback segments to use */ -ulong srv_undo_logs = 1; +ulong srv_undo_logs; /** Rate at which UNDO records should be purged. */ -ulong srv_purge_rseg_truncate_frequency = 128; +ulong srv_purge_rseg_truncate_frequency; /** Enable or Disable Truncate of UNDO tablespace. Note: If enabled then UNDO tablespace will be selected for truncate. While Server waits for undo-tablespace to truncate if user disables it, truncate action is completed but no new tablespace is marked for truncate (action is never aborted). */ -my_bool srv_undo_log_truncate = FALSE; +my_bool srv_undo_log_truncate; /** Maximum size of undo tablespace. */ unsigned long long srv_max_undo_log_size; @@ -151,7 +151,7 @@ my_bool srv_read_only_mode; dictionary tables are in the system tablespace 0 */ my_bool srv_file_per_table; /** The file format to use on new *.ibd files. */ -ulint srv_file_format = 0; +ulint srv_file_format; /** Whether to check file format during startup. A value of UNIV_FORMAT_MAX + 1 means no checking ie. FALSE. The default is to set it to the highest format we support. */ @@ -166,9 +166,9 @@ my_bool high_level_read_only; /** Place locks to records only i.e. do not use next-key locking except on duplicate key checking and foreign key checking */ -ibool srv_locks_unsafe_for_binlog = FALSE; +ibool srv_locks_unsafe_for_binlog; /** Sort buffer size in index creation */ -ulong srv_sort_buf_size = 1048576; +ulong srv_sort_buf_size; /** Maximum modification log file size for online index creation */ unsigned long long srv_online_max_size; @@ -176,19 +176,19 @@ unsigned long long srv_online_max_size; 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 */ -my_bool srv_use_native_aio = TRUE; -my_bool srv_numa_interleave = FALSE; -/* If this flag is TRUE, then we will use fallocate(PUCH_HOLE) -to the pages */ -UNIV_INTERN my_bool srv_use_trim; -/* If this flag is TRUE, then we disable doublewrite buffer */ -UNIV_INTERN my_bool srv_use_atomic_writes = FALSE; -/* If this flag IS TRUE, then we use this algorithm for page compressing the pages */ -UNIV_INTERN ulong innodb_compression_algorithm = PAGE_ZLIB_ALGORITHM; -/* Number of threads used for multi-threaded flush */ -UNIV_INTERN long srv_mtflush_threads = MTFLUSH_DEFAULT_WORKER; -/* If this flag is TRUE, then we will use multi threaded flush. */ -UNIV_INTERN my_bool srv_use_mtflush = FALSE; +my_bool srv_use_native_aio; +my_bool srv_numa_interleave; +/** innodb_use_trim; whether to use fallocate(PUNCH_HOLE) with +page_compression */ +my_bool srv_use_trim; +/** copy of innodb_use_atomic_writes; @see innobase_init() */ +my_bool srv_use_atomic_writes; +/** innodb_compression_algorithm; used with page compression */ +ulong innodb_compression_algorithm; +/** innodb_mtflush_threads; number of threads used for multi-threaded flush */ +long srv_mtflush_threads; +/** innodb_use_mtflush; whether to use multi threaded flush. */ +my_bool srv_use_mtflush; #ifdef UNIV_DEBUG /** Used by SET GLOBAL innodb_master_thread_disabled_debug = X. */ @@ -215,22 +215,27 @@ During startup, this is in bytes, and later converted to pages. */ ib_uint64_t srv_log_file_size; /** The value of the startup parameter innodb_log_file_size */ ib_uint64_t srv_log_file_size_requested; -/* size in database pages */ -ulint srv_log_buffer_size = ULINT_MAX; -ulong srv_flush_log_at_trx_commit = 1; -uint srv_flush_log_at_timeout = 1; -ulong srv_page_size = UNIV_PAGE_SIZE_DEF; -ulong srv_page_size_shift = UNIV_PAGE_SIZE_SHIFT_DEF; -ulong srv_log_write_ahead_size = 0; +/** copy of innodb_log_buffer_size, but in database pages */ +ulint srv_log_buffer_size; +/** innodb_flush_log_at_trx_commit */ +ulong srv_flush_log_at_trx_commit; +/** innodb_flush_log_at_timeout */ +uint srv_flush_log_at_timeout; +/** innodb_page_size */ +ulong srv_page_size; +/** log2 of innodb_page_size; @see innobase_init() */ +ulong srv_page_size_shift; +/** innodb_log_write_ahead_size */ +ulong srv_log_write_ahead_size; page_size_t univ_page_size(0, 0, false); -/* Try to flush dirty pages so as to avoid IO bursts at -the checkpoints. */ -char srv_adaptive_flushing = TRUE; +/** innodb_adaptive_flushing; try to flush dirty pages so as to avoid +IO bursts at the checkpoints. */ +my_bool srv_adaptive_flushing; -/* Allow IO bursts at the checkpoints ignoring io_capacity setting. */ -my_bool srv_flush_sync = TRUE; +/** innodb_flush_sync; whether to ignore io_capacity at log checkpoints */ +my_bool srv_flush_sync; /** Maximum number of times allowed to conditionally acquire mutex before switching to blocking wait on the mutex */ @@ -246,93 +251,100 @@ with mutex_enter(), which will wait until it gets the mutex. */ UNIV_INTERN os_event_t srv_allow_writes_event; #endif /* WITH_INNODB_DISALLOW_WRITES */ -/** Requested size in bytes */ -ulint srv_buf_pool_size = ULINT_MAX; +/** copy of innodb_buffer_pool_size */ +ulint srv_buf_pool_size; const ulint srv_buf_pool_min_size = 5 * 1024 * 1024; /** Default pool size in bytes */ const ulint srv_buf_pool_def_size = 128 * 1024 * 1024; /** Requested buffer pool chunk size. Each buffer pool instance consists of one or more chunks. */ ulong srv_buf_pool_chunk_unit; -/** Requested number of buffer pool instances */ +/** innodb_buffer_pool_instances (0 is interpreted as 1) */ ulong srv_buf_pool_instances; -/** Default number of buffer pool instances */ +/** Default value of innodb_buffer_pool_instances */ const ulong srv_buf_pool_instances_default = 0; -/** Number of locks to protect buf_pool->page_hash */ +/** innodb_page_hash_locks (a debug-only parameter); +number of locks to protect buf_pool->page_hash */ ulong srv_n_page_hash_locks = 16; -/** Scan depth for LRU flush batch i.e.: number of blocks scanned*/ -ulong srv_LRU_scan_depth = 1024; -/** Whether or not to flush neighbors of a block */ -ulong srv_flush_neighbors = 1; +/** innodb_lru_scan_depth; number of blocks scanned in LRU flush batch */ +ulong srv_LRU_scan_depth; +/** innodb_flush_neighbors; whether or not to flush neighbors of a block */ +ulong srv_flush_neighbors; /** Previously requested size */ -ulint srv_buf_pool_old_size = 0; +ulint srv_buf_pool_old_size; /** Current size as scaling factor for the other components */ -ulint srv_buf_pool_base_size = 0; +ulint srv_buf_pool_base_size; /** Current size in bytes */ -ulint srv_buf_pool_curr_size = 0; +ulint srv_buf_pool_curr_size; /** Dump this % of each buffer pool during BP dump */ ulong srv_buf_pool_dump_pct; /** Lock table size in bytes */ ulint srv_lock_table_size = ULINT_MAX; -UNIV_INTERN ulong srv_idle_flush_pct = 100; +/** innodb_idle_flush_pct */ +ulong srv_idle_flush_pct; -/* This parameter is deprecated. Use srv_n_io_[read|write]_threads -instead. */ -ulint srv_n_read_io_threads = ULINT_MAX; -ulint srv_n_write_io_threads = ULINT_MAX; +/** copy of innodb_read_io_threads */ +ulint srv_n_read_io_threads; +/** copy of innodb_write_io_threads */ +ulint srv_n_write_io_threads; -/* Switch to enable random read ahead. */ -my_bool srv_random_read_ahead = FALSE; -/* User settable value of the number of pages that must be present +/** innodb_random_read_ahead */ +my_bool srv_random_read_ahead; +/** innodb_read_ahead_threshold; the number of pages that must be present in the buffer cache and accessed sequentially for InnoDB to trigger a readahead request. */ -ulong srv_read_ahead_threshold = 56; +ulong srv_read_ahead_threshold; -/** Maximum on-disk size of change buffer in terms of percentage -of the buffer pool. */ -uint srv_change_buffer_max_size = CHANGE_BUFFER_DEFAULT_SIZE; +/** innodb_change_buffer_max_size; maximum on-disk size of change +buffer in terms of percentage of the buffer pool. */ +uint srv_change_buffer_max_size; -char* srv_file_flush_method_str = NULL; +char* srv_file_flush_method_str; enum srv_flush_t srv_file_flush_method = IF_WIN(SRV_ALL_O_DIRECT_FSYNC,SRV_FSYNC); -ulint srv_max_n_open_files = 300; +/** copy of innodb_open_files, initialized by innobase_init() */ +ulint srv_max_n_open_files; -/* Number of IO operations per second the server can do */ -ulong srv_io_capacity = 200; -ulong srv_max_io_capacity = 400; +/** innodb_io_capacity */ +ulong srv_io_capacity; +/** innodb_io_capacity_max */ +ulong srv_max_io_capacity; -/* The number of page cleaner threads to use.*/ -ulong srv_n_page_cleaners = 4; +/** innodb_page_cleaners; the number of page cleaner threads */ +ulong srv_n_page_cleaners; /* The InnoDB main thread tries to keep the ratio of modified pages in the buffer pool to all database pages in the buffer pool smaller than the following number. But it is not guaranteed that the value stays below that during a time of heavy update/insert activity. */ -double srv_max_buf_pool_modified_pct = 75.0; -double srv_max_dirty_pages_pct_lwm = 0.0; +/** innodb_max_dirty_pages_pct */ +double srv_max_buf_pool_modified_pct; +/** innodb_max_dirty_pages_pct_lwm */ +double srv_max_dirty_pages_pct_lwm; -/* This is the percentage of log capacity at which adaptive flushing, -if enabled, will kick in. */ -UNIV_INTERN double srv_adaptive_flushing_lwm = 10.0; +/** innodb_adaptive_flushing_lwm; the percentage of log capacity at +which adaptive flushing, if enabled, will kick in. */ +double srv_adaptive_flushing_lwm; -/* Number of iterations over which adaptive flushing is averaged. */ -ulong srv_flushing_avg_loops = 30; +/** innodb_flushing_avg_loops; number of iterations over which +adaptive flushing is averaged */ +ulong srv_flushing_avg_loops; -/* The number of purge threads to use.*/ -ulong srv_n_purge_threads = 4; +/** innodb_purge_threads; the number of purge threads to use */ +ulong srv_n_purge_threads; -/* the number of pages to purge in one batch */ -ulong srv_purge_batch_size = 20; +/** innodb_purge_batch_size, in pages */ +ulong srv_purge_batch_size; -/* Internal setting for "innodb_stats_method". Decides how InnoDB treats +/** innodb_stats_method decides how InnoDB treats NULL value when collecting statistics. By default, it is set to SRV_STATS_NULLS_EQUAL(0), ie. all NULL value are treated equal */ -ulong srv_innodb_stats_method = SRV_STATS_NULLS_EQUAL; +ulong srv_innodb_stats_method; srv_stats_t srv_stats; @@ -345,59 +357,67 @@ by SELECT or mysqldump. When this is nonzero, we do not allow any user modifications to the data. */ ulong srv_force_recovery; -/** Print all user-level transactions deadlocks to mysqld stderr */ +/** innodb_print_all_deadlocks; whether to print all user-level +transactions deadlocks to the error log */ +my_bool srv_print_all_deadlocks; -my_bool srv_print_all_deadlocks = FALSE; +/** innodb_cmp_per_index_enabled; enable +INFORMATION_SCHEMA.innodb_cmp_per_index */ +my_bool srv_cmp_per_index_enabled; -/** Enable INFORMATION_SCHEMA.innodb_cmp_per_index */ -my_bool srv_cmp_per_index_enabled = FALSE; - -/* If the following is set to 1 then we do not run purge and insert buffer +/** innodb_fast_shutdown; if 1 then we do not run purge and insert buffer merge to completion before shutdown. If it is set to 2, do not even flush the buffer pool to data files at the shutdown: we effectively 'crash' InnoDB (but lose no committed transactions). */ uint srv_fast_shutdown; -/* Generate a innodb_status.<pid> file */ -ibool srv_innodb_status = FALSE; +/** copy of innodb_status_file; generate a innodb_status.<pid> file */ +ibool srv_innodb_status; -/* Optimize prefix index queries to skip cluster index lookup when possible */ -/* Enables or disables this prefix optimization. Disabled by default. */ -UNIV_INTERN my_bool srv_prefix_index_cluster_optimization = 0; +/** innodb_prefix_index_cluster_optimization; whether to optimize +prefix index queries to skip cluster index lookup when possible */ +my_bool srv_prefix_index_cluster_optimization; -/* When estimating number of different key values in an index, sample +/** innodb_stats_transient_sample_pages; +When estimating number of different key values in an index, sample this many index pages, there are 2 ways to calculate statistics: * persistent stats that are calculated by ANALYZE TABLE and saved in the innodb database. * quick transient stats, that are used if persistent stats for the given table/index are not found in the innodb database */ -unsigned long long srv_stats_transient_sample_pages = 8; -my_bool srv_stats_persistent = TRUE; -unsigned long long srv_stats_persistent_sample_pages = 20; -my_bool srv_stats_auto_recalc = TRUE; - -/* The number of rows modified before we calculate new statistics (default 0 -= current limits) */ -UNIV_INTERN unsigned long long srv_stats_modified_counter = 0; - -/* Enable traditional statistic calculation based on number of configured -pages default true. */ -UNIV_INTERN my_bool srv_stats_sample_traditional = TRUE; - -ibool srv_use_doublewrite_buf = TRUE; - -/** doublewrite buffer is 1MB is size i.e.: it can hold 128 16K pages. -The following parameter is the size of the buffer that is used for -batch flushing i.e.: LRU flushing and flush_list flushing. The rest -of the pages are used for single page flushing. */ -ulong srv_doublewrite_batch_size = 120; - -ulong srv_replication_delay = 0; - -/*-------------------------------------------*/ -UNIV_INTERN ulong srv_n_spin_wait_rounds = 15; +unsigned long long srv_stats_transient_sample_pages; +/** innodb_stats_persistent */ +my_bool srv_stats_persistent; +/** innodb_stats_include_delete_marked */ +my_bool srv_stats_include_delete_marked; +/** innodb_stats_persistent_sample_pages */ +unsigned long long srv_stats_persistent_sample_pages; +/** innodb_stats_auto_recalc */ +my_bool srv_stats_auto_recalc; + +/** innodb_stats_modified_counter; The number of rows modified before +we calculate new statistics (default 0 = current limits) */ +unsigned long long srv_stats_modified_counter; + +/** innodb_stats_traditional; enable traditional statistic calculation +based on number of configured pages */ +my_bool srv_stats_sample_traditional; + +/** copy of innodb_doublewrite */ +ibool srv_use_doublewrite_buf; + +/** innodb_doublewrite_batch_size (a debug parameter) specifies the +number of pages to use in LRU and flush_list batch flushing. +The rest of the doublewrite buffer is used for single-page flushing. */ +ulong srv_doublewrite_batch_size = 120; + +/** innodb_replication_delay */ +ulong srv_replication_delay; + +/** innodb_sync_spin_loops */ +ulong srv_n_spin_wait_rounds; +/** innodb_spin_wait_delay */ uint srv_spin_wait_delay; -ibool srv_priority_boost = TRUE; static ulint srv_n_rows_inserted_old; static ulint srv_n_rows_updated_old; @@ -424,23 +444,29 @@ UNIV_INTERN ib_uint64_t srv_index_page_decompressed; /* Defragmentation */ UNIV_INTERN my_bool srv_defragment; -UNIV_INTERN uint srv_defragment_n_pages = 7; +/** innodb_defragment_n_pages */ +UNIV_INTERN uint srv_defragment_n_pages; UNIV_INTERN uint srv_defragment_stats_accuracy; -UNIV_INTERN uint srv_defragment_fill_factor_n_recs = 20; -UNIV_INTERN double srv_defragment_fill_factor = 0.9; -UNIV_INTERN uint srv_defragment_frequency = - SRV_DEFRAGMENT_FREQUENCY_DEFAULT; +/** innodb_defragment_fill_factor_n_recs */ +UNIV_INTERN uint srv_defragment_fill_factor_n_recs; +/** innodb_defragment_fill_factor */ +UNIV_INTERN double srv_defragment_fill_factor; +/** innodb_defragment_frequency */ +UNIV_INTERN uint srv_defragment_frequency; +/** derived from innodb_defragment_frequency; +@see innodb_defragment_frequency_update() */ UNIV_INTERN ulonglong srv_defragment_interval; /* Set the following to 0 if you want InnoDB to write messages on -stderr on startup/shutdown. */ -ibool srv_print_verbose_log = TRUE; -my_bool srv_print_innodb_monitor = FALSE; -my_bool srv_print_innodb_lock_monitor = FALSE; -my_bool srv_print_innodb_tablespace_monitor = FALSE; -my_bool srv_print_innodb_table_monitor = FALSE; -/** If this flag is set tables without primary key are not allowed */ -my_bool srv_force_primary_key = FALSE; +stderr on startup/shutdown. Not enabled on the embedded server. */ +ibool srv_print_verbose_log; +my_bool srv_print_innodb_monitor; +my_bool srv_print_innodb_lock_monitor; +my_bool srv_print_innodb_tablespace_monitor; +my_bool srv_print_innodb_table_monitor; +/** innodb_force_primary_key; whether to disallow CREATE TABLE without +PRIMARY KEY */ +my_bool srv_force_primary_key; /* Array of English strings describing the current state of an i/o handler thread */ @@ -473,19 +499,19 @@ ib_mutex_t srv_misc_tmpfile_mutex; /** Temporary file for miscellanous diagnostic output */ FILE* srv_misc_tmpfile; -static ulint srv_main_thread_process_no = 0; -static ulint srv_main_thread_id = 0; +static ulint srv_main_thread_process_no; +static ulint srv_main_thread_id; /* The following counts are used by the srv_master_thread. */ /** Iterations of the loop bounded by 'srv_active' label. */ -static ulint srv_main_active_loops = 0; +static ulint srv_main_active_loops; /** Iterations of the loop bounded by the 'srv_idle' label. */ -static ulint srv_main_idle_loops = 0; +static ulint srv_main_idle_loops; /** Iterations of the loop bounded by the 'srv_shutdown' label. */ -static ulint srv_main_shutdown_loops = 0; +static ulint srv_main_shutdown_loops; /** Log writes involving flush. */ -static ulint srv_log_writes_and_flush = 0; +static ulint srv_log_writes_and_flush; /* This is only ever touched by the master thread. It records the time when the last flush of log file has happened. The master @@ -506,10 +532,10 @@ current_time % 5 != 0. */ # define SRV_MASTER_DICT_LRU_INTERVAL (47) /** Simulate compression failures. */ -UNIV_INTERN uint srv_simulate_comp_failures = 0; +UNIV_INTERN uint srv_simulate_comp_failures; /** Buffer pool dump status frequence in percentages */ -UNIV_INTERN ulong srv_buf_dump_status_frequency = 0; +UNIV_INTERN ulong srv_buf_dump_status_frequency; /** Acquire the system_mutex. */ #define srv_sys_mutex_enter() do { \ @@ -622,14 +648,16 @@ struct srv_sys_t{ ulint n_threads_active[SRV_MASTER + 1]; /*!< number of threads active - in a thread class */ + in a thread class; protected + by both my_atomic_addlint() + and mutex */ srv_stats_t::ulint_ctr_1_t activity_count; /*!< For tracking server activity */ }; -static srv_sys_t* srv_sys = NULL; +static srv_sys_t* srv_sys; /** Event to signal srv_monitor_thread. Not protected by a mutex. Set after setting srv_print_innodb_monitor. */ @@ -709,13 +737,12 @@ srv_print_master_thread_info( /*=========================*/ FILE *file) /* in: output stream */ { - fprintf(file, "srv_master_thread loops: %lu srv_active," - " %lu srv_shutdown, %lu srv_idle\n", + fprintf(file, "srv_master_thread loops: " ULINTPF " srv_active, " + ULINTPF " srv_shutdown, " ULINTPF " srv_idle\n" + "srv_master_thread log flush and writes: " ULINTPF "\n", srv_main_active_loops, srv_main_shutdown_loops, - srv_main_idle_loops); - fprintf(file, - "srv_master_thread log flush and writes: " ULINTPF "\n", + srv_main_idle_loops, srv_log_writes_and_flush); } @@ -828,7 +855,7 @@ srv_reserve_slot( ut_ad(srv_slot_get_type(slot) == type); - ++srv_sys->n_threads_active[type]; + my_atomic_addlint(&srv_sys->n_threads_active[type], 1); srv_sys_mutex_exit(); @@ -869,16 +896,15 @@ srv_suspend_thread_low( case SRV_WORKER: ut_a(srv_n_purge_threads > 1); - ut_a(srv_sys->n_threads_active[type] > 0); break; } ut_a(!slot->suspended); slot->suspended = TRUE; - ut_a(srv_sys->n_threads_active[type] > 0); - - srv_sys->n_threads_active[type]--; + if (my_atomic_addlint(&srv_sys->n_threads_active[type], -1) < 0) { + ut_error; + } return(os_event_reset(slot->event)); } @@ -933,7 +959,7 @@ srv_resume_thread(srv_slot_t* slot, int64_t sig_count = 0, bool wait = true, ut_ad(slot->suspended); slot->suspended = FALSE; - ++srv_sys->n_threads_active[slot->type]; + my_atomic_addlint(&srv_sys->n_threads_active[slot->type], 1); srv_sys_mutex_exit(); return(timeout); } @@ -1384,13 +1410,13 @@ srv_printf_innodb_monitor( srv_conc_get_waiting_threads()); /* This is a dirty read, without holding trx_sys->mutex. */ - fprintf(file, "%lu read views open inside InnoDB\n", + fprintf(file, ULINTPF " read views open inside InnoDB\n", trx_sys->mvcc->size()); n_reserved = fil_space_get_n_reserved_extents(0); if (n_reserved > 0) { fprintf(file, - "%lu tablespace extents now reserved for" + ULINTPF " tablespace extents now reserved for" " B-tree split operations\n", n_reserved); } @@ -1482,10 +1508,10 @@ srv_export_innodb_status(void) mutex_enter(&srv_innodb_monitor_mutex); export_vars.innodb_data_pending_reads = - os_n_pending_reads; + ulint(MONITOR_VALUE(MONITOR_OS_PENDING_READS)); export_vars.innodb_data_pending_writes = - os_n_pending_writes; + ulint(MONITOR_VALUE(MONITOR_OS_PENDING_WRITES)); export_vars.innodb_data_pending_fsyncs = fil_n_pending_log_flushes @@ -1948,8 +1974,8 @@ loop: "WSREP: avoiding InnoDB self crash due to long " "semaphore wait of > %lu seconds\n" "Server is processing SST donor operation, " - "fatal_cnt now: %lu", - (ulong) srv_fatal_semaphore_wait_threshold, fatal_cnt); + "fatal_cnt now: " ULINTPF, + srv_fatal_semaphore_wait_threshold, fatal_cnt); } #endif /* WITH_WSREP */ if (fatal_cnt > 10) { @@ -2041,22 +2067,16 @@ srv_get_active_thread_type(void) return(ret); } -/*******************************************************************//** -Tells the InnoDB server that there has been activity in the database -and wakes up the master thread if it is suspended (not sleeping). Used -in the MySQL interface. Note that there is a small chance that the master -thread stays suspended (we do not protect our operation with the -srv_sys_t->mutex, for performance reasons). */ +/** Wake up the InnoDB master thread if it was suspended (not sleeping). */ void srv_active_wake_master_thread_low() -/*===============================*/ { ut_ad(!srv_read_only_mode); ut_ad(!srv_sys_mutex_own()); srv_inc_activity_count(); - if (srv_sys->n_threads_active[SRV_MASTER] == 0) { + if (my_atomic_loadlint(&srv_sys->n_threads_active[SRV_MASTER]) == 0) { srv_slot_t* slot; srv_sys_mutex_enter(); @@ -2074,35 +2094,25 @@ srv_active_wake_master_thread_low() } } -/*******************************************************************//** -Tells the purge thread that there has been activity in the database -and wakes up the purge thread if it is suspended (not sleeping). Note -that there is a small chance that the purge thread stays suspended -(we do not protect our check with the srv_sys_t:mutex and the -purge_sys->latch, for performance reasons). */ +/** Wake up the purge threads if there is work to do. */ void -srv_wake_purge_thread_if_not_active(void) -/*=====================================*/ +srv_wake_purge_thread_if_not_active() { ut_ad(!srv_sys_mutex_own()); if (purge_sys->state == PURGE_STATE_RUN - && srv_sys->n_threads_active[SRV_PURGE] == 0) { + && !my_atomic_loadlint(&srv_sys->n_threads_active[SRV_PURGE]) + && my_atomic_loadlint(&trx_sys->rseg_history_len)) { srv_release_threads(SRV_PURGE, 1); } } -/*******************************************************************//** -Wakes up the master thread if it is suspended or being suspended. */ +/** Wake up the master thread if it is suspended or being suspended. */ void -srv_wake_master_thread(void) -/*========================*/ +srv_wake_master_thread() { - ut_ad(!srv_sys_mutex_own()); - srv_inc_activity_count(); - srv_release_threads(SRV_MASTER, 1); } @@ -2688,12 +2698,8 @@ DECLARE_THREAD(srv_worker_thread)( slot = srv_reserve_slot(SRV_WORKER); ut_a(srv_n_purge_threads > 1); - - srv_sys_mutex_enter(); - - ut_a(srv_sys->n_threads_active[SRV_WORKER] < srv_n_purge_threads); - - srv_sys_mutex_exit(); + ut_a(my_atomic_loadlint(&srv_sys->n_threads_active[SRV_WORKER]) + < static_cast<lint>(srv_n_purge_threads)); /* We need to ensure that the worker threads exit after the purge coordinator thread. Otherwise the purge coordinator can @@ -2966,14 +2972,9 @@ DECLARE_THREAD(srv_purge_coordinator_thread)( ut_a(srv_purge_should_exit(thd, n_total_purged)); - ulint n_pages_purged = ULINT_MAX; - - /* Ensure that all records are purged if it is not a fast shutdown. - This covers the case where a record can be added after we exit the - loop above. */ - while (srv_fast_shutdown == 0 && n_pages_purged > 0) { - n_pages_purged = trx_purge(1, srv_purge_batch_size, false); - } + /* Ensure that all records are purged on slow shutdown. */ + while (srv_fast_shutdown == 0 + && trx_purge(1, srv_purge_batch_size, false)); #ifdef UNIV_DEBUG if (srv_fast_shutdown == 0) { @@ -2987,12 +2988,10 @@ DECLARE_THREAD(srv_purge_coordinator_thread)( delay in shutdown ,so reducing the batch size to magic number 20 (which was default in 5.5), which we hope will be sufficient to remove all the undo records */ - const uint temp_batch_size = 20; - n_pages_purged = trx_purge(1, srv_purge_batch_size <= temp_batch_size - ? srv_purge_batch_size : temp_batch_size, - true); - ut_a(n_pages_purged == 0 || srv_fast_shutdown != 0); + if (trx_purge(1, std::min(srv_purge_batch_size, 20UL), true)) { + ut_a(srv_fast_shutdown); + } /* The task queue should always be empty, independent of fast shutdown state. */ diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index bcb52fc5bfb..6d153ff1bc6 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -121,22 +121,22 @@ lsn_t srv_start_lsn; lsn_t srv_shutdown_lsn; /** TRUE if a raw partition is in use */ -ibool srv_start_raw_disk_in_use = FALSE; +ibool srv_start_raw_disk_in_use; /** Number of IO threads to use */ -ulint srv_n_file_io_threads = 0; +ulint srv_n_file_io_threads; /** TRUE if the server is being started, before rolling back any incomplete transactions */ -bool srv_startup_is_before_trx_rollback_phase = false; +bool srv_startup_is_before_trx_rollback_phase; /** TRUE if the server is being started */ -bool srv_is_being_started = false; +bool srv_is_being_started; /** TRUE if SYS_TABLESPACES is available for lookups */ -bool srv_sys_tablespaces_open = false; +bool srv_sys_tablespaces_open; /** TRUE if the server was successfully started */ -ibool srv_was_started = FALSE; +bool srv_was_started; /** TRUE if innobase_start_or_create_for_mysql() has been called */ -static ibool srv_start_has_been_called = FALSE; +static bool srv_start_has_been_called; #ifdef UNIV_DEBUG /** InnoDB system tablespace to set during recovery */ UNIV_INTERN uint srv_sys_space_size_debug; @@ -743,7 +743,7 @@ srv_check_undo_redo_logs_exists() ut_snprintf( name, sizeof(name), - "%s%cundo%03lu", + "%s%cundo%03zu", srv_undo_dir, OS_PATH_SEPARATOR, i); @@ -836,7 +836,7 @@ srv_undo_tablespaces_init(bool create_new_db) ut_snprintf( name, sizeof(name), - "%s%cundo%03lu", + "%s%cundo%03zu", srv_undo_dir, OS_PATH_SEPARATOR, i + 1); /* Undo space ids start from 1. */ @@ -872,7 +872,7 @@ srv_undo_tablespaces_init(bool create_new_db) char name[OS_FILE_MAX_PATH]; ut_snprintf(name, sizeof(name), - "%s%cundo%03lu", + "%s%cundo%03zu", srv_undo_dir, OS_PATH_SEPARATOR, undo_tablespace_ids[i]); @@ -894,6 +894,7 @@ srv_undo_tablespaces_init(bool create_new_db) } } } else { + srv_undo_tablespaces_active = srv_undo_tablespaces; n_undo_tablespaces = srv_undo_tablespaces; for (i = 1; i <= n_undo_tablespaces; ++i) { @@ -913,7 +914,7 @@ srv_undo_tablespaces_init(bool create_new_db) ut_snprintf( name, sizeof(name), - "%s%cundo%03lu", + "%s%cundo%03zu", srv_undo_dir, OS_PATH_SEPARATOR, undo_tablespace_ids[i]); @@ -949,7 +950,7 @@ srv_undo_tablespaces_init(bool create_new_db) ut_snprintf( name, sizeof(name), - "%s%cundo%03lu", srv_undo_dir, OS_PATH_SEPARATOR, i); + "%s%cundo%03zu", srv_undo_dir, OS_PATH_SEPARATOR, i); /* Undo space ids start from 1. */ err = srv_undo_tablespace_open(name, i); @@ -975,12 +976,10 @@ srv_undo_tablespaces_init(bool create_new_db) return(err != DB_SUCCESS ? err : DB_ERROR); - } else if (n_undo_tablespaces > 0) { + } else if (n_undo_tablespaces > 0) { ib::info() << "Opened " << n_undo_tablespaces - << " undo tablespaces (" - << srv_undo_tablespaces_active - << " active)"; + << " undo tablespaces"; if (srv_undo_tablespaces == 0) { ib::warn() << "innodb_undo_tablespaces=0 disables" @@ -1443,6 +1442,10 @@ innobase_start_or_create_for_mysql(void) size_t dirnamelen; unsigned i = 0; + if (srv_force_recovery == SRV_FORCE_NO_LOG_REDO) { + srv_read_only_mode = true; + } + high_level_read_only = srv_read_only_mode || srv_force_recovery > SRV_FORCE_NO_TRX_UNDO; @@ -1519,7 +1522,7 @@ innobase_start_or_create_for_mysql(void) " once during the process lifetime."; } - srv_start_has_been_called = TRUE; + srv_start_has_been_called = true; srv_is_being_started = true; @@ -2756,9 +2759,9 @@ innodb_shutdown() logs_empty_and_mark_files_at_shutdown(); - if (srv_conc_get_active_threads() != 0) { + if (ulint n_threads = srv_conc_get_active_threads()) { ib::warn() << "Query counter shows " - << srv_conc_get_active_threads() << " queries still" + << n_threads << " queries still" " inside InnoDB at shutdown"; } @@ -2889,8 +2892,8 @@ innodb_shutdown() } srv_start_state = SRV_START_STATE_NONE; - srv_was_started = FALSE; - srv_start_has_been_called = FALSE; + srv_was_started = false; + srv_start_has_been_called = false; } #if 0 // TODO: Enable this in WL#6608 diff --git a/storage/innobase/sync/sync0arr.cc b/storage/innobase/sync/sync0arr.cc index 49a8d6db35a..75919043731 100644 --- a/storage/innobase/sync/sync0arr.cc +++ b/storage/innobase/sync/sync0arr.cc @@ -514,17 +514,17 @@ sync_array_cell_print( if (mutex) { fprintf(file, - "Mutex at %p, %s, lock var %lu\n" + "Mutex at %p, %s, lock var %x\n" #ifdef UNIV_DEBUG - "Last time reserved in file %s line %lu" + "Last time reserved in file %s line %u" #endif /* UNIV_DEBUG */ "\n", (void*) mutex, policy.to_string().c_str(), - (ulong) mutex->state() + mutex->state() #ifdef UNIV_DEBUG ,name, - (ulong) policy.get_enter_line() + policy.get_enter_line() #endif /* UNIV_DEBUG */ ); } @@ -569,42 +569,47 @@ sync_array_cell_print( if (rwlock) { fprintf(file, - " RW-latch at %p created in file %s line %lu\n", + " RW-latch at %p created in file %s line %u\n", (void*) rwlock, innobase_basename(rwlock->cfile_name), - (ulong) rwlock->cline); + rwlock->cline); writer = rw_lock_get_writer(rwlock); if (writer != RW_LOCK_NOT_LOCKED) { fprintf(file, - "a writer (thread id %lu) has" + "a writer (thread id " ULINTPF ") has" " reserved it in mode %s", - (ulong) os_thread_pf(rwlock->writer_thread), + os_thread_pf(rwlock->writer_thread), writer == RW_LOCK_X ? " exclusive\n" : writer == RW_LOCK_SX ? " SX\n" : " wait exclusive\n"); } fprintf(file, - "number of readers %lu, waiters flag %lu," - " lock_word: %lx\n" + "number of readers " ULINTPF + ", waiters flag %u, " + "lock_word: " ULINTPFx "\n" "Last time read locked in file %s line %u\n" - "Last time write locked in file %s line %u\n", - (ulint) rw_lock_get_reader_count(rwlock), - (ulint) rwlock->waiters, + "Last time write locked in file %s line %u" +#if 0 /* JAN: TODO: FIX LATER */ + "\nHolder thread " ULINTPF + " file %s line " ULINTPF +#endif + "\n", + rw_lock_get_reader_count(rwlock), + rwlock->waiters, rwlock->lock_word, innobase_basename(rwlock->last_s_file_name), rwlock->last_s_line, - rwlock->last_x_file_name, - rwlock->last_x_line); - - /* JAN: TODO: FIX LATER - fprintf(file, - "Holder thread %lu file %s line %lu\n", - rwlock->thread_id, rwlock->file_name, - rwlock->line); - */ + innobase_basename(rwlock->last_x_file_name), + rwlock->last_x_line +#if 0 /* JAN: TODO: FIX LATER */ + , os_thread_pf(rwlock->thread_id), + innobase_basename(rwlock->file_name), + rwlock->line +#endif + ); } } else { @@ -1093,9 +1098,10 @@ sync_array_print_long_waits( now the values of pending calls of these. */ fprintf(stderr, - "InnoDB: Pending preads %lu, pwrites %lu\n", - (ulong) os_n_pending_reads, - (ulong) os_n_pending_writes); + "InnoDB: Pending reads " UINT64PF + ", writes " UINT64PF "\n", + MONITOR_VALUE(MONITOR_OS_PENDING_READS), + MONITOR_VALUE(MONITOR_OS_PENDING_WRITES)); srv_print_innodb_monitor = TRUE; diff --git a/storage/innobase/sync/sync0debug.cc b/storage/innobase/sync/sync0debug.cc index 135c84ad0d8..4fff24a77f1 100644 --- a/storage/innobase/sync/sync0debug.cc +++ b/storage/innobase/sync/sync0debug.cc @@ -130,7 +130,7 @@ struct LatchDebug { os_thread_id_t, Latches*, os_thread_id_less, - ut_allocator<std::pair<const std::string, latch_meta_t> > > + ut_allocator<std::pair<const os_thread_id_t, Latches*> > > ThreadMap; /** Constructor */ @@ -425,7 +425,7 @@ private: latch_level_t, std::string, latch_level_less, - ut_allocator<std::pair<latch_level_t, std::string> > > + ut_allocator<std::pair<const latch_level_t, std::string> > > Levels; /** Mutex protecting the deadlock detector data structures. */ @@ -1342,219 +1342,249 @@ sync_latch_meta_init() /* The latches should be ordered on latch_id_t. So that we can index directly into the vector to update and fetch meta-data. */ - LATCH_ADD(AUTOINC, SYNC_DICT_AUTOINC_MUTEX, autoinc_mutex_key); + LATCH_ADD_MUTEX(AUTOINC, SYNC_DICT_AUTOINC_MUTEX, autoinc_mutex_key); #if defined PFS_SKIP_BUFFER_MUTEX_RWLOCK || defined PFS_GROUP_BUFFER_SYNC - LATCH_ADD(BUF_BLOCK_MUTEX, SYNC_BUF_BLOCK, PFS_NOT_INSTRUMENTED); + LATCH_ADD_MUTEX(BUF_BLOCK_MUTEX, SYNC_BUF_BLOCK, PFS_NOT_INSTRUMENTED); #else - LATCH_ADD(BUF_BLOCK_MUTEX, SYNC_BUF_BLOCK, buffer_block_mutex_key); + LATCH_ADD_MUTEX(BUF_BLOCK_MUTEX, SYNC_BUF_BLOCK, + buffer_block_mutex_key); #endif /* PFS_SKIP_BUFFER_MUTEX_RWLOCK || PFS_GROUP_BUFFER_SYNC */ - LATCH_ADD(BUF_POOL, SYNC_BUF_POOL, buf_pool_mutex_key); + LATCH_ADD_MUTEX(BUF_POOL, SYNC_BUF_POOL, buf_pool_mutex_key); - LATCH_ADD(BUF_POOL_ZIP, SYNC_BUF_BLOCK, buf_pool_zip_mutex_key); + LATCH_ADD_MUTEX(BUF_POOL_ZIP, SYNC_BUF_BLOCK, buf_pool_zip_mutex_key); - LATCH_ADD(CACHE_LAST_READ, SYNC_TRX_I_S_LAST_READ, - cache_last_read_mutex_key); + LATCH_ADD_MUTEX(CACHE_LAST_READ, SYNC_TRX_I_S_LAST_READ, + cache_last_read_mutex_key); - LATCH_ADD(DICT_FOREIGN_ERR, SYNC_NO_ORDER_CHECK, - dict_foreign_err_mutex_key); + LATCH_ADD_MUTEX(DICT_FOREIGN_ERR, SYNC_NO_ORDER_CHECK, + dict_foreign_err_mutex_key); - LATCH_ADD(DICT_SYS, SYNC_DICT, dict_sys_mutex_key); + LATCH_ADD_MUTEX(DICT_SYS, SYNC_DICT, dict_sys_mutex_key); - LATCH_ADD(FILE_FORMAT_MAX, SYNC_FILE_FORMAT_TAG, - file_format_max_mutex_key); + LATCH_ADD_MUTEX(FILE_FORMAT_MAX, SYNC_FILE_FORMAT_TAG, + file_format_max_mutex_key); - LATCH_ADD(FIL_SYSTEM, SYNC_ANY_LATCH, fil_system_mutex_key); + LATCH_ADD_MUTEX(FIL_SYSTEM, SYNC_ANY_LATCH, fil_system_mutex_key); - LATCH_ADD(FLUSH_LIST, SYNC_BUF_FLUSH_LIST, flush_list_mutex_key); + LATCH_ADD_MUTEX(FLUSH_LIST, SYNC_BUF_FLUSH_LIST, flush_list_mutex_key); - LATCH_ADD(FTS_BG_THREADS, SYNC_FTS_BG_THREADS, - fts_bg_threads_mutex_key); + LATCH_ADD_MUTEX(FTS_BG_THREADS, SYNC_FTS_BG_THREADS, + fts_bg_threads_mutex_key); - LATCH_ADD(FTS_DELETE, SYNC_FTS_OPTIMIZE, fts_delete_mutex_key); + LATCH_ADD_MUTEX(FTS_DELETE, SYNC_FTS_OPTIMIZE, fts_delete_mutex_key); - LATCH_ADD(FTS_OPTIMIZE, SYNC_FTS_OPTIMIZE, fts_optimize_mutex_key); + LATCH_ADD_MUTEX(FTS_OPTIMIZE, SYNC_FTS_OPTIMIZE, + fts_optimize_mutex_key); - LATCH_ADD(FTS_DOC_ID, SYNC_FTS_OPTIMIZE, fts_doc_id_mutex_key); + LATCH_ADD_MUTEX(FTS_DOC_ID, SYNC_FTS_OPTIMIZE, fts_doc_id_mutex_key); - LATCH_ADD(FTS_PLL_TOKENIZE, SYNC_FTS_TOKENIZE, - fts_pll_tokenize_mutex_key); + LATCH_ADD_MUTEX(FTS_PLL_TOKENIZE, SYNC_FTS_TOKENIZE, + fts_pll_tokenize_mutex_key); - LATCH_ADD(HASH_TABLE_MUTEX, SYNC_BUF_PAGE_HASH, hash_table_mutex_key); + LATCH_ADD_MUTEX(HASH_TABLE_MUTEX, SYNC_BUF_PAGE_HASH, + hash_table_mutex_key); - LATCH_ADD(IBUF_BITMAP, SYNC_IBUF_BITMAP_MUTEX, ibuf_bitmap_mutex_key); + LATCH_ADD_MUTEX(IBUF_BITMAP, SYNC_IBUF_BITMAP_MUTEX, + ibuf_bitmap_mutex_key); - LATCH_ADD(IBUF, SYNC_IBUF_MUTEX, ibuf_mutex_key); + LATCH_ADD_MUTEX(IBUF, SYNC_IBUF_MUTEX, ibuf_mutex_key); - LATCH_ADD(IBUF_PESSIMISTIC_INSERT, SYNC_IBUF_PESS_INSERT_MUTEX, - ibuf_pessimistic_insert_mutex_key); + LATCH_ADD_MUTEX(IBUF_PESSIMISTIC_INSERT, SYNC_IBUF_PESS_INSERT_MUTEX, + ibuf_pessimistic_insert_mutex_key); - LATCH_ADD(LOG_SYS, SYNC_LOG, log_sys_mutex_key); + LATCH_ADD_MUTEX(LOG_SYS, SYNC_LOG, log_sys_mutex_key); - LATCH_ADD(LOG_WRITE, SYNC_LOG_WRITE, log_sys_write_mutex_key); + LATCH_ADD_MUTEX(LOG_WRITE, SYNC_LOG_WRITE, log_sys_write_mutex_key); - LATCH_ADD(LOG_FLUSH_ORDER, SYNC_LOG_FLUSH_ORDER, - log_flush_order_mutex_key); + LATCH_ADD_MUTEX(LOG_FLUSH_ORDER, SYNC_LOG_FLUSH_ORDER, + log_flush_order_mutex_key); - LATCH_ADD(MUTEX_LIST, SYNC_NO_ORDER_CHECK, mutex_list_mutex_key); + LATCH_ADD_MUTEX(MUTEX_LIST, SYNC_NO_ORDER_CHECK, mutex_list_mutex_key); - LATCH_ADD(PAGE_CLEANER, SYNC_PAGE_CLEANER, page_cleaner_mutex_key); + LATCH_ADD_MUTEX(PAGE_CLEANER, SYNC_PAGE_CLEANER, + page_cleaner_mutex_key); - LATCH_ADD(PURGE_SYS_PQ, SYNC_PURGE_QUEUE, purge_sys_pq_mutex_key); + LATCH_ADD_MUTEX(PURGE_SYS_PQ, SYNC_PURGE_QUEUE, + purge_sys_pq_mutex_key); - LATCH_ADD(RECALC_POOL, SYNC_STATS_AUTO_RECALC, - recalc_pool_mutex_key); + LATCH_ADD_MUTEX(RECALC_POOL, SYNC_STATS_AUTO_RECALC, + recalc_pool_mutex_key); - LATCH_ADD(RECV_SYS, SYNC_RECV, recv_sys_mutex_key); + LATCH_ADD_MUTEX(RECV_SYS, SYNC_RECV, recv_sys_mutex_key); - LATCH_ADD(RECV_WRITER, SYNC_RECV_WRITER, recv_writer_mutex_key); + LATCH_ADD_MUTEX(RECV_WRITER, SYNC_RECV_WRITER, recv_writer_mutex_key); - LATCH_ADD(REDO_RSEG, SYNC_REDO_RSEG, redo_rseg_mutex_key); + LATCH_ADD_MUTEX(REDO_RSEG, SYNC_REDO_RSEG, redo_rseg_mutex_key); - LATCH_ADD(NOREDO_RSEG, SYNC_NOREDO_RSEG, noredo_rseg_mutex_key); + LATCH_ADD_MUTEX(NOREDO_RSEG, SYNC_NOREDO_RSEG, noredo_rseg_mutex_key); #ifdef UNIV_DEBUG /* Mutex names starting with '.' are not tracked. They are assumed to be diagnostic mutexes used in debugging. */ latch_meta[LATCH_ID_RW_LOCK_DEBUG] = - LATCH_ADD(RW_LOCK_DEBUG, + LATCH_ADD_MUTEX(RW_LOCK_DEBUG, SYNC_NO_ORDER_CHECK, rw_lock_debug_mutex_key); #endif /* UNIV_DEBUG */ - LATCH_ADD(RTR_SSN_MUTEX, SYNC_ANY_LATCH, rtr_ssn_mutex_key); + LATCH_ADD_MUTEX(RTR_SSN_MUTEX, SYNC_ANY_LATCH, rtr_ssn_mutex_key); - LATCH_ADD(RTR_ACTIVE_MUTEX, SYNC_ANY_LATCH, rtr_active_mutex_key); + LATCH_ADD_MUTEX(RTR_ACTIVE_MUTEX, SYNC_ANY_LATCH, + rtr_active_mutex_key); - LATCH_ADD(RTR_MATCH_MUTEX, SYNC_ANY_LATCH, rtr_match_mutex_key); + LATCH_ADD_MUTEX(RTR_MATCH_MUTEX, SYNC_ANY_LATCH, rtr_match_mutex_key); - LATCH_ADD(RTR_PATH_MUTEX, SYNC_ANY_LATCH, rtr_path_mutex_key); + LATCH_ADD_MUTEX(RTR_PATH_MUTEX, SYNC_ANY_LATCH, rtr_path_mutex_key); - LATCH_ADD(RW_LOCK_LIST, SYNC_NO_ORDER_CHECK, rw_lock_list_mutex_key); + LATCH_ADD_MUTEX(RW_LOCK_LIST, SYNC_NO_ORDER_CHECK, + rw_lock_list_mutex_key); - LATCH_ADD(RW_LOCK_MUTEX, SYNC_NO_ORDER_CHECK, rw_lock_mutex_key); + LATCH_ADD_MUTEX(RW_LOCK_MUTEX, SYNC_NO_ORDER_CHECK, rw_lock_mutex_key); - LATCH_ADD(SRV_DICT_TMPFILE, SYNC_DICT_OPERATION, - srv_dict_tmpfile_mutex_key); + LATCH_ADD_MUTEX(SRV_DICT_TMPFILE, SYNC_DICT_OPERATION, + srv_dict_tmpfile_mutex_key); - LATCH_ADD(SRV_INNODB_MONITOR, SYNC_NO_ORDER_CHECK, - srv_innodb_monitor_mutex_key); + LATCH_ADD_MUTEX(SRV_INNODB_MONITOR, SYNC_NO_ORDER_CHECK, + srv_innodb_monitor_mutex_key); - LATCH_ADD(SRV_MISC_TMPFILE, SYNC_ANY_LATCH, - srv_misc_tmpfile_mutex_key); + LATCH_ADD_MUTEX(SRV_MISC_TMPFILE, SYNC_ANY_LATCH, + srv_misc_tmpfile_mutex_key); - LATCH_ADD(SRV_MONITOR_FILE, SYNC_NO_ORDER_CHECK, - srv_monitor_file_mutex_key); + LATCH_ADD_MUTEX(SRV_MONITOR_FILE, SYNC_NO_ORDER_CHECK, + srv_monitor_file_mutex_key); #ifdef UNIV_DEBUG - LATCH_ADD(SYNC_THREAD, SYNC_NO_ORDER_CHECK, sync_thread_mutex_key); + LATCH_ADD_MUTEX(SYNC_THREAD, SYNC_NO_ORDER_CHECK, + sync_thread_mutex_key); #endif /* UNIV_DEBUG */ - LATCH_ADD(BUF_DBLWR, SYNC_DOUBLEWRITE, buf_dblwr_mutex_key); + LATCH_ADD_MUTEX(BUF_DBLWR, SYNC_DOUBLEWRITE, buf_dblwr_mutex_key); - LATCH_ADD(TRX_UNDO, SYNC_TRX_UNDO, trx_undo_mutex_key); + LATCH_ADD_MUTEX(TRX_UNDO, SYNC_TRX_UNDO, trx_undo_mutex_key); - LATCH_ADD(TRX_POOL, SYNC_POOL, trx_pool_mutex_key); + LATCH_ADD_MUTEX(TRX_POOL, SYNC_POOL, trx_pool_mutex_key); - LATCH_ADD(TRX_POOL_MANAGER, SYNC_POOL_MANAGER, - trx_pool_manager_mutex_key); + LATCH_ADD_MUTEX(TRX_POOL_MANAGER, SYNC_POOL_MANAGER, + trx_pool_manager_mutex_key); - LATCH_ADD(TRX, SYNC_TRX, trx_mutex_key); + LATCH_ADD_MUTEX(TRX, SYNC_TRX, trx_mutex_key); - LATCH_ADD(LOCK_SYS, SYNC_LOCK_SYS, lock_mutex_key); + LATCH_ADD_MUTEX(LOCK_SYS, SYNC_LOCK_SYS, lock_mutex_key); - LATCH_ADD(LOCK_SYS_WAIT, SYNC_LOCK_WAIT_SYS, lock_wait_mutex_key); + LATCH_ADD_MUTEX(LOCK_SYS_WAIT, SYNC_LOCK_WAIT_SYS, + lock_wait_mutex_key); - LATCH_ADD(TRX_SYS, SYNC_TRX_SYS, trx_sys_mutex_key); + LATCH_ADD_MUTEX(TRX_SYS, SYNC_TRX_SYS, trx_sys_mutex_key); - LATCH_ADD(SRV_SYS, SYNC_THREADS, srv_sys_mutex_key); + LATCH_ADD_MUTEX(SRV_SYS, SYNC_THREADS, srv_sys_mutex_key); - LATCH_ADD(SRV_SYS_TASKS, SYNC_ANY_LATCH, srv_threads_mutex_key); + LATCH_ADD_MUTEX(SRV_SYS_TASKS, SYNC_ANY_LATCH, srv_threads_mutex_key); - LATCH_ADD(PAGE_ZIP_STAT_PER_INDEX, SYNC_ANY_LATCH, - page_zip_stat_per_index_mutex_key); + LATCH_ADD_MUTEX(PAGE_ZIP_STAT_PER_INDEX, SYNC_ANY_LATCH, + page_zip_stat_per_index_mutex_key); #ifndef PFS_SKIP_EVENT_MUTEX - LATCH_ADD(EVENT_MANAGER, SYNC_NO_ORDER_CHECK, event_manager_mutex_key); + LATCH_ADD_MUTEX(EVENT_MANAGER, SYNC_NO_ORDER_CHECK, + event_manager_mutex_key); #else - LATCH_ADD(EVENT_MANAGER, SYNC_NO_ORDER_CHECK, PFS_NOT_INSTRUMENTED); + LATCH_ADD_MUTEX(EVENT_MANAGER, SYNC_NO_ORDER_CHECK, + PFS_NOT_INSTRUMENTED); #endif /* !PFS_SKIP_EVENT_MUTEX */ - LATCH_ADD(EVENT_MUTEX, SYNC_NO_ORDER_CHECK, event_mutex_key); + LATCH_ADD_MUTEX(EVENT_MUTEX, SYNC_NO_ORDER_CHECK, event_mutex_key); - LATCH_ADD(SYNC_ARRAY_MUTEX, SYNC_NO_ORDER_CHECK, - sync_array_mutex_key); + LATCH_ADD_MUTEX(SYNC_ARRAY_MUTEX, SYNC_NO_ORDER_CHECK, + sync_array_mutex_key); - LATCH_ADD(THREAD_MUTEX, SYNC_NO_ORDER_CHECK, thread_mutex_key); + LATCH_ADD_MUTEX(THREAD_MUTEX, SYNC_NO_ORDER_CHECK, thread_mutex_key); - LATCH_ADD(ZIP_PAD_MUTEX, SYNC_NO_ORDER_CHECK, zip_pad_mutex_key); + LATCH_ADD_MUTEX(ZIP_PAD_MUTEX, SYNC_NO_ORDER_CHECK, zip_pad_mutex_key); - LATCH_ADD(OS_AIO_READ_MUTEX, SYNC_NO_ORDER_CHECK, PFS_NOT_INSTRUMENTED); + LATCH_ADD_MUTEX(OS_AIO_READ_MUTEX, SYNC_NO_ORDER_CHECK, + PFS_NOT_INSTRUMENTED); - LATCH_ADD(OS_AIO_WRITE_MUTEX, SYNC_NO_ORDER_CHECK, - PFS_NOT_INSTRUMENTED); + LATCH_ADD_MUTEX(OS_AIO_WRITE_MUTEX, SYNC_NO_ORDER_CHECK, + PFS_NOT_INSTRUMENTED); - LATCH_ADD(OS_AIO_LOG_MUTEX, SYNC_NO_ORDER_CHECK, PFS_NOT_INSTRUMENTED); + LATCH_ADD_MUTEX(OS_AIO_LOG_MUTEX, SYNC_NO_ORDER_CHECK, + PFS_NOT_INSTRUMENTED); - LATCH_ADD(OS_AIO_IBUF_MUTEX, SYNC_NO_ORDER_CHECK, PFS_NOT_INSTRUMENTED); + LATCH_ADD_MUTEX(OS_AIO_IBUF_MUTEX, SYNC_NO_ORDER_CHECK, + PFS_NOT_INSTRUMENTED); - LATCH_ADD(OS_AIO_SYNC_MUTEX, SYNC_NO_ORDER_CHECK, PFS_NOT_INSTRUMENTED); + LATCH_ADD_MUTEX(OS_AIO_SYNC_MUTEX, SYNC_NO_ORDER_CHECK, + PFS_NOT_INSTRUMENTED); - LATCH_ADD(ROW_DROP_LIST, SYNC_NO_ORDER_CHECK, row_drop_list_mutex_key); + LATCH_ADD_MUTEX(ROW_DROP_LIST, SYNC_NO_ORDER_CHECK, + row_drop_list_mutex_key); - LATCH_ADD(INDEX_ONLINE_LOG, SYNC_INDEX_ONLINE_LOG, - index_online_log_key); + LATCH_ADD_MUTEX(INDEX_ONLINE_LOG, SYNC_INDEX_ONLINE_LOG, + index_online_log_key); - LATCH_ADD(WORK_QUEUE, SYNC_WORK_QUEUE, PFS_NOT_INSTRUMENTED); + LATCH_ADD_MUTEX(WORK_QUEUE, SYNC_WORK_QUEUE, PFS_NOT_INSTRUMENTED); // Add the RW locks - LATCH_ADD(BTR_SEARCH, SYNC_SEARCH_SYS, btr_search_latch_key); + LATCH_ADD_RWLOCK(BTR_SEARCH, SYNC_SEARCH_SYS, btr_search_latch_key); - LATCH_ADD(BUF_BLOCK_LOCK, SYNC_LEVEL_VARYING, buf_block_lock_key); + LATCH_ADD_RWLOCK(BUF_BLOCK_LOCK, SYNC_LEVEL_VARYING, + buf_block_lock_key); #ifdef UNIV_DEBUG - LATCH_ADD(BUF_BLOCK_DEBUG, SYNC_NO_ORDER_CHECK, - buf_block_debug_latch_key); + LATCH_ADD_RWLOCK(BUF_BLOCK_DEBUG, SYNC_NO_ORDER_CHECK, + buf_block_debug_latch_key); #endif /* UNIV_DEBUG */ - LATCH_ADD(DICT_OPERATION, SYNC_DICT, dict_operation_lock_key); + LATCH_ADD_RWLOCK(DICT_OPERATION, SYNC_DICT, dict_operation_lock_key); - LATCH_ADD(CHECKPOINT, SYNC_NO_ORDER_CHECK, checkpoint_lock_key); + LATCH_ADD_RWLOCK(CHECKPOINT, SYNC_NO_ORDER_CHECK, checkpoint_lock_key); - LATCH_ADD(FIL_SPACE, SYNC_FSP, fil_space_latch_key); + LATCH_ADD_RWLOCK(FIL_SPACE, SYNC_FSP, fil_space_latch_key); - LATCH_ADD(FTS_CACHE, SYNC_FTS_CACHE, fts_cache_rw_lock_key); + LATCH_ADD_RWLOCK(FTS_CACHE, SYNC_FTS_CACHE, fts_cache_rw_lock_key); - LATCH_ADD(FTS_CACHE_INIT, SYNC_FTS_CACHE_INIT, - fts_cache_init_rw_lock_key); + LATCH_ADD_RWLOCK(FTS_CACHE_INIT, SYNC_FTS_CACHE_INIT, + fts_cache_init_rw_lock_key); - LATCH_ADD(TRX_I_S_CACHE, SYNC_TRX_I_S_RWLOCK, trx_i_s_cache_lock_key); + LATCH_ADD_RWLOCK(TRX_I_S_CACHE, SYNC_TRX_I_S_RWLOCK, + trx_i_s_cache_lock_key); - LATCH_ADD(TRX_PURGE, SYNC_PURGE_LATCH, trx_purge_latch_key); + LATCH_ADD_RWLOCK(TRX_PURGE, SYNC_PURGE_LATCH, trx_purge_latch_key); - LATCH_ADD(IBUF_INDEX_TREE, SYNC_IBUF_INDEX_TREE, - index_tree_rw_lock_key); + LATCH_ADD_RWLOCK(IBUF_INDEX_TREE, SYNC_IBUF_INDEX_TREE, + index_tree_rw_lock_key); - LATCH_ADD(INDEX_TREE, SYNC_INDEX_TREE, index_tree_rw_lock_key); + LATCH_ADD_RWLOCK(INDEX_TREE, SYNC_INDEX_TREE, index_tree_rw_lock_key); - LATCH_ADD(DICT_TABLE_STATS, SYNC_INDEX_TREE, dict_table_stats_key); + LATCH_ADD_RWLOCK(DICT_TABLE_STATS, SYNC_INDEX_TREE, + dict_table_stats_key); - LATCH_ADD(HASH_TABLE_RW_LOCK, SYNC_BUF_PAGE_HASH, + LATCH_ADD_RWLOCK(HASH_TABLE_RW_LOCK, SYNC_BUF_PAGE_HASH, hash_table_locks_key); - LATCH_ADD(SYNC_DEBUG_MUTEX, SYNC_NO_ORDER_CHECK, PFS_NOT_INSTRUMENTED); + LATCH_ADD_MUTEX(SYNC_DEBUG_MUTEX, SYNC_NO_ORDER_CHECK, + PFS_NOT_INSTRUMENTED); /* JAN: TODO: Add PFS instrumentation */ - LATCH_ADD(SCRUB_STAT_MUTEX, SYNC_NO_ORDER_CHECK, PFS_NOT_INSTRUMENTED); - LATCH_ADD(DEFRAGMENT_MUTEX, SYNC_NO_ORDER_CHECK, PFS_NOT_INSTRUMENTED); - LATCH_ADD(BTR_DEFRAGMENT_MUTEX, SYNC_NO_ORDER_CHECK, PFS_NOT_INSTRUMENTED); - LATCH_ADD(MTFLUSH_THREAD_MUTEX, SYNC_NO_ORDER_CHECK, PFS_NOT_INSTRUMENTED); - LATCH_ADD(MTFLUSH_MUTEX, SYNC_NO_ORDER_CHECK, PFS_NOT_INSTRUMENTED); - LATCH_ADD(FIL_CRYPT_MUTEX, SYNC_NO_ORDER_CHECK, PFS_NOT_INSTRUMENTED); - LATCH_ADD(FIL_CRYPT_STAT_MUTEX, SYNC_NO_ORDER_CHECK, PFS_NOT_INSTRUMENTED); - LATCH_ADD(FIL_CRYPT_DATA_MUTEX, SYNC_NO_ORDER_CHECK, PFS_NOT_INSTRUMENTED); - LATCH_ADD(FIL_CRYPT_THREADS_MUTEX, SYNC_NO_ORDER_CHECK, PFS_NOT_INSTRUMENTED); + LATCH_ADD_MUTEX(SCRUB_STAT_MUTEX, SYNC_NO_ORDER_CHECK, + PFS_NOT_INSTRUMENTED); + LATCH_ADD_MUTEX(DEFRAGMENT_MUTEX, SYNC_NO_ORDER_CHECK, + PFS_NOT_INSTRUMENTED); + LATCH_ADD_MUTEX(BTR_DEFRAGMENT_MUTEX, SYNC_NO_ORDER_CHECK, + PFS_NOT_INSTRUMENTED); + LATCH_ADD_MUTEX(MTFLUSH_THREAD_MUTEX, SYNC_NO_ORDER_CHECK, + PFS_NOT_INSTRUMENTED); + LATCH_ADD_MUTEX(MTFLUSH_MUTEX, SYNC_NO_ORDER_CHECK, + PFS_NOT_INSTRUMENTED); + LATCH_ADD_MUTEX(FIL_CRYPT_MUTEX, SYNC_NO_ORDER_CHECK, + PFS_NOT_INSTRUMENTED); + LATCH_ADD_MUTEX(FIL_CRYPT_STAT_MUTEX, SYNC_NO_ORDER_CHECK, + PFS_NOT_INSTRUMENTED); + LATCH_ADD_MUTEX(FIL_CRYPT_DATA_MUTEX, SYNC_NO_ORDER_CHECK, + PFS_NOT_INSTRUMENTED); + LATCH_ADD_MUTEX(FIL_CRYPT_THREADS_MUTEX, SYNC_NO_ORDER_CHECK, + PFS_NOT_INSTRUMENTED); latch_id_t id = LATCH_ID_NONE; @@ -1717,7 +1747,7 @@ private: const void*, File, std::less<const void*>, - ut_allocator<std::pair<const void*, File> > > + ut_allocator<std::pair<const void* const, File> > > Files; typedef OSMutex Mutex; diff --git a/storage/innobase/trx/trx0i_s.cc b/storage/innobase/trx/trx0i_s.cc index 9c5ae4d02da..fcc50b8c76d 100644 --- a/storage/innobase/trx/trx0i_s.cc +++ b/storage/innobase/trx/trx0i_s.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1612,7 +1613,8 @@ trx_i_s_create_lock_id( if (row->lock_space != ULINT_UNDEFINED) { /* record lock */ res_len = ut_snprintf(lock_id, lock_id_size, - TRX_ID_FMT ":%lu:%lu:%lu", + TRX_ID_FMT + ":" ULINTPF ":" ULINTPF ":" ULINTPF, row->lock_trx_id, row->lock_space, row->lock_page, row->lock_rec); } else { diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc index f83d9377852..b21ec75c3a6 100644 --- a/storage/innobase/trx/trx0purge.cc +++ b/storage/innobase/trx/trx0purge.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -291,7 +291,6 @@ trx_purge_add_update_undo_to_history( undo_header + TRX_UNDO_HISTORY_NODE, mtr); my_atomic_addlint(&trx_sys->rseg_history_len, 1); - srv_wake_purge_thread_if_not_active(); /* Write the trx number to the undo log header */ mlog_write_ull(undo_header + TRX_UNDO_TRX_NO, trx->no, mtr); @@ -987,27 +986,20 @@ trx_purge_initiate_truncate( initiate truncate. d. Execute actual truncate e. Remove the DDL log. */ - DBUG_EXECUTE_IF("ib_undo_trunc_before_checkpoint", - ib::info() << "ib_undo_trunc_before_checkpoint"; - DBUG_SUICIDE();); /* After truncate if server crashes then redo logging done for this undo tablespace might not stand valid as tablespace has been truncated. */ log_make_checkpoint_at(LSN_MAX, TRUE); - ib::info() << "Truncating UNDO tablespace with space identifier " - << undo_trunc->get_marked_space_id(); + const ulint space_id = undo_trunc->get_marked_space_id(); - DBUG_EXECUTE_IF("ib_undo_trunc_before_ddl_log_start", - ib::info() << "ib_undo_trunc_before_ddl_log_start"; - DBUG_SUICIDE();); + ib::info() << "Truncating UNDO tablespace " << space_id; #ifdef UNIV_DEBUG dberr_t err = #endif /* UNIV_DEBUG */ - undo_trunc->start_logging( - undo_trunc->get_marked_space_id()); + undo_trunc->start_logging(space_id); ut_ad(err == DB_SUCCESS); DBUG_EXECUTE_IF("ib_undo_trunc_before_truncate", @@ -1016,14 +1008,12 @@ trx_purge_initiate_truncate( trx_purge_cleanse_purge_queue(undo_trunc); - bool success = trx_undo_truncate_tablespace(undo_trunc); - if (!success) { + if (!trx_undo_truncate_tablespace(undo_trunc)) { /* Note: In case of error we don't enable the rsegs and neither unmark the tablespace so the tablespace continue to remain inactive. */ - ib::error() << "Failed to truncate UNDO tablespace with" - " space identifier " - << undo_trunc->get_marked_space_id(); + ib::error() << "Failed to truncate UNDO tablespace " + << space_id; return; } @@ -1046,7 +1036,7 @@ trx_purge_initiate_truncate( log_make_checkpoint_at(LSN_MAX, TRUE); - undo_trunc->done_logging(undo_trunc->get_marked_space_id()); + undo_trunc->done_logging(space_id); /* Completed truncate. Now it is safe to re-use the tablespace. */ for (ulint i = 0; i < undo_trunc->rsegs_size(); ++i) { @@ -1054,8 +1044,7 @@ trx_purge_initiate_truncate( rseg->skip_allocation = false; } - ib::info() << "Completed truncate of UNDO tablespace with space" - " identifier " << undo_trunc->get_marked_space_id(); + ib::info() << "Truncated UNDO tablespace " << space_id; undo_trunc->reset(); undo::Truncate::clear_trunc_list(); @@ -1075,7 +1064,7 @@ trx_purge_truncate_history( purge_iter_t* limit, /*!< in: truncate limit */ const ReadView* view) /*!< in: purge view */ { - ulint i; + ut_ad(trx_purge_check_limit()); /* We play safe and set the truncate limit at most to the purge view low_limit number, though this is not necessary */ @@ -1088,7 +1077,7 @@ trx_purge_truncate_history( ut_ad(limit->trx_no <= purge_sys->view.low_limit_no()); - for (i = 0; i < TRX_SYS_N_RSEGS; ++i) { + for (ulint i = 0; i < TRX_SYS_N_RSEGS; ++i) { trx_rseg_t* rseg = trx_sys->rseg_array[i]; if (rseg != NULL) { @@ -1100,8 +1089,7 @@ trx_purge_truncate_history( /* UNDO tablespace truncate. We will try to truncate as much as we can (greedy approach). This will ensure when the server is idle we try and truncate all the UNDO tablespaces. */ - ulint nchances = srv_undo_tablespaces_active; - for (i = 0; i < nchances; i++) { + for (ulint i = srv_undo_tablespaces_active; i--; ) { trx_purge_mark_undo_for_truncate(&purge_sys->undo_trunc); trx_purge_initiate_truncate(limit, &purge_sys->undo_trunc); } @@ -1638,22 +1626,6 @@ trx_purge_wait_for_workers_to_complete( ut_a(srv_get_task_queue_length() == 0); } -/******************************************************************//** -Remove old historical changes from the rollback segments. */ -static -void -trx_purge_truncate(void) -/*====================*/ -{ - ut_ad(trx_purge_check_limit()); - - if (purge_sys->limit.trx_no == 0) { - trx_purge_truncate_history(&purge_sys->iter, &purge_sys->view); - } else { - trx_purge_truncate_history(&purge_sys->limit, &purge_sys->view); - } -} - /*******************************************************************//** This function runs a purge batch. @return number of undo log pages handled in the batch */ @@ -1742,7 +1714,11 @@ run_synchronously: #endif /* UNIV_DEBUG */ if (truncate) { - trx_purge_truncate(); + trx_purge_truncate_history( + purge_sys->limit.trx_no + ? &purge_sys->limit + : &purge_sys->iter, + &purge_sys->view); } MONITOR_INC_VALUE(MONITOR_PURGE_INVOKED, 1); diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc index ec723375fe9..69f01e64b59 100644 --- a/storage/innobase/trx/trx0roll.cc +++ b/storage/innobase/trx/trx0roll.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2016, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -868,6 +868,8 @@ DECLARE_THREAD(trx_rollback_or_clean_all_recovered)( /*!< in: a dummy parameter required by os_thread_create */ { + my_thread_init(); + ut_ad(!srv_read_only_mode); #ifdef UNIV_PFS_THREAD @@ -878,6 +880,7 @@ DECLARE_THREAD(trx_rollback_or_clean_all_recovered)( trx_rollback_or_clean_is_active = false; + my_thread_end(); /* We count the number of threads in os_thread_exit(). A created thread should always use that to exit and not use return() to exit. */ diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc index 3393a0464a8..663566cf26f 100644 --- a/storage/innobase/trx/trx0rseg.cc +++ b/storage/innobase/trx/trx0rseg.cc @@ -204,7 +204,7 @@ trx_rseg_mem_restore(trx_rseg_t* rseg, mtr_t* mtr) len = flst_get_len(rseg_header + TRX_RSEG_HISTORY); if (len > 0) { - trx_sys->rseg_history_len += len; + my_atomic_addlint(&trx_sys->rseg_history_len, len); node_addr = trx_purge_get_log_from_hist( flst_get_last(rseg_header + TRX_RSEG_HISTORY, mtr)); diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc index 24983dcc2a3..47f30138ceb 100644 --- a/storage/innobase/trx/trx0sys.cc +++ b/storage/innobase/trx/trx0sys.cc @@ -258,8 +258,8 @@ trx_sys_print_mysql_binlog_offset(void) + TRX_SYS_MYSQL_LOG_OFFSET_LOW); fprintf(stderr, - "InnoDB: Last MySQL binlog file position %lu %lu," - " file name %s\n", + "InnoDB: Last MySQL binlog file position " ULINTPF " " ULINTPF + ", file name %s\n", trx_sys_mysql_bin_log_pos_high, trx_sys_mysql_bin_log_pos_low, sys_header + TRX_SYS_MYSQL_LOG_INFO + TRX_SYS_MYSQL_LOG_NAME); @@ -446,7 +446,6 @@ trx_sysf_create( page_t* page; ulint page_no; byte* ptr; - ulint len; ut_ad(mtr); @@ -481,13 +480,12 @@ trx_sysf_create( 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 + (before MySQL 5.5) define TRX_SYS_N_RSEGS as 256 and expect that the whole array is initialized. */ ptr = TRX_SYS_RSEGS + sys_header; - len = ut_max(TRX_SYS_OLD_N_RSEGS, TRX_SYS_N_RSEGS) - * TRX_SYS_RSEG_SLOT_SIZE; - memset(ptr, 0xff, len); - ptr += len; + compile_time_assert(256 >= TRX_SYS_N_RSEGS); + memset(ptr, 0xff, 256 * TRX_SYS_RSEG_SLOT_SIZE); + ptr += 256 * TRX_SYS_RSEG_SLOT_SIZE; ut_a(ptr <= page + (UNIV_PAGE_SIZE - FIL_PAGE_DATA_END)); /* Initialize all of the page. This part used to be uninitialized. */ @@ -881,7 +879,7 @@ trx_sys_create_rsegs() srv_undo_logs determines how many of the srv_available_undo_logs rollback segments may be used for logging new transactions. */ - ut_ad(srv_undo_tablespaces < TRX_SYS_N_RSEGS); + ut_ad(srv_undo_tablespaces <= TRX_SYS_MAX_UNDO_SPACES); ut_ad(srv_undo_logs <= TRX_SYS_N_RSEGS); if (srv_read_only_mode) { @@ -923,13 +921,28 @@ trx_sys_create_rsegs() " requested innodb_undo_logs"; return(false); } + + /* Increase the number of active undo + tablespace in case new rollback segment + assigned to new undo tablespace. */ + if (space > srv_undo_tablespaces_active) { + srv_undo_tablespaces_active++; + + ut_ad(srv_undo_tablespaces_active == space); + } } } ut_ad(srv_undo_logs <= srv_available_undo_logs); - ib::info() << srv_undo_logs << " out of " << srv_available_undo_logs - << " rollback segments are active."; + ib::info info; + info << srv_undo_logs << " out of " << srv_available_undo_logs; + if (srv_undo_tablespaces_active) { + info << " rollback segments in " << srv_undo_tablespaces_active + << " undo tablespaces are active."; + } else { + info << " rollback segments are active."; + } return(true); } diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 36324c43970..a6cfcf0910b 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -1908,6 +1908,7 @@ trx_commit_in_memory( trx_mutex_exit(trx); ut_a(trx->error_state == DB_SUCCESS); + srv_wake_purge_thread_if_not_active(); } /****************************************************************//** @@ -2455,6 +2456,121 @@ trx_print_latched( mem_heap_get_size(trx->lock.lock_heap)); } +#ifdef WITH_WSREP +/**********************************************************************//** +Prints info about a transaction. +Transaction information may be retrieved without having trx_sys->mutex acquired +so it may not be completely accurate. The caller must own lock_sys->mutex +and the trx must have some locks to make sure that it does not escape +without locking lock_sys->mutex. */ +UNIV_INTERN +void +wsrep_trx_print_locking( + FILE* f, + /*!< in: output stream */ + const trx_t* trx, + /*!< in: transaction */ + ulint max_query_len) + /*!< in: max query length to print, + or 0 to use the default max length */ +{ + ibool newline; + const char* op_info; + + ut_ad(lock_mutex_own()); + ut_ad(trx->lock.trx_locks.count > 0); + + fprintf(f, "TRANSACTION " TRX_ID_FMT, trx->id); + + /* trx->state may change since trx_sys->mutex is not required */ + switch (trx->state) { + case TRX_STATE_NOT_STARTED: + fputs(", not started", f); + goto state_ok; + case TRX_STATE_ACTIVE: + fprintf(f, ", ACTIVE %lu sec", + (ulong) difftime(time(NULL), trx->start_time)); + goto state_ok; + case TRX_STATE_FORCED_ROLLBACK: + fprintf(f, ", FORCED ROLLBACK, %lu sec", + (ulong) difftime(time(NULL), trx->start_time)); + goto state_ok; + case TRX_STATE_PREPARED: + fprintf(f, ", ACTIVE (PREPARED) %lu sec", + (ulong) difftime(time(NULL), trx->start_time)); + goto state_ok; + case TRX_STATE_COMMITTED_IN_MEMORY: + fputs(", COMMITTED IN MEMORY", f); + goto state_ok; + } + fprintf(f, ", state %lu", (ulong) trx->state); + ut_ad(0); +state_ok: + + /* prevent a race condition */ + op_info = trx->op_info; + + if (*op_info) { + putc(' ', f); + fputs(op_info, f); + } + + if (trx->is_recovered) { + fputs(" recovered trx", f); + } + + if (trx->declared_to_be_inside_innodb) { + fprintf(f, ", thread declared inside InnoDB %lu", + (ulong) trx->n_tickets_to_enter_innodb); + } + + putc('\n', f); + + if (trx->n_mysql_tables_in_use > 0 || trx->mysql_n_tables_locked > 0) { + fprintf(f, "mysql tables in use %lu, locked %lu\n", + (ulong) trx->n_mysql_tables_in_use, + (ulong) trx->mysql_n_tables_locked); + } + + newline = TRUE; + + /* trx->lock.que_state of an ACTIVE transaction may change + while we are not holding trx->mutex. We perform a dirty read + for performance reasons. */ + + switch (trx->lock.que_state) { + case TRX_QUE_RUNNING: + newline = FALSE; break; + case TRX_QUE_LOCK_WAIT: + fputs("LOCK WAIT ", f); break; + case TRX_QUE_ROLLING_BACK: + fputs("ROLLING BACK ", f); break; + case TRX_QUE_COMMITTING: + fputs("COMMITTING ", f); break; + default: + fprintf(f, "que state %lu ", (ulong) trx->lock.que_state); + } + + if (trx->has_search_latch) { + newline = TRUE; + fputs(", holds adaptive hash latch", f); + } + + if (trx->undo_no != 0) { + newline = TRUE; + fprintf(f, ", undo log entries " TRX_ID_FMT, trx->undo_no); + } + + if (newline) { + putc('\n', f); + } + + if (trx->mysql_thd != NULL) { + innobase_mysql_print_thd( + f, trx->mysql_thd, static_cast<uint>(max_query_len)); + } +} +#endif /* WITH_WSREP */ /**********************************************************************//** Prints info about a transaction. Acquires and releases lock_sys->mutex and trx_sys->mutex. */ diff --git a/storage/innobase/ut/ut0ut.cc b/storage/innobase/ut/ut0ut.cc index c352323eca9..2cae865cff2 100644 --- a/storage/innobase/ut/ut0ut.cc +++ b/storage/innobase/ut/ut0ut.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -214,14 +215,14 @@ ut_print_timestamp( GetLocalTime(&cal_tm); - fprintf(file, "%d-%02d-%02d %02d:%02d:%02d %#llx", + fprintf(file, "%d-%02d-%02d %02d:%02d:%02d %#zx", (int) cal_tm.wYear, (int) cal_tm.wMonth, (int) cal_tm.wDay, (int) cal_tm.wHour, (int) cal_tm.wMinute, (int) cal_tm.wSecond, - static_cast<ulonglong>(thread_id)); + thread_id); #else struct tm* cal_tm_ptr; time_t tm; @@ -230,7 +231,7 @@ ut_print_timestamp( time(&tm); localtime_r(&tm, &cal_tm); cal_tm_ptr = &cal_tm; - fprintf(file, "%d-%02d-%02d %02d:%02d:%02d %#lx", + fprintf(file, "%d-%02d-%02d %02d:%02d:%02d %#zx", cal_tm_ptr->tm_year + 1900, cal_tm_ptr->tm_mon + 1, cal_tm_ptr->tm_mday, @@ -323,7 +324,7 @@ ut_print_buf( fprintf(file, " len " ULINTPF "; hex ", len); for (data = (const byte*) buf, i = 0; i < len; i++) { - fprintf(file, "%02lx", static_cast<ulong>(*data++)); + fprintf(file, "%02x", *data++); } fputs("; asc ", file); diff --git a/storage/rocksdb/CMakeLists.txt b/storage/rocksdb/CMakeLists.txt index 3223e084709..d72b4e54e43 100644 --- a/storage/rocksdb/CMakeLists.txt +++ b/storage/rocksdb/CMakeLists.txt @@ -22,6 +22,13 @@ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "i[36]86") SKIP_ROCKSDB_PLUGIN("Intel 32 bit not supported.") ENDIF() +# Due to retrieved data being incorrect endian +include(TestBigEndian) +test_big_endian(BIG_ENDIAN) +if(BIG_ENDIAN) + SKIP_ROCKSDB_PLUGIN("Big Endian not supported.") +endif() + # # Also, disable building on 32-bit Windows # diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc index a87abfb8073..7ed8661cc74 100644 --- a/storage/spider/ha_spider.cc +++ b/storage/spider/ha_spider.cc @@ -2109,6 +2109,7 @@ int ha_spider::index_read_map_internal( result_list.desc_flg = FALSE; result_list.sorted = TRUE; result_list.key_info = &table->key_info[active_index]; + check_distinct_key_query(); result_list.limit_num = result_list.internal_limit >= result_list.split_read ? result_list.split_read : result_list.internal_limit; @@ -2624,6 +2625,7 @@ int ha_spider::index_read_last_map_internal( result_list.desc_flg = TRUE; result_list.sorted = TRUE; result_list.key_info = &table->key_info[active_index]; + check_distinct_key_query(); result_list.limit_num = result_list.internal_limit >= result_list.split_read ? result_list.split_read : result_list.internal_limit; @@ -3089,6 +3091,7 @@ int ha_spider::index_first_internal( result_list.sorted = TRUE; result_list.key_info = &table->key_info[active_index]; result_list.key_order = 0; + check_distinct_key_query(); result_list.limit_num = result_list.internal_limit >= result_list.split_read ? result_list.split_read : result_list.internal_limit; @@ -3472,6 +3475,7 @@ int ha_spider::index_last_internal( result_list.sorted = TRUE; result_list.key_info = &table->key_info[active_index]; result_list.key_order = 0; + check_distinct_key_query(); result_list.limit_num = result_list.internal_limit >= result_list.split_read ? result_list.split_read : result_list.internal_limit; @@ -3914,6 +3918,7 @@ int ha_spider::read_range_first_internal( result_list.desc_flg = FALSE; result_list.sorted = sorted; result_list.key_info = &table->key_info[active_index]; + check_distinct_key_query(); result_list.limit_num = result_list.internal_limit >= result_list.split_read ? result_list.split_read : result_list.internal_limit; @@ -12078,6 +12083,81 @@ void ha_spider::check_direct_order_limit() DBUG_VOID_RETURN; } +/******************************************************************** + * Check whether the current query is a SELECT DISTINCT using an + * index in a non-partitioned Spider configuration, with a + * projection list that consists solely of the first key prefix + * column. + * + * For a SELECT DISTINCT query using an index in a non-partitioned + * Spider configuration, with a projection list that consists + * solely of the first key prefix, set the internal row retrieval + * limit to avoid visiting each row multiple times. + ********************************************************************/ +void ha_spider::check_distinct_key_query() +{ + DBUG_ENTER( "ha_spider::check_distinct_key_query" ); + + if ( result_list.direct_distinct && !partition_handler_share->handlers && + result_list.keyread && result_list.check_direct_order_limit ) + { + // SELECT DISTINCT query using an index in a non-partitioned configuration + KEY_PART_INFO* key_part = result_list.key_info->key_part; + Field* key_field = key_part->field; + + if ( is_sole_projection_field( key_field->field_index ) ) + { + // Projection list consists solely of the first key prefix column + + // Set the internal row retrieval limit to avoid visiting each row + // multiple times. This fixes a Spider performance bug that + // caused each row to be visited multiple times. + result_list.internal_limit = 1; + } + } + + DBUG_VOID_RETURN; +} + +/******************************************************************** + * Determine whether the current query's projection list + * consists solely of the specified column. + * + * Params IN - field_index: + * Field index of the column of interest within + * its table. + * + * Returns TRUE - if the query's projection list consists + * solely of the specified column. + * FALSE - otherwise. + ********************************************************************/ +bool ha_spider::is_sole_projection_field( uint16 field_index ) +{ + // NOTE: It is assumed that spider_db_append_select_columns() has already been called + // to build the bitmap of projection fields + bool is_ha_sole_projection_field; + uint loop_index, dbton_id; + spider_db_handler* dbton_hdl; + DBUG_ENTER( "ha_spider::is_sole_projection_field" ); + + for ( loop_index = 0; loop_index < share->use_sql_dbton_count; loop_index++ ) + { + dbton_id = share->use_sql_dbton_ids[ loop_index ]; + dbton_hdl = dbton_handler[ dbton_id ]; + + if ( dbton_hdl->first_link_idx >= 0 ) + { + is_ha_sole_projection_field = dbton_hdl->is_sole_projection_field( field_index ); + if ( !is_ha_sole_projection_field ) + { + DBUG_RETURN( FALSE ); + } + } + } + + DBUG_RETURN( TRUE ); +} + int ha_spider::check_ha_range_eof() { DBUG_ENTER("ha_spider::check_ha_range_eof"); diff --git a/storage/spider/ha_spider.h b/storage/spider/ha_spider.h index bd02e34043d..87c6afaa89f 100644 --- a/storage/spider/ha_spider.h +++ b/storage/spider/ha_spider.h @@ -751,6 +751,8 @@ public: ); uint check_partitioned(); void check_direct_order_limit(); + void check_distinct_key_query(); + bool is_sole_projection_field( uint16 field_index ); int check_ha_range_eof(); int drop_tmp_tables(); bool handler_opened( diff --git a/storage/spider/spd_db_handlersocket.cc b/storage/spider/spd_db_handlersocket.cc index 8f031acdbde..51b1d1f1752 100644 --- a/storage/spider/spd_db_handlersocket.cc +++ b/storage/spider/spd_db_handlersocket.cc @@ -4994,6 +4994,15 @@ int spider_handlersocket_handler::append_explain_select_part( DBUG_RETURN(0); } +int spider_handlersocket_handler::is_sole_projection_field( + uint16 field_index +) { + DBUG_ENTER("spider_handlersocket_handler::is_sole_projection_field"); + DBUG_PRINT("info", ("spider this=%p", this)); + DBUG_ASSERT(0); + DBUG_RETURN(0); +} + bool spider_handlersocket_handler::is_bulk_insert_exec_period( bool bulk_end ) { diff --git a/storage/spider/spd_db_handlersocket.h b/storage/spider/spd_db_handlersocket.h index d3fdf5564b7..a3955aea044 100644 --- a/storage/spider/spd_db_handlersocket.h +++ b/storage/spider/spd_db_handlersocket.h @@ -776,6 +776,9 @@ public: ulong sql_type, int link_idx ); + bool is_sole_projection_field( + uint16 field_index + ); bool is_bulk_insert_exec_period( bool bulk_end ); diff --git a/storage/spider/spd_db_include.h b/storage/spider/spd_db_include.h index 936951d3860..56bc2ccad42 100644 --- a/storage/spider/spd_db_include.h +++ b/storage/spider/spd_db_include.h @@ -1279,6 +1279,9 @@ public: ulong sql_type, int link_idx ) = 0; + virtual bool is_sole_projection_field( + uint16 field_index + ) = 0; virtual bool is_bulk_insert_exec_period( bool bulk_end ) = 0; diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index f902508e9c4..385b122c274 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -9516,6 +9516,65 @@ int spider_mysql_handler::append_explain_select( DBUG_RETURN(0); } +/******************************************************************** + * Determine whether the current query's projection list + * consists solely of the specified column. + * + * Params IN - field_index: + * Field index of the column of interest within + * its table. + * + * Returns TRUE - if the query's projection list consists + * solely of the specified column. + * FALSE - otherwise. + ********************************************************************/ +bool spider_mysql_handler::is_sole_projection_field( uint16 field_index ) +{ + // Determine whether the projection list consists solely of the field of interest + bool is_field_in_projection_list = FALSE; + TABLE* table = spider->get_table(); + uint16 projection_field_count = 0; + uint16 projection_field_index; + Field** field; + DBUG_ENTER( "spider_mysql_handler::is_sole_projection_field" ); + + for ( field = table->field; *field ; field++ ) + { + projection_field_index = ( *field )->field_index; + + if ( !( minimum_select_bit_is_set( projection_field_index ) ) ) + { + // Current field is not in the projection list + continue; + } + + projection_field_count++; + + if ( !is_field_in_projection_list ) + { + if ( field_index == projection_field_index ) + { + // Field of interest is in the projection list + is_field_in_projection_list = TRUE; + } + } + + if ( is_field_in_projection_list && ( projection_field_count != 1 ) ) + { + // Field of interest is not the sole column in the projection list + DBUG_RETURN( FALSE ); + } + } + + if ( is_field_in_projection_list && ( projection_field_count == 1 ) ) + { + // Field of interest is the only column in the projection list + DBUG_RETURN( TRUE ); + } + + DBUG_RETURN( FALSE ); +} + bool spider_mysql_handler::is_bulk_insert_exec_period( bool bulk_end ) { diff --git a/storage/spider/spd_db_mysql.h b/storage/spider/spd_db_mysql.h index 9a4f08ade98..482289d1d68 100644 --- a/storage/spider/spd_db_mysql.h +++ b/storage/spider/spd_db_mysql.h @@ -1128,6 +1128,9 @@ public: ulong sql_type, int link_idx ); + bool is_sole_projection_field( + uint16 field_index + ); bool is_bulk_insert_exec_period( bool bulk_end ); diff --git a/storage/spider/spd_db_oracle.cc b/storage/spider/spd_db_oracle.cc index 5e6c89b10d0..5b322b9c4d7 100644 --- a/storage/spider/spd_db_oracle.cc +++ b/storage/spider/spd_db_oracle.cc @@ -9571,6 +9571,65 @@ int spider_oracle_handler::append_explain_select( DBUG_RETURN(0); } +/******************************************************************** + * Determine whether the current query's projection list + * consists solely of the specified column. + * + * Params IN - field_index: + * Field index of the column of interest within + * its table. + * + * Returns TRUE - if the query's projection list consists + * solely of the specified column. + * FALSE - otherwise. + ********************************************************************/ +bool spider_oracle_handler::is_sole_projection_field( uint16 field_index ) +{ + // Determine whether the projection list consists solely of the field of interest + bool is_field_in_projection_list = FALSE; + TABLE* table = spider->get_table(); + uint16 projection_field_count = 0; + uint16 projection_field_index; + Field** field; + DBUG_ENTER( "spider_oracle_handler::is_sole_projection_field" ); + + for ( field = table->field; *field; field++ ) + { + projection_field_index = ( *field )->field_index; + + if ( !( minimum_select_bit_is_set( projection_field_index ) ) ) + { + // Current field is not in the projection list + continue; + } + + projection_field_count++; + + if ( !is_field_in_projection_list ) + { + if (field_index == projection_field_index) + { + // Field of interest is in the projection list + is_field_in_projection_list = TRUE; + } + } + + if ( is_field_in_projection_list && ( projection_field_count != 1 ) ) + { + // Field of interest is not the sole column in the projection list + DBUG_RETURN( FALSE ); + } + } + + if ( is_field_in_projection_list && ( projection_field_count == 1 ) ) + { + // Field of interest is the only column in the projection list + DBUG_RETURN( TRUE ); + } + + DBUG_RETURN( FALSE ); +} + bool spider_oracle_handler::is_bulk_insert_exec_period( bool bulk_end ) { diff --git a/storage/spider/spd_db_oracle.h b/storage/spider/spd_db_oracle.h index 0e84435d9be..7a070f498da 100644 --- a/storage/spider/spd_db_oracle.h +++ b/storage/spider/spd_db_oracle.h @@ -1208,6 +1208,9 @@ public: ulong sql_type, int link_idx ); + bool is_sole_projection_field( + uint16 field_index + ); bool is_bulk_insert_exec_period( bool bulk_end ); diff --git a/storage/xtradb/btr/btr0btr.cc b/storage/xtradb/btr/btr0btr.cc index 417eeb2c367..48411b6ff6a 100644 --- a/storage/xtradb/btr/btr0btr.cc +++ b/storage/xtradb/btr/btr0btr.cc @@ -3277,7 +3277,7 @@ func_start: btr_page_create(new_block, new_page_zip, cursor->index, btr_page_get_level(page, mtr), mtr); /* Only record the leaf level page splits. */ - if (btr_page_get_level(page, mtr) == 0) { + if (page_is_leaf(page)) { cursor->index->stat_defrag_n_page_split ++; cursor->index->stat_defrag_modified_counter ++; btr_defragment_save_defrag_stats_if_needed(cursor->index); diff --git a/storage/xtradb/btr/btr0defragment.cc b/storage/xtradb/btr/btr0defragment.cc index 8de85e746ca..3f4185341a6 100644 --- a/storage/xtradb/btr/btr0defragment.cc +++ b/storage/xtradb/btr/btr0defragment.cc @@ -233,7 +233,7 @@ btr_defragment_add_index( return NULL; } - if (btr_page_get_level(page, &mtr) == 0) { + if (page_is_leaf(page)) { // Index root is a leaf page, no need to defragment. mtr_commit(&mtr); return NULL; diff --git a/storage/xtradb/buf/buf0buf.cc b/storage/xtradb/buf/buf0buf.cc index 70cd9610b18..78ebbb7902b 100644 --- a/storage/xtradb/buf/buf0buf.cc +++ b/storage/xtradb/buf/buf0buf.cc @@ -5931,23 +5931,22 @@ buf_print_io_instance( pool_info->pages_written_rate); if (pool_info->n_page_get_delta) { - double hit_rate = ((1000 * pool_info->page_read_delta) - / pool_info->n_page_get_delta); + double hit_rate = double(pool_info->page_read_delta) + / pool_info->n_page_get_delta; - if (hit_rate > 1000) { - hit_rate = 1000; + if (hit_rate > 1) { + hit_rate = 1; } - hit_rate = 1000 - hit_rate; - fprintf(file, - "Buffer pool hit rate %lu / 1000," - " young-making rate %lu / 1000 not %lu / 1000\n", - (ulint) hit_rate, - (ulint) (1000 * pool_info->young_making_delta - / pool_info->n_page_get_delta), - (ulint) (1000 * pool_info->not_young_making_delta - / pool_info->n_page_get_delta)); + "Buffer pool hit rate " ULINTPF " / 1000," + " young-making rate " ULINTPF " / 1000 not " + ULINTPF " / 1000\n", + ulint(1000 * (1 - hit_rate)), + ulint(1000 * double(pool_info->young_making_delta) + / pool_info->n_page_get_delta), + ulint(1000 * double(pool_info->not_young_making_delta) + / pool_info->n_page_get_delta)); } else { fputs("No buffer pool page gets since the last printout\n", file); @@ -6245,70 +6244,54 @@ buf_pool_reserve_tmp_slot( return (free_slot); } -/********************************************************************//** -Encrypts a buffer page right before it's flushed to disk -@param[in,out] bpage Page control block -@param[in,out] src_frame Source page -@param[in] space_id Tablespace id -@return either unencrypted source page or decrypted page. -*/ +/** Encryption and page_compression hook that is called just before +a page is written to disk. +@param[in,out] space tablespace +@param[in,out] bpage buffer page +@param[in] src_frame physical page frame that is being encrypted +@return page frame to be written to file +(may be src_frame or an encrypted/compressed copy of it) */ +UNIV_INTERN byte* buf_page_encrypt_before_write( + fil_space_t* space, buf_page_t* bpage, - byte* src_frame, - ulint space_id) + byte* src_frame) { + ut_ad(space->id == bpage->space); bpage->real_size = UNIV_PAGE_SIZE; fil_page_type_validate(src_frame); - if (bpage->offset == 0) { + switch (bpage->offset) { + case 0: /* Page 0 of a tablespace is not encrypted/compressed */ ut_ad(bpage->key_version == 0); return src_frame; - } - - if (bpage->space == TRX_SYS_SPACE && bpage->offset == TRX_SYS_PAGE_NO) { - /* don't encrypt/compress page as it contains address to dblwr buffer */ - bpage->key_version = 0; - return src_frame; - } - - fil_space_t* space = fil_space_acquire_silent(space_id); - - /* Tablespace must exist during write operation */ - if (!space) { - /* This could be true on discard if we have injected a error - case e.g. in innodb.innodb-wl5522-debug-zip so that space - is already marked as stop_new_ops = true. */ - return src_frame; + case TRX_SYS_PAGE_NO: + if (bpage->space == TRX_SYS_SPACE) { + /* don't encrypt/compress page as it contains + address to dblwr buffer */ + bpage->key_version = 0; + return src_frame; + } } fil_space_crypt_t* crypt_data = space->crypt_data; - bool encrypted = true; + const bool encrypted = crypt_data + && !crypt_data->not_encrypted() + && crypt_data->type != CRYPT_SCHEME_UNENCRYPTED + && (!crypt_data->is_default_encryption() + || srv_encrypt_tables); - if (space->crypt_data != NULL && space->crypt_data->not_encrypted()) { - /* Encryption is disabled */ - encrypted = false; - } - - if (!srv_encrypt_tables && (crypt_data == NULL || crypt_data->is_default_encryption())) { - /* Encryption is disabled */ - encrypted = false; - } - - /* Is encryption needed? */ - if (crypt_data == NULL || crypt_data->type == CRYPT_SCHEME_UNENCRYPTED) { - /* An unencrypted table */ + if (!encrypted) { bpage->key_version = 0; - encrypted = false; } - bool page_compressed = fil_space_is_page_compressed(bpage->space); + bool page_compressed = FSP_FLAGS_HAS_PAGE_COMPRESSION(space->flags); if (!encrypted && !page_compressed) { /* No need to encrypt or page compress the page */ - fil_space_release(space); return src_frame; } @@ -6336,25 +6319,21 @@ buf_page_encrypt_before_write( bpage->real_size = page_size; slot->out_buf = dst_frame = tmp; -#ifdef UNIV_DEBUG - fil_page_type_validate(tmp); -#endif - + ut_d(fil_page_type_validate(tmp)); } else { /* First we compress the page content */ ulint out_len = 0; - ulint block_size = fil_space_get_block_size(bpage->space, bpage->offset, page_size); - - byte *tmp = fil_compress_page(bpage->space, - (byte *)src_frame, - slot->comp_buf, - page_size, - fil_space_get_page_compression_level(bpage->space), - block_size, - encrypted, - &out_len, - IF_LZO(slot->lzo_mem, NULL) - ); + + byte *tmp = fil_compress_page( + space, + (byte *)src_frame, + slot->comp_buf, + page_size, + fsp_flags_get_page_compression_level(space->flags), + fil_space_get_block_size(space, bpage->offset), + encrypted, + &out_len, + IF_LZO(slot->lzo_mem, NULL)); bpage->real_size = out_len; @@ -6379,7 +6358,6 @@ buf_page_encrypt_before_write( fil_page_type_validate(dst_frame); #endif - fil_space_release(space); // return dst_frame which will be written return dst_frame; } @@ -6433,9 +6411,9 @@ buf_page_decrypt_after_read( /* decompress using comp_buf to dst_frame */ fil_decompress_page(slot->comp_buf, - dst_frame, - size, - &bpage->write_size); + dst_frame, + ulong(size), + &bpage->write_size); /* Mark this slot as free */ slot->reserved = false; @@ -6487,13 +6465,10 @@ buf_page_decrypt_after_read( #endif /* decompress using comp_buf to dst_frame */ fil_decompress_page(slot->comp_buf, - dst_frame, - size, - &bpage->write_size); - -#ifdef UNIV_DEBUG - fil_page_type_validate(dst_frame); -#endif + dst_frame, + ulong(size), + &bpage->write_size); + ut_d(fil_page_type_validate(dst_frame)); } /* Mark this slot as free */ diff --git a/storage/xtradb/buf/buf0dblwr.cc b/storage/xtradb/buf/buf0dblwr.cc index b11c32064bf..55c5e4d543a 100644 --- a/storage/xtradb/buf/buf0dblwr.cc +++ b/storage/xtradb/buf/buf0dblwr.cc @@ -538,7 +538,7 @@ buf_dblwr_process() /* Decompress the page before validating the checksum. */ fil_decompress_page( - NULL, read_buf, UNIV_PAGE_SIZE, + NULL, read_buf, srv_page_size, NULL, true); } @@ -565,7 +565,7 @@ buf_dblwr_process() /* Decompress the page before validating the checksum. */ fil_decompress_page( - NULL, page, UNIV_PAGE_SIZE, NULL, true); + NULL, page, srv_page_size, NULL, true); } if (!fil_space_verify_crypt_checksum(page, zip_size, NULL, page_no) @@ -1001,7 +1001,7 @@ flush: srv_stats.dblwr_writes.inc(); /* Now flush the doublewrite buffer data to disk */ - fil_flush(TRX_SYS_SPACE); + fil_flush(ulint(TRX_SYS_SPACE)); /* We know that the writes have been flushed to disk now and in recovery we will find them in the doublewrite buffer @@ -1249,7 +1249,7 @@ retry: } /* Now flush the doublewrite buffer data to disk */ - fil_flush(TRX_SYS_SPACE); + fil_flush(ulint(TRX_SYS_SPACE)); /* We know that the write has been flushed to disk now and during recovery we will find it in the doublewrite buffer diff --git a/storage/xtradb/buf/buf0flu.cc b/storage/xtradb/buf/buf0flu.cc index e7ed7204920..ffd40157c30 100644 --- a/storage/xtradb/buf/buf0flu.cc +++ b/storage/xtradb/buf/buf0flu.cc @@ -873,11 +873,12 @@ buf_flush_write_block_low( buf_flush_t flush_type, /*!< in: type of flush */ bool sync) /*!< in: true if sync IO request */ { + fil_space_t* space = fil_space_acquire(bpage->space, true); + if (!space) { + return; + } ulint zip_size = buf_page_get_zip_size(bpage); page_t* frame = NULL; - ulint space_id = buf_page_get_space(bpage); - atomic_writes_t awrites = fil_space_get_atomic_writes(space_id); - #ifdef UNIV_DEBUG buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); ut_ad(!mutex_own(&buf_pool->LRU_list_mutex)); @@ -947,7 +948,7 @@ buf_flush_write_block_low( break; } - frame = buf_page_encrypt_before_write(bpage, frame, space_id); + frame = buf_page_encrypt_before_write(space, bpage, frame); if (!srv_use_doublewrite_buf || !buf_dblwr) { fil_io(OS_FILE_WRITE | OS_AIO_SIMULATED_WAKE_LATER, @@ -968,7 +969,8 @@ buf_flush_write_block_low( atomic writes should be used, no doublewrite buffer is used. */ - if (awrites == ATOMIC_WRITES_ON) { + if (fsp_flags_get_atomic_writes(space->flags) + == ATOMIC_WRITES_ON) { fil_io(OS_FILE_WRITE | OS_AIO_SIMULATED_WAKE_LATER, FALSE, buf_page_get_space(bpage), @@ -991,10 +993,12 @@ buf_flush_write_block_low( are working on. */ if (sync) { ut_ad(flush_type == BUF_FLUSH_SINGLE_PAGE); - fil_flush(buf_page_get_space(bpage)); + fil_flush(space); buf_page_io_complete(bpage); } + fil_space_release(space); + /* Increment the counter of I/O operations used for selecting LRU policy. */ buf_LRU_stat_inc_io(); diff --git a/storage/xtradb/buf/buf0rea.cc b/storage/xtradb/buf/buf0rea.cc index 15465699726..be2ee56504b 100644 --- a/storage/xtradb/buf/buf0rea.cc +++ b/storage/xtradb/buf/buf0rea.cc @@ -998,15 +998,11 @@ not_to_recover: count++; if (count > 1000) { - fprintf(stderr, - "InnoDB: Error: InnoDB has waited for" - " 10 seconds for pending\n" - "InnoDB: reads to the buffer pool to" - " be finished.\n" - "InnoDB: Number of pending reads %lu," - " pending pread calls %lu\n", - (ulong) buf_pool->n_pend_reads, - (ulong) os_file_n_pending_preads); + ib_logf(IB_LOG_LEVEL_ERROR, + "waited for 10 seconds for " ULINTPF + " pending reads to the buffer pool to" + " be finished", + buf_pool->n_pend_reads); os_aio_print_debug = TRUE; } diff --git a/storage/xtradb/dict/dict0stats.cc b/storage/xtradb/dict/dict0stats.cc index 6a28f3cdf8f..33b6c2e23e0 100644 --- a/storage/xtradb/dict/dict0stats.cc +++ b/storage/xtradb/dict/dict0stats.cc @@ -1576,7 +1576,7 @@ dict_stats_analyze_index_below_cur( page = buf_block_get_frame(block); - if (btr_page_get_level(page, mtr) == 0) { + if (page_is_leaf(page)) { /* leaf level */ break; } @@ -1620,7 +1620,7 @@ dict_stats_analyze_index_below_cur( } /* make sure we got a leaf page as a result from the above loop */ - ut_ad(btr_page_get_level(page, &mtr) == 0); + ut_ad(page_is_leaf(page)); /* scan the leaf page and find the number of distinct keys, when looking only at the first n_prefix columns; also estimate diff --git a/storage/xtradb/fil/fil0crypt.cc b/storage/xtradb/fil/fil0crypt.cc index aa95de7efea..f37d5e19ad6 100644 --- a/storage/xtradb/fil/fil0crypt.cc +++ b/storage/xtradb/fil/fil0crypt.cc @@ -694,7 +694,8 @@ fil_space_encrypt( comp_mem = (byte *)malloc(UNIV_PAGE_SIZE); uncomp_mem = (byte *)malloc(UNIV_PAGE_SIZE); memcpy(comp_mem, src_frame, UNIV_PAGE_SIZE); - fil_decompress_page(uncomp_mem, comp_mem, UNIV_PAGE_SIZE, NULL); + fil_decompress_page(uncomp_mem, comp_mem, + srv_page_size, NULL); src = uncomp_mem; } @@ -704,7 +705,8 @@ fil_space_encrypt( /* Need to decompress the page if it was also compressed */ if (page_compressed_encrypted) { memcpy(comp_mem, tmp_mem, UNIV_PAGE_SIZE); - fil_decompress_page(tmp_mem, comp_mem, UNIV_PAGE_SIZE, NULL); + fil_decompress_page(tmp_mem, comp_mem, + srv_page_size, NULL); } bool corrupted = buf_page_is_corrupted(true, tmp_mem, zip_size, space); @@ -1492,20 +1494,21 @@ fil_crypt_realloc_iops( if (10 * state->cnt_waited > state->batch) { /* if we waited more than 10% re-estimate max_iops */ - uint avg_wait_time_us = + ulint avg_wait_time_us = state->sum_waited_us / state->cnt_waited; + if (avg_wait_time_us == 0) { + avg_wait_time_us = 1; // prevent division by zero + } + DBUG_PRINT("ib_crypt", - ("thr_no: %u - update estimated_max_iops from %u to %u.", + ("thr_no: %u - update estimated_max_iops from %u to " + ULINTPF ".", state->thread_no, state->estimated_max_iops, 1000000 / avg_wait_time_us)); - if (avg_wait_time_us == 0) { - avg_wait_time_us = 1; // prevent division by zero - } - - state->estimated_max_iops = 1000000 / avg_wait_time_us; + state->estimated_max_iops = uint(1000000 / avg_wait_time_us); state->cnt_waited = 0; state->sum_waited_us = 0; } else { @@ -1739,33 +1742,27 @@ fil_crypt_find_page_to_rotate( fil_space_crypt_t *crypt_data = space->crypt_data; - /* Space might already be dropped */ - if (crypt_data) { - mutex_enter(&crypt_data->mutex); - ut_ad(key_state->key_id == crypt_data->key_id); - - if (crypt_data->rotate_state.next_offset < - crypt_data->rotate_state.max_offset) { + mutex_enter(&crypt_data->mutex); + ut_ad(key_state->key_id == crypt_data->key_id); - state->offset = crypt_data->rotate_state.next_offset; - ulint remaining = crypt_data->rotate_state.max_offset - - crypt_data->rotate_state.next_offset; + bool found = crypt_data->rotate_state.max_offset >= + crypt_data->rotate_state.next_offset; - if (batch <= remaining) { - state->batch = batch; - } else { - state->batch = remaining; - } + if (found) { + state->offset = crypt_data->rotate_state.next_offset; + ulint remaining = crypt_data->rotate_state.max_offset - + crypt_data->rotate_state.next_offset; - crypt_data->rotate_state.next_offset += batch; - mutex_exit(&crypt_data->mutex); - return true; + if (batch <= remaining) { + state->batch = batch; + } else { + state->batch = remaining; } - - mutex_exit(&crypt_data->mutex); } - return false; + crypt_data->rotate_state.next_offset += batch; + mutex_exit(&crypt_data->mutex); + return found; } /*********************************************************************** @@ -2343,7 +2340,7 @@ DECLARE_THREAD(fil_crypt_thread)( fil_crypt_start_rotate_space(&new_state, &thr); /* iterate all pages (cooperativly with other threads) */ - while (!thr.should_shutdown() && thr.space && + while (!thr.should_shutdown() && fil_crypt_find_page_to_rotate(&new_state, &thr)) { /* rotate a (set) of pages */ @@ -2352,6 +2349,8 @@ DECLARE_THREAD(fil_crypt_thread)( /* If space is marked as stopping, release space and stop rotation. */ if (thr.space->is_stopping()) { + fil_crypt_complete_rotate_space( + &new_state, &thr); fil_space_release(thr.space); thr.space = NULL; break; diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index e7244d719c8..e504ab3947e 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -5993,31 +5993,34 @@ fil_space_get_node( return (node); } -/********************************************************************//** -Return block size of node in file space -@return file block size */ + +/** Determine the block size of the data file. +@param[in] space tablespace +@param[in] offset page number +@return block size */ UNIV_INTERN ulint -fil_space_get_block_size( -/*=====================*/ - ulint space_id, - ulint block_offset, - ulint len) +fil_space_get_block_size(const fil_space_t* space, unsigned offset) { - ulint block_size = 512; - ut_ad(!mutex_own(&fil_system->mutex)); - - mutex_enter(&fil_system->mutex); - fil_space_t* space = fil_space_get_space(space_id); + ut_ad(space->n_pending_ops > 0); - if (space) { - fil_node_t* node = fil_space_get_node(space, space_id, &block_offset, 0, len); + ulint block_size = 512; - if (node) { - block_size = node->file_block_size; + for (fil_node_t* node = UT_LIST_GET_FIRST(space->chain); + node != NULL; + node = UT_LIST_GET_NEXT(chain, node)) { + block_size = node->file_block_size; + if (node->size > offset) { + break; } + offset -= node->size; + } + + /* Currently supporting block size up to 4K, + fall back to default if bigger requested. */ + if (block_size > 4096) { + block_size = 512; } - mutex_exit(&fil_system->mutex); return block_size; } @@ -6398,14 +6401,29 @@ fil_flush( mutex_exit(&fil_system->mutex); } -/**********************************************************************//** -Flushes to disk the writes in file spaces of the given type possibly cached by -the OS. */ +/** Flush a tablespace. +@param[in,out] space tablespace to flush */ UNIV_INTERN void -fil_flush_file_spaces( -/*==================*/ - ulint purpose) /*!< in: FIL_TABLESPACE, FIL_LOG */ +fil_flush(fil_space_t* space) +{ + ut_ad(space->n_pending_ops > 0); + + if (!space->is_stopping()) { + mutex_enter(&fil_system->mutex); + if (!space->is_stopping()) { + fil_flush_low(space); + } + mutex_exit(&fil_system->mutex); + } +} + +/** Flush to disk the writes in file spaces of the given type +possibly cached by the OS. +@param[in] purpose FIL_TYPE_TABLESPACE or FIL_TYPE_LOG */ +UNIV_INTERN +void +fil_flush_file_spaces(ulint purpose) { fil_space_t* space; ulint* space_ids; @@ -6772,7 +6790,8 @@ fil_iterate( /* If the original page is page_compressed, we need to decompress page before we can update it. */ if (page_compressed) { - fil_decompress_page(NULL, dst, size, NULL); + fil_decompress_page(NULL, dst, ulong(size), + NULL); updated = true; } @@ -6832,12 +6851,14 @@ fil_iterate( if (page_compressed) { ulint len = 0; - fil_compress_page(space_id, + + fil_compress_page( + NULL, src, NULL, size, - fil_space_get_page_compression_level(space_id), - fil_space_get_block_size(space_id, offset, size), + 0,/* FIXME: compression level */ + 512,/* FIXME: use proper block size */ encrypted, &len, NULL); @@ -6848,6 +6869,8 @@ fil_iterate( /* If tablespace is encrypted, encrypt page before we write it back. Note that we should not encrypt the buffer that is in buffer pool. */ + /* NOTE: At this stage of IMPORT the + buffer pool is not being used at all! */ if (decrypted && encrypted) { byte *dest = writeptr + (i * size); ulint space = mach_read_from_4( @@ -7401,7 +7424,6 @@ fil_space_acquire_low(ulint id, bool silent, bool for_io = false) if (!silent) { ib_logf(IB_LOG_LEVEL_WARN, "Trying to access missing" " tablespace " ULINTPF ".", id); - ut_error; } } else if (!for_io && space->is_stopping()) { space = NULL; diff --git a/storage/xtradb/fil/fil0pagecompress.cc b/storage/xtradb/fil/fil0pagecompress.cc index 303ab5102fb..8b2449983df 100644 --- a/storage/xtradb/fil/fil0pagecompress.cc +++ b/storage/xtradb/fil/fil0pagecompress.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (C) 2013, 2016, MariaDB Corporation. All Rights Reserved. +Copyright (C) 2013, 2017, MariaDB Corporation. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -91,8 +91,7 @@ UNIV_INTERN byte* fil_compress_page( /*==============*/ - ulint space_id, /*!< in: tablespace id of the - table. */ + fil_space_t* space, /*!< in,out: tablespace (NULL during IMPORT) */ byte* buf, /*!< in: buffer from which to write; in aio this must be appropriately aligned */ byte* out_buf, /*!< out: compressed buffer */ @@ -110,9 +109,12 @@ fil_compress_page( ulint write_size=0; /* Cache to avoid change during function execution */ ulint comp_method = innodb_compression_algorithm; - ulint orig_page_type; bool allocated=false; + /* page_compression does not apply to tables or tablespaces + that use ROW_FORMAT=COMPRESSED */ + ut_ad(!space || !FSP_FLAGS_GET_ZIP_SSIZE(space->flags)); + if (encrypted) { header_len += FIL_PAGE_COMPRESSION_METHOD_SIZE; } @@ -133,21 +135,14 @@ fil_compress_page( ut_ad(len); ut_ad(out_len); - /* read original page type */ - orig_page_type = mach_read_from_2(buf + FIL_PAGE_TYPE); - - fil_system_enter(); - fil_space_t* space = fil_space_get_by_id(space_id); - fil_system_exit(); - /* Let's not compress file space header or extent descriptor */ - if (orig_page_type == 0 || - orig_page_type == FIL_PAGE_TYPE_FSP_HDR || - orig_page_type == FIL_PAGE_TYPE_XDES || - orig_page_type == FIL_PAGE_PAGE_COMPRESSED) { + switch (fil_page_get_type(buf)) { + case 0: + case FIL_PAGE_TYPE_FSP_HDR: + case FIL_PAGE_TYPE_XDES: + case FIL_PAGE_PAGE_COMPRESSED: *out_len = len; - goto err_exit; } @@ -157,11 +152,11 @@ fil_compress_page( comp_level = page_zip_level; } -#ifdef UNIV_PAGECOMPRESS_DEBUG - ib_logf(IB_LOG_LEVEL_INFO, - "Preparing for compress for space %lu name %s len %lu.", - space_id, fil_space_name(space), len); -#endif /* UNIV_PAGECOMPRESS_DEBUG */ + DBUG_PRINT("compress", + ("Preparing for space " ULINTPF " '%s' len " ULINTPF, + space ? space->id : 0, + space ? space->name : "(import)", + len)); write_size = UNIV_PAGE_SIZE - header_len; @@ -176,12 +171,15 @@ fil_compress_page( /* If error we leave the actual page as it was */ #ifndef UNIV_PAGECOMPRESS_DEBUG - if (space->printed_compression_failure == false) { + if (space && !space->printed_compression_failure) { + space->printed_compression_failure = true; #endif ib_logf(IB_LOG_LEVEL_WARN, - "Compression failed for space %lu name %s len %lu rt %d write %lu.", - space_id, fil_space_name(space), len, err, write_size); - space->printed_compression_failure = true; + "Compression failed for space " ULINTPF + " name %s len " ULINTPF + " err %d write_size " ULINTPF ".", + space->id, space->name, len, + err, write_size); #ifndef UNIV_PAGECOMPRESS_DEBUG } #endif @@ -197,11 +195,14 @@ fil_compress_page( buf, len, out_buf+header_len, &write_size, lzo_mem); if (err != LZO_E_OK || write_size > UNIV_PAGE_SIZE-header_len) { - if (space->printed_compression_failure == false) { - ib_logf(IB_LOG_LEVEL_WARN, - "Compression failed for space %lu name %s len %lu err %d write_size %lu.", - space_id, fil_space_name(space), len, err, write_size); + if (space && !space->printed_compression_failure) { space->printed_compression_failure = true; + ib_logf(IB_LOG_LEVEL_WARN, + "Compression failed for space " ULINTPF + " name %s len " ULINTPF + " err %d write_size " ULINTPF ".", + space->id, space->name, len, + err, write_size); } srv_stats.pages_page_compression_error.inc(); @@ -226,11 +227,14 @@ fil_compress_page( (size_t)write_size); if (err != LZMA_OK || out_pos > UNIV_PAGE_SIZE-header_len) { - if (space->printed_compression_failure == false) { - ib_logf(IB_LOG_LEVEL_WARN, - "Compression failed for space %lu name %s len %lu err %d write_size %lu", - space_id, fil_space_name(space), len, err, out_pos); + if (space && !space->printed_compression_failure) { space->printed_compression_failure = true; + ib_logf(IB_LOG_LEVEL_WARN, + "Compression failed for space " ULINTPF + " name %s len " ULINTPF + " err %d write_size " ULINTPF ".", + space->id, space->name, len, + err, out_pos); } srv_stats.pages_page_compression_error.inc(); @@ -257,11 +261,14 @@ fil_compress_page( 0); if (err != BZ_OK || write_size > UNIV_PAGE_SIZE-header_len) { - if (space->printed_compression_failure == false) { - ib_logf(IB_LOG_LEVEL_WARN, - "Compression failed for space %lu name %s len %lu err %d write_size %lu.", - space_id, fil_space_name(space), len, err, write_size); + if (space && !space->printed_compression_failure) { space->printed_compression_failure = true; + ib_logf(IB_LOG_LEVEL_WARN, + "Compression failed for space " ULINTPF + " name %s len " ULINTPF + " err %d write_size " ULINTPF ".", + space->id, space->name, len, + err, write_size); } srv_stats.pages_page_compression_error.inc(); @@ -284,11 +291,14 @@ fil_compress_page( (size_t*)&write_size); if (cstatus != SNAPPY_OK || write_size > UNIV_PAGE_SIZE-header_len) { - if (space->printed_compression_failure == false) { - ib_logf(IB_LOG_LEVEL_WARN, - "Compression failed for space %lu name %s len %lu err %d write_size %lu.", - space_id, fil_space_name(space), len, (int)cstatus, write_size); + if (space && !space->printed_compression_failure) { space->printed_compression_failure = true; + ib_logf(IB_LOG_LEVEL_WARN, + "Compression failed for space " ULINTPF + " name %s len " ULINTPF + " err %d write_size " ULINTPF ".", + space->id, space->name, len, + (int)cstatus, write_size); } srv_stats.pages_page_compression_error.inc(); @@ -300,16 +310,20 @@ fil_compress_page( #endif /* HAVE_SNAPPY */ case PAGE_ZLIB_ALGORITHM: - err = compress2(out_buf+header_len, (ulong*)&write_size, buf, len, comp_level); + err = compress2(out_buf+header_len, (ulong*)&write_size, buf, + uLong(len), comp_level); if (err != Z_OK) { /* If error we leave the actual page as it was */ - if (space->printed_compression_failure == false) { - ib_logf(IB_LOG_LEVEL_WARN, - "Compression failed for space %lu name %s len %lu rt %d write %lu.", - space_id, fil_space_name(space), len, err, write_size); + if (space && !space->printed_compression_failure) { space->printed_compression_failure = true; + ib_logf(IB_LOG_LEVEL_WARN, + "Compression failed for space " ULINTPF + " name %s len " ULINTPF + " rt %d write_size " ULINTPF ".", + space->id, space->name, len, + err, write_size); } srv_stats.pages_page_compression_error.inc(); @@ -364,11 +378,10 @@ fil_compress_page( uncomp_page = static_cast<byte *>(ut_malloc(UNIV_PAGE_SIZE)); memcpy(comp_page, out_buf, UNIV_PAGE_SIZE); - fil_decompress_page(uncomp_page, comp_page, len, NULL); + fil_decompress_page(uncomp_page, comp_page, ulong(len), NULL); - if(buf_page_is_corrupted(false, uncomp_page, 0, space)) { - buf_page_print(uncomp_page, 0, BUF_PAGE_PRINT_NO_CRASH); - ut_error; + if (buf_page_is_corrupted(false, uncomp_page, 0, space)) { + buf_page_print(uncomp_page, 0, 0); } ut_free(comp_page); @@ -396,11 +409,12 @@ fil_compress_page( #endif } -#ifdef UNIV_PAGECOMPRESS_DEBUG - ib_logf(IB_LOG_LEVEL_INFO, - "Compression succeeded for space %lu name %s len %lu out_len %lu.", - space_id, fil_space_name(space), len, write_size); -#endif /* UNIV_PAGECOMPRESS_DEBUG */ + DBUG_PRINT("compress", + ("Succeeded for space " ULINTPF + " '%s' len " ULINTPF " out_len " ULINTPF, + space ? space->id : 0, + space ? space->name : "(import)", + len, write_size)); srv_stats.page_compression_saved.add((len - write_size)); srv_stats.pages_page_compressed.inc(); diff --git a/storage/xtradb/include/buf0buf.h b/storage/xtradb/include/buf0buf.h index 1774d9445ff..4a632e2345f 100644 --- a/storage/xtradb/include/buf0buf.h +++ b/storage/xtradb/include/buf0buf.h @@ -1534,17 +1534,19 @@ buf_own_zip_mutex_for_page( MY_ATTRIBUTE((nonnull,warn_unused_result)); #endif /* UNIV_DEBUG */ -/********************************************************************//** -The hook that is called just before a page is written to disk. -The function encrypts the content of the page and returns a pointer -to a frame that will be written instead of the real frame. */ +/** Encryption and page_compression hook that is called just before +a page is written to disk. +@param[in,out] space tablespace +@param[in,out] bpage buffer page +@param[in] src_frame physical page frame that is being encrypted +@return page frame to be written to file +(may be src_frame or an encrypted/compressed copy of it) */ UNIV_INTERN byte* buf_page_encrypt_before_write( -/*==========================*/ - buf_page_t* page, /*!< in/out: buffer page to be flushed */ - byte* frame, /*!< in: src frame */ - ulint space_id); /*!< in: space id */ + fil_space_t* space, + buf_page_t* bpage, + byte* src_frame); /********************************************************************** The hook that is called after page is written to disk. diff --git a/storage/xtradb/include/dict0dict.ic b/storage/xtradb/include/dict0dict.ic index 81da2fa5580..e3de7a33123 100644 --- a/storage/xtradb/include/dict0dict.ic +++ b/storage/xtradb/include/dict0dict.ic @@ -540,15 +540,16 @@ dict_tf_is_valid( /* Make sure there are no bits that we do not know about. */ if (unused != 0) { - fprintf(stderr, - "InnoDB: Error: table unused flags are %ld" + "InnoDB: Error: table unused flags are " ULINTPF " in the data dictionary and are corrupted\n" "InnoDB: Error: data dictionary flags are\n" - "InnoDB: compact %ld atomic_blobs %ld\n" - "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n" - "InnoDB: page_compression %ld page_compression_level %ld\n" - "InnoDB: atomic_writes %ld\n", + "InnoDB: compact " ULINTPF " atomic_blobs " ULINTPF + "\nInnoDB: unused " ULINTPF " data_dir " ULINTPF + " zip_ssize " ULINTPF + "\nInnoDB: page_compression " ULINTPF + " page_compression_level " ULINTPF + "\nInnoDB: atomic_writes " ULINTPF "\n", unused, compact, atomic_blobs, unused, data_dir, zip_ssize, page_compression, page_compression_level, atomic_writes @@ -564,17 +565,20 @@ dict_tf_is_valid( if (!compact) { fprintf(stderr, - "InnoDB: Error: table compact flags are %ld" + "InnoDB: Error: table compact flags are " + ULINTPF " in the data dictionary and are corrupted\n" "InnoDB: Error: data dictionary flags are\n" - "InnoDB: compact %ld atomic_blobs %ld\n" - "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n" - "InnoDB: page_compression %ld page_compression_level %ld\n" - "InnoDB: atomic_writes %ld\n", + "InnoDB: compact " ULINTPF + " atomic_blobs " ULINTPF "\n" + "InnoDB: unused " ULINTPF + " data_dir " ULINTPF " zip_ssize " ULINTPF + "\nInnoDB: page_compression " ULINTPF + " page_compression_level " ULINTPF + "\nInnoDB: atomic_writes " ULINTPF "\n", compact, compact, atomic_blobs, unused, data_dir, zip_ssize, page_compression, page_compression_level, atomic_writes ); - return(false); } @@ -582,17 +586,18 @@ dict_tf_is_valid( /* Antelope does not support COMPRESSED row format. */ fprintf(stderr, - "InnoDB: Error: table flags are %ld" + "InnoDB: Error: table flags are " ULINTPF " in the data dictionary and are corrupted\n" "InnoDB: Error: data dictionary flags are\n" - "InnoDB: compact %ld atomic_blobs %ld\n" - "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n" - "InnoDB: page_compression %ld page_compression_level %ld\n" - "InnoDB: atomic_writes %ld\n", + "InnoDB: compact " ULINTPF " atomic_blobs " ULINTPF + "\nInnoDB: unused " ULINTPF " data_dir " ULINTPF + " zip_ssize " ULINTPF + "\nInnoDB: page_compression " ULINTPF + " page_compression_level " ULINTPF + "\nInnoDB: atomic_writes " ULINTPF "\n", flags, compact, atomic_blobs, unused, data_dir, zip_ssize, page_compression, page_compression_level, atomic_writes ); - return(false); } @@ -606,12 +611,17 @@ dict_tf_is_valid( || zip_ssize > PAGE_ZIP_SSIZE_MAX) { fprintf(stderr, - "InnoDB: Error: table compact flags are %ld in the data dictionary and are corrupted\n" + "InnoDB: Error: table compact flags are " + ULINTPF + " in the data dictionary and are corrupted\n" "InnoDB: Error: data dictionary flags are\n" - "InnoDB: compact %ld atomic_blobs %ld\n" - "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n" - "InnoDB: page_compression %ld page_compression_level %ld\n" - "InnoDB: atomic_writes %ld\n", + "InnoDB: compact " ULINTPF + " atomic_blobs " ULINTPF "\n" + "InnoDB: unused " ULINTPF + " data_dir " ULINTPF " zip_ssize " ULINTPF + "\nInnoDB: page_compression " ULINTPF + " page_compression_level " ULINTPF + "\nInnoDB: atomic_writes " ULINTPF "\n", flags, compact, atomic_blobs, unused, data_dir, zip_ssize, page_compression, page_compression_level, atomic_writes @@ -630,16 +640,19 @@ dict_tf_is_valid( || !atomic_blobs) { fprintf(stderr, - "InnoDB: Error: table flags are %ld in the data dictionary and are corrupted\n" + "InnoDB: Error: table flags are " ULINTPF + " in the data dictionary and are corrupted\n" "InnoDB: Error: data dictionary flags are\n" - "InnoDB: compact %ld atomic_blobs %ld\n" - "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n" - "InnoDB: page_compression %ld page_compression_level %ld\n" - "InnoDB: atomic_writes %ld\n", + "InnoDB: compact " ULINTPF + " atomic_blobs " ULINTPF "\n" + "InnoDB: unused " ULINTPF + " data_dir " ULINTPF " zip_ssize " ULINTPF + "\nInnoDB: page_compression " ULINTPF + " page_compression_level " ULINTPF + "\nInnoDB: atomic_writes " ULINTPF "\n", flags, compact, atomic_blobs, unused, data_dir, zip_ssize, page_compression, page_compression_level, atomic_writes ); - return(false); } } @@ -649,12 +662,16 @@ dict_tf_is_valid( if(atomic_writes > ATOMIC_WRITES_OFF) { fprintf(stderr, - "InnoDB: Error: table flags are %ld in the data dictionary and are corrupted\n" + "InnoDB: Error: table flags are " ULINTPF + " in the data dictionary and are corrupted\n" "InnoDB: Error: data dictionary flags are\n" - "InnoDB: compact %ld atomic_blobs %ld\n" - "InnoDB: unused %ld data_dir %ld zip_ssize %ld\n" - "InnoDB: page_compression %ld page_compression_level %ld\n" - "InnoDB: atomic_writes %ld\n", + "InnoDB: compact " ULINTPF + " atomic_blobs " ULINTPF "\n" + "InnoDB: unused " ULINTPF + " data_dir " ULINTPF " zip_ssize " ULINTPF + "\nInnoDB: page_compression " ULINTPF + " page_compression_level " ULINTPF + "\nInnoDB: atomic_writes " ULINTPF "\n", flags, compact, atomic_blobs, unused, data_dir, zip_ssize, page_compression, page_compression_level, atomic_writes ); @@ -699,7 +716,7 @@ dict_sys_tables_type_validate( if (redundant) { if (zip_ssize || atomic_blobs) { - fprintf(stderr, "InnoDB: Error: SYS_TABLES::TYPE=Redundant, zip_ssize %lu atomic_blobs %lu\n", + fprintf(stderr, "InnoDB: Error: SYS_TABLES::TYPE=Redundant, zip_ssize " ULINTPF " atomic_blobs " ULINTPF "\n", zip_ssize, atomic_blobs); return(ULINT_UNDEFINED); } @@ -707,7 +724,7 @@ dict_sys_tables_type_validate( /* Make sure there are no bits that we do not know about. */ if (unused) { - fprintf(stderr, "InnoDB: Error: SYS_TABLES::TYPE=%lu, unused %lu\n", + fprintf(stderr, "InnoDB: Error: SYS_TABLES::TYPE=" ULINTPF ", unused " ULINTPF "\n", type, unused); return(ULINT_UNDEFINED); } @@ -723,7 +740,7 @@ dict_sys_tables_type_validate( } else if (zip_ssize) { /* Antelope does not support COMPRESSED format. */ - fprintf(stderr, "InnoDB: Error: SYS_TABLES::TYPE=%lu, zip_ssize %lu\n", + fprintf(stderr, "InnoDB: Error: SYS_TABLES::TYPE=" ULINTPF ", zip_ssize " ULINTPF "\n", type, zip_ssize); return(ULINT_UNDEFINED); } @@ -734,14 +751,14 @@ dict_sys_tables_type_validate( should be in N_COLS, but we already know about the low_order_bit and DICT_N_COLS_COMPACT flags. */ if (!atomic_blobs) { - fprintf(stderr, "InnoDB: Error: SYS_TABLES::TYPE=%lu, zip_ssize %lu atomic_blobs %lu\n", + fprintf(stderr, "InnoDB: Error: SYS_TABLES::TYPE=" ULINTPF ", zip_ssize " ULINTPF " atomic_blobs " ULINTPF "\n", type, zip_ssize, atomic_blobs); return(ULINT_UNDEFINED); } /* Validate that the number is within allowed range. */ if (zip_ssize > PAGE_ZIP_SSIZE_MAX) { - fprintf(stderr, "InnoDB: Error: SYS_TABLES::TYPE=%lu, zip_ssize %lu max %d\n", + fprintf(stderr, "InnoDB: Error: SYS_TABLES::TYPE=" ULINTPF ", zip_ssize " ULINTPF " max %d\n", type, zip_ssize, PAGE_ZIP_SSIZE_MAX); return(ULINT_UNDEFINED); } @@ -759,8 +776,8 @@ dict_sys_tables_type_validate( low_order_bit and DICT_N_COLS_COMPACT flags. */ if (!atomic_blobs || !page_compression) { - fprintf(stderr, "InnoDB: Error: SYS_TABLES::TYPE=%lu, page_compression %lu page_compression_level %lu\n" - "InnoDB: Error: atomic_blobs %lu\n", + fprintf(stderr, "InnoDB: Error: SYS_TABLES::TYPE=" ULINTPF ", page_compression " ULINTPF " page_compression_level " ULINTPF "\n" + "InnoDB: Error: atomic_blobs " ULINTPF "\n", type, page_compression, page_compression_level, atomic_blobs); return(ULINT_UNDEFINED); } @@ -768,7 +785,7 @@ dict_sys_tables_type_validate( /* Validate that the atomic writes number is within allowed range. */ if (atomic_writes > ATOMIC_WRITES_OFF) { - fprintf(stderr, "InnoDB: Error: SYS_TABLES::TYPE=%lu, atomic_writes %lu\n", + fprintf(stderr, "InnoDB: Error: SYS_TABLES::TYPE=" ULINTPF ", atomic_writes " ULINTPF "\n", type, atomic_writes); return(ULINT_UNDEFINED); } diff --git a/storage/xtradb/include/fil0crypt.h b/storage/xtradb/include/fil0crypt.h index cfc2d850883..e7e9676aa3a 100644 --- a/storage/xtradb/include/fil0crypt.h +++ b/storage/xtradb/include/fil0crypt.h @@ -109,7 +109,7 @@ struct fil_space_crypt_t : st_encryption_scheme The object is expected to be placed in a buffer that has been zero-initialized. */ fil_space_crypt_t( - ulint new_type, + uint new_type, uint new_min_key_version, uint new_key_id, fil_encryption_t new_encryption) @@ -117,10 +117,10 @@ struct fil_space_crypt_t : st_encryption_scheme min_key_version(new_min_key_version), page0_offset(0), encryption(new_encryption), - key_found(), + mutex(), + key_found(new_min_key_version), rotate_state() { - key_found = new_min_key_version; key_id = new_key_id; my_random_bytes(iv, sizeof(iv)); mutex_create(fil_crypt_data_mutex_key, diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h index 698039afede..d73a68d9d34 100644 --- a/storage/xtradb/include/fil0fil.h +++ b/storage/xtradb/include/fil0fil.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2017, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2013, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1120,16 +1120,13 @@ _fil_io( #define fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message, write_size) \ _fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message, write_size, NULL) -/*******************************************************************//** -Returns the block size of the file space +/** Determine the block size of the data file. +@param[in] space tablespace +@param[in] offset page number @return block size */ UNIV_INTERN ulint -fil_space_get_block_size( -/*=====================*/ - ulint id, /*!< in: space id */ - ulint offset, /*!< in: page offset */ - ulint len); /*!< in: page len */ +fil_space_get_block_size(const fil_space_t* space, unsigned offset); /**********************************************************************//** Waits for an aio operation to complete. This function is used to write the @@ -1151,14 +1148,18 @@ fil_flush( /*======*/ ulint space_id); /*!< in: file space id (this can be a group of log files or a tablespace of the database) */ -/**********************************************************************//** -Flushes to disk writes in file spaces of the given type possibly cached by -the OS. */ +/** Flush a tablespace. +@param[in,out] space tablespace to flush */ UNIV_INTERN void -fil_flush_file_spaces( -/*==================*/ - ulint purpose); /*!< in: FIL_TABLESPACE, FIL_LOG */ +fil_flush(fil_space_t* space); + +/** Flush to disk the writes in file spaces of the given type +possibly cached by the OS. +@param[in] purpose FIL_TYPE_TABLESPACE or FIL_TYPE_LOG */ +UNIV_INTERN +void +fil_flush_file_spaces(ulint purpose); /******************************************************************//** Checks the consistency of the tablespace cache. @return TRUE if ok */ @@ -1459,14 +1460,6 @@ fil_get_next_space_safe( #endif /* UNIV_INNOCHECKSUM */ -/*******************************************************************//** -Return space flags */ -UNIV_INLINE -ulint -fil_space_flags( -/*===========*/ - fil_space_t* space); /*!< in: space */ - /****************************************************************//** Does error handling when a file operation fails. @return TRUE if we should retry the operation */ diff --git a/storage/xtradb/include/fil0fil.ic b/storage/xtradb/include/fil0fil.ic index 1179eea8b8e..6c2504c9f8c 100644 --- a/storage/xtradb/include/fil0fil.ic +++ b/storage/xtradb/include/fil0fil.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2015, MariaDB Corporation. +Copyright (c) 2015, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -27,28 +27,6 @@ Created 31/03/2015 Jan Lindström #define fil0fil_ic /*******************************************************************//** -Return space name */ -UNIV_INLINE -char* -fil_space_name( -/*===========*/ - fil_space_t* space) /*!< in: space */ -{ - return (space->name); -} - -/*******************************************************************//** -Return space flags */ -UNIV_INLINE -ulint -fil_space_flags( -/*===========*/ - fil_space_t* space) /*!< in: space */ -{ - return (space->flags); -} - -/*******************************************************************//** Return page type name */ UNIV_INLINE const char* @@ -137,7 +115,7 @@ fil_page_type_validate( page_type == FIL_PAGE_TYPE_ZBLOB2 || page_type == FIL_PAGE_TYPE_COMPRESSED))) { - uint key_version = mach_read_from_4(page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); + ulint key_version = mach_read_from_4(page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); bool page_compressed = (page_type == FIL_PAGE_PAGE_COMPRESSED); bool page_compressed_encrypted = (page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED); ulint space = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); @@ -148,30 +126,18 @@ fil_page_type_validate( fil_space_t* rspace = fil_space_get_by_id(space); fil_system_exit(); - /* Dump out the page info */ - fprintf(stderr, "InnoDB: Space %lu offset %lu name %s page_type %lu page_type_name %s\n" - "InnoDB: key_version %u page_compressed %d page_compressed_encrypted %d lsn %llu compressed_len %lu\n", - space, offset, rspace->name, page_type, fil_get_page_type_name(page_type), - key_version, page_compressed, page_compressed_encrypted, (ulonglong)lsn, compressed_len); - fflush(stderr); - - ut_ad(page_type == FIL_PAGE_PAGE_COMPRESSED || - page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED || - page_type == FIL_PAGE_INDEX || - page_type == FIL_PAGE_UNDO_LOG || - page_type == FIL_PAGE_INODE || - page_type == FIL_PAGE_IBUF_FREE_LIST || - page_type == FIL_PAGE_TYPE_ALLOCATED || - page_type == FIL_PAGE_IBUF_BITMAP || - page_type == FIL_PAGE_TYPE_SYS || - page_type == FIL_PAGE_TYPE_TRX_SYS || - page_type == FIL_PAGE_TYPE_FSP_HDR || - page_type == FIL_PAGE_TYPE_XDES || - page_type == FIL_PAGE_TYPE_BLOB || - page_type == FIL_PAGE_TYPE_ZBLOB || - page_type == FIL_PAGE_TYPE_ZBLOB2 || - page_type == FIL_PAGE_TYPE_COMPRESSED); + fprintf(stderr, "InnoDB: Page " ULINTPF ":" ULINTPF + " name %s page_type " ULINTPF " page_type_name %s\n" + "InnoDB: key_version " ULINTPF + " page_compressed %d page_compressed_encrypted %d lsn " + LSN_PF " compressed_len " ULINTPF "\n", + space, offset, rspace->name, page_type, + fil_get_page_type_name(page_type), + key_version, + page_compressed, page_compressed_encrypted, + lsn, compressed_len); + ut_error; return false; } diff --git a/storage/xtradb/include/fil0pagecompress.h b/storage/xtradb/include/fil0pagecompress.h index 1fe5cb66bf6..73667c5420e 100644 --- a/storage/xtradb/include/fil0pagecompress.h +++ b/storage/xtradb/include/fil0pagecompress.h @@ -31,33 +31,6 @@ Created 11/12/2013 Jan Lindström jan.lindstrom@skysql.com ***********************************************************************/ /*******************************************************************//** -Returns the page compression level flag of the space, or 0 if the space -is not compressed. The tablespace must be cached in the memory cache. -@return page compression level if page compressed, ULINT_UNDEFINED if space not found */ -UNIV_INLINE -ulint -fil_space_get_page_compression_level( -/*=================================*/ - ulint id); /*!< in: space id */ -/*******************************************************************//** -Returns the page compression flag of the space, or false if the space -is not compressed. The tablespace must be cached in the memory cache. -@return true if page compressed, false if not or space not found */ -UNIV_INLINE -bool -fil_space_is_page_compressed( -/*=========================*/ - ulint id); /*!< in: space id */ -/*******************************************************************//** -Returns the atomic writes flag of the space, or false if the space -is not using atomic writes. The tablespace must be cached in the memory cache. -@return atomic write table option value */ -UNIV_INLINE -atomic_writes_t -fil_space_get_atomic_writes( -/*=========================*/ - ulint id); /*!< in: space id */ -/*******************************************************************//** Find out wheather the page is index page or not @return true if page type index page, false if not */ UNIV_INLINE @@ -84,8 +57,7 @@ UNIV_INTERN byte* fil_compress_page( /*==============*/ - ulint space_id, /*!< in: tablespace id of the - table. */ + fil_space_t* space, /*!< in,out: tablespace (NULL during IMPORT) */ byte* buf, /*!< in: buffer from which to write; in aio this must be appropriately aligned */ byte* out_buf, /*!< out: compressed buffer */ diff --git a/storage/xtradb/include/fsp0pagecompress.ic b/storage/xtradb/include/fsp0pagecompress.ic index 48163277feb..14f968e319e 100644 --- a/storage/xtradb/include/fsp0pagecompress.ic +++ b/storage/xtradb/include/fsp0pagecompress.ic @@ -85,47 +85,6 @@ fil_page_is_compressed_encrypted( return(mach_read_from_2(buf+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED); } -#ifndef UNIV_INNOCHECKSUM -/*******************************************************************//** -Returns the page compression level of the space, or 0 if the space -is not compressed. The tablespace must be cached in the memory cache. -@return page compression level, 0 if space not found */ -UNIV_INLINE -ulint -fil_space_get_page_compression_level( -/*=================================*/ - ulint id) /*!< in: space id */ -{ - ulint flags; - - flags = fil_space_get_flags(id); - - if (flags && flags != ULINT_UNDEFINED) { - - return(fsp_flags_get_page_compression_level(flags)); - } - - return(0); -} - -/*******************************************************************//** -Extract the page compression from space. -@return true if space is page compressed, false if space is not found -or space is not page compressed. */ -UNIV_INLINE -bool -fil_space_is_page_compressed( -/*=========================*/ - ulint id) /*!< in: space id */ -{ - ulint flags = fil_space_get_flags(id); - - return(flags != ULINT_UNDEFINED - && FSP_FLAGS_HAS_PAGE_COMPRESSION(flags)); -} - -#endif /* UNIV_INNOCHECKSUM */ - /****************************************************************//** Get the name of the compression algorithm used for page compression. @@ -166,28 +125,6 @@ fil_get_compression_alg_name( #ifndef UNIV_INNOCHECKSUM /*******************************************************************//** -Returns the atomic writes flag of the space, or false if the space -is not using atomic writes. The tablespace must be cached in the memory cache. -@return atomic writes table option value */ -UNIV_INLINE -atomic_writes_t -fil_space_get_atomic_writes( -/*========================*/ - ulint id) /*!< in: space id */ -{ - ulint flags; - - flags = fil_space_get_flags(id); - - if (flags && flags != ULINT_UNDEFINED) { - - return((atomic_writes_t)fsp_flags_get_atomic_writes(flags)); - } - - return((atomic_writes_t)0); -} - -/*******************************************************************//** Find out wheather the page is page compressed with lzo method @return true if page is page compressed with lzo method, false if not */ UNIV_INLINE diff --git a/storage/xtradb/include/os0file.h b/storage/xtradb/include/os0file.h index d6f0ecfb69c..06bb6a6fbac 100644 --- a/storage/xtradb/include/os0file.h +++ b/storage/xtradb/include/os0file.h @@ -2,7 +2,7 @@ Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2009, Percona Inc. -Copyright (c) 2013, 2017, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2013, 2017, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Percona Inc.. Those modifications are @@ -52,16 +52,6 @@ extern ibool os_has_said_disk_full; /** Flag: enable debug printout for asynchronous i/o */ extern ibool os_aio_print_debug; -/** Number of pending os_file_pread() operations */ -extern ulint os_file_n_pending_preads; -/** Number of pending os_file_pwrite() operations */ -extern ulint os_file_n_pending_pwrites; - -/** Number of pending read operations */ -extern ulint os_n_pending_reads; -/** Number of pending write operations */ -extern ulint os_n_pending_writes; - #ifdef __WIN__ /** We define always WIN_ASYNC_IO, and check at run-time whether diff --git a/storage/xtradb/include/os0sync.h b/storage/xtradb/include/os0sync.h index f6207555f1a..48c56a73369 100644 --- a/storage/xtradb/include/os0sync.h +++ b/storage/xtradb/include/os0sync.h @@ -718,10 +718,7 @@ os_atomic_clear(volatile lock_word_t* ptr) # define HAVE_ATOMIC_BUILTINS # define HAVE_ATOMIC_BUILTINS_BYTE - -# ifndef _WIN32 -# define HAVE_ATOMIC_BUILTINS_64 -# endif +# define HAVE_ATOMIC_BUILTINS_64 /**********************************************************//** Atomic compare and exchange of signed integers (both 32 and 64 bit). diff --git a/storage/xtradb/include/srv0mon.h b/storage/xtradb/include/srv0mon.h index 3b030d56d29..63fd449ee18 100644 --- a/storage/xtradb/include/srv0mon.h +++ b/storage/xtradb/include/srv0mon.h @@ -2,7 +2,7 @@ Copyright (c) 2010, 2013, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2016, MariaDB Corporation. +Copyright (c) 2013, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -571,22 +571,30 @@ on the counters */ /** Increment a monitor counter under mutex protection. Use MONITOR_INC if appropriate mutex protection already exists. +@param mutex mutex to acquire and release @param monitor monitor to be incremented by 1 -@param mutex mutex to acquire and relese */ -# define MONITOR_MUTEX_INC(mutex, monitor) \ +@param enabled whether the monitor is enabled */ +#define MONITOR_MUTEX_INC_LOW(mutex, monitor, enabled) \ ut_ad(!mutex_own(mutex)); \ - if (MONITOR_IS_ON(monitor)) { \ + if (enabled) { \ mutex_enter(mutex); \ if (++MONITOR_VALUE(monitor) > MONITOR_MAX_VALUE(monitor)) { \ MONITOR_MAX_VALUE(monitor) = MONITOR_VALUE(monitor); \ } \ mutex_exit(mutex); \ } +/** Increment a monitor counter under mutex protection. +Use MONITOR_INC if appropriate mutex protection already exists. +@param mutex mutex to acquire and release +@param monitor monitor to be incremented by 1 */ +#define MONITOR_MUTEX_INC(mutex, monitor) \ + MONITOR_MUTEX_INC_LOW(mutex, monitor, MONITOR_IS_ON(monitor)) /** Decrement a monitor counter under mutex protection. Use MONITOR_DEC if appropriate mutex protection already exists. +@param mutex mutex to acquire and release @param monitor monitor to be decremented by 1 -@param mutex mutex to acquire and relese */ -# define MONITOR_MUTEX_DEC(mutex, monitor) \ +@param enabled whether the monitor is enabled */ +#define MONITOR_MUTEX_DEC_LOW(mutex, monitor, enabled) \ ut_ad(!mutex_own(mutex)); \ if (MONITOR_IS_ON(monitor)) { \ mutex_enter(mutex); \ @@ -595,13 +603,20 @@ Use MONITOR_DEC if appropriate mutex protection already exists. } \ mutex_exit(mutex); \ } +/** Decrement a monitor counter under mutex protection. +Use MONITOR_DEC if appropriate mutex protection already exists. +@param mutex mutex to acquire and release +@param monitor monitor to be decremented by 1 */ +#define MONITOR_MUTEX_DEC(mutex, monitor) \ + MONITOR_MUTEX_DEC_LOW(mutex, monitor, MONITOR_IS_ON(monitor)) #if defined HAVE_ATOMIC_BUILTINS_64 /** Atomically increment a monitor counter. Use MONITOR_INC if appropriate mutex protection exists. -@param monitor monitor to be incremented by 1 */ -# define MONITOR_ATOMIC_INC(monitor) \ - if (MONITOR_IS_ON(monitor)) { \ +@param monitor monitor to be incremented by 1 +@param enabled whether the monitor is enabled */ +# define MONITOR_ATOMIC_INC_LOW(monitor, enabled) \ + if (enabled) { \ ib_uint64_t value; \ value = os_atomic_increment_uint64( \ (ib_uint64_t*) &MONITOR_VALUE(monitor), 1); \ @@ -614,9 +629,10 @@ Use MONITOR_INC if appropriate mutex protection exists. /** Atomically decrement a monitor counter. Use MONITOR_DEC if appropriate mutex protection exists. -@param monitor monitor to be decremented by 1 */ -# define MONITOR_ATOMIC_DEC(monitor) \ - if (MONITOR_IS_ON(monitor)) { \ +@param monitor monitor to be decremented by 1 +@param enabled whether the monitor is enabled */ +# define MONITOR_ATOMIC_DEC_LOW(monitor, enabled) \ + if (enabled) { \ ib_uint64_t value; \ value = os_atomic_decrement_uint64( \ (ib_uint64_t*) &MONITOR_VALUE(monitor), 1); \ @@ -647,14 +663,29 @@ srv_mon_free(void); /** Atomically increment a monitor counter. Use MONITOR_INC if appropriate mutex protection exists. -@param monitor monitor to be incremented by 1 */ -# define MONITOR_ATOMIC_INC(monitor) MONITOR_MUTEX_INC(&monitor_mutex, monitor) +@param monitor monitor to be incremented by 1 +@param enabled whether the monitor is enabled */ +# define MONITOR_ATOMIC_INC_LOW(monitor, enabled) \ + MONITOR_MUTEX_INC_LOW(&monitor_mutex, monitor, enabled) /** Atomically decrement a monitor counter. Use MONITOR_DEC if appropriate mutex protection exists. -@param monitor monitor to be decremented by 1 */ -# define MONITOR_ATOMIC_DEC(monitor) MONITOR_MUTEX_DEC(&monitor_mutex, monitor) +@param monitor monitor to be decremented by 1 +@param enabled whether the monitor is enabled */ +# define MONITOR_ATOMIC_DEC_LOW(monitor, enabled) \ + MONITOR_MUTEX_DEC_LOW(&monitor_mutex, monitor, enabled) #endif /* HAVE_ATOMIC_BUILTINS_64 */ +/** Atomically increment a monitor counter if it is enabled. +Use MONITOR_INC if appropriate mutex protection exists. +@param monitor monitor to be incremented by 1 */ +#define MONITOR_ATOMIC_INC(monitor) \ + MONITOR_ATOMIC_INC_LOW(monitor, MONITOR_IS_ON(monitor)) +/** Atomically decrement a monitor counter if it is enabled. +Use MONITOR_DEC if appropriate mutex protection exists. +@param monitor monitor to be decremented by 1 */ +#define MONITOR_ATOMIC_DEC(monitor) \ + MONITOR_ATOMIC_DEC_LOW(monitor, MONITOR_IS_ON(monitor)) + #define MONITOR_DEC(monitor) \ if (MONITOR_IS_ON(monitor)) { \ MONITOR_VALUE(monitor)--; \ diff --git a/storage/xtradb/include/trx0trx.h b/storage/xtradb/include/trx0trx.h index e621d4226a7..766d61039b4 100644 --- a/storage/xtradb/include/trx0trx.h +++ b/storage/xtradb/include/trx0trx.h @@ -348,6 +348,23 @@ trx_print_latched( or 0 to use the default max length */ MY_ATTRIBUTE((nonnull)); +#ifdef WITH_WSREP +/**********************************************************************//** +Prints info about a transaction. +Transaction information may be retrieved without having trx_sys->mutex acquired +so it may not be completely accurate. The caller must own lock_sys->mutex +and the trx must have some locks to make sure that it does not escape +without locking lock_sys->mutex. */ +UNIV_INTERN +void +wsrep_trx_print_locking( +/*==============*/ + FILE* f, /*!< in: output stream */ + const trx_t* trx, /*!< in: transaction */ + ulint max_query_len) /*!< in: max query length to print, + or 0 to use the default max length */ + MY_ATTRIBUTE((nonnull)); +#endif /* WITH_WSREP */ /**********************************************************************//** Prints info about a transaction. Acquires and releases lock_sys->mutex and trx_sys->mutex. */ diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i index 1e375ba2c09..e698f08f15b 100644 --- a/storage/xtradb/include/univ.i +++ b/storage/xtradb/include/univ.i @@ -304,22 +304,12 @@ definitions: */ #endif /* !UNIV_MUST_NOT_INLINE */ -#ifdef _WIN32 -#define UNIV_WORD_SIZE 4 -#elif defined(_WIN64) -#define UNIV_WORD_SIZE 8 -#else -/** MySQL config.h generated by GNU autoconf will define SIZEOF_LONG in Posix */ -#define UNIV_WORD_SIZE SIZEOF_LONG -#endif +#define UNIV_WORD_SIZE SIZEOF_SIZE_T /** The following alignment is used in memory allocations in memory heap management to ensure correct alignment for doubles etc. */ #define UNIV_MEM_ALIGNMENT 8 -/** The following alignment is used in aligning lints etc. */ -#define UNIV_WORD_ALIGNMENT UNIV_WORD_SIZE - /* DATABASE VERSION CONTROL ======================== @@ -478,13 +468,12 @@ the word size of the machine, that is on a 32-bit platform 32 bits, and on a macro ULINTPF. */ -#ifdef __WIN__ +#ifdef _WIN32 /* Use the integer types and formatting strings defined in Visual Studio. */ -# define UINT32PF "%I32u" -# define INT64PF "%I64d" -# define UINT64PF "%I64u" -# define UINT64PFx "%016I64x" -# define DBUG_LSN_PF "%llu" +# define UINT32PF "%u" +# define INT64PF "%lld" +# define UINT64PF "%llu" +# define UINT64PFx "%016llx" typedef __int64 ib_int64_t; typedef unsigned __int64 ib_uint64_t; typedef unsigned __int32 ib_uint32_t; @@ -494,13 +483,12 @@ typedef unsigned __int32 ib_uint32_t; # define INT64PF "%" PRId64 # define UINT64PF "%" PRIu64 # define UINT64PFx "%016" PRIx64 -# define DBUG_LSN_PF UINT64PF typedef int64_t ib_int64_t; typedef uint64_t ib_uint64_t; typedef uint32_t ib_uint32_t; -# endif /* __WIN__ */ +#endif -# define IB_ID_FMT UINT64PF +#define IB_ID_FMT UINT64PF /* Type used for all log sequence number storage and arithmetics */ typedef ib_uint64_t lsn_t; diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc index 0d555ed2dd7..717fbf02536 100644 --- a/storage/xtradb/lock/lock0lock.cc +++ b/storage/xtradb/lock/lock0lock.cc @@ -1762,7 +1762,6 @@ wsrep_kill_victim( is in the queue*/ } else if (lock->trx != trx) { if (wsrep_log_conflicts) { - mutex_enter(&trx_sys->mutex); if (bf_this) { fputs("\n*** Priority TRANSACTION:\n", stderr); @@ -1771,7 +1770,7 @@ wsrep_kill_victim( stderr); } - trx_print_latched(stderr, trx, 3000); + wsrep_trx_print_locking(stderr, trx, 3000); if (bf_other) { fputs("\n*** Priority TRANSACTION:\n", @@ -1780,10 +1779,7 @@ wsrep_kill_victim( fputs("\n*** Victim TRANSACTION:\n", stderr); } - - trx_print_latched(stderr, lock->trx, 3000); - - mutex_exit(&trx_sys->mutex); + wsrep_trx_print_locking(stderr, lock->trx, 3000); fputs("*** WAITING FOR THIS LOCK TO BE GRANTED:\n", stderr); diff --git a/storage/xtradb/log/log0recv.cc b/storage/xtradb/log/log0recv.cc index 6b7c8d77824..120f1432ccf 100644 --- a/storage/xtradb/log/log0recv.cc +++ b/storage/xtradb/log/log0recv.cc @@ -1728,7 +1728,7 @@ recv_recover_page_func( } DBUG_PRINT("ib_log", - ("apply " DBUG_LSN_PF ": %u len %u " + ("apply " LSN_PF ": %u len %u " "page %u:%u", recv->start_lsn, (unsigned) recv->type, (unsigned) recv->len, @@ -2391,7 +2391,7 @@ loop: recv_sys->recovered_lsn = new_recovered_lsn; DBUG_PRINT("ib_log", - ("scan " DBUG_LSN_PF ": log rec %u len %u " + ("scan " LSN_PF ": log rec %u len %u " "page %u:%u", old_lsn, (unsigned) type, (unsigned) len, (unsigned) space, (unsigned) page_no)); @@ -2483,7 +2483,7 @@ loop: #endif /* UNIV_LOG_DEBUG */ DBUG_PRINT("ib_log", - ("scan " DBUG_LSN_PF ": multi-log rec %u " + ("scan " LSN_PF ": multi-log rec %u " "len %u page %u:%u", recv_sys->recovered_lsn, (unsigned) type, (unsigned) len, diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc index ed84834e6ea..03200fee80b 100644 --- a/storage/xtradb/os/os0file.cc +++ b/storage/xtradb/os/os0file.cc @@ -2,7 +2,7 @@ Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2009, Percona Inc. -Copyright (c) 2013, 2017, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2013, 2017, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Percona Inc.. Those modifications are @@ -339,21 +339,6 @@ UNIV_INTERN time_t os_last_printout; UNIV_INTERN ibool os_has_said_disk_full = FALSE; -#if !defined(UNIV_HOTBACKUP) \ - && (!defined(HAVE_ATOMIC_BUILTINS) || UNIV_WORD_SIZE < 8) -/** The mutex protecting the following counts of pending I/O operations */ -static os_ib_mutex_t os_file_count_mutex; -#endif /* !UNIV_HOTBACKUP && (!HAVE_ATOMIC_BUILTINS || UNIV_WORD_SIZE < 8) */ - -/** Number of pending os_file_pread() operations */ -UNIV_INTERN ulint os_file_n_pending_preads; -/** Number of pending os_file_pwrite() operations */ -UNIV_INTERN ulint os_file_n_pending_pwrites; -/** Number of pending write operations */ -UNIV_INTERN ulint os_n_pending_writes; -/** Number of pending read operations */ -UNIV_INTERN ulint os_n_pending_reads; - #if defined(WIN_ASYNC_IO) || defined(LINUX_NATIVE_AIO) /** After first fallocate failure we will disable os_file_trim */ static bool os_fallocate_failed; @@ -1021,10 +1006,6 @@ void os_io_init_simple(void) /*===================*/ { -#if !defined(HAVE_ATOMIC_BUILTINS) || UNIV_WORD_SIZE < 8 - os_file_count_mutex = os_mutex_create(); -#endif /* !HAVE_ATOMIC_BUILTINS || UNIV_WORD_SIZE < 8 */ - for (ulint i = 0; i < OS_FILE_N_SEEK_MUTEXES; i++) { os_file_seek_mutexes[i] = os_mutex_create(); } @@ -2811,10 +2792,6 @@ os_file_pread( trx_t* trx) { off_t offs; -#if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD) - ssize_t n_bytes; - ssize_t n_read; -#endif /* HAVE_PREAD && !HAVE_BROKEN_PREAD */ ulint sec; ulint ms; ib_uint64_t start_time; @@ -2844,22 +2821,16 @@ os_file_pread( } else { start_time = 0; } -#if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD) -#if defined(HAVE_ATOMIC_BUILTINS) && UNIV_WORD_SIZE == 8 - (void) os_atomic_increment_ulint(&os_n_pending_reads, 1); - (void) os_atomic_increment_ulint(&os_file_n_pending_preads, 1); - MONITOR_ATOMIC_INC(MONITOR_OS_PENDING_READS); -#else - os_mutex_enter(os_file_count_mutex); - os_file_n_pending_preads++; - os_n_pending_reads++; - MONITOR_INC(MONITOR_OS_PENDING_READS); - os_mutex_exit(os_file_count_mutex); -#endif /* HAVE_ATOMIC_BUILTINS && UNIV_WORD == 8 */ + + const bool monitor = MONITOR_IS_ON(MONITOR_OS_PENDING_READS); +#ifdef HAVE_PREAD + MONITOR_ATOMIC_INC_LOW(MONITOR_OS_PENDING_READS, monitor); + + ssize_t n_bytes; /* Handle partial reads and signal interruptions correctly */ for (n_bytes = 0; n_bytes < (ssize_t) n; ) { - n_read = pread(file, buf, (ssize_t)n - n_bytes, offs); + ssize_t n_read = pread(file, buf, (ssize_t)n - n_bytes, offs); if (n_read > 0) { n_bytes += n_read; offs += n_read; @@ -2871,17 +2842,7 @@ os_file_pread( } } -#if defined(HAVE_ATOMIC_BUILTINS) && UNIV_WORD_SIZE == 8 - (void) os_atomic_decrement_ulint(&os_n_pending_reads, 1); - (void) os_atomic_decrement_ulint(&os_file_n_pending_preads, 1); - MONITOR_ATOMIC_DEC(MONITOR_OS_PENDING_READS); -#else - os_mutex_enter(os_file_count_mutex); - os_file_n_pending_preads--; - os_n_pending_reads--; - MONITOR_DEC(MONITOR_OS_PENDING_READS); - os_mutex_exit(os_file_count_mutex); -#endif /* !HAVE_ATOMIC_BUILTINS || UNIV_WORD == 8 */ + MONITOR_ATOMIC_DEC_LOW(MONITOR_OS_PENDING_READS, monitor); if (UNIV_UNLIKELY(start_time != 0)) { @@ -2900,15 +2861,7 @@ os_file_pread( ulint i; #endif /* !UNIV_HOTBACKUP */ -#if defined(HAVE_ATOMIC_BUILTINS) && UNIV_WORD_SIZE == 8 - (void) os_atomic_increment_ulint(&os_n_pending_reads, 1); - MONITOR_ATOMIC_INC(MONITOR_OS_PENDING_READS); -#else - os_mutex_enter(os_file_count_mutex); - os_n_pending_reads++; - MONITOR_INC(MONITOR_OS_PENDING_READS); - os_mutex_exit(os_file_count_mutex); -#endif /* HAVE_ATOMIC_BUILTINS && UNIV_WORD == 8 */ + MONITOR_ATOMIC_INC_LOW(MONITOR_OS_PENDING_READS, monitor); #ifndef UNIV_HOTBACKUP /* Protect the seek / read operation with a mutex */ i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES; @@ -2938,15 +2891,7 @@ os_file_pread( os_mutex_exit(os_file_seek_mutexes[i]); #endif /* !UNIV_HOTBACKUP */ -#if defined(HAVE_ATOMIC_BUILTINS) && UNIV_WORD_SIZE == 8 - (void) os_atomic_decrement_ulint(&os_n_pending_reads, 1); - MONITOR_ATOIC_DEC(MONITOR_OS_PENDING_READS); -#else - os_mutex_enter(os_file_count_mutex); - os_n_pending_reads--; - MONITOR_DEC(MONITOR_OS_PENDING_READS); - os_mutex_exit(os_file_count_mutex); -#endif /* HAVE_ATOMIC_BUILTINS && UNIV_WORD_SIZE == 8 */ + MONITOR_ATOMIC_DEC_LOW(MONITOR_OS_PENDING_READS, monitor); if (UNIV_UNLIKELY(start_time != 0) { @@ -2992,18 +2937,9 @@ os_file_pwrite( os_n_file_writes++; -#if defined(HAVE_PWRITE) && !defined(HAVE_BROKEN_PREAD) -#if !defined(HAVE_ATOMIC_BUILTINS) || UNIV_WORD_SIZE < 8 - os_mutex_enter(os_file_count_mutex); - os_file_n_pending_pwrites++; - os_n_pending_writes++; - MONITOR_INC(MONITOR_OS_PENDING_WRITES); - os_mutex_exit(os_file_count_mutex); -#else - (void) os_atomic_increment_ulint(&os_n_pending_writes, 1); - (void) os_atomic_increment_ulint(&os_file_n_pending_pwrites, 1); - MONITOR_ATOMIC_INC(MONITOR_OS_PENDING_WRITES); -#endif /* !HAVE_ATOMIC_BUILTINS || UNIV_WORD < 8 */ + const bool monitor = MONITOR_IS_ON(MONITOR_OS_PENDING_WRITES); +#ifdef HAVE_PWRITE + MONITOR_ATOMIC_INC_LOW(MONITOR_OS_PENDING_WRITES, monitor); /* Handle partial writes and signal interruptions correctly */ for (ret = 0; ret < (ssize_t) n; ) { @@ -3022,17 +2958,7 @@ os_file_pwrite( } } -#if !defined(HAVE_ATOMIC_BUILTINS) || UNIV_WORD_SIZE < 8 - os_mutex_enter(os_file_count_mutex); - os_file_n_pending_pwrites--; - os_n_pending_writes--; - MONITOR_DEC(MONITOR_OS_PENDING_WRITES); - os_mutex_exit(os_file_count_mutex); -#else - (void) os_atomic_decrement_ulint(&os_n_pending_writes, 1); - (void) os_atomic_decrement_ulint(&os_file_n_pending_pwrites, 1); - MONITOR_ATOMIC_DEC(MONITOR_OS_PENDING_WRITES); -#endif /* !HAVE_ATOMIC_BUILTINS || UNIV_WORD < 8 */ + MONITOR_ATOMIC_DEC_LOW(MONITOR_OS_PENDING_WRITES, monitor); return(ret); #else @@ -3042,10 +2968,7 @@ os_file_pwrite( ulint i; # endif /* !UNIV_HOTBACKUP */ - os_mutex_enter(os_file_count_mutex); - os_n_pending_writes++; - MONITOR_INC(MONITOR_OS_PENDING_WRITES); - os_mutex_exit(os_file_count_mutex); + MONITOR_ATOMIC_INC_LOW(MONITOR_OS_PENDING_WRITES, monitor); # ifndef UNIV_HOTBACKUP /* Protect the seek / write operation with a mutex */ @@ -3079,14 +3002,10 @@ func_exit: os_mutex_exit(os_file_seek_mutexes[i]); # endif /* !UNIV_HOTBACKUP */ - os_mutex_enter(os_file_count_mutex); - os_n_pending_writes--; - MONITOR_DEC(MONITOR_OS_PENDING_WRITES); - os_mutex_exit(os_file_count_mutex); - + MONITOR_ATOMIC_DEC_LOW(MONITOR_OS_PENDING_WRITES, monitor); return(ret); } -#endif /* !UNIV_HOTBACKUP */ +#endif /* HAVE_PWRITE */ } #endif @@ -3118,15 +3037,13 @@ os_file_read_func( os_n_file_reads++; os_bytes_read_since_printout += n; + const bool monitor = MONITOR_IS_ON(MONITOR_OS_PENDING_READS); try_again: ut_ad(buf); ut_ad(n > 0); - os_mutex_enter(os_file_count_mutex); - os_n_pending_reads++; - MONITOR_INC(MONITOR_OS_PENDING_READS); - os_mutex_exit(os_file_count_mutex); + MONITOR_ATOMIC_INC_LOW(MONITOR_OS_PENDING_READS, monitor); memset (&overlapped, 0, sizeof (overlapped)); overlapped.Offset = (DWORD)(offset & 0xFFFFFFFF); @@ -3139,10 +3056,7 @@ try_again: else if(GetLastError() == ERROR_IO_PENDING) { ret = GetOverlappedResult(file, &overlapped, (DWORD *)&len, TRUE); } - os_mutex_enter(os_file_count_mutex); - os_n_pending_reads--; - MONITOR_DEC(MONITOR_OS_PENDING_READS); - os_mutex_exit(os_file_count_mutex); + MONITOR_ATOMIC_DEC_LOW(MONITOR_OS_PENDING_READS, monitor); if (ret && len == n) { return(TRUE); @@ -3226,15 +3140,13 @@ os_file_read_no_error_handling_func( os_n_file_reads++; os_bytes_read_since_printout += n; + const bool monitor = MONITOR_IS_ON(MONITOR_OS_PENDING_READS); try_again: ut_ad(buf); ut_ad(n > 0); - os_mutex_enter(os_file_count_mutex); - os_n_pending_reads++; - MONITOR_INC(MONITOR_OS_PENDING_READS); - os_mutex_exit(os_file_count_mutex); + MONITOR_ATOMIC_INC_LOW(MONITOR_OS_PENDING_READS, monitor); memset (&overlapped, 0, sizeof (overlapped)); overlapped.Offset = (DWORD)(offset & 0xFFFFFFFF); @@ -3247,10 +3159,7 @@ try_again: else if(GetLastError() == ERROR_IO_PENDING) { ret = GetOverlappedResult(file, &overlapped, (DWORD *)&len, TRUE); } - os_mutex_enter(os_file_count_mutex); - os_n_pending_reads--; - MONITOR_DEC(MONITOR_OS_PENDING_READS); - os_mutex_exit(os_file_count_mutex); + MONITOR_ATOMIC_DEC_LOW(MONITOR_OS_PENDING_READS, monitor); if (ret && len == n) { return(TRUE); @@ -3344,13 +3253,10 @@ os_file_write_func( ut_ad(buf); ut_ad(n > 0); - + const bool monitor = MONITOR_IS_ON(MONITOR_OS_PENDING_WRITES); retry: - os_mutex_enter(os_file_count_mutex); - os_n_pending_writes++; - MONITOR_INC(MONITOR_OS_PENDING_WRITES); - os_mutex_exit(os_file_count_mutex); + MONITOR_ATOMIC_INC_LOW(MONITOR_OS_PENDING_WRITES, monitor); memset (&overlapped, 0, sizeof (overlapped)); overlapped.Offset = (DWORD)(offset & 0xFFFFFFFF); @@ -3365,10 +3271,7 @@ retry: ret = GetOverlappedResult(file, &overlapped, (DWORD *)&len, TRUE); } - os_mutex_enter(os_file_count_mutex); - os_n_pending_writes--; - MONITOR_DEC(MONITOR_OS_PENDING_WRITES); - os_mutex_exit(os_file_count_mutex); + MONITOR_ATOMIC_DEC_LOW(MONITOR_OS_PENDING_WRITES, monitor); if (ret && len == n) { @@ -4463,10 +4366,6 @@ os_aio_free(void) } } -#if !defined(HAVE_ATOMIC_BUILTINS) || UNIV_WORD_SIZE < 8 - os_mutex_free(os_file_count_mutex); -#endif /* !HAVE_ATOMIC_BUILTINS || UNIV_WORD_SIZE < 8 */ - for (ulint i = 0; i < OS_FILE_N_SEEK_MUTEXES; i++) { os_mutex_free(os_file_seek_mutexes[i]); } @@ -6192,19 +6091,24 @@ os_aio_print( time_elapsed = 0.001 + difftime(current_time, os_last_printout); fprintf(file, - "Pending flushes (fsync) log: %lu; buffer pool: %lu\n" - "%lu OS file reads, %lu OS file writes, %lu OS fsyncs\n", - (ulong) fil_n_pending_log_flushes, - (ulong) fil_n_pending_tablespace_flushes, - (ulong) os_n_file_reads, - (ulong) os_n_file_writes, - (ulong) os_n_fsyncs); - - if (os_file_n_pending_preads != 0 || os_file_n_pending_pwrites != 0) { + "Pending flushes (fsync) log: " ULINTPF + "; buffer pool: " ULINTPF "\n" + ULINTPF " OS file reads, " + ULINTPF " OS file writes, " + ULINTPF " OS fsyncs\n", + fil_n_pending_log_flushes, + fil_n_pending_tablespace_flushes, + os_n_file_reads, + os_n_file_writes, + os_n_fsyncs); + + const ulint n_reads = ulint(MONITOR_VALUE(MONITOR_OS_PENDING_READS)); + const ulint n_writes = ulint(MONITOR_VALUE(MONITOR_OS_PENDING_WRITES)); + + if (n_reads != 0 || n_writes != 0) { fprintf(file, - "%lu pending preads, %lu pending pwrites\n", - (ulong) os_file_n_pending_preads, - (ulong) os_file_n_pending_pwrites); + ULINTPF " pending reads, " ULINTPF " pending writes\n", + n_reads, n_writes); } if (os_n_file_reads == os_n_file_reads_old) { diff --git a/storage/xtradb/row/row0ftsort.cc b/storage/xtradb/row/row0ftsort.cc index 29ddffd2587..4542aa31a6c 100644 --- a/storage/xtradb/row/row0ftsort.cc +++ b/storage/xtradb/row/row0ftsort.cc @@ -1320,10 +1320,9 @@ row_fts_build_sel_tree_level( int child_left; int child_right; ulint i; - ulint num_item; + ulint num_item = ulint(1) << level; - start = static_cast<ulint>((1 << level) - 1); - num_item = static_cast<ulint>(1 << level); + start = num_item - 1; for (i = 0; i < num_item; i++) { child_left = sel_tree[(start + i) * 2 + 1]; @@ -1392,7 +1391,7 @@ row_fts_build_sel_tree( treelevel++; } - start = (1 << treelevel) - 1; + start = (ulint(1) << treelevel) - 1; for (i = 0; i < (int) fts_sort_pll_degree; i++) { sel_tree[i + start] = i; diff --git a/storage/xtradb/row/row0import.cc b/storage/xtradb/row/row0import.cc index 6dc01907710..baa7bcbea09 100644 --- a/storage/xtradb/row/row0import.cc +++ b/storage/xtradb/row/row0import.cc @@ -583,8 +583,8 @@ AbstractCallback::init( } else if (!is_compressed_table() && m_page_size != UNIV_PAGE_SIZE) { ib_logf(IB_LOG_LEVEL_ERROR, - "Page size %lu of ibd file is not the same " - "as the server page size %lu", + "Page size " ULINTPF " of ibd file is not the same " + "as the server page size " ULINTPF, m_page_size, UNIV_PAGE_SIZE); return(DB_CORRUPTION); @@ -593,8 +593,8 @@ AbstractCallback::init( ib_logf(IB_LOG_LEVEL_ERROR, "File size " UINT64PF " is not a multiple " - "of the page size %lu", - (ib_uint64_t) file_size, (ulong) m_page_size); + "of the page size " ULINTPF, + (ib_uint64_t) file_size, m_page_size); return(DB_CORRUPTION); } @@ -695,8 +695,8 @@ FetchIndexRootPages::operator() ( if (block->page.offset * m_page_size != offset) { ib_logf(IB_LOG_LEVEL_ERROR, "Page offset doesn't match file offset: " - "page offset: %lu, file offset: %lu", - (ulint) block->page.offset, + "page offset: %u, file offset: " ULINTPF, + block->page.offset, (ulint) (offset / m_page_size)); err = DB_CORRUPTION; @@ -1134,10 +1134,9 @@ row_import::match_index_columns( ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH, - "Index field count %lu doesn't match" - " tablespace metadata file value %lu", - (ulong) index->n_fields, - (ulong) cfg_index->m_n_fields); + "Index field count %u doesn't match" + " tablespace metadata file value " ULINTPF, + index->n_fields, cfg_index->m_n_fields); return(DB_ERROR); } @@ -1154,34 +1153,31 @@ row_import::match_index_columns( ER_TABLE_SCHEMA_MISMATCH, "Index field name %s doesn't match" " tablespace metadata field name %s" - " for field position %lu", - field->name, cfg_field->name, (ulong) i); + " for field position " ULINTPF, + field->name, cfg_field->name, i); err = DB_ERROR; } if (cfg_field->prefix_len != field->prefix_len) { ib_errf(thd, IB_LOG_LEVEL_ERROR, - ER_TABLE_SCHEMA_MISMATCH, - "Index %s field %s prefix len %lu" - " doesn't match metadata file value" - " %lu", - index->name, field->name, - (ulong) field->prefix_len, - (ulong) cfg_field->prefix_len); + ER_TABLE_SCHEMA_MISMATCH, + "Index %s field %s prefix len %u" + " doesn't match metadata file value %u", + index->name, field->name, + field->prefix_len, cfg_field->prefix_len); err = DB_ERROR; } if (cfg_field->fixed_len != field->fixed_len) { ib_errf(thd, IB_LOG_LEVEL_ERROR, - ER_TABLE_SCHEMA_MISMATCH, - "Index %s field %s fixed len %lu" - " doesn't match metadata file value" - " %lu", - index->name, field->name, - (ulong) field->fixed_len, - (ulong) cfg_field->fixed_len); + ER_TABLE_SCHEMA_MISMATCH, + "Index %s field %s fixed len %u" + " doesn't match metadata file value %u", + index->name, field->name, + field->fixed_len, + cfg_field->fixed_len); err = DB_ERROR; } @@ -1223,12 +1219,11 @@ row_import::match_table_columns( } else if (cfg_col_index != col->ind) { ib_errf(thd, IB_LOG_LEVEL_ERROR, - ER_TABLE_SCHEMA_MISMATCH, - "Column %s ordinal value mismatch, it's at " - "%lu in the table and %lu in the tablespace " - "meta-data file", - col_name, - (ulong) col->ind, (ulong) cfg_col_index); + ER_TABLE_SCHEMA_MISMATCH, + "Column %s ordinal value mismatch, it's at %u" + " in the table and " ULINTPF + " in the tablespace meta-data file", + col_name, col->ind, cfg_col_index); err = DB_ERROR; } else { @@ -1310,23 +1305,20 @@ row_import::match_schema( THD* thd) UNIV_NOTHROW { /* Do some simple checks. */ - const unsigned relevant_flags = m_flags & ~DICT_TF_MASK_DATA_DIR; - const unsigned relevant_table_flags - = m_table->flags & ~DICT_TF_MASK_DATA_DIR; - if (relevant_flags != relevant_table_flags) { + if ((m_table->flags ^ m_flags) & ~DICT_TF_MASK_DATA_DIR) { ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH, - "Table flags don't match, server table has 0x%x " - "and the meta-data file has 0x%x", - relevant_table_flags, relevant_flags); + "Table flags don't match, server table has 0x%x" + " and the meta-data file has 0x%lx", + m_table->flags, ulong(m_flags)); return(DB_ERROR); } else if (m_table->n_cols != m_n_cols) { ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH, - "Number of columns don't match, table has %lu " - "columns but the tablespace meta-data file has " - "%lu columns", - (ulong) m_table->n_cols, (ulong) m_n_cols); + "Number of columns don't match, table has %u " + "columns but the tablespace meta-data file has " + ULINTPF " columns", + m_table->n_cols, m_n_cols); return(DB_ERROR); } else if (UT_LIST_GET_LEN(m_table->indexes) != m_n_indexes) { @@ -1336,11 +1328,10 @@ row_import::match_schema( table matching the IMPORT definition. */ ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH, - "Number of indexes don't match, table has %lu " - "indexes but the tablespace meta-data file has " - "%lu indexes", - (ulong) UT_LIST_GET_LEN(m_table->indexes), - (ulong) m_n_indexes); + "Number of indexes don't match, table has " ULINTPF + " indexes but the tablespace meta-data file has " + ULINTPF " indexes", + UT_LIST_GET_LEN(m_table->indexes), m_n_indexes); return(DB_ERROR); } @@ -1416,8 +1407,8 @@ row_import::set_root_by_heuristic() UNIV_NOTHROW table_name, sizeof(table_name), m_table->name, FALSE); ib_logf(IB_LOG_LEVEL_WARN, - "Table %s should have %lu indexes but the tablespace " - "has %lu indexes", + "Table %s should have " ULINTPF + " indexes but the tablespace has " ULINTPF " indexes", table_name, UT_LIST_GET_LEN(m_table->indexes), m_n_indexes); @@ -1655,9 +1646,10 @@ PageConverter::adjust_cluster_index_blob_column( ib_errf(m_trx->mysql_thd, IB_LOG_LEVEL_ERROR, ER_INNODB_INDEX_CORRUPT, - "Externally stored column(%lu) has a reference " - "length of %lu in the cluster index %s", - (ulong) i, (ulong) len, index_name); + "Externally stored column(" ULINTPF + ") has a reference length of " ULINTPF + " in the cluster index %s", + i, len, index_name); return(DB_CORRUPTION); } @@ -2021,7 +2013,8 @@ PageConverter::update_page( return(err); } - ib_logf(IB_LOG_LEVEL_WARN, "Unknown page type (%lu)", page_type); + ib_logf(IB_LOG_LEVEL_WARN, "Unknown page type (" ULINTPF ")", + page_type); return(DB_CORRUPTION); } @@ -2058,7 +2051,8 @@ PageConverter::validate( if (checksum != 0) { /* Checksum check passed in buf_page_is_corrupted(). */ ib_logf(IB_LOG_LEVEL_WARN, - "%s: Page %lu checksum %lu should be zero.", + "%s: Page %lu checksum " ULINTPF + " should be zero.", m_filepath, (ulong) (offset / m_page_size), checksum); } @@ -2372,11 +2366,10 @@ row_import_adjust_root_pages_of_secondary_indexes( ib_errf(trx->mysql_thd, IB_LOG_LEVEL_WARN, ER_INNODB_INDEX_CORRUPT, - "Index '%s' contains %lu entries, " - "should be %lu, you should recreate " + "Index '%s' contains " ULINTPF " entries, " + "should be " ULINTPF ", you should recreate " "this index.", index_name, - (ulong) purge.get_n_rows(), - (ulong) n_rows_in_table); + purge.get_n_rows(), n_rows_in_table); index->type |= DICT_CORRUPT; @@ -2727,7 +2720,7 @@ row_import_read_index_data( if (len > OS_FILE_MAX_PATH) { ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_INNODB_INDEX_CORRUPT, - "Index name length (%lu) is too long, " + "Index name length (" ULINTPF ") is too long, " "the meta-data is corrupt", len); return(DB_CORRUPTION); @@ -2808,8 +2801,8 @@ row_import_read_indexes( } else if (cfg->m_n_indexes > 1024) { // FIXME: What is the upper limit? */ ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR, - "Number of indexes in meta-data file is too high: %lu", - (ulong) cfg->m_n_indexes); + "Number of indexes in meta-data file is too high: " + ULINTPF, cfg->m_n_indexes); cfg->m_n_indexes = 0; return(DB_CORRUPTION); @@ -2907,8 +2900,8 @@ row_import_read_columns( if (len == 0 || len > 128) { ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR, - "Column name length %lu, is invalid", - (ulong) len); + "Column name length " ULINTPF ", is invalid", + len); return(DB_CORRUPTION); } @@ -3079,8 +3072,9 @@ row_import_read_v1( ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH, "Tablespace to be imported has a different " "page size than this server. Server page size " - "is %lu, whereas tablespace page size is %lu", - UNIV_PAGE_SIZE, (ulong) cfg->m_page_size); + "is " ULINTPF ", whereas tablespace page size is " + ULINTPF, + UNIV_PAGE_SIZE, cfg->m_page_size); return(DB_ERROR); } @@ -3145,8 +3139,8 @@ row_import_read_meta_data( return(row_import_read_v1(file, thd, &cfg)); default: ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR, - "Unsupported meta-data version number (%lu), " - "file ignored", (ulong) cfg.m_version); + "Unsupported meta-data version number (" ULINTPF "), " + "file ignored", cfg.m_version); } return(DB_ERROR); diff --git a/storage/xtradb/row/row0merge.cc b/storage/xtradb/row/row0merge.cc index 72be305d481..24cd9687a47 100644 --- a/storage/xtradb/row/row0merge.cc +++ b/storage/xtradb/row/row0merge.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2014, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -26,6 +26,7 @@ Completed by Sunny Bains and Marko Makela *******************************************************/ #include <my_config.h> #include <log.h> +#include <sql_class.h> #include "row0merge.h" #include "row0ext.h" @@ -188,7 +189,8 @@ row_merge_tuple_print( } ut_print_buf(f, dfield_get_data(field), len); if (len != field_len) { - fprintf(f, " (total %lu bytes)", field_len); + fprintf(f, " (total " ULINTPF " bytes)", + field_len); } } } @@ -881,9 +883,9 @@ row_merge_buf_write( ut_ad(b < &block[srv_sort_buf_size]); #ifdef UNIV_DEBUG if (row_merge_print_write) { - fprintf(stderr, "row_merge_buf_write %p,%d,%lu %lu", - (void*) b, of->fd, (ulong) of->offset, - (ulong) i); + fprintf(stderr, "row_merge_buf_write %p,%d," + ULINTPF " " ULINTPF, + (void*) b, of->fd, of->offset, i); row_merge_tuple_print(stderr, entry, n_fields); } #endif /* UNIV_DEBUG */ @@ -900,8 +902,8 @@ row_merge_buf_write( #endif /* UNIV_DEBUG_VALGRIND */ #ifdef UNIV_DEBUG if (row_merge_print_write) { - fprintf(stderr, "row_merge_buf_write %p,%d,%lu EOF\n", - (void*) b, of->fd, (ulong) of->offset); + fprintf(stderr, "row_merge_buf_write %p,%d," ULINTPF " EOF\n", + (void*) b, of->fd, of->offset); } #endif /* UNIV_DEBUG */ } @@ -960,15 +962,8 @@ row_merge_read( #ifdef UNIV_DEBUG if (row_merge_print_block_read) { - fprintf(stderr, "row_merge_read fd=%d ofs=%lu\n", - fd, (ulong) offset); - } -#endif /* UNIV_DEBUG */ - -#ifdef UNIV_DEBUG - if (row_merge_print_block_read) { - fprintf(stderr, "row_merge_read fd=%d ofs=%lu\n", - fd, (ulong) offset); + fprintf(stderr, "row_merge_read fd=%d ofs=" ULINTPF "\n", + fd, offset); } #endif /* UNIV_DEBUG */ @@ -1032,8 +1027,8 @@ row_merge_write( #ifdef UNIV_DEBUG if (row_merge_print_block_write) { - fprintf(stderr, "row_merge_write fd=%d ofs=%lu\n", - fd, (ulong) offset); + fprintf(stderr, "row_merge_write fd=%d ofs=" ULINTPF "\n", + fd, offset); } #endif /* UNIV_DEBUG */ @@ -1088,9 +1083,10 @@ row_merge_read_rec( *mrec = NULL; #ifdef UNIV_DEBUG if (row_merge_print_read) { - fprintf(stderr, "row_merge_read %p,%p,%d,%lu EOF\n", + fprintf(stderr, "row_merge_read %p,%p,%d," ULINTPF + " EOF\n", (const void*) b, (const void*) block, - fd, (ulong) *foffs); + fd, *foffs); } #endif /* UNIV_DEBUG */ return(NULL); @@ -1208,9 +1204,9 @@ err_exit: func_exit: #ifdef UNIV_DEBUG if (row_merge_print_read) { - fprintf(stderr, "row_merge_read %p,%p,%d,%lu ", + fprintf(stderr, "row_merge_read %p,%p,%d," ULINTPF " ", (const void*) b, (const void*) block, - fd, (ulong) *foffs); + fd, *foffs); rec_print_comp(stderr, *mrec, offsets); putc('\n', stderr); } @@ -1244,8 +1240,8 @@ row_merge_write_rec_low( ut_ad(e == rec_offs_extra_size(offsets) + 1); if (row_merge_print_write) { - fprintf(stderr, "row_merge_write %p,%d,%lu ", - (void*) b, fd, (ulong) foffs); + fprintf(stderr, "row_merge_write %p,%d," ULINTPF " ", + (void*) b, fd, foffs); rec_print_comp(stderr, mrec, offsets); putc('\n', stderr); } @@ -1358,8 +1354,8 @@ row_merge_write_eof( ut_ad(foffs); #ifdef UNIV_DEBUG if (row_merge_print_write) { - fprintf(stderr, "row_merge_write %p,%p,%d,%lu EOF\n", - (void*) b, (void*) block, fd, (ulong) *foffs); + fprintf(stderr, "row_merge_write %p,%p,%d," ULINTPF " EOF\n", + (void*) b, (void*) block, fd, *foffs); } #endif /* UNIV_DEBUG */ @@ -2258,11 +2254,12 @@ row_merge_blocks( #ifdef UNIV_DEBUG if (row_merge_print_block) { fprintf(stderr, - "row_merge_blocks fd=%d ofs=%lu + fd=%d ofs=%lu" - " = fd=%d ofs=%lu\n", - file->fd, (ulong) *foffs0, - file->fd, (ulong) *foffs1, - of->fd, (ulong) of->offset); + "row_merge_blocks fd=%d ofs=" ULINTPF + " + fd=%d ofs=" ULINTPF + " = fd=%d ofs=" ULINTPF "\n", + file->fd, *foffs0, + file->fd, *foffs1, + of->fd, of->offset); } #endif /* UNIV_DEBUG */ @@ -2373,10 +2370,10 @@ row_merge_blocks_copy( #ifdef UNIV_DEBUG if (row_merge_print_block) { fprintf(stderr, - "row_merge_blocks_copy fd=%d ofs=%lu" - " = fd=%d ofs=%lu\n", - file->fd, (ulong) foffs0, - of->fd, (ulong) of->offset); + "row_merge_blocks_copy fd=%d ofs=" ULINTPF + " = fd=%d ofs=" ULINTPF "\n", + file->fd, *foffs0, + of->fd, of->offset); } #endif /* UNIV_DEBUG */ @@ -2635,7 +2632,11 @@ row_merge_sort( thd_progress_init(trx->mysql_thd, 1); } - sql_print_information("InnoDB: Online DDL : merge-sorting has estimated %lu runs", num_runs); + if (global_system_variables.log_warnings > 2) { + sql_print_information("InnoDB: Online DDL : merge-sorting" + " has estimated " ULINTPF " runs", + num_runs); + } /* Merge the runs until we have one big run */ do { @@ -4060,9 +4061,11 @@ row_merge_build_indexes( duplicate keys. */ innobase_rec_reset(table); - sql_print_information("InnoDB: Online DDL : Start"); - sql_print_information("InnoDB: Online DDL : Start reading clustered " - "index of the table and create temporary files"); + if (global_system_variables.log_warnings > 2) { + sql_print_information("InnoDB: Online DDL : Start reading" + " clustered index of the table" + " and create temporary files"); + } pct_cost = COST_READ_CLUSTERED_INDEX * 100 / (total_static_cost + total_dynamic_cost); @@ -4089,8 +4092,11 @@ row_merge_build_indexes( pct_progress += pct_cost; - sql_print_information("InnoDB: Online DDL : End of reading " - "clustered index of the table and create temporary files"); + if (global_system_variables.log_warnings > 2) { + sql_print_information("InnoDB: Online DDL : End of reading " + "clustered index of the table" + " and create temporary files"); + } for (i = 0; i < n_indexes; i++) { total_index_blocks += merge_files[i].offset; @@ -4186,8 +4192,7 @@ wait_again: DEBUG_FTS_SORT_PRINT("FTS_SORT: Complete Insert\n"); #endif } else if (merge_files[i].fd != -1) { - char buf[3 * NAME_LEN]; - char *bufend; + char buf[NAME_LEN + 1]; row_merge_dup_t dup = { sort_idx, table, col_map, 0}; @@ -4196,18 +4201,25 @@ wait_again: total_index_blocks)) / (total_static_cost + total_dynamic_cost) * PCT_COST_MERGESORT_INDEX * 100; - - bufend = innobase_convert_name( + char* bufend = innobase_convert_name( buf, sizeof buf, - indexes[i]->name, strlen(indexes[i]->name), + indexes[i]->name, + strlen(indexes[i]->name), trx->mysql_thd, FALSE); - buf[bufend - buf]='\0'; - sql_print_information("InnoDB: Online DDL : Start merge-sorting" - " index %s (%lu / %lu), estimated cost : %2.4f", - buf, (i+1), n_indexes, pct_cost); + if (global_system_variables.log_warnings > 2) { + sql_print_information("InnoDB: Online DDL :" + " Start merge-sorting" + " index %s" + " (" ULINTPF + " / " ULINTPF ")," + " estimated cost :" + " %2.4f", + buf, i + 1, n_indexes, + pct_cost); + } error = row_merge_sort( trx, &dup, &merge_files[i], @@ -4217,9 +4229,14 @@ wait_again: pct_progress += pct_cost; - sql_print_information("InnoDB: Online DDL : End of " - " merge-sorting index %s (%lu / %lu)", - buf, (i+1), n_indexes); + if (global_system_variables.log_warnings > 2) { + sql_print_information("InnoDB: Online DDL :" + " End of " + " merge-sorting index %s" + " (" ULINTPF + " / " ULINTPF ")", + buf, i + 1, n_indexes); + } DBUG_EXECUTE_IF( "ib_merge_wait_after_sort", @@ -4232,10 +4249,15 @@ wait_again: (total_static_cost + total_dynamic_cost) * PCT_COST_INSERT_INDEX * 100; - sql_print_information("InnoDB: Online DDL : Start " - "building index %s (%lu / %lu), estimated " - "cost : %2.4f", buf, (i+1), - n_indexes, pct_cost); + if (global_system_variables.log_warnings > 2) { + sql_print_information( + "InnoDB: Online DDL : Start " + "building index %s" + " (" ULINTPF + " / " ULINTPF "), estimated " + "cost : %2.4f", buf, i + 1, + n_indexes, pct_cost); + } error = row_merge_insert_index_tuples( trx->id, sort_idx, old_table, @@ -4244,9 +4266,13 @@ wait_again: crypt_data, crypt_block, new_table->space); pct_progress += pct_cost; - sql_print_information("InnoDB: Online DDL : " - "End of building index %s (%lu / %lu)", - buf, (i+1), n_indexes); + if (global_system_variables.log_warnings > 2) { + sql_print_information( + "InnoDB: Online DDL : " + "End of building index %s" + " (" ULINTPF " / " ULINTPF ")", + buf, i + 1, n_indexes); + } } } @@ -4263,15 +4289,16 @@ wait_again: ut_ad(sort_idx->online_status == ONLINE_INDEX_COMPLETE); } else { - sql_print_information("InnoDB: Online DDL : Start applying row log"); + if (global_system_variables.log_warnings > 2) { + sql_print_information( + "InnoDB: Online DDL : Applying" + " log to index"); + } DEBUG_SYNC_C("row_log_apply_before"); error = row_log_apply(trx, sort_idx, table); DEBUG_SYNC_C("row_log_apply_after"); - sql_print_information("InnoDB: Online DDL : End of applying row log"); } - sql_print_information("InnoDB: Online DDL : Completed"); - if (error != DB_SUCCESS) { trx->error_key_num = key_numbers[i]; goto func_exit; diff --git a/storage/xtradb/srv/srv0mon.cc b/storage/xtradb/srv/srv0mon.cc index 7c2e549e188..47abae66192 100644 --- a/storage/xtradb/srv/srv0mon.cc +++ b/storage/xtradb/srv/srv0mon.cc @@ -2,7 +2,7 @@ Copyright (c) 2010, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2016, MariaDB Corporation. +Copyright (c) 2013, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -690,11 +690,11 @@ static monitor_info_t innodb_counter_info[] = MONITOR_DEFAULT_START, MONITOR_OVLD_OS_FSYNC}, {"os_pending_reads", "os", "Number of reads pending", - MONITOR_NONE, + MONITOR_DEFAULT_ON, MONITOR_DEFAULT_START, MONITOR_OS_PENDING_READS}, {"os_pending_writes", "os", "Number of writes pending", - MONITOR_NONE, + MONITOR_DEFAULT_ON, MONITOR_DEFAULT_START, MONITOR_OS_PENDING_WRITES}, {"os_log_bytes_written", "os", diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc index f8c8c330f0c..1c40baee04b 100644 --- a/storage/xtradb/srv/srv0srv.cc +++ b/storage/xtradb/srv/srv0srv.cc @@ -1814,10 +1814,10 @@ srv_export_innodb_status(void) mutex_enter(&srv_innodb_monitor_mutex); export_vars.innodb_data_pending_reads = - os_n_pending_reads; + ulint(MONITOR_VALUE(MONITOR_OS_PENDING_READS)); export_vars.innodb_data_pending_writes = - os_n_pending_writes; + ulint(MONITOR_VALUE(MONITOR_OS_PENDING_WRITES)); export_vars.innodb_data_pending_fsyncs = fil_n_pending_log_flushes diff --git a/storage/xtradb/sync/sync0arr.cc b/storage/xtradb/sync/sync0arr.cc index c311d2cbd7d..134d16ae58e 100644 --- a/storage/xtradb/sync/sync0arr.cc +++ b/storage/xtradb/sync/sync0arr.cc @@ -522,13 +522,14 @@ sync_array_cell_print( if (mutex) { fprintf(file, "Mutex at %p '%s', lock var %lu\n" - "Last time reserved by thread %lu in file %s line %lu, " - "waiters flag %lu\n", + "Last time reserved by thread " ULINTPF + " in file %s line " ULINTPF ", " + "waiters flag " ULINTPF "\n", (void*) mutex, mutex->cmutex_name, (ulong) mutex->lock_word, - mutex->thread_id, - mutex->file_name, (ulong) mutex->line, - (ulong) mutex->waiters); + os_thread_pf(mutex->thread_id), + mutex->file_name, mutex->line, + mutex->waiters); } /* If stacktrace feature is enabled we will send a SIGUSR2 @@ -582,9 +583,9 @@ sync_array_cell_print( if (writer && writer != RW_LOCK_NOT_LOCKED) { fprintf(file, - "a writer (thread id %lu) has" + "a writer (thread id " ULINTPF ") has" " reserved it in mode %s", - (ulong) os_thread_pf(rwlock->writer_thread), + os_thread_pf(rwlock->writer_thread), writer == RW_LOCK_EX ? " exclusive\n" : " wait exclusive\n"); @@ -593,21 +594,23 @@ sync_array_cell_print( } fprintf(file, - "number of readers %lu, waiters flag %lu, " + "number of readers " ULINTPF + ", waiters flag " ULINTPF ", " "lock_word: %lx\n" - "Last time read locked in file %s line %lu\n" - "Last time write locked in file %s line %lu\n", - (ulong) rw_lock_get_reader_count(rwlock), - (ulong) rwlock->waiters, + "Last time read locked in file %s line %u\n" + "Last time write locked in file %s line %u\n" + "Holder thread " ULINTPF + " file %s line " ULINTPF "\n", + rw_lock_get_reader_count(rwlock), + rwlock->waiters, rwlock->lock_word, innobase_basename(rwlock->last_s_file_name), - (ulong) rwlock->last_s_line, - rwlock->last_x_file_name, - (ulong) rwlock->last_x_line); - - fprintf(file, - "Holder thread %lu file %s line %lu\n", - rwlock->thread_id, rwlock->file_name, rwlock->line); + rwlock->last_s_line, + innobase_basename(rwlock->last_x_file_name), + rwlock->last_x_line, + os_thread_pf(rwlock->thread_id), + innobase_basename(rwlock->file_name), + rwlock->line); /* If stacktrace feature is enabled we will send a SIGUSR2 signal to thread that has locked RW-latch with write mode. @@ -1175,9 +1178,10 @@ sync_array_print_long_waits( now the values of pending calls of these. */ fprintf(stderr, - "InnoDB: Pending preads %lu, pwrites %lu\n", - (ulong) os_file_n_pending_preads, - (ulong) os_file_n_pending_pwrites); + "InnoDB: Pending reads " UINT64PF + ", writes " UINT64PF "\n", + MONITOR_VALUE(MONITOR_OS_PENDING_READS), + MONITOR_VALUE(MONITOR_OS_PENDING_WRITES)); srv_print_innodb_monitor = TRUE; os_event_set(srv_monitor_event); diff --git a/storage/xtradb/trx/trx0trx.cc b/storage/xtradb/trx/trx0trx.cc index 439897a5b96..92d7525ea84 100644 --- a/storage/xtradb/trx/trx0trx.cc +++ b/storage/xtradb/trx/trx0trx.cc @@ -2161,6 +2161,118 @@ trx_print_latched( mem_heap_get_size(trx->lock.lock_heap)); } +#ifdef WITH_WSREP +/**********************************************************************//** +Prints info about a transaction. +Transaction information may be retrieved without having trx_sys->mutex acquired +so it may not be completely accurate. The caller must own lock_sys->mutex +and the trx must have some locks to make sure that it does not escape +without locking lock_sys->mutex. */ +UNIV_INTERN +void +wsrep_trx_print_locking( +/*==========*/ + FILE* f, + /*!< in: output stream */ + const trx_t* trx, + /*!< in: transaction */ + ulint max_query_len) + /*!< in: max query length to print, + or 0 to use the default max length */ +{ + ibool newline; + const char* op_info; + + ut_ad(lock_mutex_own()); + ut_ad(trx->lock.trx_locks.count > 0); + + fprintf(f, "TRANSACTION " TRX_ID_FMT, trx->id); + + /* trx->state may change since trx_sys->mutex is not required */ + switch (trx->state) { + case TRX_STATE_NOT_STARTED: + fputs(", not started", f); + goto state_ok; + case TRX_STATE_ACTIVE: + fprintf(f, ", ACTIVE %lu sec", + (ulong) difftime(time(NULL), trx->start_time)); + goto state_ok; + case TRX_STATE_PREPARED: + fprintf(f, ", ACTIVE (PREPARED) %lu sec", + (ulong) difftime(time(NULL), trx->start_time)); + goto state_ok; + case TRX_STATE_COMMITTED_IN_MEMORY: + fputs(", COMMITTED IN MEMORY", f); + goto state_ok; + } + fprintf(f, ", state %lu", (ulong) trx->state); + ut_ad(0); +state_ok: + + /* prevent a race condition */ + op_info = trx->op_info; + + if (*op_info) { + putc(' ', f); + fputs(op_info, f); + } + + if (trx->is_recovered) { + fputs(" recovered trx", f); + } + + if (trx->declared_to_be_inside_innodb) { + fprintf(f, ", thread declared inside InnoDB %lu", + (ulong) trx->n_tickets_to_enter_innodb); + } + + putc('\n', f); + + if (trx->n_mysql_tables_in_use > 0 || trx->mysql_n_tables_locked > 0) { + fprintf(f, "mysql tables in use %lu, locked %lu\n", + (ulong) trx->n_mysql_tables_in_use, + (ulong) trx->mysql_n_tables_locked); + } + + newline = TRUE; + + /* trx->lock.que_state of an ACTIVE transaction may change + while we are not holding trx->mutex. We perform a dirty read + for performance reasons. */ + + switch (trx->lock.que_state) { + case TRX_QUE_RUNNING: + newline = FALSE; break; + case TRX_QUE_LOCK_WAIT: + fputs("LOCK WAIT ", f); break; + case TRX_QUE_ROLLING_BACK: + fputs("ROLLING BACK ", f); break; + case TRX_QUE_COMMITTING: + fputs("COMMITTING ", f); break; + default: + fprintf(f, "que state %lu ", (ulong) trx->lock.que_state); + } + + if (trx->has_search_latch) { + newline = TRUE; + fputs(", holds adaptive hash latch", f); + } + + if (trx->undo_no != 0) { + newline = TRUE; + fprintf(f, ", undo log entries " TRX_ID_FMT, trx->undo_no); + } + + if (newline) { + putc('\n', f); + } + + if (trx->mysql_thd != NULL) { + innobase_mysql_print_thd( + f, trx->mysql_thd, static_cast<uint>(max_query_len)); + } +} +#endif /* WITH_WSREP */ /**********************************************************************//** Prints info about a transaction. Acquires and releases lock_sys->mutex and trx_sys->mutex. */ |