diff options
59 files changed, 1706 insertions, 1079 deletions
diff --git a/storage/xtradb/api/api0api.cc b/storage/xtradb/api/api0api.cc index c5299156d7a..bb65dd82216 100644 --- a/storage/xtradb/api/api0api.cc +++ b/storage/xtradb/api/api0api.cc @@ -1489,7 +1489,8 @@ ib_insert_row_with_lock_retry( que_thr_stop_for_mysql(thr); thr->lock_state = QUE_THR_LOCK_ROW; - lock_wait = ib_handle_errors(&err, trx, thr, savept); + lock_wait = static_cast<ib_bool_t>( + ib_handle_errors(&err, trx, thr, savept)); thr->lock_state = QUE_THR_LOCK_NOLOCK; } else { lock_wait = FALSE; @@ -1823,8 +1824,8 @@ ib_update_row_with_lock_retry( if (err != DB_RECORD_NOT_FOUND) { thr->lock_state = QUE_THR_LOCK_ROW; - lock_wait = ib_handle_errors( - &err, trx, thr, savept); + lock_wait = static_cast<ib_bool_t>( + ib_handle_errors(&err, trx, thr, savept)); thr->lock_state = QUE_THR_LOCK_NOLOCK; } else { @@ -1977,7 +1978,8 @@ ib_delete_row( upd = ib_update_vector_create(cursor); - page_format = dict_table_is_comp(index->table); + page_format = static_cast<ib_bool_t>( + dict_table_is_comp(index->table)); ib_read_tuple(rec, page_format, tuple, NULL, NULL); upd->n_fields = ib_tuple_get_n_cols(ib_tpl); @@ -2043,7 +2045,8 @@ ib_cursor_delete_row( ib_bool_t page_format; mtr_t mtr; - page_format = dict_table_is_comp(index->table); + page_format = static_cast<ib_bool_t>( + dict_table_is_comp(index->table)); mtr_start(&mtr); @@ -2116,7 +2119,8 @@ ib_cursor_read_row( const rec_t* rec; ib_bool_t page_format; - page_format = dict_table_is_comp(tuple->index->table); + page_format = static_cast<ib_bool_t>( + dict_table_is_comp(tuple->index->table)); rec = btr_pcur_get_rec(pcur); if (prebuilt->innodb_api_rec && @@ -2360,7 +2364,7 @@ ib_col_set_value( for that. */ if (ib_col_is_capped(dtype)) { - len = ut_min(len, col_len); + len = ut_min(len, static_cast<ib_ulint_t>(col_len)); if (dst == NULL || len > dfield_get_len(dfield)) { dst = mem_heap_alloc(tuple->heap, col_len); @@ -2421,12 +2425,12 @@ ib_col_set_value( ut_a(pad_char != ULINT_UNDEFINED); memset((byte*) dst + len, - pad_char, - col_len - len); + static_cast<int>(pad_char), + static_cast<size_t>(col_len - len)); memcpy(dst, src, len); - len = col_len; + len = static_cast<ib_ulint_t>(col_len); break; } case DATA_BLOB: @@ -2467,7 +2471,7 @@ ib_col_set_value( &error); if (true_len < len) { - len = true_len; + len = static_cast<ib_ulint_t>(true_len); } } } @@ -2508,7 +2512,7 @@ ib_col_set_value( col_len--; } - len = col_len; + len = static_cast<ib_ulint_t>(col_len); } break; } @@ -2544,7 +2548,8 @@ ib_col_get_len( data_len = dfield_get_len(dfield); - return(data_len == UNIV_SQL_NULL ? IB_SQL_NULL : data_len); + return(static_cast<ib_ulint_t>( + data_len == UNIV_SQL_NULL ? IB_SQL_NULL : data_len)); } /*****************************************************************//** @@ -2640,7 +2645,7 @@ ib_col_copy_value_low( data_len = IB_SQL_NULL; } - return(data_len); + return(static_cast<ib_ulint_t>(data_len)); } /*****************************************************************//** @@ -2750,14 +2755,15 @@ ib_col_get_meta_low( ib_col_meta->type = static_cast<ib_col_type_t>( dtype_get_mtype(dfield_get_type(dfield))); - ib_col_meta->type_len = dtype_get_len(dfield_get_type(dfield)); + ib_col_meta->type_len = static_cast<ib_u32_t>( + dtype_get_len(dfield_get_type(dfield))); prtype = (ib_u16_t) dtype_get_prtype(dfield_get_type(dfield)); ib_col_meta->attr = ib_col_get_attr(prtype); ib_col_meta->client_type = prtype & DATA_MYSQL_TYPE_MASK; - return(data_len); + return(static_cast<ib_ulint_t>(data_len)); } /*************************************************************//** @@ -3243,10 +3249,12 @@ ib_tuple_get_n_user_cols( const ib_tuple_t* tuple = (const ib_tuple_t*) ib_tpl; if (tuple->type == TPL_TYPE_ROW) { - return(dict_table_get_n_user_cols(tuple->index->table)); + return(static_cast<ib_ulint_t>( + dict_table_get_n_user_cols(tuple->index->table))); } - return(dict_index_get_n_ordering_defined_by_user(tuple->index)); + return(static_cast<ib_ulint_t>( + dict_index_get_n_ordering_defined_by_user(tuple->index))); } /*****************************************************************//** @@ -3260,7 +3268,7 @@ ib_tuple_get_n_cols( { const ib_tuple_t* tuple = (const ib_tuple_t*) ib_tpl; - return(dtuple_get_n_fields(tuple->ptr)); + return(static_cast<ib_ulint_t>(dtuple_get_n_fields(tuple->ptr))); } /*****************************************************************//** @@ -3563,7 +3571,9 @@ ib_tuple_write_int( return(DB_DATA_MISMATCH); } - return(ib_col_set_value(ib_tpl, col_no, value, type_len, true)); + return(ib_col_set_value( + ib_tpl, static_cast<ib_ulint_t>(col_no), + value, static_cast<ib_ulint_t>(type_len), true)); } /*****************************************************************//** @@ -3889,7 +3899,8 @@ ib_table_truncate( /* Remember the memcached_sync_count and set it to 0, so the truncate can be executed. */ if (table != NULL && err == DB_SUCCESS) { - memcached_sync = table->memcached_sync_count; + memcached_sync = static_cast<ib_ulint_t>( + table->memcached_sync_count); table->memcached_sync_count = 0; } diff --git a/storage/xtradb/btr/btr0cur.cc b/storage/xtradb/btr/btr0cur.cc index fb12aac18b1..5e0473daa85 100644 --- a/storage/xtradb/btr/btr0cur.cc +++ b/storage/xtradb/btr/btr0cur.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2014, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Copyright (c) 2012, Facebook Inc. @@ -3102,10 +3102,7 @@ btr_cur_del_mark_set_clust_rec( trx = thr_get_trx(thr); if (dict_index_is_online_ddl(index)) { - row_log_table_delete( - rec, index, offsets, false, - trx_read_trx_id(row_get_trx_id_offset(index, offsets) - + rec)); + row_log_table_delete(rec, index, offsets, NULL); } row_upd_rec_sys_fields(rec, page_zip, index, offsets, trx, roll_ptr); @@ -4713,7 +4710,7 @@ btr_store_big_rec_extern_fields( c_stream.next_in = (Bytef*) big_rec_vec->fields[i].data; - c_stream.avail_in = extern_len; + c_stream.avail_in = static_cast<uInt>(extern_len); } for (;;) { @@ -4804,7 +4801,7 @@ alloc_another: c_stream.next_out = page + FIL_PAGE_DATA; c_stream.avail_out - = page_zip_get_size(page_zip) + = static_cast<uInt>(page_zip_get_size(page_zip)) - FIL_PAGE_DATA; err = deflate(&c_stream, Z_FINISH); @@ -5467,7 +5464,7 @@ btr_copy_zblob_prefix( z_stream d_stream; d_stream.next_out = buf; - d_stream.avail_out = len; + d_stream.avail_out = static_cast<uInt>(len); d_stream.next_in = Z_NULL; d_stream.avail_in = 0; @@ -5529,7 +5526,7 @@ btr_copy_zblob_prefix( } d_stream.next_in = bpage->zip.data + offset; - d_stream.avail_in = zip_size - offset; + d_stream.avail_in = static_cast<uInt>(zip_size - offset); err = inflate(&d_stream, Z_NO_FLUSH); switch (err) { diff --git a/storage/xtradb/buf/buf0buddy.cc b/storage/xtradb/buf/buf0buddy.cc index 442ee80235f..8f6be0cf2af 100644 --- a/storage/xtradb/buf/buf0buddy.cc +++ b/storage/xtradb/buf/buf0buddy.cc @@ -131,7 +131,7 @@ buf_buddy_stamp_free( buf_buddy_free_t* buf, /*!< in/out: block to stamp */ ulint i) /*!< in: block size */ { - ut_d(memset(buf, i, BUF_BUDDY_LOW << i)); + ut_d(memset(buf, static_cast<int>(i), BUF_BUDDY_LOW << i)); buf_buddy_mem_invalid(buf, i); mach_write_to_4(buf->stamp.bytes + BUF_BUDDY_STAMP_OFFSET, BUF_BUDDY_STAMP_FREE); diff --git a/storage/xtradb/buf/buf0buf.cc b/storage/xtradb/buf/buf0buf.cc index 69dcc4ce9cb..27e2af20298 100644 --- a/storage/xtradb/buf/buf0buf.cc +++ b/storage/xtradb/buf/buf0buf.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -495,6 +495,26 @@ buf_block_alloc( #endif /* !UNIV_HOTBACKUP */ /********************************************************************//** +Checks if a page is all zeroes. +@return TRUE if the page is all zeroes */ +bool +buf_page_is_zeroes( +/*===============*/ + const byte* read_buf, /*!< in: a database page */ + const ulint zip_size) /*!< in: size of compressed page; + 0 for uncompressed pages */ +{ + const ulint page_size = zip_size ? zip_size : UNIV_PAGE_SIZE; + + for (ulint i = 0; i < page_size; i++) { + if (read_buf[i] != 0) { + return(false); + } + } + return(true); +} + +/********************************************************************//** Checks if a page is corrupt. @return TRUE if corrupted */ UNIV_INTERN @@ -1322,8 +1342,8 @@ buf_pool_init_instance( /* Number of locks protecting page_hash must be a power of two */ - srv_n_page_hash_locks = - ut_2_power_up(srv_n_page_hash_locks); + srv_n_page_hash_locks = static_cast<ulong>( + ut_2_power_up(srv_n_page_hash_locks)); ut_a(srv_n_page_hash_locks != 0); ut_a(srv_n_page_hash_locks <= MAX_PAGE_HASH_LOCKS); @@ -1710,8 +1730,8 @@ page_found: mutex_enter(&buf_pool->zip_mutex); bpage->state = BUF_BLOCK_ZIP_PAGE; - bpage->space = space; - bpage->offset = offset; + bpage->space = static_cast<ib_uint32_t>(space); + bpage->offset = static_cast<ib_uint32_t>(offset); bpage->buf_fix_count = 1; mutex_exit(&buf_pool->zip_mutex); @@ -2908,12 +2928,12 @@ got_block: os_atomic_increment_ulint(&buf_pool->n_pend_unzip, 1); + mutex_exit(&buf_pool->zip_mutex); + access_time = buf_page_is_accessed(&block->page); buf_block_mutex_exit(block); - mutex_exit(&buf_pool->zip_mutex); - buf_page_free_descriptor(bpage); /* Decompress the page while not holding @@ -3794,8 +3814,8 @@ err_exit: buf_page_init_low(bpage); bpage->state = BUF_BLOCK_ZIP_PAGE; - bpage->space = space; - bpage->offset = offset; + bpage->space = static_cast<ib_uint32_t>(space); + bpage->offset = static_cast<ib_uint32_t>(offset); #ifdef UNIV_DEBUG bpage->in_page_hash = FALSE; diff --git a/storage/xtradb/buf/buf0dblwr.cc b/storage/xtradb/buf/buf0dblwr.cc index c1bc0ee4c6e..f4d1c637e3e 100644 --- a/storage/xtradb/buf/buf0dblwr.cc +++ b/storage/xtradb/buf/buf0dblwr.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2014, 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 @@ -352,11 +352,12 @@ we already have a doublewrite buffer created in the data files. If we are upgrading to an InnoDB version which supports multiple tablespaces, then this function performs the necessary update operations. If we are in a crash recovery, this function loads the pages from double write buffer into memory. */ -UNIV_INTERN void buf_dblwr_init_or_load_pages( -/*==========================*/ - bool load_corrupt_pages) +/*=========================*/ + os_file_t file, + char* path, + bool load_corrupt_pages) { byte* buf; byte* read_buf; @@ -368,6 +369,7 @@ buf_dblwr_init_or_load_pages( byte* doublewrite; ulint space_id; ulint i; + ulint block_bytes = 0; recv_dblwr_t& recv_dblwr = recv_sys->dblwr; /* We do the file i/o past the buffer pool */ @@ -379,9 +381,9 @@ buf_dblwr_init_or_load_pages( /* Read the trx sys header to check if we are using the doublewrite buffer */ + off_t trx_sys_page = TRX_SYS_PAGE_NO * UNIV_PAGE_SIZE; + os_file_read(file, read_buf, trx_sys_page, UNIV_PAGE_SIZE); - fil_io(OS_FILE_READ, true, TRX_SYS_SPACE, 0, TRX_SYS_PAGE_NO, 0, - UNIV_PAGE_SIZE, read_buf, NULL); doublewrite = read_buf + TRX_SYS_DOUBLEWRITE; if (mach_read_from_4(doublewrite + TRX_SYS_DOUBLEWRITE_MAGIC) @@ -415,13 +417,12 @@ buf_dblwr_init_or_load_pages( /* Read the pages from the doublewrite buffer to memory */ - fil_io(OS_FILE_READ, true, TRX_SYS_SPACE, 0, block1, 0, - TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE, - buf, NULL); - fil_io(OS_FILE_READ, true, TRX_SYS_SPACE, 0, block2, 0, - TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE, - buf + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE, - NULL); + block_bytes = TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE; + + os_file_read(file, buf, block1 * UNIV_PAGE_SIZE, block_bytes); + os_file_read(file, buf + block_bytes, block2 * UNIV_PAGE_SIZE, + block_bytes); + /* Check if any of these pages is half-written in data files, in the intended position */ @@ -447,8 +448,9 @@ buf_dblwr_init_or_load_pages( + i - TRX_SYS_DOUBLEWRITE_BLOCK_SIZE; } - fil_io(OS_FILE_WRITE, true, space_id, 0, source_page_no, 0, - UNIV_PAGE_SIZE, page, NULL); + os_file_write(path, file, page, + source_page_no * UNIV_PAGE_SIZE, + UNIV_PAGE_SIZE); } else if (load_corrupt_pages) { @@ -458,7 +460,9 @@ buf_dblwr_init_or_load_pages( page += UNIV_PAGE_SIZE; } - fil_flush_file_spaces(FIL_TABLESPACE); + if (reset_space_ids) { + os_file_flush(file); + } leave_func: ut_free(unaligned_read_buf); @@ -567,13 +571,29 @@ buf_dblwr_process() ib_logf(IB_LOG_LEVEL_INFO, "Recovered the page from" " the doublewrite buffer."); + + } else if (buf_page_is_zeroes(read_buf, zip_size)) { + + if (!buf_page_is_zeroes(page, zip_size) + && !buf_page_is_corrupted(true, page, + zip_size)) { + + /* Database page contained only + zeroes, while a valid copy is + available in dblwr buffer. */ + + fil_io(OS_FILE_WRITE, true, space_id, + zip_size, page_no, 0, + zip_size ? zip_size + : UNIV_PAGE_SIZE, + page, NULL); + } } } } fil_flush_file_spaces(FIL_TABLESPACE); ut_free(unaligned_read_buf); - recv_dblwr.pages.clear(); } /****************************************************************//** diff --git a/storage/xtradb/buf/buf0flu.cc b/storage/xtradb/buf/buf0flu.cc index 9e92cf321a7..df9187109c7 100644 --- a/storage/xtradb/buf/buf0flu.cc +++ b/storage/xtradb/buf/buf0flu.cc @@ -78,7 +78,10 @@ in thrashing. */ /** Handled page counters for a single flush */ struct flush_counters_t { ulint flushed; /*!< number of dirty pages flushed */ - ulint evicted; /*!< number of clean pages evicted */ + ulint evicted; /*!< number of clean pages evicted, including + evicted uncompressed page images */ + ulint unzip_LRU_evicted;/*!< number of uncompressed page images + evicted */ }; /******************************************************************//** @@ -749,9 +752,11 @@ buf_flush_update_zip_checksum( { ut_a(zip_size > 0); - ib_uint32_t checksum = page_zip_calc_checksum( - page, zip_size, - static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm)); + ib_uint32_t checksum = static_cast<ib_uint32_t>( + page_zip_calc_checksum( + page, zip_size, + static_cast<srv_checksum_algorithm_t>( + srv_checksum_algorithm))); mach_write_to_8(page + FIL_PAGE_LSN, lsn); memset(page + FIL_PAGE_FILE_FLUSH_LSN, 0, 8); @@ -1506,6 +1511,7 @@ buf_flush_LRU_list_batch( n->flushed = 0; n->evicted = 0; + n->unzip_LRU_evicted = 0; ut_ad(mutex_own(&buf_pool->LRU_list_mutex)); @@ -1641,21 +1647,22 @@ buf_do_LRU_batch( flush_counters_t* n) /*!< out: flushed/evicted page counts */ { - ulint count = 0; - if (buf_LRU_evict_from_unzip_LRU(buf_pool)) { - count += buf_free_from_unzip_LRU_list_batch(buf_pool, max); + n->unzip_LRU_evicted + += buf_free_from_unzip_LRU_list_batch(buf_pool, max); + } else { + n->unzip_LRU_evicted = 0; } - if (max > count) { - buf_flush_LRU_list_batch(buf_pool, max - count, limited_scan, - n); + if (max > n->unzip_LRU_evicted) { + buf_flush_LRU_list_batch(buf_pool, max - n->unzip_LRU_evicted, + limited_scan, n); } else { n->evicted = 0; n->flushed = 0; } - n->flushed += count; + n->evicted += n->unzip_LRU_evicted; } /*******************************************************************//** @@ -2269,9 +2276,15 @@ buf_flush_LRU_tail(void) requested_pages[i] += lru_chunk_size; + /* If we failed to flush or evict this + instance, do not bother anymore. But take into + account that we might have zero flushed pages + because the flushing request was fully + satisfied by unzip_LRU evictions. */ if (requested_pages[i] >= scan_depth[i] || !(srv_cleaner_eviction_factor - ? n.evicted : n.flushed)) { + ? n.evicted + : (n.flushed + n.unzip_LRU_evicted))) { active_instance[i] = false; remaining_instances--; @@ -2507,7 +2520,7 @@ page_cleaner_flush_pages_if_needed(void) } if (last_pages && cur_lsn - last_lsn > lsn_avg_rate / 2) { - age_factor = prev_pages / last_pages; + age_factor = static_cast<int>(prev_pages / last_pages); } MONITOR_SET(MONITOR_FLUSH_N_TO_FLUSH_REQUESTED, n_pages); diff --git a/storage/xtradb/buf/buf0lru.cc b/storage/xtradb/buf/buf0lru.cc index d3e0eda0257..d0904f4b8ad 100644 --- a/storage/xtradb/buf/buf0lru.cc +++ b/storage/xtradb/buf/buf0lru.cc @@ -1357,7 +1357,8 @@ loop: memset(&block->page.zip, 0, sizeof block->page.zip); if (started_monitor) { - srv_print_innodb_monitor = mon_value_was; + srv_print_innodb_monitor = + static_cast<my_bool>(mon_value_was); } return(block); @@ -2210,11 +2211,12 @@ not_freed: buf_pool->page_hash, thus inaccessible by any other thread. */ - checksum = page_zip_calc_checksum( - b->zip.data, - page_zip_get_size(&b->zip), - static_cast<srv_checksum_algorithm_t>( - srv_checksum_algorithm)); + checksum = static_cast<ib_uint32_t>( + page_zip_calc_checksum( + b->zip.data, + page_zip_get_size(&b->zip), + static_cast<srv_checksum_algorithm_t>( + srv_checksum_algorithm))); mach_write_to_4(b->zip.data + FIL_PAGE_SPACE_OR_CHKSUM, checksum); diff --git a/storage/xtradb/dict/dict0dict.cc b/storage/xtradb/dict/dict0dict.cc index 5cc013b7d6b..1aa40f92836 100644 --- a/storage/xtradb/dict/dict0dict.cc +++ b/storage/xtradb/dict/dict0dict.cc @@ -6229,9 +6229,8 @@ dict_fs2utf8( db[db_len] = '\0'; strconvert( - &my_charset_filename, db, db_len, - system_charset_info, db_utf8, db_utf8_size, - &errors); + &my_charset_filename, db, db_len, system_charset_info, + db_utf8, static_cast<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); @@ -6256,8 +6255,8 @@ dict_fs2utf8( errors = 0; strconvert( - &my_charset_filename, buf, buf_p - buf, - system_charset_info, table_utf8, table_utf8_size, + &my_charset_filename, buf, buf_p - buf, system_charset_info, + table_utf8, static_cast<uint>(table_utf8_size), &errors); if (errors != 0) { diff --git a/storage/xtradb/dict/dict0load.cc b/storage/xtradb/dict/dict0load.cc index 9add88c0ea5..013a5fb7b37 100644 --- a/storage/xtradb/dict/dict0load.cc +++ b/storage/xtradb/dict/dict0load.cc @@ -1065,7 +1065,8 @@ loop: bool is_temp = false; bool discarded = false; - ib_uint32_t flags2 = mach_read_from_4(field); + ib_uint32_t flags2 = static_cast<ib_uint32_t>( + mach_read_from_4(field)); /* Check that the tablespace (the .ibd file) really exists; print a warning to the .err log if not. diff --git a/storage/xtradb/dict/dict0stats.cc b/storage/xtradb/dict/dict0stats.cc index 68c02a301cd..928bdb3f2ef 100644 --- a/storage/xtradb/dict/dict0stats.cc +++ b/storage/xtradb/dict/dict0stats.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2009, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2009, 2014, 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 @@ -46,6 +46,7 @@ Created Jan 06, 2010 Vasil Dimov #include "ut0rnd.h" /* ut_rnd_interval() */ #include "ut0ut.h" /* ut_format_name(), ut_time() */ +#include <map> #include <vector> /* Sampling algorithm description @{ @@ -143,6 +144,17 @@ data: b,b,b,b,b,b,g,g,j,j,j, x, y then we would store 5,7,10,11,12 in the array. */ typedef std::vector<ib_uint64_t> boundaries_t; +/* This is used to arrange the index based on the index name. +@return true if index_name1 is smaller than index_name2. */ +struct index_cmp +{ + bool operator()(const char* index_name1, const char* index_name2) const { + return(strcmp(index_name1, index_name2) < 0); + } +}; + +typedef std::map<const char*, dict_index_t*, index_cmp> index_map_t; + /*********************************************************************//** Checks whether an index should be ignored in stats manipulations: * stats fetch @@ -266,22 +278,24 @@ dict_stats_persistent_storage_check( return(true); } -/*********************************************************************//** -Executes a given SQL statement using the InnoDB internal SQL parser -in its own transaction and commits it. +/** Executes a given SQL statement using the InnoDB internal SQL parser. This function will free the pinfo object. +@param[in,out] pinfo pinfo to pass to que_eval_sql() must already +have any literals bound to it +@param[in] sql SQL string to execute +@param[in,out] trx in case of NULL the function will allocate and +free the trx object. If it is not NULL then it will be rolled back +only in the case of error, but not freed. @return DB_SUCCESS or error code */ static dberr_t dict_stats_exec_sql( -/*================*/ - pars_info_t* pinfo, /*!< in/out: pinfo to pass to que_eval_sql() - must already have any literals bound to it */ - const char* sql) /*!< in: SQL string to execute */ + pars_info_t* pinfo, + const char* sql, + trx_t* trx) { - trx_t* trx; dberr_t err; - + bool trx_started = false; #ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX)); #endif /* UNIV_SYNC_DEBUG */ @@ -292,11 +306,24 @@ dict_stats_exec_sql( return(DB_STATS_DO_NOT_EXIST); } - trx = trx_allocate_for_background(); - trx_start_if_not_started(trx); + if (trx == NULL) { + trx = trx_allocate_for_background(); + trx_start_if_not_started(trx); + trx_started = true; + } err = que_eval_sql(pinfo, sql, FALSE, trx); /* pinfo is freed here */ + DBUG_EXECUTE_IF("stats_index_error", + if (!trx_started) { + err = DB_STATS_DO_NOT_EXIST; + trx->error_state = DB_STATS_DO_NOT_EXIST; + }); + + if (!trx_started && err == DB_SUCCESS) { + return(DB_SUCCESS); + } + if (err == DB_SUCCESS) { trx_commit_for_mysql(trx); } else { @@ -308,7 +335,9 @@ dict_stats_exec_sql( ut_a(trx->error_state == DB_SUCCESS); } - trx_free_for_background(trx); + if (trx_started) { + trx_free_for_background(trx); + } return(err); } @@ -1588,7 +1617,8 @@ dict_stats_analyze_index_for_n_prefix( == !(REC_INFO_MIN_REC_FLAG & rec_get_info_bits( btr_pcur_get_rec(&pcur), page_is_comp(page)))); - last_idx_on_level = boundaries->at(n_diff_for_this_prefix - 1); + last_idx_on_level = boundaries->at( + static_cast<unsigned int>(n_diff_for_this_prefix - 1)); rec_idx = 0; @@ -1600,7 +1630,7 @@ dict_stats_analyze_index_for_n_prefix( for (i = 0; i < n_recs_to_dive_below; i++) { ib_uint64_t left; ib_uint64_t right; - ulint rnd; + ib_uint64_t rnd; ib_uint64_t dive_below_idx; /* there are n_diff_for_this_prefix elements @@ -1641,9 +1671,11 @@ dict_stats_analyze_index_for_n_prefix( /* we do not pass (left, right) because we do not want to ask ut_rnd_interval() to work with too big numbers since ib_uint64_t could be bigger than ulint */ - rnd = ut_rnd_interval(0, (ulint) (right - left)); + rnd = static_cast<ib_uint64_t>( + ut_rnd_interval(0, static_cast<ulint>(right - left))); - dive_below_idx = boundaries->at(left + rnd); + dive_below_idx = boundaries->at( + static_cast<unsigned int>(left + rnd)); #if 0 DEBUG_PRINTF(" %s(): dive below record with index=" @@ -2084,20 +2116,28 @@ dict_stats_update_persistent( } #include "mysql_com.h" -/*********************************************************************//** -Save an individual index's statistic into the persistent statistics +/** Save an individual index's statistic into the persistent statistics storage. +@param[in] index index to be updated +@param[in] last_update timestamp of the stat +@param[in] stat_name name of the stat +@param[in] stat_value value of the stat +@param[in] sample_size n pages sampled or NULL +@param[in] stat_description description of the stat +@param[in,out] trx in case of NULL the function will +allocate and free the trx object. If it is not NULL then it will be +rolled back only in the case of error, but not freed. @return DB_SUCCESS or error code */ static dberr_t dict_stats_save_index_stat( -/*=======================*/ - dict_index_t* index, /*!< in: index */ - lint last_update, /*!< in: timestamp of the stat */ - const char* stat_name, /*!< in: name of the stat */ - ib_uint64_t stat_value, /*!< in: value of the stat */ - ib_uint64_t* sample_size, /*!< in: n pages sampled or NULL */ - const char* stat_description)/*!< in: description of the stat */ + dict_index_t* index, + lint last_update, + const char* stat_name, + ib_uint64_t stat_value, + ib_uint64_t* sample_size, + const char* stat_description, + trx_t* trx) { pars_info_t* pinfo; dberr_t ret; @@ -2158,7 +2198,7 @@ dict_stats_save_index_stat( ":sample_size,\n" ":stat_description\n" ");\n" - "END;"); + "END;", trx); if (ret != DB_SUCCESS) { char buf_table[MAX_FULL_NAME_LEN]; @@ -2241,7 +2281,7 @@ dict_stats_save( ":clustered_index_size,\n" ":sum_of_other_index_sizes\n" ");\n" - "END;"); + "END;", NULL); if (ret != DB_SUCCESS) { char buf[MAX_FULL_NAME_LEN]; @@ -2251,15 +2291,46 @@ dict_stats_save( "%s: %s\n", ut_format_name(table->name, TRUE, buf, sizeof(buf)), ut_strerr(ret)); - goto end; + + mutex_exit(&dict_sys->mutex); + rw_lock_x_unlock(&dict_operation_lock); + + dict_stats_snapshot_free(table); + + return(ret); } + trx_t* trx = trx_allocate_for_background(); + trx_start_if_not_started(trx); + dict_index_t* index; + index_map_t indexes; + + /* Below we do all the modifications in innodb_index_stats in a single + transaction for performance reasons. Modifying more than one row in a + single transaction may deadlock with other transactions if they + lock the rows in different order. Other transaction could be for + example when we DROP a table and do + DELETE FROM innodb_index_stats WHERE database_name = '...' + AND table_name = '...'; which will affect more than one row. To + prevent deadlocks we always lock the rows in the same order - the + order of the PK, which is (database_name, table_name, index_name, + stat_name). This is why below we sort the indexes by name and then + for each index, do the mods ordered by stat_name. */ for (index = dict_table_get_first_index(table); index != NULL; index = dict_table_get_next_index(index)) { + indexes[index->name] = index; + } + + index_map_t::const_iterator it; + + for (it = indexes.begin(); it != indexes.end(); ++it) { + + index = it->second; + if (only_for_index != NULL && index->id != *only_for_index) { continue; } @@ -2270,24 +2341,6 @@ dict_stats_save( ut_ad(!dict_index_is_univ(index)); - ret = dict_stats_save_index_stat(index, now, "size", - index->stat_index_size, - NULL, - "Number of pages " - "in the index"); - if (ret != DB_SUCCESS) { - goto end; - } - - ret = dict_stats_save_index_stat(index, now, "n_leaf_pages", - index->stat_n_leaf_pages, - NULL, - "Number of leaf pages " - "in the index"); - if (ret != DB_SUCCESS) { - goto end; - } - for (ulint i = 0; i < index->n_uniq; i++) { char stat_name[16]; @@ -2315,15 +2368,37 @@ dict_stats_save( index, now, stat_name, index->stat_n_diff_key_vals[i], &index->stat_n_sample_sizes[i], - stat_description); + stat_description, trx); if (ret != DB_SUCCESS) { goto end; } } + + ret = dict_stats_save_index_stat(index, now, "n_leaf_pages", + index->stat_n_leaf_pages, + NULL, + "Number of leaf pages " + "in the index", trx); + if (ret != DB_SUCCESS) { + goto end; + } + + ret = dict_stats_save_index_stat(index, now, "size", + index->stat_index_size, + NULL, + "Number of pages " + "in the index", trx); + if (ret != DB_SUCCESS) { + goto end; + } } + trx_commit_for_mysql(trx); + end: + trx_free_for_background(trx); + mutex_exit(&dict_sys->mutex); rw_lock_x_unlock(&dict_operation_lock); @@ -3138,7 +3213,7 @@ dict_stats_drop_index( "database_name = :database_name AND\n" "table_name = :table_name AND\n" "index_name = :index_name;\n" - "END;\n"); + "END;\n", NULL); mutex_exit(&dict_sys->mutex); rw_lock_x_unlock(&dict_operation_lock); @@ -3206,7 +3281,7 @@ dict_stats_delete_from_table_stats( "DELETE FROM \"" TABLE_STATS_NAME "\" WHERE\n" "database_name = :database_name AND\n" "table_name = :table_name;\n" - "END;\n"); + "END;\n", NULL); return(ret); } @@ -3244,7 +3319,7 @@ dict_stats_delete_from_index_stats( "DELETE FROM \"" INDEX_STATS_NAME "\" WHERE\n" "database_name = :database_name AND\n" "table_name = :table_name;\n" - "END;\n"); + "END;\n", NULL); return(ret); } @@ -3367,7 +3442,7 @@ dict_stats_rename_in_table_stats( "WHERE\n" "database_name = :old_dbname_utf8 AND\n" "table_name = :old_tablename_utf8;\n" - "END;\n"); + "END;\n", NULL); return(ret); } @@ -3413,7 +3488,7 @@ dict_stats_rename_in_index_stats( "WHERE\n" "database_name = :old_dbname_utf8 AND\n" "table_name = :old_tablename_utf8;\n" - "END;\n"); + "END;\n", NULL); return(ret); } diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index ee3c3943ab8..486a931242b 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2014, 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 @@ -3625,17 +3625,6 @@ fil_report_bad_tablespace( (ulong) expected_id, (ulong) expected_flags); } -struct fsp_open_info { - ibool success; /*!< Has the tablespace been opened? */ - const char* check_msg; /*!< fil_check_first_page() message */ - ibool valid; /*!< Is the tablespace valid? */ - os_file_t file; /*!< File handle */ - char* filepath; /*!< File path to open */ - lsn_t lsn; /*!< Flushed LSN from header page */ - ulint id; /*!< Space ID */ - ulint flags; /*!< Tablespace flags */ -}; - /********************************************************************//** Tries to open a single-table tablespace and optionally checks that the space id in it is correct. If this does not succeed, print an error message @@ -4117,8 +4106,7 @@ fil_user_tablespace_find_space_id( ut_free(buf); ib_logf(IB_LOG_LEVEL_INFO, "Page size: %lu, Possible space_id " - "count:" UINT64PF, page_size, - static_cast<ib_uint64_t>(verify.size())); + "count:%lu", page_size, (ulint) verify.size()); const ulint pages_corrupted = 3; for (ulint missed = 0; missed <= pages_corrupted; ++missed) { @@ -4148,53 +4136,53 @@ fil_user_tablespace_find_space_id( } /*******************************************************************//** -Finds the page 0 of the given space id from the double write buffer, and -copies it to the corresponding .ibd file. +Finds the given page_no of the given space id from the double write buffer, +and copies it to the corresponding .ibd file. @return true if copy was successful, or false. */ -static bool -fil_user_tablespace_restore_page0( +fil_user_tablespace_restore_page( /*==============================*/ - fsp_open_info* fsp) /* in: contains space id and .ibd file - information */ + fsp_open_info* fsp, /* in: contains space id and .ibd + file information */ + ulint page_no) /* in: page_no to obtain from double + write buffer */ { bool err; ulint flags; ulint zip_size; - ulint page_no; ulint page_size; ulint buflen; byte* page; - ib_logf(IB_LOG_LEVEL_INFO, "Restoring first page of tablespace %lu", - fsp->id); + ib_logf(IB_LOG_LEVEL_INFO, "Restoring page %lu of tablespace %lu", + page_no, fsp->id); - if (fsp->id == 0) { - err = false; - goto out; - } - - // find if double write buffer has page0 of given space id - page = recv_sys->dblwr.find_first_page(fsp->id); + // find if double write buffer has page_no of given space id + page = recv_sys->dblwr.find_page(fsp->id, page_no); if (!page) { + ib_logf(IB_LOG_LEVEL_WARN, "Doublewrite does not have " + "page_no=%lu of space: %lu", page_no, fsp->id); err = false; goto out; } flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page); zip_size = fsp_flags_get_zip_size(flags); - page_no = page_get_page_no(page); page_size = fsp_flags_get_page_size(flags); - ut_ad(page_no == 0); + ut_ad(page_no == page_get_page_no(page)); buflen = zip_size ? zip_size: page_size; ib_logf(IB_LOG_LEVEL_INFO, "Writing %lu bytes into file: %s", buflen, fsp->filepath); - err = os_file_write(fsp->filepath, fsp->file, page, 0, buflen); + err = os_file_write(fsp->filepath, fsp->file, page, + (zip_size ? zip_size : page_size) * page_no, + buflen); + + os_file_flush(fsp->file); out: return(err); } @@ -4229,7 +4217,9 @@ check_first_page: return; } restore_attempted = true; - if (!fil_user_tablespace_restore_page0(fsp)) { + + if (fsp->id > 0 + && !fil_user_tablespace_restore_page(fsp, 0)) { return; } goto check_first_page; diff --git a/storage/xtradb/fts/fts0blex.cc b/storage/xtradb/fts/fts0blex.cc index 6082261e74c..f83523825d2 100644 --- a/storage/xtradb/fts/fts0blex.cc +++ b/storage/xtradb/fts/fts0blex.cc @@ -35,7 +35,7 @@ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. + * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 @@ -52,7 +52,7 @@ typedef uint32_t flex_uint32_t; typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; +typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; @@ -184,15 +184,15 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE; #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 - #define YY_LESS_LINENO(n) - +#define YY_LESS_LINENO(n) + /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = yyg->yy_hold_char; \ YY_RESTORE_YY_MORE_OFFSET \ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ @@ -245,9 +245,9 @@ struct yy_buffer_state */ int yy_at_bol; - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + /* Whether to try to fill the input buffer when we reach the * end of it. */ @@ -314,9 +314,9 @@ void fts0bfree (void * , yyscan_t yyscanner __attribute__((unused)) __ #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ - fts0bensure_buffer_stack (yyscanner); \ + fts0bensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ - fts0b_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ + fts0b_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } @@ -324,9 +324,9 @@ void fts0bfree (void * , yyscan_t yyscanner __attribute__((unused)) __ #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ - fts0bensure_buffer_stack (yyscanner); \ + fts0bensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ - fts0b_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ + fts0b_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } @@ -354,7 +354,7 @@ static void yy_fatal_error (yyconst char msg[] , yyscan_t yyscanner __ */ #define YY_DO_BEFORE_ACTION \ yyg->yytext_ptr = yy_bp; \ - yyleng = (size_t) (yy_cp - yy_bp); \ + yyleng = static_cast<int>(yy_cp - yy_bp); \ yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; @@ -499,37 +499,37 @@ this program; if not, write to the Free Software Foundation, Inc., /* Holds the entire state of the reentrant scanner. */ struct yyguts_t - { - - /* User-defined. Not touched by flex. */ - YY_EXTRA_TYPE yyextra_r; - - /* The rest are the same as the globals declared in the non-reentrant scanner. */ - FILE *yyin_r, *yyout_r; - size_t yy_buffer_stack_top; /**< index of top of stack. */ - size_t yy_buffer_stack_max; /**< capacity of stack. */ - YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ - char yy_hold_char; - int yy_n_chars; - int yyleng_r; - char *yy_c_buf_p; - int yy_init; - int yy_start; - int yy_did_buffer_switch_on_eof; - int yy_start_stack_ptr; - int yy_start_stack_depth; - int *yy_start_stack; - yy_state_type yy_last_accepting_state; - char* yy_last_accepting_cpos; - - int yylineno_r; - int yy_flex_debug_r; - - char *yytext_r; - int yy_more_flag; - int yy_more_len; - - }; /* end struct yyguts_t */ +{ + + /* User-defined. Not touched by flex. */ + YY_EXTRA_TYPE yyextra_r; + + /* The rest are the same as the globals declared in the non-reentrant scanner. */ + FILE *yyin_r, *yyout_r; + size_t yy_buffer_stack_top; /**< index of top of stack. */ + size_t yy_buffer_stack_max; /**< capacity of stack. */ + YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ + char yy_hold_char; + int yy_n_chars; + int yyleng_r; + char *yy_c_buf_p; + int yy_init; + int yy_start; + int yy_did_buffer_switch_on_eof; + int yy_start_stack_ptr; + int yy_start_stack_depth; + int *yy_start_stack; + yy_state_type yy_last_accepting_state; + char* yy_last_accepting_cpos; + + int yylineno_r; + int yy_flex_debug_r; + + char *yytext_r; + int yy_more_flag; + int yy_more_len; + +}; /* end struct yyguts_t */ static int yy_init_globals (yyscan_t yyscanner ); @@ -622,8 +622,8 @@ static int input (yyscan_t yyscanner ); if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ - size_t n; \ - for ( n = 0; n < max_size && \ + int n; \ + for ( n = 0; n < static_cast<int>(max_size) && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ @@ -635,7 +635,8 @@ static int input (yyscan_t yyscanner ); else \ { \ errno=0; \ - while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + while ( (result = static_cast<int>(fread(buf, 1, max_size, yyin))) \ + == 0 && ferror(yyin) ) \ { \ if( errno != EINTR) \ { \ @@ -703,12 +704,12 @@ YY_DECL register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; #line 43 "fts0blex.l" -#line 711 "fts0blex.cc" +#line 712 "fts0blex.cc" if ( !yyg->yy_init ) { @@ -839,7 +840,7 @@ YY_RULE_SETUP #line 73 "fts0blex.l" ECHO; YY_BREAK -#line 842 "fts0blex.cc" +#line 843 "fts0blex.cc" case YY_STATE_EOF(INITIAL): yyterminate(); @@ -982,7 +983,7 @@ case YY_STATE_EOF(INITIAL): */ static int yy_get_next_buffer (yyscan_t yyscanner) { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = yyg->yytext_ptr; register int number_to_move, i; @@ -1027,8 +1028,8 @@ static int yy_get_next_buffer (yyscan_t yyscanner) else { - int num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + int num_to_read = static_cast<int>( + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1); while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ @@ -1041,7 +1042,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) if ( b->yy_is_our_buffer ) { - int new_size = b->yy_buf_size * 2; + int new_size = static_cast<int>(b->yy_buf_size * 2); if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; @@ -1062,8 +1063,8 @@ static int yy_get_next_buffer (yyscan_t yyscanner) yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; + num_to_read = static_cast<int>( + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1); } @@ -1072,7 +1073,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - yyg->yy_n_chars, (size_t) num_to_read ); + yyg->yy_n_chars, num_to_read); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } @@ -1115,11 +1116,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) /* yy_get_previous_state - get the state just before the EOB char was reached */ - static yy_state_type yy_get_previous_state (yyscan_t yyscanner) +static yy_state_type yy_get_previous_state (yyscan_t yyscanner) { register yy_state_type yy_current_state; register char *yy_cp; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_current_state = yyg->yy_start; @@ -1148,10 +1149,10 @@ static int yy_get_next_buffer (yyscan_t yyscanner) * synopsis * next_state = yy_try_NUL_trans( current_state ); */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) +static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) { register int yy_is_jam; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ register char *yy_cp = yyg->yy_c_buf_p; register YY_CHAR yy_c = 1; @@ -1174,14 +1175,14 @@ static int yy_get_next_buffer (yyscan_t yyscanner) #ifndef YY_NO_INPUT #ifdef __cplusplus - static int yyinput (yyscan_t yyscanner) + static int yyinput (yyscan_t yyscanner) #else - static int input (yyscan_t yyscanner) + static int input (yyscan_t yyscanner) #endif { int c; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; *yyg->yy_c_buf_p = yyg->yy_hold_char; @@ -1252,14 +1253,14 @@ static int yy_get_next_buffer (yyscan_t yyscanner) * @param yyscanner The scanner object. * @note This function does not reset the start condition to @c INITIAL . */ - void fts0brestart (FILE * input_file , yyscan_t yyscanner) +void fts0brestart (FILE * input_file , yyscan_t yyscanner) { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! YY_CURRENT_BUFFER ){ - fts0bensure_buffer_stack (yyscanner); + fts0bensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = - fts0b_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + fts0b_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); } fts0b_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); @@ -1270,15 +1271,15 @@ static int yy_get_next_buffer (yyscan_t yyscanner) * @param new_buffer The new input buffer. * @param yyscanner The scanner object. */ - void fts0b_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) +void fts0b_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* TODO. We should be able to replace this entire function body * with * fts0bpop_buffer_state(); * fts0bpush_buffer_state(new_buffer); - */ + */ fts0bensure_buffer_stack (yyscanner); if ( YY_CURRENT_BUFFER == new_buffer ) return; @@ -1304,7 +1305,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) static void fts0b_load_buffer_state (yyscan_t yyscanner) { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; @@ -1317,10 +1318,10 @@ static void fts0b_load_buffer_state (yyscan_t yyscanner) * @param yyscanner The scanner object. * @return the allocated buffer state. */ - YY_BUFFER_STATE fts0b_create_buffer (FILE * file, int size , yyscan_t yyscanner) +YY_BUFFER_STATE fts0b_create_buffer (FILE * file, int size , yyscan_t yyscanner) { YY_BUFFER_STATE b; - + b = (YY_BUFFER_STATE) fts0balloc(sizeof( struct yy_buffer_state ) ,yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in fts0b_create_buffer()" ); @@ -1345,9 +1346,9 @@ static void fts0b_load_buffer_state (yyscan_t yyscanner) * @param b a buffer created with fts0b_create_buffer() * @param yyscanner The scanner object. */ - void fts0b_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) +void fts0b_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; @@ -1365,28 +1366,28 @@ static void fts0b_load_buffer_state (yyscan_t yyscanner) * This function is sometimes called more than once on the same buffer, * such as during a fts0brestart() or at EOF. */ - static void fts0b_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) +static void fts0b_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) { int oerrno = errno; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; fts0b_flush_buffer(b ,yyscanner); b->yy_input_file = file; b->yy_fill_buffer = 1; - /* If b is the current buffer, then fts0b_init_buffer was _probably_ - * called from fts0brestart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != YY_CURRENT_BUFFER){ - b->yy_bs_lineno = 1; - b->yy_bs_column = 0; - } - - b->yy_is_interactive = 0; - + /* If b is the current buffer, then fts0b_init_buffer was _probably_ + * called from fts0brestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = 0; + errno = oerrno; } @@ -1394,9 +1395,9 @@ static void fts0b_load_buffer_state (yyscan_t yyscanner) * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * @param yyscanner The scanner object. */ - void fts0b_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) +void fts0b_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; @@ -1426,7 +1427,7 @@ static void fts0b_load_buffer_state (yyscan_t yyscanner) */ void fts0bpush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (new_buffer == NULL) return; @@ -1457,7 +1458,7 @@ void fts0bpush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) */ void fts0bpop_buffer_state (yyscan_t yyscanner) { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!YY_CURRENT_BUFFER) return; @@ -1478,23 +1479,23 @@ void fts0bpop_buffer_state (yyscan_t yyscanner) static void fts0bensure_buffer_stack (yyscan_t yyscanner) { int num_to_alloc; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!yyg->yy_buffer_stack) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. - */ + */ num_to_alloc = 1; yyg->yy_buffer_stack = (struct yy_buffer_state**)fts0balloc (num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in fts0bensure_buffer_stack()" ); - + memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - + yyg->yy_buffer_stack_max = num_to_alloc; yyg->yy_buffer_stack_top = 0; return; @@ -1505,7 +1506,7 @@ static void fts0bensure_buffer_stack (yyscan_t yyscanner) /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; - num_to_alloc = yyg->yy_buffer_stack_max + grow_size; + num_to_alloc = static_cast<int>(yyg->yy_buffer_stack_max + grow_size); yyg->yy_buffer_stack = (struct yy_buffer_state**)fts0brealloc (yyg->yy_buffer_stack, num_to_alloc * sizeof(struct yy_buffer_state*) @@ -1523,12 +1524,12 @@ static void fts0bensure_buffer_stack (yyscan_t yyscanner) * @param base the character buffer * @param size the size in bytes of the character buffer * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. + * @return the newly allocated buffer state object. */ YY_BUFFER_STATE fts0b_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) { YY_BUFFER_STATE b; - + if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) @@ -1543,7 +1544,7 @@ YY_BUFFER_STATE fts0b_scan_buffer (char * base, yy_size_t size , yyscan_t yysc b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; + b->yy_n_chars = static_cast<int>(b->yy_buf_size); b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; @@ -1564,8 +1565,7 @@ YY_BUFFER_STATE fts0b_scan_buffer (char * base, yy_size_t size , yyscan_t yysc */ YY_BUFFER_STATE fts0b_scan_string (yyconst char * yystr , yyscan_t yyscanner) { - - return fts0b_scan_bytes(yystr,strlen(yystr) ,yyscanner); + return fts0b_scan_bytes(yystr,static_cast<int>(strlen(yystr)), yyscanner); } /** Setup the input buffer state to scan the given bytes. The next call to fts0blex() will @@ -1581,7 +1581,7 @@ YY_BUFFER_STATE fts0b_scan_bytes (yyconst char * yybytes, int _yybytes_len , y char *buf; yy_size_t n; int i; - + /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; buf = (char *) fts0balloc(n ,yyscanner ); @@ -1622,8 +1622,8 @@ static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner __ do \ { \ /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = yyg->yy_hold_char; \ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ yyg->yy_hold_char = *yyg->yy_c_buf_p; \ @@ -1639,8 +1639,8 @@ static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner __ */ YY_EXTRA_TYPE fts0bget_extra (yyscan_t yyscanner) { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyextra; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyextra; } /** Get the current line number. @@ -1648,12 +1648,12 @@ YY_EXTRA_TYPE fts0bget_extra (yyscan_t yyscanner) */ int fts0bget_lineno (yyscan_t yyscanner) { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yylineno; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (! YY_CURRENT_BUFFER) + return 0; + + return yylineno; } /** Get the current column number. @@ -1661,12 +1661,12 @@ int fts0bget_lineno (yyscan_t yyscanner) */ int fts0bget_column (yyscan_t yyscanner) { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yycolumn; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (! YY_CURRENT_BUFFER) + return 0; + + return yycolumn; } /** Get the input stream. @@ -1674,8 +1674,8 @@ int fts0bget_column (yyscan_t yyscanner) */ FILE *fts0bget_in (yyscan_t yyscanner) { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyin; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyin; } /** Get the output stream. @@ -1683,8 +1683,8 @@ FILE *fts0bget_in (yyscan_t yyscanner) */ FILE *fts0bget_out (yyscan_t yyscanner) { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyout; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyout; } /** Get the length of the current token. @@ -1692,8 +1692,8 @@ FILE *fts0bget_out (yyscan_t yyscanner) */ int fts0bget_leng (yyscan_t yyscanner) { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyleng; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyleng; } /** Get the current token. @@ -1702,8 +1702,8 @@ int fts0bget_leng (yyscan_t yyscanner) char *fts0bget_text (yyscan_t yyscanner) { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yytext; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yytext; } /** Set the user-defined data. This data is never touched by the scanner. @@ -1712,8 +1712,8 @@ char *fts0bget_text (yyscan_t yyscanner) */ void fts0bset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyextra = user_defined ; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyextra = user_defined ; } /** Set the current line number. @@ -1722,13 +1722,13 @@ void fts0bset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) */ void fts0bset_lineno (int line_number , yyscan_t yyscanner) { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* lineno is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + yy_fatal_error( "fts0bset_lineno called with no buffer" , yyscanner); - /* lineno is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "fts0bset_lineno called with no buffer" , yyscanner); - - yylineno = line_number; + yylineno = line_number; } /** Set the current column. @@ -1737,13 +1737,13 @@ void fts0bset_lineno (int line_number , yyscan_t yyscanner) */ void fts0bset_column (int column_no , yyscan_t yyscanner) { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - /* column is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "fts0bset_column called with no buffer" , yyscanner); - - yycolumn = column_no; + /* column is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + yy_fatal_error( "fts0bset_column called with no buffer" , yyscanner); + + yycolumn = column_no; } /** Set the input stream. This does not discard the current @@ -1754,26 +1754,26 @@ void fts0bset_column (int column_no , yyscan_t yyscanner) */ void fts0bset_in (FILE * in_str , yyscan_t yyscanner) { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyin = in_str ; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyin = in_str ; } void fts0bset_out (FILE * out_str , yyscan_t yyscanner) { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyout = out_str ; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyout = out_str ; } int fts0bget_debug (yyscan_t yyscanner) { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yy_flex_debug; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yy_flex_debug; } void fts0bset_debug (int bdebug , yyscan_t yyscanner) { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yy_flex_debug = bdebug ; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yy_flex_debug = bdebug ; } /* Accessor methods for yylval and yylloc */ @@ -1788,22 +1788,22 @@ void fts0bset_debug (int bdebug , yyscan_t yyscanner) int fts0blex_init(yyscan_t* ptr_yy_globals) { - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } + if (ptr_yy_globals == NULL){ + errno = EINVAL; + return 1; + } - *ptr_yy_globals = (yyscan_t) fts0balloc ( sizeof( struct yyguts_t ), NULL ); + *ptr_yy_globals = (yyscan_t) fts0balloc ( sizeof( struct yyguts_t ), NULL ); - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } + if (*ptr_yy_globals == NULL){ + errno = ENOMEM; + return 1; + } - /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); + /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ + memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - return yy_init_globals ( *ptr_yy_globals ); + return yy_init_globals ( *ptr_yy_globals ); } /* fts0blex_init_extra has the same functionality as fts0blex_init, but follows the @@ -1817,70 +1817,70 @@ int fts0blex_init(yyscan_t* ptr_yy_globals) int fts0blex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) { - struct yyguts_t dummy_yyguts; - - fts0bset_extra (yy_user_defined, &dummy_yyguts); - - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) fts0balloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in - yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - fts0bset_extra (yy_user_defined, *ptr_yy_globals); - - return yy_init_globals ( *ptr_yy_globals ); + struct yyguts_t dummy_yyguts; + + fts0bset_extra (yy_user_defined, &dummy_yyguts); + + if (ptr_yy_globals == NULL){ + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) fts0balloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); + + if (*ptr_yy_globals == NULL){ + errno = ENOMEM; + return 1; + } + + /* By setting to 0xAA, we expose bugs in + yy_init_globals. Leave at 0x00 for releases. */ + memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); + + fts0bset_extra (yy_user_defined, *ptr_yy_globals); + + return yy_init_globals ( *ptr_yy_globals ); } static int yy_init_globals (yyscan_t yyscanner) { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - /* Initialization is the same as for the non-reentrant scanner. - * This function is called from fts0blex_destroy(), so don't allocate here. - */ - - yyg->yy_buffer_stack = 0; - yyg->yy_buffer_stack_top = 0; - yyg->yy_buffer_stack_max = 0; - yyg->yy_c_buf_p = (char *) 0; - yyg->yy_init = 0; - yyg->yy_start = 0; - - yyg->yy_start_stack_ptr = 0; - yyg->yy_start_stack_depth = 0; - yyg->yy_start_stack = NULL; - -/* Defined in main.c */ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from fts0blex_destroy(), so don't allocate here. + */ + + yyg->yy_buffer_stack = 0; + yyg->yy_buffer_stack_top = 0; + yyg->yy_buffer_stack_max = 0; + yyg->yy_c_buf_p = (char *) 0; + yyg->yy_init = 0; + yyg->yy_start = 0; + + yyg->yy_start_stack_ptr = 0; + yyg->yy_start_stack_depth = 0; + yyg->yy_start_stack = NULL; + + /* Defined in main.c */ #ifdef YY_STDINIT - yyin = stdin; - yyout = stdout; + yyin = stdin; + yyout = stdout; #else - yyin = (FILE *) 0; - yyout = (FILE *) 0; + yyin = (FILE *) 0; + yyout = (FILE *) 0; #endif - /* For future reference: Set errno on error, since we are called by - * fts0blex_init() - */ - return 0; + /* For future reference: Set errno on error, since we are called by + * fts0blex_init() + */ + return 0; } /* fts0blex_destroy is for both reentrant and non-reentrant scanners. */ int fts0blex_destroy (yyscan_t yyscanner) { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - /* Pop the buffer stack, destroying each element. */ + /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ fts0b_delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); YY_CURRENT_BUFFER_LVALUE = NULL; @@ -1891,18 +1891,18 @@ int fts0blex_destroy (yyscan_t yyscanner) fts0bfree(yyg->yy_buffer_stack ,yyscanner); yyg->yy_buffer_stack = NULL; - /* Destroy the start condition stack. */ - fts0bfree(yyg->yy_start_stack ,yyscanner ); - yyg->yy_start_stack = NULL; + /* Destroy the start condition stack. */ + fts0bfree(yyg->yy_start_stack ,yyscanner ); + yyg->yy_start_stack = NULL; - /* Reset the globals. This is important in a non-reentrant scanner so the next time - * fts0blex() is called, initialization will occur. */ - yy_init_globals( yyscanner); + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * fts0blex() is called, initialization will occur. */ + yy_init_globals( yyscanner); - /* Destroy the main struct (reentrant only). */ - fts0bfree ( yyscanner , yyscanner ); - yyscanner = NULL; - return 0; + /* Destroy the main struct (reentrant only). */ + fts0bfree ( yyscanner , yyscanner ); + yyscanner = NULL; + return 0; } /* @@ -1955,5 +1955,3 @@ void fts0bfree (void * ptr , yyscan_t yyscanner __attribute__((unused #line 73 "fts0blex.l" - - diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc index 47deee8d8e6..795f08da966 100644 --- a/storage/xtradb/fts/fts0fts.cc +++ b/storage/xtradb/fts/fts0fts.cc @@ -6747,7 +6747,7 @@ fts_valid_stopword_table( return(innobase_get_fts_charset( static_cast<int>(col->prtype & DATA_MYSQL_TYPE_MASK), - static_cast<ulint>(dtype_get_charset_coll(col->prtype)))); + static_cast<uint>(dtype_get_charset_coll(col->prtype)))); } /**********************************************************************//** diff --git a/storage/xtradb/fts/fts0opt.cc b/storage/xtradb/fts/fts0opt.cc index 2efb5d05c21..a9f3a25530d 100644 --- a/storage/xtradb/fts/fts0opt.cc +++ b/storage/xtradb/fts/fts0opt.cc @@ -620,7 +620,7 @@ fts_zip_read_word( zip->zp->avail_in = FTS_MAX_WORD_LEN; } else { - zip->zp->avail_in = zip->block_sz; + zip->zp->avail_in = static_cast<uInt>(zip->block_sz); } ++zip->pos; @@ -721,7 +721,7 @@ fts_fetch_index_words( ib_vector_push(zip->blocks, &block); zip->zp->next_out = block; - zip->zp->avail_out = zip->block_sz; + zip->zp->avail_out = static_cast<uInt>(zip->block_sz); } switch (zip->status = deflate(zip->zp, Z_NO_FLUSH)) { @@ -1099,10 +1099,10 @@ fts_optimize_lookup( doc_id_t last_doc_id) /*!< in: doc id to lookup */ { int pos; - int upper = ib_vector_size(doc_ids); + int upper = static_cast<int>(ib_vector_size(doc_ids)); fts_update_t* array = (fts_update_t*) doc_ids->data; - pos = fts_bsearch(array, lower, upper, first_doc_id); + pos = fts_bsearch(array, static_cast<int>(lower), upper, first_doc_id); ut_a(abs(pos) <= upper + 1); diff --git a/storage/xtradb/fts/fts0pars.cc b/storage/xtradb/fts/fts0pars.cc index ef361b3c9c6..83d465b0988 100644 --- a/storage/xtradb/fts/fts0pars.cc +++ b/storage/xtradb/fts/fts0pars.cc @@ -1,19 +1,19 @@ /* A Bison parser, made by GNU Bison 2.5. */ /* Bison implementation for Yacc-like parsers in C - + Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. - + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ @@ -26,7 +26,7 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ @@ -1919,14 +1919,20 @@ fts_lexer_create( if (boolean_mode) { fts0blex_init(&fts_lexer->yyscanner); - fts0b_scan_bytes((char*) query, query_len, fts_lexer->yyscanner); - fts_lexer->scanner = (fts_scan) fts_blexer; + fts0b_scan_bytes( + reinterpret_cast<const char*>(query), + static_cast<int>(query_len), + fts_lexer->yyscanner); + fts_lexer->scanner = reinterpret_cast<fts_scan>(fts_blexer); /* FIXME: Debugging */ /* fts0bset_debug(1 , fts_lexer->yyscanner); */ } else { fts0tlex_init(&fts_lexer->yyscanner); - fts0t_scan_bytes((char*) query, query_len, fts_lexer->yyscanner); - fts_lexer->scanner = (fts_scan) fts_tlexer; + fts0t_scan_bytes( + reinterpret_cast<const char*>(query), + static_cast<int>(query_len), + fts_lexer->yyscanner); + fts_lexer->scanner = reinterpret_cast<fts_scan>(fts_tlexer); } return(fts_lexer); diff --git a/storage/xtradb/fts/fts0que.cc b/storage/xtradb/fts/fts0que.cc index 189c43768cd..c5c5f954789 100644 --- a/storage/xtradb/fts/fts0que.cc +++ b/storage/xtradb/fts/fts0que.cc @@ -47,9 +47,7 @@ Completed 2011/7/10 Sunny and Jimmy Yang #define RANK_DOWNGRADE (-1.0F) #define RANK_UPGRADE (1.0F) -/* Maximum number of words supported in a proximity search. -FIXME, this limitation can be removed easily. Need to see -if we want to enforce such limitation */ +/* Maximum number of words supported in a phrase or proximity search. */ #define MAX_PROXIMITY_ITEM 128 /* Memory used by rbt itself for create and node add */ @@ -183,6 +181,8 @@ struct fts_select_t { the FTS index */ }; +typedef std::vector<ulint> pos_vector_t; + /** structure defines a set of ranges for original documents, each of which has a minimum position and maximum position. Text in such range should contain all words in the proximity search. We will need to count the @@ -192,9 +192,9 @@ struct fts_proximity_t { ulint n_pos; /*!< number of position set, defines a range (min to max) containing all matching words */ - ulint* min_pos; /*!< the minimum position (in bytes) + pos_vector_t min_pos; /*!< the minimum position (in bytes) of the range */ - ulint* max_pos; /*!< the maximum position (in bytes) + pos_vector_t max_pos; /*!< the maximum position (in bytes) of the range */ }; @@ -758,7 +758,7 @@ fts_query_union_doc_id( fts_update_t* array = (fts_update_t*) query->deleted->doc_ids->data; /* Check if the doc id is deleted and it's not already in our set. */ - if (fts_bsearch(array, 0, size, doc_id) < 0 + if (fts_bsearch(array, 0, static_cast<int>(size), doc_id) < 0 && rbt_search(query->doc_ids, &parent, &doc_id) != 0) { fts_ranking_t ranking; @@ -789,7 +789,7 @@ fts_query_remove_doc_id( fts_update_t* array = (fts_update_t*) query->deleted->doc_ids->data; /* Check if the doc id is deleted and it's in our set. */ - if (fts_bsearch(array, 0, size, doc_id) < 0 + if (fts_bsearch(array, 0, static_cast<int>(size), doc_id) < 0 && rbt_search(query->doc_ids, &parent, &doc_id) == 0) { ut_free(rbt_remove_node(query->doc_ids, parent.last)); @@ -819,7 +819,7 @@ fts_query_change_ranking( fts_update_t* array = (fts_update_t*) query->deleted->doc_ids->data; /* Check if the doc id is deleted and it's in our set. */ - if (fts_bsearch(array, 0, size, doc_id) < 0 + if (fts_bsearch(array, 0, static_cast<int>(size), doc_id) < 0 && rbt_search(query->doc_ids, &parent, &doc_id) == 0) { fts_ranking_t* ranking; @@ -865,7 +865,7 @@ fts_query_intersect_doc_id( if it matches 'b' and it's in doc_ids.(multi_exist = true). */ /* Check if the doc id is deleted and it's in our set */ - if (fts_bsearch(array, 0, size, doc_id) < 0) { + if (fts_bsearch(array, 0, static_cast<int>(size), doc_id) < 0) { fts_ranking_t new_ranking; if (rbt_search(query->doc_ids, &parent, &doc_id) != 0) { @@ -1705,6 +1705,9 @@ fts_proximity_is_word_in_range( { fts_proximity_t* proximity_pos = phrase->proximity_pos; + ut_ad(proximity_pos->n_pos == proximity_pos->min_pos.size()); + ut_ad(proximity_pos->n_pos == proximity_pos->max_pos.size()); + /* Search each matched position pair (with min and max positions) and count the number of words in the range */ for (ulint i = 0; i < proximity_pos->n_pos; i++) { @@ -1922,6 +1925,7 @@ fts_query_fetch_document( if (cur_len != UNIV_SQL_NULL && cur_len != 0) { if (phrase->proximity_pos) { + ut_ad(prev_len + cur_len <= total_len); memcpy(document_text + prev_len, data, cur_len); } else { /* For phrase search */ @@ -1932,17 +1936,18 @@ fts_query_fetch_document( cur_len, prev_len, phrase->heap); } + + /* Document positions are calculated from the beginning + of the first field, need to save the length for each + searched field to adjust the doc position when search + phrases. */ + prev_len += cur_len + 1; } if (phrase->found) { break; } - /* Document positions are calculated from the beginning - of the first field, need to save the length for each - searched field to adjust the doc position when search - phrases. */ - prev_len += cur_len + 1; exp = que_node_get_next(exp); } @@ -2588,6 +2593,11 @@ fts_query_phrase_search( } num_token = ib_vector_size(tokens); + if (num_token > MAX_PROXIMITY_ITEM) { + query->error = DB_FTS_TOO_MANY_WORDS_IN_PHRASE; + goto func_exit; + } + ut_ad(ib_vector_size(orig_tokens) >= num_token); /* Ignore empty strings. */ @@ -2613,7 +2623,7 @@ fts_query_phrase_search( heap_alloc, sizeof(fts_match_t), 64); } else { - ut_a(num_token < MAX_PROXIMITY_ITEM); + ut_a(num_token <= MAX_PROXIMITY_ITEM); query->match_array = (ib_vector_t**) mem_heap_alloc( heap, @@ -3497,14 +3507,14 @@ fts_query_prepare_result( doc_freq = rbt_value(fts_doc_freq_t, node); /* Don't put deleted docs into result */ - if (fts_bsearch(array, 0, size, doc_freq->doc_id) + if (fts_bsearch(array, 0, static_cast<int>(size), doc_freq->doc_id) >= 0) { continue; } ranking.doc_id = doc_freq->doc_id; - ranking.rank = doc_freq->freq * word_freq->idf - * word_freq->idf; + ranking.rank = static_cast<fts_rank_t>( + doc_freq->freq * word_freq->idf * word_freq->idf); ranking.words = NULL; fts_query_add_ranking(query, result->rankings_by_id, @@ -4236,10 +4246,6 @@ fts_phrase_or_proximity_search( ulint j; ulint k = 0; fts_proximity_t qualified_pos; - ulint qualified_pos_buf[MAX_PROXIMITY_ITEM * 2]; - - qualified_pos.min_pos = &qualified_pos_buf[0]; - qualified_pos.max_pos = &qualified_pos_buf[MAX_PROXIMITY_ITEM]; match[0] = static_cast<fts_match_t*>( ib_vector_get(query->match_array[0], i)); @@ -4371,7 +4377,7 @@ fts_proximity_get_positions( qualified_pos->n_pos = 0; - ut_a(num_match < MAX_PROXIMITY_ITEM); + ut_a(num_match <= MAX_PROXIMITY_ITEM); /* Each word could appear multiple times in a doc. So we need to walk through each word's position list, and find @@ -4426,8 +4432,8 @@ fts_proximity_get_positions( length encoding, record the min_pos and max_pos, we will need to verify the actual number of characters */ - qualified_pos->min_pos[qualified_pos->n_pos] = min_pos; - qualified_pos->max_pos[qualified_pos->n_pos] = max_pos; + qualified_pos->min_pos.push_back(min_pos); + qualified_pos->max_pos.push_back(max_pos); qualified_pos->n_pos++; } @@ -4436,7 +4442,5 @@ fts_proximity_get_positions( idx[min_idx]++; } - ut_ad(qualified_pos->n_pos <= MAX_PROXIMITY_ITEM); - return(qualified_pos->n_pos != 0); } diff --git a/storage/xtradb/fts/fts0sql.cc b/storage/xtradb/fts/fts0sql.cc index 14bc3ec44c9..cb8eff3cacc 100644 --- a/storage/xtradb/fts/fts0sql.cc +++ b/storage/xtradb/fts/fts0sql.cc @@ -117,7 +117,7 @@ fts_get_table_name_prefix( if (slash) { /* Print up to and including the separator. */ - dbname_len = (slash - fts_table->parent) + 1; + dbname_len = static_cast<int>(slash - fts_table->parent) + 1; } len = fts_get_table_id(fts_table, table_id); @@ -152,7 +152,8 @@ fts_get_table_name( prefix_name = fts_get_table_name_prefix(fts_table); - name_len = strlen(prefix_name) + 1 + strlen(fts_table->suffix) + 1; + name_len = static_cast<int>( + strlen(prefix_name) + 1 + strlen(fts_table->suffix) + 1); name = static_cast<char*>(mem_alloc(name_len)); diff --git a/storage/xtradb/fts/fts0tlex.cc b/storage/xtradb/fts/fts0tlex.cc index f78456d8795..ef17ab1acf2 100644 --- a/storage/xtradb/fts/fts0tlex.cc +++ b/storage/xtradb/fts/fts0tlex.cc @@ -35,7 +35,7 @@ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. + * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 @@ -52,7 +52,7 @@ typedef uint32_t flex_uint32_t; typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; +typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; @@ -185,7 +185,7 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE; #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) - + /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ @@ -247,7 +247,7 @@ struct yy_buffer_state int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ - + /* Whether to try to fill the input buffer when we reach the * end of it. */ @@ -354,7 +354,7 @@ static void yy_fatal_error (yyconst char msg[] , yyscan_t yyscanner __ */ #define YY_DO_BEFORE_ACTION \ yyg->yytext_ptr = yy_bp; \ - yyleng = (size_t) (yy_cp - yy_bp); \ + yyleng = static_cast<int>(yy_cp - yy_bp); \ yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; @@ -618,8 +618,8 @@ static int input (yyscan_t yyscanner ); if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ - size_t n; \ - for ( n = 0; n < max_size && \ + int n; \ + for ( n = 0; n < static_cast<int>(max_size) && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ @@ -631,7 +631,8 @@ static int input (yyscan_t yyscanner ); else \ { \ errno=0; \ - while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + while ( (result = static_cast<int>(fread(buf, 1, max_size, yyin)))==0 \ + && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ @@ -1019,8 +1020,8 @@ static int yy_get_next_buffer (yyscan_t yyscanner) else { - int num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + int num_to_read =static_cast<int>( + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1); while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ @@ -1033,7 +1034,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) if ( b->yy_is_our_buffer ) { - int new_size = b->yy_buf_size * 2; + int new_size = static_cast<int>(b->yy_buf_size * 2); if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; @@ -1054,8 +1055,8 @@ static int yy_get_next_buffer (yyscan_t yyscanner) yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; + num_to_read = static_cast<int>( + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1); } @@ -1064,7 +1065,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - yyg->yy_n_chars, (size_t) num_to_read ); + yyg->yy_n_chars, num_to_read); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } @@ -1312,7 +1313,7 @@ static void fts0t_load_buffer_state (yyscan_t yyscanner) YY_BUFFER_STATE fts0t_create_buffer (FILE * file, int size , yyscan_t yyscanner) { YY_BUFFER_STATE b; - + b = (YY_BUFFER_STATE) fts0talloc(sizeof( struct yy_buffer_state ) ,yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in fts0t_create_buffer()" ); @@ -1378,7 +1379,7 @@ static void fts0t_load_buffer_state (yyscan_t yyscanner) } b->yy_is_interactive = 0; - + errno = oerrno; } @@ -1484,9 +1485,9 @@ static void fts0tensure_buffer_stack (yyscan_t yyscanner) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in fts0tensure_buffer_stack()" ); - + memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - + yyg->yy_buffer_stack_max = num_to_alloc; yyg->yy_buffer_stack_top = 0; return; @@ -1497,7 +1498,7 @@ static void fts0tensure_buffer_stack (yyscan_t yyscanner) /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; - num_to_alloc = yyg->yy_buffer_stack_max + grow_size; + num_to_alloc = static_cast<int>(yyg->yy_buffer_stack_max + grow_size); yyg->yy_buffer_stack = (struct yy_buffer_state**)fts0trealloc (yyg->yy_buffer_stack, num_to_alloc * sizeof(struct yy_buffer_state*) @@ -1515,12 +1516,12 @@ static void fts0tensure_buffer_stack (yyscan_t yyscanner) * @param base the character buffer * @param size the size in bytes of the character buffer * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. + * @return the newly allocated buffer state object. */ YY_BUFFER_STATE fts0t_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) { YY_BUFFER_STATE b; - + if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) @@ -1535,7 +1536,7 @@ YY_BUFFER_STATE fts0t_scan_buffer (char * base, yy_size_t size , yyscan_t yysc b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; + b->yy_n_chars = static_cast<int>(b->yy_buf_size); b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; @@ -1556,8 +1557,8 @@ YY_BUFFER_STATE fts0t_scan_buffer (char * base, yy_size_t size , yyscan_t yysc */ YY_BUFFER_STATE fts0t_scan_string (yyconst char * yystr , yyscan_t yyscanner) { - - return fts0t_scan_bytes(yystr,strlen(yystr) ,yyscanner); + + return fts0t_scan_bytes(yystr,static_cast<int>(strlen(yystr)) ,yyscanner); } /** Setup the input buffer state to scan the given bytes. The next call to fts0tlex() will @@ -1573,7 +1574,7 @@ YY_BUFFER_STATE fts0t_scan_bytes (yyconst char * yybytes, int _yybytes_len , y char *buf; yy_size_t n; int i; - + /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; buf = (char *) fts0talloc(n ,yyscanner ); @@ -1641,10 +1642,10 @@ YY_EXTRA_TYPE fts0tget_extra (yyscan_t yyscanner) int fts0tget_lineno (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - + if (! YY_CURRENT_BUFFER) return 0; - + return yylineno; } @@ -1654,10 +1655,10 @@ int fts0tget_lineno (yyscan_t yyscanner) int fts0tget_column (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - + if (! YY_CURRENT_BUFFER) return 0; - + return yycolumn; } @@ -1718,8 +1719,8 @@ void fts0tset_lineno (int line_number , yyscan_t yyscanner) /* lineno is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "fts0tset_lineno called with no buffer" , yyscanner); - + yy_fatal_error( "fts0tset_lineno called with no buffer" , yyscanner); + yylineno = line_number; } @@ -1733,8 +1734,8 @@ void fts0tset_column (int column_no , yyscan_t yyscanner) /* column is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "fts0tset_column called with no buffer" , yyscanner); - + yy_fatal_error( "fts0tset_column called with no buffer" , yyscanner); + yycolumn = column_no; } @@ -1817,20 +1818,20 @@ int fts0tlex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) errno = EINVAL; return 1; } - + *ptr_yy_globals = (yyscan_t) fts0talloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); - + if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } - + /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - + fts0tset_extra (yy_user_defined, *ptr_yy_globals); - + return yy_init_globals ( *ptr_yy_globals ); } diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index b90806724fe..d5f0966cda8 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. +Copyright (c) 2000, 2014, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, 2009 Google Inc. Copyright (c) 2009, Percona Inc. Copyright (c) 2012, Facebook Inc. @@ -1817,6 +1817,8 @@ convert_error_code_to_mysql( return(HA_ERR_TABLESPACE_EXISTS); case DB_IDENTIFIER_TOO_LONG: return(HA_ERR_INTERNAL_ERROR); + case DB_FTS_TOO_MANY_WORDS_IN_PHRASE: + return(HA_ERR_FTS_TOO_MANY_WORDS_IN_PHRASE); } } @@ -1924,11 +1926,11 @@ innobase_check_identifier_length( CHARSET_INFO *cs = system_charset_info; DBUG_ENTER("innobase_check_identifier_length"); - uint res = cs->cset->well_formed_len(cs, id, id + strlen(id), - NAME_CHAR_LEN, - &well_formed_error); + size_t len = cs->cset->well_formed_len( + cs, id, id + strlen(id), + NAME_CHAR_LEN, &well_formed_error); - if (well_formed_error || res == NAME_CHAR_LEN) { + if (well_formed_error || len == NAME_CHAR_LEN) { my_error(ER_TOO_LONG_IDENT, MYF(0), id); DBUG_RETURN(true); } @@ -2783,7 +2785,7 @@ innobase_query_caching_of_table_permitted( store a result to the query cache or retrieve it */ char* full_name, /*!< in: normalized path to the table */ - uint full_name_len, /*!< in: length of the normalized path + uint full_name_len, /*!< in: length of the normalized path to the table */ ulonglong *unused) /*!< unused for this engine */ { @@ -3356,7 +3358,8 @@ innobase_init( internal_innobase_data_file_path); if (ret == FALSE) { sql_print_error( - "InnoDB: syntax error in innodb_data_file_path"); + "InnoDB: syntax error in innodb_data_file_path" + " or size specified is less than 1 megabyte"); mem_free_and_error: srv_free_paths_and_sizes(); my_free(internal_innobase_data_file_path); @@ -3508,8 +3511,8 @@ innobase_change_buffering_inited_ok: } else { /* The user has not set the value. We should set it based on innodb_io_capacity. */ - srv_max_io_capacity = - ut_max(2 * srv_io_capacity, 2000); + srv_max_io_capacity = static_cast<ulong>( + ut_max(2 * srv_io_capacity, 2000)); } } else if (srv_max_io_capacity < srv_io_capacity) { @@ -3761,8 +3764,8 @@ innobase_change_buffering_inited_ok: /* Adjust the innodb_undo_logs config object */ innobase_undo_logs_init_default_max(); - innobase_old_blocks_pct = buf_LRU_old_ratio_update( - innobase_old_blocks_pct, TRUE); + innobase_old_blocks_pct = static_cast<uint>( + buf_LRU_old_ratio_update(innobase_old_blocks_pct, TRUE)); ibuf_max_size_update(innobase_change_buffer_max_size); @@ -4480,8 +4483,8 @@ innobase_rollback_to_savepoint( /*****************************************************************//** Check whether innodb state allows to safely release MDL locks after -rollback to savepoint. -When binlog is on, MDL locks acquired after savepoint unit are not +rollback to savepoint. +When binlog is on, MDL locks acquired after savepoint unit are not released if there are any locks held in InnoDB. @return true if it is safe, false if its not safe. */ static @@ -5754,7 +5757,7 @@ table_opened: /* Find corresponding cluster index key length in MySQL's key_info[] array */ - for (ulint i = 0; i < table->s->keys; i++) { + for (uint i = 0; i < table->s->keys; i++) { dict_index_t* index; index = innobase_get_index(i); if (dict_index_is_clust(index)) { @@ -6120,8 +6123,9 @@ innobase_fts_text_cmp( const fts_string_t* s1 = (const fts_string_t*) p1; const fts_string_t* s2 = (const fts_string_t*) p2; - return(ha_compare_text(charset, s1->f_str, s1->f_len, - s2->f_str, s2->f_len, 0, 0)); + return(ha_compare_text( + charset, s1->f_str, static_cast<uint>(s1->f_len), + s2->f_str, static_cast<uint>(s2->f_len), 0, 0)); } /******************************************************************//** compare two character string case insensitively according to their charset. */ @@ -6142,8 +6146,9 @@ innobase_fts_text_case_cmp( newlen = strlen((const char*) s2->f_str); - return(ha_compare_text(charset, s1->f_str, s1->f_len, - s2->f_str, newlen, 0, 0)); + return(ha_compare_text( + charset, s1->f_str, static_cast<uint>(s1->f_len), + s2->f_str, static_cast<uint>(newlen), 0, 0)); } /******************************************************************//** Get the first character's code position for FTS index partition. */ @@ -6189,8 +6194,9 @@ innobase_fts_text_cmp_prefix( const fts_string_t* s2 = (const fts_string_t*) p2; int result; - result = ha_compare_text(charset, s2->f_str, s2->f_len, - s1->f_str, s1->f_len, 1, 0); + result = ha_compare_text( + charset, s2->f_str, static_cast<uint>(s2->f_len), + s1->f_str, static_cast<uint>(s1->f_len), 1, 0); /* We switched s1, s2 position in ha_compare_text. So we need to negate the result */ @@ -6760,8 +6766,8 @@ build_template_needs_field( return(field); } - if (bitmap_is_set(table->read_set, sql_idx) - || bitmap_is_set(table->write_set, sql_idx)) { + if (bitmap_is_set(table->read_set, static_cast<uint>(sql_idx)) + || bitmap_is_set(table->write_set, static_cast<uint>(sql_idx))) { /* This field is needed in the query */ return(field); @@ -9483,7 +9489,7 @@ create_table_def( /* we assume in dtype_form_prtype() that this fits in two bytes */ - ut_a(field->type() <= MAX_CHAR_COLL_NUM); + ut_a(static_cast<uint>(field->type()) <= MAX_CHAR_COLL_NUM); col_len = field->pack_length(); /* The MySQL pack length contains 1 or 2 bytes length field @@ -12564,12 +12570,14 @@ get_foreign_key_info( tmp_buff[len] = 0; len = filename_to_tablename(tmp_buff, name_buff, sizeof(name_buff)); - f_key_info.referenced_db = thd_make_lex_string(thd, 0, name_buff, len, 1); + f_key_info.referenced_db = thd_make_lex_string( + thd, 0, name_buff, static_cast<unsigned int>(len), 1); /* Referenced (parent) table name */ ptr = dict_remove_db_name(foreign->referenced_table_name); len = filename_to_tablename(ptr, name_buff, sizeof(name_buff)); - f_key_info.referenced_table = thd_make_lex_string(thd, 0, name_buff, len, 1); + f_key_info.referenced_table = thd_make_lex_string( + thd, 0, name_buff, static_cast<unsigned int>(len), 1); /* Dependent (child) database name */ len = dict_get_db_name_len(foreign->foreign_table_name); @@ -12578,12 +12586,14 @@ get_foreign_key_info( tmp_buff[len] = 0; len = filename_to_tablename(tmp_buff, name_buff, sizeof(name_buff)); - f_key_info.foreign_db = thd_make_lex_string(thd, 0, name_buff, len, 1); + f_key_info.foreign_db = thd_make_lex_string( + thd, 0, name_buff, static_cast<unsigned int>(len), 1); /* Dependent (child) table name */ ptr = dict_remove_db_name(foreign->foreign_table_name); len = filename_to_tablename(ptr, name_buff, sizeof(name_buff)); - f_key_info.foreign_table = thd_make_lex_string(thd, 0, name_buff, len, 1); + f_key_info.foreign_table = thd_make_lex_string( + thd, 0, name_buff, static_cast<unsigned int>(len), 1); do { ptr = foreign->foreign_col_names[i]; @@ -12610,9 +12620,9 @@ get_foreign_key_info( ptr = "RESTRICT"; } - f_key_info.delete_method = thd_make_lex_string(thd, - f_key_info.delete_method, - ptr, len, 1); + f_key_info.delete_method = thd_make_lex_string( + thd, f_key_info.delete_method, ptr, + static_cast<unsigned int>(len), 1); if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE) { len = 7; @@ -12628,9 +12638,9 @@ get_foreign_key_info( ptr = "RESTRICT"; } - f_key_info.update_method = thd_make_lex_string(thd, - f_key_info.update_method, - ptr, len, 1); + f_key_info.update_method = thd_make_lex_string( + thd, f_key_info.update_method, ptr, + static_cast<unsigned int>(len), 1); if (foreign->referenced_index && foreign->referenced_index->name) { referenced_key_name = thd_make_lex_string(thd, @@ -13431,7 +13441,8 @@ innodb_show_status( memcpy(str + len, truncated_msg, sizeof truncated_msg - 1); len += sizeof truncated_msg - 1; usable_len = (MAX_STATUS_SIZE - 1) - len; - fseek(srv_monitor_file, flen - usable_len, SEEK_SET); + fseek(srv_monitor_file, + static_cast<long>(flen - usable_len), SEEK_SET); len += fread(str + len, 1, usable_len, srv_monitor_file); flen = len; } else { @@ -13441,9 +13452,10 @@ innodb_show_status( mutex_exit(&srv_monitor_file_mutex); - ret_val= stat_print(thd, innobase_hton_name, - (uint) strlen(innobase_hton_name), - STRING_WITH_LEN(""), str, flen); + ret_val= stat_print( + thd, innobase_hton_name, + static_cast<uint>(strlen(innobase_hton_name)), + STRING_WITH_LEN(""), str, static_cast<uint>(flen)); my_free(str); @@ -13547,10 +13559,12 @@ innodb_mutex_show_status( continue; } - buf1len = my_snprintf(buf1, sizeof buf1, "%s", - lock->lock_name); - buf2len = my_snprintf(buf2, sizeof buf2, "os_waits=%lu", - (ulong) lock->count_os_wait); + buf1len = (uint) my_snprintf( + buf1, sizeof buf1, "%s", + lock->lock_name); + buf2len = (uint) my_snprintf( + buf2, sizeof buf2, "os_waits=%lu", + static_cast<ulong>(lock->count_os_wait)); if (stat_print(thd, innobase_hton_name, hton_name_len, buf1, buf1len, @@ -13579,7 +13593,7 @@ innodb_mutex_show_status( mutex_exit(&rw_lock_list_mutex); #ifdef UNIV_DEBUG - buf2len = my_snprintf(buf2, sizeof buf2, + buf2len = static_cast<uint>(my_snprintf(buf2, sizeof buf2, "count=%lu, spin_waits=%lu, spin_rounds=%lu, " "os_waits=%lu, os_yields=%lu, os_wait_times=%lu", (ulong) rw_lock_count, @@ -13587,7 +13601,7 @@ innodb_mutex_show_status( (ulong) rw_lock_count_spin_rounds, (ulong) rw_lock_count_os_wait, (ulong) rw_lock_count_os_yield, - (ulong) (rw_lock_wait_time / 1000)); + (ulong) (rw_lock_wait_time / 1000))); if (stat_print(thd, innobase_hton_name, hton_name_len, STRING_WITH_LEN("rw_lock_mutexes"), buf2, buf2len)) { @@ -14120,6 +14134,21 @@ ha_innobase::get_auto_increment( current = *first_value; + /* If the increment step of the auto increment column + decreases then it is not affecting the immediate + next value in the series. */ + if (prebuilt->autoinc_increment > increment) { + + current = autoinc - prebuilt->autoinc_increment; + + current = innobase_next_autoinc( + current, 1, increment, 1, col_max_value); + + dict_table_autoinc_initialize(prebuilt->table, current); + + *first_value = current; + } + /* Compute the last value in the interval */ next_value = innobase_next_autoinc( current, *nb_reserved_values, increment, offset, @@ -14339,7 +14368,7 @@ my_bool ha_innobase::register_query_cache_table( /*====================================*/ THD* thd, /*!< in: user thread handle */ - char* table_key, /*!< in: normalized path to the + char* table_key, /*!< in: normalized path to the table */ uint key_length, /*!< in: length of the normalized path to the table */ @@ -15337,8 +15366,9 @@ innodb_old_blocks_pct_update( const void* save) /*!< in: immediate result from check function */ { - innobase_old_blocks_pct = buf_LRU_old_ratio_update( - *static_cast<const uint*>(save), TRUE); + innobase_old_blocks_pct = static_cast<uint>( + buf_LRU_old_ratio_update( + *static_cast<const uint*>(save), TRUE)); } /****************************************************************//** @@ -15361,6 +15391,66 @@ innodb_change_buffer_max_size_update( ibuf_max_size_update(innobase_change_buffer_max_size); } +#ifdef UNIV_DEBUG +ulong srv_fil_make_page_dirty_debug = 0; +ulong srv_saved_page_number_debug = 0; + +/****************************************************************//** +Save an InnoDB page number. */ +static +void +innodb_save_page_no( +/*================*/ + 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 */ +{ + srv_saved_page_number_debug = *static_cast<const ulong*>(save); + + ib_logf(IB_LOG_LEVEL_INFO, + "Saving InnoDB page number: %lu", + srv_saved_page_number_debug); +} + +/****************************************************************//** +Make the first page of given user tablespace dirty. */ +static +void +innodb_make_page_dirty( +/*===================*/ + 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 */ +{ + mtr_t mtr; + ulong space_id = *static_cast<const ulong*>(save); + + mtr_start(&mtr); + + buf_block_t* block = buf_page_get( + space_id, 0, srv_saved_page_number_debug, RW_X_LATCH, &mtr); + + if (block) { + byte* page = block->frame; + ib_logf(IB_LOG_LEVEL_INFO, + "Dirtying page:%lu of space:%lu", + page_get_page_no(page), + page_get_space_id(page)); + mlog_write_ulint(page + FIL_PAGE_TYPE, + fil_page_get_type(page), + MLOG_2BYTES, &mtr); + } + mtr_commit(&mtr); +} +#endif // UNIV_DEBUG /*************************************************************//** Find the corresponding ibuf_use_t value that indexes into @@ -17453,7 +17543,7 @@ static MYSQL_SYSVAR_ULONG(ft_total_cache_size, fts_max_total_cache_size, static MYSQL_SYSVAR_ULONG(ft_result_cache_limit, fts_result_cache_limit, PLUGIN_VAR_RQCMDARG, "InnoDB Fulltext search query result cache limit in bytes", - NULL, NULL, 2000000000L, 1000000L, ~0UL, 0); + NULL, NULL, 2000000000L, 1000000L, 4294967295UL, 0); static MYSQL_SYSVAR_ULONG(ft_min_token_size, fts_min_token_size, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, @@ -17591,7 +17681,7 @@ static MYSQL_SYSVAR_ULONG(thread_sleep_delay, srv_thread_sleep_delay, NULL, NULL, 10000L, 0L, - ~0UL, 0); + 1000000L, 0); static MYSQL_SYSVAR_STR(data_file_path, innobase_data_file_path, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, @@ -17836,6 +17926,16 @@ static MYSQL_SYSVAR_BOOL(trx_purge_view_update_only_debug, "It is to create artificially the situation the purge view have been updated " "but the each purges were not done yet.", NULL, NULL, FALSE); + +static MYSQL_SYSVAR_ULONG(fil_make_page_dirty_debug, + srv_fil_make_page_dirty_debug, PLUGIN_VAR_OPCMDARG, + "Make the first page of the given tablespace dirty.", + NULL, innodb_make_page_dirty, 0, 0, UINT_MAX32, 0); + +static MYSQL_SYSVAR_ULONG(saved_page_number_debug, + srv_saved_page_number_debug, PLUGIN_VAR_OPCMDARG, + "An InnoDB page number.", + NULL, innodb_save_page_no, 0, 0, UINT_MAX32, 0); #endif /* UNIV_DEBUG */ const char *corrupt_table_action_names[]= @@ -18058,6 +18158,8 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(trx_rseg_n_slots_debug), MYSQL_SYSVAR(limit_optimistic_insert_debug), MYSQL_SYSVAR(trx_purge_view_update_only_debug), + MYSQL_SYSVAR(fil_make_page_dirty_debug), + MYSQL_SYSVAR(saved_page_number_debug), #endif /* UNIV_DEBUG */ MYSQL_SYSVAR(corrupt_table_action), MYSQL_SYSVAR(fake_changes), @@ -18146,7 +18248,7 @@ innobase_undo_logs_init_default_max() { MYSQL_SYSVAR_NAME(undo_logs).max_val = MYSQL_SYSVAR_NAME(undo_logs).def_val - = srv_available_undo_logs; + = static_cast<unsigned long>(srv_available_undo_logs); } #ifdef UNIV_COMPILE_TEST_FUNCS @@ -18485,7 +18587,8 @@ innobase_convert_to_filename_charset( CHARSET_INFO* cs_to = &my_charset_filename; CHARSET_INFO* cs_from = system_charset_info; - return(strconvert(cs_from, from, strlen(from), cs_to, to, len, &errors)); + return(strconvert(cs_from, from, strlen(from), cs_to, to, + static_cast<uint>(len), &errors)); } /********************************************************************** @@ -18502,7 +18605,8 @@ innobase_convert_to_system_charset( CHARSET_INFO* cs1 = &my_charset_filename; CHARSET_INFO* cs2 = system_charset_info; - return(strconvert(cs1, from, strlen(from), cs2, to, len, errors)); + return(strconvert(cs1, from, strlen(from), cs2, to, + static_cast<uint>(len), errors)); } diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index 13c6752ce8f..0ba299d6869 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2005, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2005, 2014, 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 @@ -65,6 +65,7 @@ static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ALTER_REBUILD | Alter_inplace_info::ALTER_COLUMN_ORDER | Alter_inplace_info::DROP_COLUMN | Alter_inplace_info::ADD_COLUMN + | Alter_inplace_info::RECREATE_TABLE /* | Alter_inplace_info::ALTER_COLUMN_TYPE | Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH @@ -898,7 +899,7 @@ innobase_get_foreign_key_info( /* Check whether there exist such index in the the index create clause */ if (!index && !innobase_find_equiv_index( - column_names, i, + column_names, static_cast<uint>(i), ha_alter_info->key_info_buffer, ha_alter_info->index_add_buffer, ha_alter_info->index_add_count)) { @@ -1005,6 +1006,12 @@ innobase_get_foreign_key_info( } referenced_num_col = i; + } else { + /* Not possible to add a foreign key without a + referenced column */ + mutex_exit(&dict_sys->mutex); + my_error(ER_CANNOT_ADD_FOREIGN, MYF(0), tbl_namep); + goto err_exit; } if (!innobase_init_foreign( @@ -1124,16 +1131,16 @@ innobase_col_to_mysql( /* These column types should never be shipped to MySQL. */ ut_ad(0); - case DATA_FIXBINARY: case DATA_FLOAT: case DATA_DOUBLE: case DATA_DECIMAL: /* Above are the valid column types for MySQL data. */ ut_ad(flen == len); /* fall through */ + case DATA_FIXBINARY: case DATA_CHAR: /* We may have flen > len when there is a shorter - prefix on a CHAR column. */ + prefix on the CHAR and BINARY column. */ ut_ad(flen >= len); #else /* UNIV_DEBUG */ default: diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc index 5603f8cfbe4..70819ba6395 100644 --- a/storage/xtradb/handler/i_s.cc +++ b/storage/xtradb/handler/i_s.cc @@ -283,7 +283,7 @@ field_store_string( if (str != NULL) { - ret = field->store(str, strlen(str), + ret = field->store(str, static_cast<uint>(strlen(str)), system_charset_info); field->set_notnull(); } else { @@ -320,11 +320,13 @@ field_store_index_name( char buf[NAME_LEN + 1]; buf[0] = '?'; memcpy(buf + 1, index_name + 1, strlen(index_name)); - ret = field->store(buf, strlen(buf), - system_charset_info); + ret = field->store( + buf, static_cast<uint>(strlen(buf)), + system_charset_info); } else { - ret = field->store(index_name, strlen(index_name), - system_charset_info); + ret = field->store( + index_name, static_cast<uint>(strlen(index_name)), + system_charset_info); } field->set_notnull(); @@ -347,7 +349,7 @@ field_store_ulint( if (n != ULINT_UNDEFINED) { - ret = field->store(n); + ret = field->store(static_cast<double>(n)); field->set_notnull(); } else { @@ -653,14 +655,15 @@ fill_innodb_trx_from_cache( /* trx_mysql_thread_id */ OK(fields[IDX_TRX_MYSQL_THREAD_ID]->store( - row->trx_mysql_thread_id)); + static_cast<double>(row->trx_mysql_thread_id))); /* trx_query */ if (row->trx_query) { /* store will do appropriate character set conversion check */ fields[IDX_TRX_QUERY]->store( - row->trx_query, strlen(row->trx_query), + row->trx_query, + static_cast<uint>(strlen(row->trx_query)), row->trx_query_cs); fields[IDX_TRX_QUERY]->set_notnull(); } else { @@ -705,11 +708,11 @@ fill_innodb_trx_from_cache( /* trx_unique_checks */ OK(fields[IDX_TRX_UNIQUE_CHECKS]->store( - row->trx_unique_checks)); + static_cast<double>(row->trx_unique_checks))); /* trx_foreign_key_checks */ OK(fields[IDX_TRX_FOREIGN_KEY_CHECKS]->store( - row->trx_foreign_key_checks)); + static_cast<double>(row->trx_foreign_key_checks))); /* trx_last_foreign_key_error */ OK(field_store_string(fields[IDX_TRX_LAST_FOREIGN_KEY_ERROR], @@ -717,7 +720,7 @@ fill_innodb_trx_from_cache( /* trx_adaptive_hash_latched */ OK(fields[IDX_TRX_ADAPTIVE_HASH_LATCHED]->store( - row->trx_has_search_latch)); + static_cast<double>(row->trx_has_search_latch))); /* trx_adaptive_hash_timeout */ OK(fields[IDX_TRX_ADAPTIVE_HASH_TIMEOUT]->store( @@ -725,11 +728,11 @@ fill_innodb_trx_from_cache( /* trx_is_read_only*/ OK(fields[IDX_TRX_READ_ONLY]->store( - (long) row->trx_is_read_only, true)); + (longlong) row->trx_is_read_only, true)); /* trx_is_autocommit_non_locking */ OK(fields[IDX_TRX_AUTOCOMMIT_NON_LOCKING]->store( - (long) row->trx_is_autocommit_non_locking, + (longlong) row->trx_is_autocommit_non_locking, true)); OK(schema_table_store_record(thd, table)); @@ -967,8 +970,9 @@ fill_innodb_locks_from_cache( row->lock_table, strlen(row->lock_table), thd, TRUE); - OK(fields[IDX_LOCK_TABLE]->store(buf, bufend - buf, - system_charset_info)); + OK(fields[IDX_LOCK_TABLE]->store( + buf, static_cast<uint>(bufend - buf), + system_charset_info)); /* lock_index */ if (row->lock_index != NULL) { @@ -1448,13 +1452,16 @@ i_s_cmp_fill_low( clear it. We could introduce mutex protection, but it could cause a measureable performance hit in page0zip.cc. */ - table->field[1]->store(zip_stat->compressed); - table->field[2]->store(zip_stat->compressed_ok); + table->field[1]->store( + static_cast<double>(zip_stat->compressed)); + table->field[2]->store( + static_cast<double>(zip_stat->compressed_ok)); table->field[3]->store( - (ulong) (zip_stat->compressed_usec / 1000000)); - table->field[4]->store(zip_stat->decompressed); + static_cast<double>(zip_stat->compressed_usec / 1000000)); + table->field[4]->store( + static_cast<double>(zip_stat->decompressed)); table->field[5]->store( - (ulong) (zip_stat->decompressed_usec / 1000000)); + static_cast<double>(zip_stat->decompressed_usec / 1000000)); if (reset) { memset(zip_stat, 0, sizeof *zip_stat); @@ -1777,19 +1784,19 @@ i_s_cmp_per_index_fill_low( } fields[IDX_COMPRESS_OPS]->store( - iter->second.compressed); + static_cast<double>(iter->second.compressed)); fields[IDX_COMPRESS_OPS_OK]->store( - iter->second.compressed_ok); + static_cast<double>(iter->second.compressed_ok)); fields[IDX_COMPRESS_TIME]->store( - (long) (iter->second.compressed_usec / 1000000)); + static_cast<double>(iter->second.compressed_usec / 1000000)); fields[IDX_UNCOMPRESS_OPS]->store( - iter->second.decompressed); + static_cast<double>(iter->second.decompressed)); fields[IDX_UNCOMPRESS_TIME]->store( - (long) (iter->second.decompressed_usec / 1000000)); + static_cast<double>(iter->second.decompressed_usec / 1000000)); if (schema_table_store_record(thd, table)) { status = 1; @@ -2072,15 +2079,17 @@ i_s_cmpmem_fill_low( buddy_stat = &buf_pool->buddy_stat[x]; table->field[0]->store(BUF_BUDDY_LOW << x); - table->field[1]->store(i); - table->field[2]->store(buddy_stat->used); - table->field[3]->store(UNIV_LIKELY(x < BUF_BUDDY_SIZES) + table->field[1]->store(static_cast<double>(i)); + table->field[2]->store(static_cast<double>( + buddy_stat->used)); + table->field[3]->store(static_cast<double>( + (x < BUF_BUDDY_SIZES) ? UT_LIST_GET_LEN(buf_pool->zip_free[x]) - : 0); + : 0)); table->field[4]->store( (longlong) buddy_stat->relocated, true); table->field[5]->store( - (ulong) (buddy_stat->relocated_usec / 1000000)); + static_cast<double>(buddy_stat->relocated_usec / 1000000)); if (reset) { /* This is protected by @@ -2627,8 +2636,8 @@ i_s_metrics_fill( if (time_diff) { OK(fields[METRIC_AVG_VALUE_RESET]->store( - (double )MONITOR_VALUE(count) - / time_diff)); + static_cast<double>( + MONITOR_VALUE(count) / time_diff))); fields[METRIC_AVG_VALUE_RESET]->set_notnull(); } else { fields[METRIC_AVG_VALUE_RESET]->set_null(); @@ -3253,9 +3262,11 @@ i_s_fts_index_cache_fill_one_index( if (index_charset->cset != system_charset_info->cset) { conv_str.f_n_char = my_convert( reinterpret_cast<char*>(conv_str.f_str), - conv_str.f_len, system_charset_info, + static_cast<uint32>(conv_str.f_len), + system_charset_info, reinterpret_cast<char*>(word->text.f_str), - word->text.f_len, index_charset, &dummy_errors); + static_cast<uint32>(word->text.f_len), + index_charset, &dummy_errors); ut_ad(conv_str.f_n_char <= conv_str.f_len); conv_str.f_str[conv_str.f_n_char] = 0; word_str = reinterpret_cast<char*>(conv_str.f_str); @@ -3296,13 +3307,13 @@ i_s_fts_index_cache_fill_one_index( true)); OK(fields[I_S_FTS_DOC_COUNT]->store( - node->doc_count)); + static_cast<double>(node->doc_count))); OK(fields[I_S_FTS_ILIST_DOC_ID]->store( (longlong) doc_id, true)); OK(fields[I_S_FTS_ILIST_DOC_POS]->store( - pos)); + static_cast<double>(pos))); OK(schema_table_store_record( thd, table)); @@ -3604,9 +3615,11 @@ i_s_fts_index_table_fill_one_fetch( if (index_charset->cset != system_charset_info->cset) { conv_str->f_n_char = my_convert( reinterpret_cast<char*>(conv_str->f_str), - conv_str->f_len, system_charset_info, + static_cast<uint32>(conv_str->f_len), + system_charset_info, reinterpret_cast<char*>(word->text.f_str), - word->text.f_len, index_charset, &dummy_errors); + static_cast<uint32>(word->text.f_len), + index_charset, &dummy_errors); ut_ad(conv_str->f_n_char <= conv_str->f_len); conv_str->f_str[conv_str->f_n_char] = 0; word_str = reinterpret_cast<char*>(conv_str->f_str); @@ -3648,13 +3661,13 @@ i_s_fts_index_table_fill_one_fetch( true)); OK(fields[I_S_FTS_DOC_COUNT]->store( - node->doc_count)); + static_cast<double>(node->doc_count))); OK(fields[I_S_FTS_ILIST_DOC_ID]->store( (longlong) doc_id, true)); OK(fields[I_S_FTS_ILIST_DOC_POS]->store( - pos)); + static_cast<double>(pos))); OK(schema_table_store_record( thd, table)); @@ -4376,31 +4389,41 @@ i_s_innodb_stats_fill( fields = table->field; - OK(fields[IDX_BUF_STATS_POOL_ID]->store(info->pool_unique_id)); + OK(fields[IDX_BUF_STATS_POOL_ID]->store( + static_cast<double>(info->pool_unique_id))); - OK(fields[IDX_BUF_STATS_POOL_SIZE]->store(info->pool_size)); + OK(fields[IDX_BUF_STATS_POOL_SIZE]->store( + static_cast<double>(info->pool_size))); - OK(fields[IDX_BUF_STATS_LRU_LEN]->store(info->lru_len)); + OK(fields[IDX_BUF_STATS_LRU_LEN]->store( + static_cast<double>(info->lru_len))); - OK(fields[IDX_BUF_STATS_OLD_LRU_LEN]->store(info->old_lru_len)); + OK(fields[IDX_BUF_STATS_OLD_LRU_LEN]->store( + static_cast<double>(info->old_lru_len))); - OK(fields[IDX_BUF_STATS_FREE_BUFFERS]->store(info->free_list_len)); + OK(fields[IDX_BUF_STATS_FREE_BUFFERS]->store( + static_cast<double>(info->free_list_len))); OK(fields[IDX_BUF_STATS_FLUSH_LIST_LEN]->store( - info->flush_list_len)); + static_cast<double>(info->flush_list_len))); - OK(fields[IDX_BUF_STATS_PENDING_ZIP]->store(info->n_pend_unzip)); + OK(fields[IDX_BUF_STATS_PENDING_ZIP]->store( + static_cast<double>(info->n_pend_unzip))); - OK(fields[IDX_BUF_STATS_PENDING_READ]->store(info->n_pend_reads)); + OK(fields[IDX_BUF_STATS_PENDING_READ]->store( + static_cast<double>(info->n_pend_reads))); - OK(fields[IDX_BUF_STATS_FLUSH_LRU]->store(info->n_pending_flush_lru)); + OK(fields[IDX_BUF_STATS_FLUSH_LRU]->store( + static_cast<double>(info->n_pending_flush_lru))); - OK(fields[IDX_BUF_STATS_FLUSH_LIST]->store(info->n_pending_flush_list)); + OK(fields[IDX_BUF_STATS_FLUSH_LIST]->store( + static_cast<double>(info->n_pending_flush_list))); - OK(fields[IDX_BUF_STATS_PAGE_YOUNG]->store(info->n_pages_made_young)); + OK(fields[IDX_BUF_STATS_PAGE_YOUNG]->store( + static_cast<double>(info->n_pages_made_young))); OK(fields[IDX_BUF_STATS_PAGE_NOT_YOUNG]->store( - info->n_pages_not_made_young)); + static_cast<double>(info->n_pages_not_made_young))); OK(fields[IDX_BUF_STATS_PAGE_YOUNG_RATE]->store( info->page_made_young_rate)); @@ -4408,42 +4431,53 @@ i_s_innodb_stats_fill( OK(fields[IDX_BUF_STATS_PAGE_NOT_YOUNG_RATE]->store( info->page_not_made_young_rate)); - OK(fields[IDX_BUF_STATS_PAGE_READ]->store(info->n_pages_read)); + OK(fields[IDX_BUF_STATS_PAGE_READ]->store( + static_cast<double>(info->n_pages_read))); - OK(fields[IDX_BUF_STATS_PAGE_CREATED]->store(info->n_pages_created)); + OK(fields[IDX_BUF_STATS_PAGE_CREATED]->store( + static_cast<double>(info->n_pages_created))); - OK(fields[IDX_BUF_STATS_PAGE_WRITTEN]->store(info->n_pages_written)); + OK(fields[IDX_BUF_STATS_PAGE_WRITTEN]->store( + static_cast<double>(info->n_pages_written))); - OK(fields[IDX_BUF_STATS_GET]->store(info->n_page_gets)); + OK(fields[IDX_BUF_STATS_GET]->store( + static_cast<double>(info->n_page_gets))); - OK(fields[IDX_BUF_STATS_PAGE_READ_RATE]->store(info->pages_read_rate)); + OK(fields[IDX_BUF_STATS_PAGE_READ_RATE]->store( + info->pages_read_rate)); - OK(fields[IDX_BUF_STATS_PAGE_CREATE_RATE]->store(info->pages_created_rate)); + OK(fields[IDX_BUF_STATS_PAGE_CREATE_RATE]->store( + info->pages_created_rate)); - OK(fields[IDX_BUF_STATS_PAGE_WRITTEN_RATE]->store(info->pages_written_rate)); + OK(fields[IDX_BUF_STATS_PAGE_WRITTEN_RATE]->store( + info->pages_written_rate)); if (info->n_page_get_delta) { OK(fields[IDX_BUF_STATS_HIT_RATE]->store( - 1000 - (1000 * info->page_read_delta - / info->n_page_get_delta))); + static_cast<double>( + 1000 - (1000 * info->page_read_delta + / info->n_page_get_delta)))); OK(fields[IDX_BUF_STATS_MADE_YOUNG_PCT]->store( - 1000 * info->young_making_delta - / info->n_page_get_delta)); + static_cast<double>( + 1000 * info->young_making_delta + / info->n_page_get_delta))); OK(fields[IDX_BUF_STATS_NOT_MADE_YOUNG_PCT]->store( - 1000 * info->not_young_making_delta - / info->n_page_get_delta)); + static_cast<double>( + 1000 * info->not_young_making_delta + / info->n_page_get_delta))); } else { OK(fields[IDX_BUF_STATS_HIT_RATE]->store(0)); OK(fields[IDX_BUF_STATS_MADE_YOUNG_PCT]->store(0)); OK(fields[IDX_BUF_STATS_NOT_MADE_YOUNG_PCT]->store(0)); } - OK(fields[IDX_BUF_STATS_READ_AHREAD]->store(info->n_ra_pages_read)); + OK(fields[IDX_BUF_STATS_READ_AHREAD]->store( + static_cast<double>(info->n_ra_pages_read))); OK(fields[IDX_BUF_STATS_READ_AHEAD_EVICTED]->store( - info->n_ra_pages_evicted)); + static_cast<double>(info->n_ra_pages_evicted))); OK(fields[IDX_BUF_STATS_READ_AHEAD_RATE]->store( info->pages_readahead_rate)); @@ -4451,13 +4485,17 @@ i_s_innodb_stats_fill( OK(fields[IDX_BUF_STATS_READ_AHEAD_EVICT_RATE]->store( info->pages_evicted_rate)); - OK(fields[IDX_BUF_STATS_LRU_IO_SUM]->store(info->io_sum)); + OK(fields[IDX_BUF_STATS_LRU_IO_SUM]->store( + static_cast<double>(info->io_sum))); - OK(fields[IDX_BUF_STATS_LRU_IO_CUR]->store(info->io_cur)); + OK(fields[IDX_BUF_STATS_LRU_IO_CUR]->store( + static_cast<double>(info->io_cur))); - OK(fields[IDX_BUF_STATS_UNZIP_SUM]->store(info->unzip_sum)); + OK(fields[IDX_BUF_STATS_UNZIP_SUM]->store( + static_cast<double>(info->unzip_sum))); - OK(fields[IDX_BUF_STATS_UNZIP_CUR]->store( info->unzip_cur)); + OK(fields[IDX_BUF_STATS_UNZIP_CUR]->store( + static_cast<double>(info->unzip_cur))); DBUG_RETURN(schema_table_store_record(thd, table)); } @@ -4800,13 +4838,17 @@ i_s_innodb_buffer_page_fill( state_str = NULL; - OK(fields[IDX_BUFFER_POOL_ID]->store(page_info->pool_id)); + OK(fields[IDX_BUFFER_POOL_ID]->store( + static_cast<double>(page_info->pool_id))); - OK(fields[IDX_BUFFER_BLOCK_ID]->store(page_info->block_id)); + OK(fields[IDX_BUFFER_BLOCK_ID]->store( + static_cast<double>(page_info->block_id))); - OK(fields[IDX_BUFFER_PAGE_SPACE]->store(page_info->space_id)); + OK(fields[IDX_BUFFER_PAGE_SPACE]->store( + static_cast<double>(page_info->space_id))); - OK(fields[IDX_BUFFER_PAGE_NUM]->store(page_info->page_num)); + OK(fields[IDX_BUFFER_PAGE_NUM]->store( + static_cast<double>(page_info->page_num))); OK(field_store_string( fields[IDX_BUFFER_PAGE_TYPE], @@ -4858,7 +4900,7 @@ i_s_innodb_buffer_page_fill( OK(fields[IDX_BUFFER_PAGE_TABLE_NAME]->store( table_name, - table_name_end - table_name, + static_cast<uint>(table_name_end - table_name), system_charset_info)); fields[IDX_BUFFER_PAGE_TABLE_NAME]->set_notnull(); @@ -5512,23 +5554,27 @@ i_s_innodb_buf_page_lru_fill( page_info = info_array + i; - OK(fields[IDX_BUF_LRU_POOL_ID]->store(page_info->pool_id)); + OK(fields[IDX_BUF_LRU_POOL_ID]->store( + static_cast<double>(page_info->pool_id))); - OK(fields[IDX_BUF_LRU_POS]->store(page_info->block_id)); + OK(fields[IDX_BUF_LRU_POS]->store( + static_cast<double>(page_info->block_id))); - OK(fields[IDX_BUF_LRU_PAGE_SPACE]->store(page_info->space_id)); + OK(fields[IDX_BUF_LRU_PAGE_SPACE]->store( + static_cast<double>(page_info->space_id))); - OK(fields[IDX_BUF_LRU_PAGE_NUM]->store(page_info->page_num)); + OK(fields[IDX_BUF_LRU_PAGE_NUM]->store( + static_cast<double>(page_info->page_num))); OK(field_store_string( fields[IDX_BUF_LRU_PAGE_TYPE], i_s_page_type[page_info->page_type].type_str)); OK(fields[IDX_BUF_LRU_PAGE_FLUSH_TYPE]->store( - page_info->flush_type)); + static_cast<double>(page_info->flush_type))); OK(fields[IDX_BUF_LRU_PAGE_FIX_COUNT]->store( - page_info->fix_count)); + static_cast<double>(page_info->fix_count))); if (page_info->hashed) { OK(field_store_string( @@ -5570,7 +5616,7 @@ i_s_innodb_buf_page_lru_fill( OK(fields[IDX_BUF_LRU_PAGE_TABLE_NAME]->store( table_name, - table_name_end - table_name, + static_cast<uint>(table_name_end - table_name), system_charset_info)); fields[IDX_BUF_LRU_PAGE_TABLE_NAME]->set_notnull(); @@ -5972,7 +6018,8 @@ i_s_dict_fill_sys_tables( OK(field_store_string(fields[SYS_TABLES_ROW_FORMAT], row_format)); - OK(fields[SYS_TABLES_ZIP_PAGE_SIZE]->store(zip_size)); + OK(fields[SYS_TABLES_ZIP_PAGE_SIZE]->store( + static_cast<double>(zip_size))); OK(schema_table_store_record(thd, table_to_fill)); @@ -6240,13 +6287,13 @@ i_s_dict_fill_sys_tablestats( TRUE)); OK(fields[SYS_TABLESTATS_CLUST_SIZE]->store( - table->stat_clustered_index_size)); + static_cast<double>(table->stat_clustered_index_size))); OK(fields[SYS_TABLESTATS_INDEX_SIZE]->store( - table->stat_sum_of_other_index_sizes)); + static_cast<double>(table->stat_sum_of_other_index_sizes))); OK(fields[SYS_TABLESTATS_MODIFIED]->store( - (ulint) table->stat_modified_counter)); + static_cast<double>(table->stat_modified_counter))); } else { OK(field_store_string(fields[SYS_TABLESTATS_INIT], "Uninitialized")); @@ -6265,7 +6312,7 @@ i_s_dict_fill_sys_tablestats( OK(fields[SYS_TABLESTATS_AUTONINC]->store(table->autoinc, TRUE)); OK(fields[SYS_TABLESTATS_TABLE_REF_COUNT]->store( - table->n_ref_count)); + static_cast<double>(table->n_ref_count))); OK(schema_table_store_record(thd, table_to_fill)); @@ -6951,7 +6998,7 @@ i_s_dict_fill_sys_fields( OK(field_store_string(fields[SYS_FIELD_NAME], field->name)); - OK(fields[SYS_FIELD_POS]->store(pos)); + OK(fields[SYS_FIELD_POS]->store(static_cast<double>(pos))); OK(schema_table_store_record(thd, table_to_fill)); @@ -7395,7 +7442,7 @@ i_s_dict_fill_sys_foreign_cols( OK(field_store_string(fields[SYS_FOREIGN_COL_REF_NAME], ref_col_name)); - OK(fields[SYS_FOREIGN_COL_POS]->store(pos)); + OK(fields[SYS_FOREIGN_COL_POS]->store(static_cast<double>(pos))); OK(schema_table_store_record(thd, table_to_fill)); @@ -7644,11 +7691,13 @@ i_s_dict_fill_sys_tablespaces( fields = table_to_fill->field; - OK(fields[SYS_TABLESPACES_SPACE]->store(space)); + OK(fields[SYS_TABLESPACES_SPACE]->store( + static_cast<double>(space))); OK(field_store_string(fields[SYS_TABLESPACES_NAME], name)); - OK(fields[SYS_TABLESPACES_FLAGS]->store(flags)); + OK(fields[SYS_TABLESPACES_FLAGS]->store( + static_cast<double>(flags))); OK(field_store_string(fields[SYS_TABLESPACES_FILE_FORMAT], file_format)); @@ -7656,9 +7705,11 @@ i_s_dict_fill_sys_tablespaces( OK(field_store_string(fields[SYS_TABLESPACES_ROW_FORMAT], row_format)); - OK(fields[SYS_TABLESPACES_PAGE_SIZE]->store(page_size)); + OK(fields[SYS_TABLESPACES_PAGE_SIZE]->store( + static_cast<double>(page_size))); - OK(fields[SYS_TABLESPACES_ZIP_PAGE_SIZE]->store(zip_size)); + OK(fields[SYS_TABLESPACES_ZIP_PAGE_SIZE]->store( + static_cast<double>(zip_size))); OK(schema_table_store_record(thd, table_to_fill)); diff --git a/storage/xtradb/ibuf/ibuf0ibuf.cc b/storage/xtradb/ibuf/ibuf0ibuf.cc index 7e5d5532ee3..3969d284a97 100644 --- a/storage/xtradb/ibuf/ibuf0ibuf.cc +++ b/storage/xtradb/ibuf/ibuf0ibuf.cc @@ -2963,7 +2963,8 @@ ibuf_get_volume_buffered_hash( fold = ut_fold_binary(data, len); hash += (fold / (CHAR_BIT * sizeof *hash)) % size; - bitmask = 1 << (fold % (CHAR_BIT * sizeof *hash)); + bitmask = static_cast<ulint>( + 1 << (fold % (CHAR_BIT * sizeof(*hash)))); if (*hash & bitmask) { @@ -3978,7 +3979,7 @@ skip_watch: /********************************************************************//** During merge, inserts to an index page a secondary index entry extracted -from the insert buffer. +from the insert buffer. @return newly inserted record */ static __attribute__((nonnull)) rec_t* diff --git a/storage/xtradb/include/buf0buf.h b/storage/xtradb/include/buf0buf.h index 8e2c283476a..39b06b69924 100644 --- a/storage/xtradb/include/buf0buf.h +++ b/storage/xtradb/include/buf0buf.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2014, 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 @@ -642,6 +642,15 @@ buf_page_is_corrupted( ulint zip_size) /*!< in: size of compressed page; 0 for uncompressed pages */ __attribute__((nonnull, warn_unused_result)); +/********************************************************************//** +Checks if a page is all zeroes. +@return TRUE if the page is all zeroes */ +bool +buf_page_is_zeroes( +/*===============*/ + const byte* read_buf, /*!< in: a database page */ + const ulint zip_size); /*!< in: size of compressed page; + 0 for uncompressed pages */ #ifndef UNIV_HOTBACKUP /**********************************************************************//** Gets the space id, page offset, and byte offset within page of a diff --git a/storage/xtradb/include/buf0buf.ic b/storage/xtradb/include/buf0buf.ic index fa366fd2a56..c49061621f3 100644 --- a/storage/xtradb/include/buf0buf.ic +++ b/storage/xtradb/include/buf0buf.ic @@ -408,8 +408,8 @@ buf_block_set_file_page( ulint page_no)/*!< in: page number */ { buf_block_set_state(block, BUF_BLOCK_FILE_PAGE); - block->page.space = space; - block->page.offset = page_no; + block->page.space = static_cast<ib_uint32_t>(space); + block->page.offset = static_cast<ib_uint32_t>(page_no); } /*********************************************************************//** @@ -647,7 +647,7 @@ buf_page_set_accessed( if (bpage->access_time == 0) { /* Make this the time of the first access. */ - bpage->access_time = ut_time_ms(); + bpage->access_time = static_cast<uint>(ut_time_ms()); } } diff --git a/storage/xtradb/include/buf0dblwr.h b/storage/xtradb/include/buf0dblwr.h index 740286d0a82..a62a6400d97 100644 --- a/storage/xtradb/include/buf0dblwr.h +++ b/storage/xtradb/include/buf0dblwr.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2014, 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 @@ -52,11 +52,12 @@ we already have a doublewrite buffer created in the data files. If we are upgrading to an InnoDB version which supports multiple tablespaces, then this function performs the necessary update operations. If we are in a crash recovery, this function loads the pages from double write buffer into memory. */ -UNIV_INTERN void buf_dblwr_init_or_load_pages( /*=========================*/ - bool load_corrupt_pages); + os_file_t file, + char* path, + bool load_corrupt_pages); /****************************************************************//** Process the double write buffer pages. */ diff --git a/storage/xtradb/include/db0err.h b/storage/xtradb/include/db0err.h index 17fef0dc1f4..744b80ecd05 100644 --- a/storage/xtradb/include/db0err.h +++ b/storage/xtradb/include/db0err.h @@ -128,6 +128,8 @@ enum dberr_t { DB_FTS_EXCEED_RESULT_CACHE_LIMIT, /*!< FTS query memory exceeds result cache limit */ DB_TEMP_FILE_WRITE_FAILURE, /*!< Temp file write failure */ + DB_FTS_TOO_MANY_WORDS_IN_PHRASE, + /*< Too many words in a phrase */ /* The following are partial failure codes */ DB_FAIL = 1000, diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h index 074906d8959..f32dc1f699f 100644 --- a/storage/xtradb/include/fil0fil.h +++ b/storage/xtradb/include/fil0fil.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2014, 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 @@ -177,6 +177,17 @@ extern ulint fil_n_pending_tablespace_flushes; /** Number of files currently open */ extern ulint fil_n_file_opened; +struct fsp_open_info { + ibool success; /*!< Has the tablespace been opened? */ + const char* check_msg; /*!< fil_check_first_page() message */ + ibool valid; /*!< Is the tablespace valid? */ + os_file_t file; /*!< File handle */ + char* filepath; /*!< File path to open */ + lsn_t lsn; /*!< Flushed LSN from header page */ + ulint id; /*!< Space ID */ + ulint flags; /*!< Tablespace flags */ +}; + #ifndef UNIV_HOTBACKUP /*******************************************************************//** Returns the version number of a tablespace, -1 if not found. @@ -994,6 +1005,18 @@ fil_mtr_rename_log( mtr_t* mtr) /*!< in/out: mini-transaction */ __attribute__((nonnull)); +/*******************************************************************//** +Finds the given page_no of the given space id from the double write buffer, +and copies it to the corresponding .ibd file. +@return true if copy was successful, or false. */ +bool +fil_user_tablespace_restore_page( +/*==============================*/ + fsp_open_info* fsp, /* in: contains space id and .ibd + file information */ + ulint page_no); /* in: page_no to obtain from double + write buffer */ + #endif /* !UNIV_INNOCHECKSUM */ /************************************************************************* diff --git a/storage/xtradb/include/lock0lock.h b/storage/xtradb/include/lock0lock.h index 3a3a28ef525..633e4f6626b 100644 --- a/storage/xtradb/include/lock0lock.h +++ b/storage/xtradb/include/lock0lock.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2014, 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 @@ -904,22 +904,15 @@ lock_trx_has_rec_x_lock( remains set when the waiting lock is granted, or if the lock is inherited to a neighboring record */ -#define LOCK_CONV_BY_OTHER 4096 /*!< this bit is set when the lock is created - by other transaction */ -#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION|LOCK_CONV_BY_OTHER)&LOCK_MODE_MASK + +#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION)&LOCK_MODE_MASK # error #endif -#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION|LOCK_CONV_BY_OTHER)&LOCK_TYPE_MASK +#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION)&LOCK_TYPE_MASK # error #endif /* @} */ -/** Checks if this is a waiting lock created by lock->trx itself. -@param type_mode lock->type_mode -@return whether it is a waiting lock belonging to lock->trx */ -#define lock_is_wait_not_by_other(type_mode) \ - ((type_mode & (LOCK_CONV_BY_OTHER | LOCK_WAIT)) == LOCK_WAIT) - /** Lock operation struct */ struct lock_op_t{ dict_table_t* table; /*!< table to be locked */ diff --git a/storage/xtradb/include/log0recv.h b/storage/xtradb/include/log0recv.h index e21599cffab..805b6c66768 100644 --- a/storage/xtradb/include/log0recv.h +++ b/storage/xtradb/include/log0recv.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2014, 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 @@ -408,9 +408,13 @@ struct recv_addr_t{ struct recv_dblwr_t { void add(byte* page); - byte* find_first_page(ulint space_id); + byte* find_page(ulint space_id, ulint page_no); std::list<byte *> pages; /* Pages from double write buffer */ + + void operator() () { + pages.clear(); + } }; /** Recovery system data structure */ diff --git a/storage/xtradb/include/os0sync.h b/storage/xtradb/include/os0sync.h index 91ad7e3b860..ea5d09ec535 100644 --- a/storage/xtradb/include/os0sync.h +++ b/storage/xtradb/include/os0sync.h @@ -598,7 +598,7 @@ amount of increment. */ (win_xchg_and_add(ptr, amount) + amount) # define os_atomic_increment_uint32(ptr, amount) \ - ((ulint) _InterlockedExchangeAdd((long*) ptr, amount)) + ((ulint) InterlockedExchangeAdd((long*) ptr, amount)) # define os_atomic_increment_ulint(ptr, amount) \ ((ulint) (win_xchg_and_add((lint*) ptr, (lint) amount) + amount)) @@ -613,7 +613,7 @@ Returns the resulting value, ptr is pointer to target, amount is the amount to decrement. There is no atomic substract function on Windows */ # define os_atomic_decrement_uint32(ptr, amount) \ - ((ulint) _InterlockedExchangeAdd((long*) ptr, (-amount))) + ((ulint) InterlockedExchangeAdd((long*) ptr, (-amount))) # define os_atomic_decrement_lint(ptr, amount) \ (win_xchg_and_add(ptr, -(lint) amount) - amount) diff --git a/storage/xtradb/include/os0sync.ic b/storage/xtradb/include/os0sync.ic index 33c238ceb47..9a7e520ece6 100644 --- a/storage/xtradb/include/os0sync.ic +++ b/storage/xtradb/include/os0sync.ic @@ -112,8 +112,10 @@ pfs_os_fast_mutex_lock( PSI_mutex_locker* locker; PSI_mutex_locker_state state; - locker = PSI_MUTEX_CALL(start_mutex_wait)(&state, fast_mutex->pfs_psi, - PSI_MUTEX_LOCK, file_name, line); + locker = PSI_MUTEX_CALL(start_mutex_wait)( + &state, fast_mutex->pfs_psi, + PSI_MUTEX_LOCK, file_name, + static_cast<uint>(line)); os_fast_mutex_lock_func(&fast_mutex->mutex); diff --git a/storage/xtradb/include/row0log.h b/storage/xtradb/include/row0log.h index 41dac63963d..62715fe8808 100644 --- a/storage/xtradb/include/row0log.h +++ b/storage/xtradb/include/row0log.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2011, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2011, 2014, 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 @@ -122,10 +122,9 @@ row_log_table_delete( dict_index_t* index, /*!< in/out: clustered index, S-latched or X-latched */ const ulint* offsets,/*!< in: rec_get_offsets(rec,index) */ - bool purge, /*!< in: true=purging BLOBs */ - trx_id_t trx_id) /*!< in: DB_TRX_ID of the record before - it was deleted */ - UNIV_COLD __attribute__((nonnull)); + const byte* sys) /*!< in: DB_TRX_ID,DB_ROLL_PTR that should + be logged, or NULL to use those in rec */ + UNIV_COLD __attribute__((nonnull(1,2,3))); /******************************************************//** Logs an update operation to a table that is being rebuilt. @@ -158,8 +157,10 @@ row_log_table_get_pk( or X-latched */ const ulint* offsets,/*!< in: rec_get_offsets(rec,index), or NULL */ + byte* sys, /*!< out: DB_TRX_ID,DB_ROLL_PTR for + row_log_table_delete(), or NULL */ mem_heap_t** heap) /*!< in/out: memory heap where allocated */ - UNIV_COLD __attribute__((nonnull(1,2,4), warn_unused_result)); + UNIV_COLD __attribute__((nonnull(1,2,5), warn_unused_result)); /******************************************************//** Logs an insert to a table that is being rebuilt. diff --git a/storage/xtradb/include/sync0rw.ic b/storage/xtradb/include/sync0rw.ic index 097adfded37..3511987dbb0 100644 --- a/storage/xtradb/include/sync0rw.ic +++ b/storage/xtradb/include/sync0rw.ic @@ -874,12 +874,15 @@ pfs_rw_lock_x_lock_func( /* Record the entry of rw x lock request in performance schema */ locker = PSI_RWLOCK_CALL(start_rwlock_wrwait)( - &state, lock->pfs_psi, PSI_RWLOCK_WRITELOCK, file_name, line); + &state, lock->pfs_psi, PSI_RWLOCK_WRITELOCK, + file_name, static_cast<uint>(line)); - rw_lock_x_lock_func(lock, pass, file_name, line); + rw_lock_x_lock_func( + lock, pass, file_name, static_cast<uint>(line)); - if (locker != NULL) + if (locker != NULL) { PSI_RWLOCK_CALL(end_rwlock_wrwait)(locker, 0); + } } else { @@ -946,12 +949,15 @@ pfs_rw_lock_x_lock_func_nowait( /* Record the entry of rw x lock request in performance schema */ locker = PSI_RWLOCK_CALL(start_rwlock_wrwait)( - &state, lock->pfs_psi, PSI_RWLOCK_WRITELOCK, file_name, line); + &state, lock->pfs_psi, PSI_RWLOCK_WRITELOCK, + file_name, static_cast<uint>(line)); ret = rw_lock_x_lock_func_nowait(lock, file_name, line); - if (locker != NULL) - PSI_RWLOCK_CALL(end_rwlock_wrwait)(locker, ret); + if (locker != NULL) { + PSI_RWLOCK_CALL(end_rwlock_wrwait)( + locker, static_cast<int>(ret)); + } } else { @@ -1021,12 +1027,14 @@ pfs_rw_lock_s_lock_func( /* Instrumented to inform we are aquiring a shared rwlock */ locker = PSI_RWLOCK_CALL(start_rwlock_rdwait)( - &state, lock->pfs_psi, PSI_RWLOCK_READLOCK, file_name, line); + &state, lock->pfs_psi, PSI_RWLOCK_READLOCK, + file_name, static_cast<uint>(line)); rw_lock_s_lock_func(lock, pass, file_name, line); - if (locker != NULL) + if (locker != NULL) { PSI_RWLOCK_CALL(end_rwlock_rdwait)(locker, 0); + } } else { @@ -1100,12 +1108,15 @@ pfs_rw_lock_s_lock_low( /* Instrumented to inform we are aquiring a shared rwlock */ locker = PSI_RWLOCK_CALL(start_rwlock_rdwait)( - &state, lock->pfs_psi, PSI_RWLOCK_READLOCK, file_name, line); + &state, lock->pfs_psi, PSI_RWLOCK_READLOCK, + file_name, static_cast<uint>(line)); ret = rw_lock_s_lock_low(lock, pass, file_name, line); - if (locker != NULL) - PSI_RWLOCK_CALL(end_rwlock_rdwait)(locker, ret); + if (locker != NULL) { + PSI_RWLOCK_CALL(end_rwlock_rdwait)( + locker, static_cast<int>(ret)); + } } else { diff --git a/storage/xtradb/include/sync0sync.h b/storage/xtradb/include/sync0sync.h index 19cfcddd1f5..788f765f919 100644 --- a/storage/xtradb/include/sync0sync.h +++ b/storage/xtradb/include/sync0sync.h @@ -984,6 +984,7 @@ struct ib_prio_mutex_t { priority in the global wait array waiting for this mutex to be released. */ + UT_LIST_NODE_T(ib_prio_mutex_t) list; }; /** Constant determining how long spin wait is continued before suspending diff --git a/storage/xtradb/include/sync0sync.ic b/storage/xtradb/include/sync0sync.ic index d6a95156ff4..c3529af5262 100644 --- a/storage/xtradb/include/sync0sync.ic +++ b/storage/xtradb/include/sync0sync.ic @@ -354,7 +354,8 @@ pfs_mutex_enter_func( locker = PSI_MUTEX_CALL(start_mutex_wait)( &state, mutex->pfs_psi, - PSI_MUTEX_LOCK, file_name, line); + PSI_MUTEX_LOCK, file_name, + static_cast<uint>(line)); mutex_enter_func(mutex, file_name, line); @@ -423,7 +424,8 @@ pfs_mutex_enter_nowait_func( locker = PSI_MUTEX_CALL(start_mutex_wait)( &state, mutex->pfs_psi, - PSI_MUTEX_TRYLOCK, file_name, line); + PSI_MUTEX_TRYLOCK, file_name, + static_cast<uint>(line)); ret = mutex_enter_nowait_func(mutex, file_name, line); diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i index eded44789a8..572788f7242 100644 --- a/storage/xtradb/include/univ.i +++ b/storage/xtradb/include/univ.i @@ -44,10 +44,10 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_MAJOR 5 #define INNODB_VERSION_MINOR 6 -#define INNODB_VERSION_BUGFIX 16 +#define INNODB_VERSION_BUGFIX 17 #ifndef PERCONA_INNODB_VERSION -#define PERCONA_INNODB_VERSION 64.2 +#define PERCONA_INNODB_VERSION 65.0 #endif /* Enable UNIV_LOG_ARCHIVE in XtraDB */ diff --git a/storage/xtradb/include/ut0ut.h b/storage/xtradb/include/ut0ut.h index 163dc23b363..0caf379d8fa 100644 --- a/storage/xtradb/include/ut0ut.h +++ b/storage/xtradb/include/ut0ut.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2014, 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 @@ -51,6 +51,19 @@ Created 1/20/1994 Heikki Tuuri /** Time stamp */ typedef time_t ib_time_t; +/* In order to call a piece of code, when a function returns or when the +scope ends, use this utility class. It will invoke the given function +object in its destructor. */ +template<typename F> +struct ut_when_dtor { + ut_when_dtor(F& p) : f(p) {} + ~ut_when_dtor() { + f(); + } +private: + F& f; +}; + #ifndef UNIV_HOTBACKUP # if defined(HAVE_PAUSE_INSTRUCTION) /* According to the gcc info page, asm volatile means that the diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc index 3e60680882a..4f9395e27d8 100644 --- a/storage/xtradb/lock/lock0lock.cc +++ b/storage/xtradb/lock/lock0lock.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2014, 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 @@ -854,16 +854,11 @@ lock_reset_lock_and_trx_wait( /*=========================*/ lock_t* lock) /*!< in/out: record lock */ { + ut_ad(lock->trx->lock.wait_lock == lock); ut_ad(lock_get_wait(lock)); ut_ad(lock_mutex_own()); - /* Reset the back pointer in trx to this waiting lock request */ - if (!(lock->type_mode & LOCK_CONV_BY_OTHER)) { - ut_ad(lock->trx->lock.wait_lock == lock); - lock->trx->lock.wait_lock = NULL; - } else { - ut_ad(lock_get_type_low(lock) == LOCK_REC); - } + lock->trx->lock.wait_lock = NULL; lock->type_mode &= ~LOCK_WAIT; } @@ -1486,7 +1481,7 @@ lock_rec_has_expl( const buf_block_t* block, /*!< in: buffer block containing the record */ ulint heap_no,/*!< in: heap number of the record */ - const trx_t* trx) /*!< in: transaction */ + trx_id_t trx_id) /*!< in: transaction id */ { lock_t* lock; @@ -1499,13 +1494,13 @@ lock_rec_has_expl( lock != NULL; lock = lock_rec_get_next(heap_no, lock)) { - if (lock->trx == trx + if (lock->trx->id == trx_id && !lock_rec_get_insert_intention(lock) - && !lock_is_wait_not_by_other(lock->type_mode) && lock_mode_stronger_or_eq( lock_get_mode(lock), static_cast<enum lock_mode>( precise_mode & LOCK_MODE_MASK)) + && !lock_get_wait(lock) && (!lock_rec_get_rec_not_gap(lock) || (precise_mode & LOCK_REC_NOT_GAP) || heap_no == PAGE_HEAP_NO_SUPREMUM) @@ -1524,7 +1519,7 @@ lock_rec_has_expl( /*********************************************************************//** Checks if some other transaction has a lock request in the queue. @return lock or NULL */ -static +static __attribute__((nonnull, warn_unused_result)) const lock_t* lock_rec_other_has_expl_req( /*========================*/ @@ -1538,9 +1533,7 @@ lock_rec_other_has_expl_req( const buf_block_t* block, /*!< in: buffer block containing the record */ ulint heap_no,/*!< in: heap number of the record */ - const trx_t* trx) /*!< in: transaction, or NULL if - requests by all transactions - are taken into account */ + trx_id_t trx_id) /*!< in: transaction */ { const lock_t* lock; @@ -1553,7 +1546,7 @@ lock_rec_other_has_expl_req( lock != NULL; lock = lock_rec_get_next_const(heap_no, lock)) { - if (lock->trx != trx + if (lock->trx->id != trx_id && (gap || !(lock_rec_get_gap(lock) || heap_no == PAGE_HEAP_NO_SUPREMUM)) @@ -1689,6 +1682,69 @@ lock_sec_rec_some_has_impl( return(trx_id); } +#ifdef UNIV_DEBUG +/*********************************************************************//** +Checks if some transaction, other than given trx_id, has an explicit +lock on the given rec, in the given precise_mode. +@return the transaction, whose id is not equal to trx_id, that has an +explicit lock on the given rec, in the given precise_mode or NULL.*/ +static +trx_t* +lock_rec_other_trx_holds_expl( +/*==========================*/ + ulint precise_mode, /*!< in: LOCK_S or LOCK_X + possibly ORed to LOCK_GAP or + LOCK_REC_NOT_GAP. */ + trx_id_t trx_id, /*!< in: trx holding implicit + lock on rec */ + const rec_t* rec, /*!< in: user record */ + const buf_block_t* block) /*!< in: buffer block + containing the record */ +{ + trx_t* holds = NULL; + + lock_mutex_enter(); + mutex_enter(&trx_sys->mutex); + + trx_id_t* impl_trx_desc = trx_find_descriptor(trx_sys->descriptors, + trx_sys->descr_n_used, + trx_id); + if (impl_trx_desc) { + ut_ad(trx_id == *impl_trx_desc); + ulint heap_no = page_rec_get_heap_no(rec); + ulint rw_trx_count = trx_sys->descr_n_used; + trx_id_t* rw_trx_snapshot = static_cast<trx_id_t *> + (ut_malloc(sizeof(trx_id_t) * rw_trx_count)); + memcpy(rw_trx_snapshot, trx_sys->descriptors, + sizeof(trx_id_t) * rw_trx_count); + + mutex_exit(&trx_sys->mutex); + + for (ulint i = 0; i < rw_trx_count; i++) { + + lock_t* expl_lock = lock_rec_has_expl(precise_mode, + block, heap_no, + rw_trx_snapshot[i]); + if (expl_lock && expl_lock->trx->id != trx_id) { + /* An explicit lock is held by trx other than + the trx holding the implicit lock. */ + holds = expl_lock->trx; + break; + } + } + + ut_free(rw_trx_snapshot); + + } else { + mutex_exit(&trx_sys->mutex); + } + + lock_mutex_exit(); + + return(holds); +} +#endif /* UNIV_DEBUG */ + /*********************************************************************//** Return approximate number or record locks (bits set in the bitmap) for this transaction. Since delete-marked records may be removed, the @@ -1815,7 +1871,7 @@ lock_rec_create( } ut_ad(trx_mutex_own(trx)); - if (lock_is_wait_not_by_other(type_mode)) { + if (type_mode & LOCK_WAIT) { lock_set_lock_and_trx_wait(lock, trx); } @@ -1855,12 +1911,11 @@ lock_rec_enqueue_waiting( const buf_block_t* block, /*!< in: buffer block containing the record */ ulint heap_no,/*!< in: heap number of the record */ - lock_t* lock, /*!< in: lock object; NULL if a new - one should be created. */ dict_index_t* index, /*!< in: index of record */ que_thr_t* thr) /*!< in: query thread */ { trx_t* trx; + lock_t* lock; trx_id_t victim_trx_id; ulint sec; ulint ms; @@ -1901,20 +1956,10 @@ lock_rec_enqueue_waiting( ut_ad(0); } - if (lock == NULL) { - /* Enqueue the lock request that will wait - to be granted, note that we already own - the trx mutex. */ - lock = lock_rec_create( - type_mode | LOCK_WAIT, block, heap_no, - index, trx, TRUE); - } else { - ut_ad(lock->type_mode & LOCK_WAIT); - ut_ad(lock->type_mode & LOCK_CONV_BY_OTHER); - - lock->type_mode &= ~LOCK_CONV_BY_OTHER; - lock_set_lock_and_trx_wait(lock, trx); - } + /* Enqueue the lock request that will wait to be granted, note that + we already own the trx mutex. */ + lock = lock_rec_create( + type_mode | LOCK_WAIT, block, heap_no, index, trx, TRUE); /* Release the mutex to obey the latching order. This is safe, because lock_deadlock_check_and_resolve() @@ -2018,7 +2063,7 @@ lock_rec_add_to_queue( : LOCK_S; const lock_t* other_lock = lock_rec_other_has_expl_req(mode, 0, LOCK_WAIT, - block, heap_no, trx); + block, heap_no, trx->id); ut_a(!other_lock); } #endif /* UNIV_DEBUG */ @@ -2190,7 +2235,6 @@ lock_rec_lock_slow( que_thr_t* thr) /*!< in: query thread */ { trx_t* trx; - lock_t* lock; dberr_t err = DB_SUCCESS; ut_ad(lock_mutex_own()); @@ -2210,26 +2254,7 @@ lock_rec_lock_slow( trx = thr_get_trx(thr); trx_mutex_enter(trx); - lock = lock_rec_has_expl(mode, block, heap_no, trx); - if (lock) { - if (lock->type_mode & LOCK_CONV_BY_OTHER) { - /* This lock or lock waiting was created by the other - transaction, not by the transaction (trx) itself. - So, the transaction (trx) should treat it collectly - according as whether granted or not. */ - - if (lock->type_mode & LOCK_WAIT) { - /* This lock request was not granted yet. - Should wait for granted. */ - - goto enqueue_waiting; - } else { - /* This lock request was already granted. - Just clearing the flag. */ - - lock->type_mode &= ~LOCK_CONV_BY_OTHER; - } - } + if (lock_rec_has_expl(mode, block, heap_no, trx->id)) { /* The trx already has a strong enough lock on rec: do nothing */ @@ -2243,10 +2268,8 @@ lock_rec_lock_slow( have a lock strong enough already granted on the record, we have to wait. */ - ut_ad(lock == NULL); -enqueue_waiting: err = lock_rec_enqueue_waiting( - mode, block, heap_no, lock, index, thr); + mode, block, heap_no, index, thr); } else if (!impl) { /* Set the requested lock on the record, note that @@ -2341,7 +2364,7 @@ lock_rec_has_to_wait_in_queue( heap_no = lock_rec_find_set_bit(wait_lock); bit_offset = heap_no / 8; - bit_mask = 1 << (heap_no % 8); + bit_mask = static_cast<ulint>(1 << (heap_no % 8)); for (lock = lock_rec_get_first_on_page_addr(space, page_no); lock != wait_lock; @@ -2401,8 +2424,7 @@ lock_grant( TRX_QUE_LOCK_WAIT state, and there is no need to end the lock wait for it */ - if (!(lock->type_mode & LOCK_CONV_BY_OTHER) - && lock->trx->lock.que_state == TRX_QUE_LOCK_WAIT) { + if (lock->trx->lock.que_state == TRX_QUE_LOCK_WAIT) { que_thr_t* thr; thr = que_thr_end_lock_wait(lock->trx); @@ -2429,7 +2451,6 @@ lock_rec_cancel( ut_ad(lock_mutex_own()); ut_ad(lock_get_type_low(lock) == LOCK_REC); - ut_ad(!(lock->type_mode & LOCK_CONV_BY_OTHER)); /* Reset the bit (there can be only one set bit) in the lock bitmap */ lock_rec_reset_nth_bit(lock, lock_rec_find_set_bit(lock)); @@ -2598,12 +2619,8 @@ lock_rec_reset_and_release_wait( lock != NULL; lock = lock_rec_get_next(heap_no, lock)) { - if (lock_is_wait_not_by_other(lock->type_mode)) { + if (lock_get_wait(lock)) { lock_rec_cancel(lock); - } else if (lock_get_wait(lock)) { - /* just reset LOCK_WAIT */ - lock_rec_reset_nth_bit(lock, heap_no); - lock_reset_lock_and_trx_wait(lock); } else { lock_rec_reset_nth_bit(lock, heap_no); } @@ -3910,7 +3927,7 @@ lock_deadlock_search( } ut_a(lock == NULL && ctx->depth == 0); - + /* No deadlock found. */ return(0); } @@ -4065,7 +4082,6 @@ lock_table_create( ut_ad(table && trx); ut_ad(lock_mutex_own()); ut_ad(trx_mutex_own(trx)); - ut_ad(!(type_mode & LOCK_CONV_BY_OTHER)); /* Non-locking autocommit read-only transactions should not set any locks. */ @@ -5206,11 +5222,14 @@ lock_print_info_summary( the state of the variable for display. */ switch (purge_sys->state){ - case PURGE_STATE_EXIT: case PURGE_STATE_INIT: /* Should never be in this state while the system is running. */ ut_error; + case PURGE_STATE_EXIT: + fprintf(file, "exited"); + break; + case PURGE_STATE_DISABLED: fprintf(file, "disabled"); break; @@ -5544,7 +5563,6 @@ lock_rec_queue_validate( const dict_index_t* index, /*!< in: index, or NULL if not known */ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ { - const trx_t* impl_trx; const lock_t* lock; ulint heap_no; @@ -5586,23 +5604,27 @@ lock_rec_queue_validate( if (!index); else if (dict_index_is_clust(index)) { trx_id_t trx_id; + trx_id_t* trx_desc; /* Unlike the non-debug code, this invariant can only succeed if the check and assertion are covered by the lock mutex. */ trx_id = lock_clust_rec_some_has_impl(rec, index, offsets); - impl_trx = trx_rw_get_active_trx_by_id(trx_id, NULL); + trx_desc = trx_find_descriptor(trx_sys->descriptors, + trx_sys->descr_n_used, + trx_id); ut_ad(lock_mutex_own()); - /* impl_trx cannot be committed until lock_mutex_exit() + /* trx_id cannot be committed until lock_mutex_exit() because lock_trx_release_locks() acquires lock_sys->mutex */ - if (impl_trx != NULL + if (trx_desc != NULL && lock_rec_other_has_expl_req(LOCK_S, 0, LOCK_WAIT, - block, heap_no, impl_trx)) { + block, heap_no, trx_id)) { + ut_ad(trx_id == *trx_desc); ut_a(lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, - block, heap_no, impl_trx)); + block, heap_no, trx_id)); } } @@ -5626,7 +5648,8 @@ lock_rec_queue_validate( mode = LOCK_S; } ut_a(!lock_rec_other_has_expl_req( - mode, 0, 0, block, heap_no, lock->trx)); + mode, 0, 0, block, heap_no, + lock->trx->id)); } else if (lock_get_wait(lock) && !lock_rec_get_gap(lock)) { @@ -6001,7 +6024,7 @@ lock_rec_insert_check_and_lock( err = lock_rec_enqueue_waiting( LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION, - block, next_rec_heap_no, NULL, index, thr); + block, next_rec_heap_no, index, thr); trx_mutex_exit(trx); } else { @@ -6079,11 +6102,14 @@ lock_rec_convert_impl_to_expl( /* The transaction can be committed before the trx_is_active(trx_id, NULL) check below, because we are not holding lock_mutex. */ + + ut_ad(!lock_rec_other_trx_holds_expl(LOCK_S | LOCK_REC_NOT_GAP, + trx_id, rec, block)); } if (trx_id != 0) { - trx_t* impl_trx; - ulint heap_no = page_rec_get_heap_no(rec); + trx_id_t* impl_trx_desc; + ulint heap_no = page_rec_get_heap_no(rec); lock_mutex_enter(); @@ -6091,31 +6117,25 @@ lock_rec_convert_impl_to_expl( explicit x-lock set on the record, set one for it */ mutex_enter(&trx_sys->mutex); - impl_trx = trx_rw_get_active_trx_by_id(trx_id, NULL); + impl_trx_desc = trx_find_descriptor(trx_sys->descriptors, + trx_sys->descr_n_used, + trx_id); mutex_exit(&trx_sys->mutex); - /* impl_trx cannot be committed until lock_mutex_exit() + /* trx_id cannot be committed until lock_mutex_exit() because lock_trx_release_locks() acquires lock_sys->mutex */ - if (impl_trx != NULL + if (impl_trx_desc != NULL && !lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, block, - heap_no, impl_trx)) { + heap_no, trx_id)) { ulint type_mode = (LOCK_REC | LOCK_X | LOCK_REC_NOT_GAP); - /* If the delete-marked record was locked already, - we should reserve lock waiting for impl_trx as - implicit lock. Because cannot lock at this moment.*/ - - if (rec_get_deleted_flag(rec, rec_offs_comp(offsets)) - && lock_rec_other_has_conflicting( - static_cast<enum lock_mode> - (LOCK_X | LOCK_REC_NOT_GAP), block, - heap_no, impl_trx)) { - - type_mode |= (LOCK_WAIT - | LOCK_CONV_BY_OTHER); - } + mutex_enter(&trx_sys->mutex); + trx_t* impl_trx = trx_rw_get_active_trx_by_id(trx_id, + NULL); + mutex_exit(&trx_sys->mutex); + ut_ad(impl_trx != NULL); lock_rec_add_to_queue( type_mode, block, heap_no, index, @@ -6790,7 +6810,6 @@ lock_cancel_waiting_and_release( ut_ad(lock_mutex_own()); ut_ad(trx_mutex_own(lock->trx)); - ut_ad(!(lock->type_mode & LOCK_CONV_BY_OTHER)); lock->trx->lock.cancel = TRUE; @@ -7168,7 +7187,7 @@ lock_trx_has_rec_x_lock( if (UNIV_LIKELY(srv_fake_changes_locks)) { ut_a(lock_rec_has_expl(rec_lock | LOCK_REC_NOT_GAP, - block, heap_no, trx)); + block, heap_no, trx->id)); } lock_mutex_exit(); return(true); diff --git a/storage/xtradb/log/log0recv.cc b/storage/xtradb/log/log0recv.cc index bf239299268..0db2b6ef5ed 100644 --- a/storage/xtradb/log/log0recv.cc +++ b/storage/xtradb/log/log0recv.cc @@ -3042,8 +3042,6 @@ recv_init_crash_recovery(void) ib_logf(IB_LOG_LEVEL_INFO, "Reading tablespace information from the .ibd files..."); - buf_dblwr_init_or_load_pages(true); - fil_load_single_table_tablespaces(); /* If we are using the doublewrite method, we will @@ -3101,6 +3099,7 @@ recv_recovery_from_checkpoint_start_func( byte* log_hdr_buf; byte* log_hdr_buf_base = (byte*)alloca(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE); dberr_t err; + ut_when_dtor<recv_dblwr_t> tmp(recv_sys->dblwr); log_hdr_buf = static_cast<byte *> (ut_align(log_hdr_buf_base, OS_FILE_LOG_BLOCK_SIZE)); @@ -3118,11 +3117,6 @@ recv_recovery_from_checkpoint_start_func( # define LIMIT_LSN LSN_MAX #endif /* UNIV_LOG_ARCHIVE */ - if (TYPE_CHECKPOINT) { - recv_sys_create(); - recv_sys_init(buf_pool_get_curr_size()); - } - if (srv_force_recovery >= SRV_FORCE_NO_LOG_REDO) { ib_logf(IB_LOG_LEVEL_INFO, @@ -3372,11 +3366,6 @@ recv_recovery_from_checkpoint_start_func( } } } - - if (!recv_needed_recovery && !srv_read_only_mode) { - /* Init the doublewrite buffer memory structure */ - buf_dblwr_init_or_load_pages(false); - } } /* We currently have only one log group */ @@ -4086,7 +4075,7 @@ void recv_dblwr_t::add(byte* page) pages.push_back(page); } -byte* recv_dblwr_t::find_first_page(ulint space_id) +byte* recv_dblwr_t::find_page(ulint space_id, ulint page_no) { std::vector<byte*> matches; byte* result = 0; @@ -4095,7 +4084,7 @@ byte* recv_dblwr_t::find_first_page(ulint space_id) i != pages.end(); ++i) { if ((page_get_space_id(*i) == space_id) - && (page_get_page_no(*i) == 0)) { + && (page_get_page_no(*i) == page_no)) { matches.push_back(*i); } } diff --git a/storage/xtradb/os/os0sync.cc b/storage/xtradb/os/os0sync.cc index 392dbe0d7a7..e42c5900c0c 100644 --- a/storage/xtradb/os/os0sync.cc +++ b/storage/xtradb/os/os0sync.cc @@ -644,7 +644,7 @@ os_event_wait_time_low( ut_a(event); if (time_in_usec != OS_SYNC_INFINITE_TIME) { - time_in_ms = time_in_usec / 1000; + time_in_ms = static_cast<DWORD>(time_in_usec / 1000); err = WaitForSingleObject(event->handle, time_in_ms); } else { err = WaitForSingleObject(event->handle, INFINITE); @@ -663,7 +663,7 @@ os_event_wait_time_low( ut_a(sleep_condition_variable != NULL); if (time_in_usec != OS_SYNC_INFINITE_TIME) { - time_in_ms = time_in_usec / 1000; + time_in_ms = static_cast<DWORD>(time_in_usec / 1000); } else { time_in_ms = INFINITE; } diff --git a/storage/xtradb/page/page0zip.cc b/storage/xtradb/page/page0zip.cc index ed73fb37d41..1e533a4bbbe 100644 --- a/storage/xtradb/page/page0zip.cc +++ b/storage/xtradb/page/page0zip.cc @@ -171,7 +171,7 @@ page_zip_empty_size( + 1/* end of modification log */ - REC_N_NEW_EXTRA_BYTES/* omitted bytes */) /* subtract the space for page_zip_fields_encode() */ - - compressBound(2 * (n_fields + 1)); + - compressBound(static_cast<uLong>(2 * (n_fields + 1))); return(size > 0 ? (ulint) size : 0); } #endif /* !UNIV_HOTBACKUP */ @@ -852,8 +852,8 @@ page_zip_compress_node_ptrs( rec_offs_extra_size(offsets)); /* Compress the extra bytes. */ - c_stream->avail_in = rec - REC_N_NEW_EXTRA_BYTES - - c_stream->next_in; + c_stream->avail_in = static_cast<uInt>( + rec - REC_N_NEW_EXTRA_BYTES - c_stream->next_in); if (c_stream->avail_in) { err = deflate(c_stream, Z_NO_FLUSH); @@ -865,8 +865,8 @@ page_zip_compress_node_ptrs( /* Compress the data bytes, except node_ptr. */ c_stream->next_in = (byte*) rec; - c_stream->avail_in = rec_offs_data_size(offsets) - - REC_NODE_PTR_SIZE; + c_stream->avail_in = static_cast<uInt>( + rec_offs_data_size(offsets) - REC_NODE_PTR_SIZE); if (c_stream->avail_in) { err = deflate(c_stream, Z_NO_FLUSH); @@ -907,8 +907,9 @@ page_zip_compress_sec( const rec_t* rec = *recs++; /* Compress everything up to this record. */ - c_stream->avail_in = rec - REC_N_NEW_EXTRA_BYTES - - c_stream->next_in; + c_stream->avail_in = static_cast<uInt>( + rec - REC_N_NEW_EXTRA_BYTES + - c_stream->next_in); if (UNIV_LIKELY(c_stream->avail_in)) { UNIV_MEM_ASSERT_RW(c_stream->next_in, @@ -973,8 +974,8 @@ page_zip_compress_clust_ext( ut_ad(len == DATA_ROLL_PTR_LEN); /* Compress any preceding bytes. */ - c_stream->avail_in - = src - c_stream->next_in; + c_stream->avail_in = static_cast<uInt>( + src - c_stream->next_in); if (c_stream->avail_in) { err = deflate(c_stream, Z_NO_FLUSH); @@ -1003,8 +1004,8 @@ page_zip_compress_clust_ext( ut_ad(len >= BTR_EXTERN_FIELD_REF_SIZE); src += len - BTR_EXTERN_FIELD_REF_SIZE; - c_stream->avail_in = src - - c_stream->next_in; + c_stream->avail_in = static_cast<uInt>( + src - c_stream->next_in); if (UNIV_LIKELY(c_stream->avail_in)) { err = deflate(c_stream, Z_NO_FLUSH); if (UNIV_UNLIKELY(err != Z_OK)) { @@ -1099,8 +1100,9 @@ page_zip_compress_clust( rec_offs_extra_size(offsets)); /* Compress the extra bytes. */ - c_stream->avail_in = rec - REC_N_NEW_EXTRA_BYTES - - c_stream->next_in; + c_stream->avail_in = static_cast<uInt>( + rec - REC_N_NEW_EXTRA_BYTES + - c_stream->next_in); if (c_stream->avail_in) { err = deflate(c_stream, Z_NO_FLUSH); @@ -1147,7 +1149,8 @@ page_zip_compress_clust( rec_offs_extra_size(offsets)); /* Compress any preceding bytes. */ - c_stream->avail_in = src - c_stream->next_in; + c_stream->avail_in = static_cast<uInt>( + src - c_stream->next_in); if (c_stream->avail_in) { err = deflate(c_stream, Z_NO_FLUSH); @@ -1174,8 +1177,8 @@ page_zip_compress_clust( } /* Compress the last bytes of the record. */ - c_stream->avail_in = rec + rec_offs_data_size(offsets) - - c_stream->next_in; + c_stream->avail_in = static_cast<uInt>( + rec + rec_offs_data_size(offsets) - c_stream->next_in); if (c_stream->avail_in) { err = deflate(c_stream, Z_NO_FLUSH); @@ -1331,7 +1334,7 @@ page_zip_compress( /* Compress the data payload. */ page_zip_set_alloc(&c_stream, heap); - err = deflateInit2(&c_stream, level, + err = deflateInit2(&c_stream, static_cast<int>(level), Z_DEFLATED, UNIV_PAGE_SIZE_SHIFT, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY); ut_a(err == Z_OK); @@ -1339,7 +1342,8 @@ page_zip_compress( c_stream.next_out = buf; /* Subtract the space reserved for uncompressed data. */ /* Page header and the end marker of the modification log */ - c_stream.avail_out = buf_end - buf - 1; + c_stream.avail_out = static_cast<uInt>(buf_end - buf - 1); + /* Dense page directory and uncompressed columns, if any */ if (page_is_leaf(page)) { if (dict_index_is_clust(index)) { @@ -1368,9 +1372,9 @@ page_zip_compress( goto zlib_error; } - c_stream.avail_out -= n_dense * slot_size; - c_stream.avail_in = page_zip_fields_encode(n_fields, index, - trx_id_col, fields); + c_stream.avail_out -= static_cast<uInt>(n_dense * slot_size); + c_stream.avail_in = static_cast<uInt>( + page_zip_fields_encode(n_fields, index, trx_id_col, fields)); c_stream.next_in = fields; if (UNIV_LIKELY(!trx_id_col)) { trx_id_col = ULINT_UNDEFINED; @@ -1425,9 +1429,9 @@ page_zip_compress( /* Compress any trailing garbage, in case the last record was allocated from an originally longer space on the free list, or the data of the last record from page_zip_compress_sec(). */ - c_stream.avail_in - = page_header_get_field(page, PAGE_HEAP_TOP) - - (c_stream.next_in - page); + c_stream.avail_in = static_cast<uInt>( + page_header_get_field(page, PAGE_HEAP_TOP) + - (c_stream.next_in - page)); ut_a(c_stream.avail_in <= UNIV_PAGE_SIZE - PAGE_ZIP_START - PAGE_DIR); UNIV_MEM_ASSERT_RW(c_stream.next_in, c_stream.avail_in); @@ -2227,15 +2231,15 @@ page_zip_decompress_node_ptrs( const byte* storage; /* Subtract the space reserved for uncompressed data. */ - d_stream->avail_in -= n_dense - * (PAGE_ZIP_DIR_SLOT_SIZE + REC_NODE_PTR_SIZE); + d_stream->avail_in -= static_cast<uInt>( + n_dense * (PAGE_ZIP_DIR_SLOT_SIZE + REC_NODE_PTR_SIZE)); /* Decompress the records in heap_no order. */ for (slot = 0; slot < n_dense; slot++) { rec_t* rec = recs[slot]; - d_stream->avail_out = rec - REC_N_NEW_EXTRA_BYTES - - d_stream->next_out; + d_stream->avail_out = static_cast<uInt>( + rec - REC_N_NEW_EXTRA_BYTES - d_stream->next_out); ut_ad(d_stream->avail_out < UNIV_PAGE_SIZE - PAGE_ZIP_START - PAGE_DIR); @@ -2271,8 +2275,8 @@ page_zip_decompress_node_ptrs( ut_ad(!rec_offs_any_extern(offsets)); /* Decompress the data bytes, except node_ptr. */ - d_stream->avail_out = rec_offs_data_size(offsets) - - REC_NODE_PTR_SIZE; + d_stream->avail_out =static_cast<uInt>( + rec_offs_data_size(offsets) - REC_NODE_PTR_SIZE); switch (inflate(d_stream, Z_SYNC_FLUSH)) { case Z_STREAM_END: @@ -2301,9 +2305,9 @@ page_zip_decompress_node_ptrs( /* Decompress any trailing garbage, in case the last record was allocated from an originally longer space on the free list. */ - d_stream->avail_out = page_header_get_field(page_zip->data, - PAGE_HEAP_TOP) - - page_offset(d_stream->next_out); + d_stream->avail_out = static_cast<uInt>( + page_header_get_field(page_zip->data, PAGE_HEAP_TOP) + - page_offset(d_stream->next_out)); if (UNIV_UNLIKELY(d_stream->avail_out > UNIV_PAGE_SIZE - PAGE_ZIP_START - PAGE_DIR)) { @@ -2416,14 +2420,15 @@ page_zip_decompress_sec( ut_a(!dict_index_is_clust(index)); /* Subtract the space reserved for uncompressed data. */ - d_stream->avail_in -= n_dense * PAGE_ZIP_DIR_SLOT_SIZE; + d_stream->avail_in -= static_cast<uint>( + n_dense * PAGE_ZIP_DIR_SLOT_SIZE); for (slot = 0; slot < n_dense; slot++) { rec_t* rec = recs[slot]; /* Decompress everything up to this record. */ - d_stream->avail_out = rec - REC_N_NEW_EXTRA_BYTES - - d_stream->next_out; + d_stream->avail_out = static_cast<uint>( + rec - REC_N_NEW_EXTRA_BYTES - d_stream->next_out); if (UNIV_LIKELY(d_stream->avail_out)) { switch (inflate(d_stream, Z_SYNC_FLUSH)) { @@ -2454,9 +2459,9 @@ page_zip_decompress_sec( /* Decompress the data of the last record and any trailing garbage, in case the last record was allocated from an originally longer space on the free list. */ - d_stream->avail_out = page_header_get_field(page_zip->data, - PAGE_HEAP_TOP) - - page_offset(d_stream->next_out); + d_stream->avail_out = static_cast<uInt>( + page_header_get_field(page_zip->data, PAGE_HEAP_TOP) + - page_offset(d_stream->next_out)); if (UNIV_UNLIKELY(d_stream->avail_out > UNIV_PAGE_SIZE - PAGE_ZIP_START - PAGE_DIR)) { @@ -2569,7 +2574,8 @@ page_zip_decompress_clust_ext( return(FALSE); } - d_stream->avail_out = dst - d_stream->next_out; + d_stream->avail_out = static_cast<uInt>( + dst - d_stream->next_out); switch (inflate(d_stream, Z_SYNC_FLUSH)) { case Z_STREAM_END: @@ -2600,7 +2606,8 @@ page_zip_decompress_clust_ext( ut_ad(len >= BTR_EXTERN_FIELD_REF_SIZE); dst += len - BTR_EXTERN_FIELD_REF_SIZE; - d_stream->avail_out = dst - d_stream->next_out; + d_stream->avail_out = static_cast<uInt>( + dst - d_stream->next_out); switch (inflate(d_stream, Z_SYNC_FLUSH)) { case Z_STREAM_END: case Z_OK: @@ -2666,16 +2673,17 @@ page_zip_decompress_clust( ut_a(dict_index_is_clust(index)); /* Subtract the space reserved for uncompressed data. */ - d_stream->avail_in -= n_dense * (PAGE_ZIP_DIR_SLOT_SIZE - + DATA_TRX_ID_LEN - + DATA_ROLL_PTR_LEN); + d_stream->avail_in -= static_cast<uInt>(n_dense) + * (PAGE_ZIP_DIR_SLOT_SIZE + + DATA_TRX_ID_LEN + + DATA_ROLL_PTR_LEN); /* Decompress the records in heap_no order. */ for (slot = 0; slot < n_dense; slot++) { rec_t* rec = recs[slot]; - d_stream->avail_out = rec - REC_N_NEW_EXTRA_BYTES - - d_stream->next_out; + d_stream->avail_out =static_cast<uInt>( + rec - REC_N_NEW_EXTRA_BYTES - d_stream->next_out); ut_ad(d_stream->avail_out < UNIV_PAGE_SIZE - PAGE_ZIP_START - PAGE_DIR); @@ -2733,7 +2741,8 @@ page_zip_decompress_clust( goto zlib_error; } - d_stream->avail_out = dst - d_stream->next_out; + d_stream->avail_out = static_cast<uInt>( + dst - d_stream->next_out); switch (inflate(d_stream, Z_SYNC_FLUSH)) { case Z_STREAM_END: @@ -2762,8 +2771,8 @@ page_zip_decompress_clust( } /* Decompress the last bytes of the record. */ - d_stream->avail_out = rec_get_end(rec, offsets) - - d_stream->next_out; + d_stream->avail_out = static_cast<uInt>( + rec_get_end(rec, offsets) - d_stream->next_out); switch (inflate(d_stream, Z_SYNC_FLUSH)) { case Z_STREAM_END: @@ -2783,9 +2792,9 @@ page_zip_decompress_clust( /* Decompress any trailing garbage, in case the last record was allocated from an originally longer space on the free list. */ - d_stream->avail_out = page_header_get_field(page_zip->data, - PAGE_HEAP_TOP) - - page_offset(d_stream->next_out); + d_stream->avail_out = static_cast<uInt>( + page_header_get_field(page_zip->data, PAGE_HEAP_TOP) + - page_offset(d_stream->next_out)); if (UNIV_UNLIKELY(d_stream->avail_out > UNIV_PAGE_SIZE - PAGE_ZIP_START - PAGE_DIR)) { @@ -3041,7 +3050,8 @@ zlib_error: d_stream.next_in = page_zip->data + PAGE_DATA; /* Subtract the space reserved for the page header and the end marker of the modification log. */ - d_stream.avail_in = page_zip_get_size(page_zip) - (PAGE_DATA + 1); + d_stream.avail_in = static_cast<uInt>( + page_zip_get_size(page_zip) - (PAGE_DATA + 1)); d_stream.next_out = page + PAGE_ZIP_START; d_stream.avail_out = UNIV_PAGE_SIZE - PAGE_ZIP_START; @@ -3500,7 +3510,7 @@ page_zip_write_rec_ext( externs -= blob_no * BTR_EXTERN_FIELD_REF_SIZE; if (create) { - page_zip->n_blobs += n_ext; + page_zip->n_blobs += static_cast<unsigned>(n_ext); ASSERT_ZERO_BLOB(ext_end - n_ext * BTR_EXTERN_FIELD_REF_SIZE); memmove(ext_end - n_ext @@ -4408,7 +4418,7 @@ page_zip_dir_delete( * BTR_EXTERN_FIELD_REF_SIZE; externs -= blob_no * BTR_EXTERN_FIELD_REF_SIZE; - page_zip->n_blobs -= n_ext; + page_zip->n_blobs -= static_cast<unsigned>(n_ext); /* Shift and zero fill the array. */ memmove(ext_end + n_ext * BTR_EXTERN_FIELD_REF_SIZE, ext_end, (page_zip->n_blobs - blob_no) @@ -4863,8 +4873,10 @@ page_zip_calc_checksum( adler = adler32(0L, s + FIL_PAGE_OFFSET, FIL_PAGE_LSN - FIL_PAGE_OFFSET); adler = adler32(adler, s + FIL_PAGE_TYPE, 2); - adler = adler32(adler, s + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, - size - FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); + adler = adler32( + adler, s + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, + static_cast<uInt>(size) + - FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); return((ulint) adler); case SRV_CHECKSUM_ALGORITHM_NONE: @@ -4894,8 +4906,8 @@ page_zip_verify_checksum( ib_uint32_t crc32 = 0 /* silence bogus warning */; ib_uint32_t innodb = 0 /* silence bogus warning */; - stored = mach_read_from_4( - (const unsigned char*) data + FIL_PAGE_SPACE_OR_CHKSUM); + stored = static_cast<ib_uint32_t>(mach_read_from_4( + static_cast<const unsigned char*>(data) + FIL_PAGE_SPACE_OR_CHKSUM)); /* declare empty pages non-corrupted */ if (stored == 0) { @@ -4910,9 +4922,9 @@ page_zip_verify_checksum( return(TRUE); } - calc = page_zip_calc_checksum( + calc = static_cast<ib_uint32_t>(page_zip_calc_checksum( data, size, static_cast<srv_checksum_algorithm_t>( - srv_checksum_algorithm)); + srv_checksum_algorithm))); if (stored == calc) { return(TRUE); @@ -4928,15 +4940,15 @@ page_zip_verify_checksum( return(TRUE); } crc32 = calc; - innodb = page_zip_calc_checksum( - data, size, SRV_CHECKSUM_ALGORITHM_INNODB); + innodb = static_cast<ib_uint32_t>(page_zip_calc_checksum( + data, size, SRV_CHECKSUM_ALGORITHM_INNODB)); break; case SRV_CHECKSUM_ALGORITHM_INNODB: if (stored == BUF_NO_CHECKSUM_MAGIC) { return(TRUE); } - crc32 = page_zip_calc_checksum( - data, size, SRV_CHECKSUM_ALGORITHM_CRC32); + crc32 = static_cast<ib_uint32_t>(page_zip_calc_checksum( + data, size, SRV_CHECKSUM_ALGORITHM_CRC32)); innodb = calc; break; case SRV_CHECKSUM_ALGORITHM_NONE: diff --git a/storage/xtradb/pars/lexyy.cc b/storage/xtradb/pars/lexyy.cc index 16458dda637..07476320e03 100644 --- a/storage/xtradb/pars/lexyy.cc +++ b/storage/xtradb/pars/lexyy.cc @@ -35,7 +35,7 @@ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. + * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 @@ -2424,8 +2424,8 @@ static int yy_get_next_buffer (void) else { - int num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + int num_to_read = static_cast<int>( + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1); while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ @@ -2438,7 +2438,7 @@ static int yy_get_next_buffer (void) if ( b->yy_is_our_buffer ) { - int new_size = b->yy_buf_size * 2; + int new_size = static_cast<int>(b->yy_buf_size * 2); if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; @@ -2459,8 +2459,9 @@ static int yy_get_next_buffer (void) (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; + num_to_read = static_cast<int>( + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + - number_to_move - 1); } @@ -2643,7 +2644,7 @@ static int yy_get_next_buffer (void) /** Immediately switch to a different input stream. * @param input_file A readable stream. - * + * * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file ) @@ -2661,7 +2662,7 @@ static int yy_get_next_buffer (void) /** Switch to a different input buffer. * @param new_buffer The new input buffer. - * + * */ __attribute__((unused)) static void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) { @@ -2705,7 +2706,7 @@ static void yy_load_buffer_state (void) /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * + * * @return the allocated buffer state. */ static YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) @@ -2734,7 +2735,7 @@ static void yy_load_buffer_state (void) /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() - * + * */ void yy_delete_buffer (YY_BUFFER_STATE b ) { @@ -2759,7 +2760,7 @@ static void yy_load_buffer_state (void) { int oerrno = errno; - + yy_flush_buffer(b ); b->yy_input_file = file; @@ -2775,13 +2776,13 @@ static void yy_load_buffer_state (void) } b->yy_is_interactive = 0; - + errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * + * */ void yy_flush_buffer (YY_BUFFER_STATE b ) { @@ -2810,7 +2811,7 @@ static void yy_load_buffer_state (void) * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. - * + * */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) { @@ -2840,7 +2841,7 @@ void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. - * + * */ void yypop_buffer_state (void) { @@ -2864,7 +2865,7 @@ void yypop_buffer_state (void) static void yyensure_buffer_stack (void) { int num_to_alloc; - + if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this @@ -2890,7 +2891,8 @@ static void yyensure_buffer_stack (void) /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; - num_to_alloc = (yy_buffer_stack_max) + grow_size; + num_to_alloc = static_cast<int>( + (yy_buffer_stack_max) + grow_size); (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) @@ -2934,7 +2936,7 @@ static void yy_fatal_error (yyconst char* msg ) /* Accessor methods (get/set functions) to struct members. */ /** Get the current line number. - * + * */ int yyget_lineno (void) { @@ -2943,7 +2945,7 @@ int yyget_lineno (void) } /** Get the input stream. - * + * */ FILE *yyget_in (void) { @@ -2951,7 +2953,7 @@ FILE *yyget_in (void) } /** Get the output stream. - * + * */ FILE *yyget_out (void) { @@ -2959,7 +2961,7 @@ FILE *yyget_out (void) } /** Get the length of the current token. - * + * */ yy_size_t yyget_leng (void) { @@ -2967,7 +2969,7 @@ yy_size_t yyget_leng (void) } /** Get the current token. - * + * */ char *yyget_text (void) @@ -2977,18 +2979,18 @@ char *yyget_text (void) /** Set the current line number. * @param line_number - * + * */ void yyset_lineno (int line_number ) { - + yylineno = line_number; } /** Set the input stream. This does not discard the current * input buffer. * @param in_str A readable stream. - * + * * @see yy_switch_to_buffer */ void yyset_in (FILE * in_str ) @@ -3042,7 +3044,7 @@ static int yy_init_globals (void) /* yylex_destroy is for both reentrant and non-reentrant scanners. */ __attribute__((unused)) static int yylex_destroy (void) { - + /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer(YY_CURRENT_BUFFER ); diff --git a/storage/xtradb/pars/pars0pars.cc b/storage/xtradb/pars/pars0pars.cc index fff0b1efd01..f051481184b 100644 --- a/storage/xtradb/pars/pars0pars.cc +++ b/storage/xtradb/pars/pars0pars.cc @@ -2160,8 +2160,9 @@ pars_get_lex_chars( { int len; - len = pars_sym_tab_global->string_len - - pars_sym_tab_global->next_char_pos; + len = static_cast<int>( + pars_sym_tab_global->string_len + - pars_sym_tab_global->next_char_pos); if (len == 0) { #ifdef YYDEBUG /* fputs("SQL string ends\n", stderr); */ diff --git a/storage/xtradb/rem/rem0cmp.cc b/storage/xtradb/rem/rem0cmp.cc index db0fdf3ee21..426cf9e3ac5 100644 --- a/storage/xtradb/rem/rem0cmp.cc +++ b/storage/xtradb/rem/rem0cmp.cc @@ -316,8 +316,8 @@ cmp_dfield_dfield_like_prefix( dfield_t* dfield1,/* in: data field; must have type field set */ dfield_t* dfield2)/* in: data field */ { - const dtype_t* type; - ulint ret; + const dtype_t* type; + int ret; ut_ad(dfield_check_typed(dfield1)); @@ -325,21 +325,21 @@ cmp_dfield_dfield_like_prefix( if (type->mtype >= DATA_FLOAT) { ret = innobase_mysql_cmp_prefix( - (int)(type->prtype & DATA_MYSQL_TYPE_MASK), - (uint) dtype_get_charset_coll(type->prtype), + static_cast<int>(type->prtype & DATA_MYSQL_TYPE_MASK), + static_cast<uint>(dtype_get_charset_coll(type->prtype)), + static_cast<byte*>(dfield_get_data(dfield1)), + static_cast<uint>(dfield_get_len(dfield1)), + static_cast<byte*>(dfield_get_data(dfield2)), + static_cast<uint>(dfield_get_len(dfield2))); + } else { + ret = (cmp_data_data_like_prefix( static_cast<byte*>(dfield_get_data(dfield1)), dfield_get_len(dfield1), - static_cast<byte*>(dfield_get_data(dfield2)), - dfield_get_len(dfield2)); - } else { - ret = (cmp_data_data_like_prefix( - static_cast<byte*>(dfield_get_data(dfield1)), - dfield_get_len(dfield1), - static_cast<byte*>(dfield_get_data(dfield2)), - dfield_get_len(dfield2))); - } - - return(ret); + static_cast<byte*>(dfield_get_data(dfield2)), + dfield_get_len(dfield2))); + } + + return(ret); } /*************************************************************//** @@ -506,7 +506,8 @@ cmp_data_data_slow_varchar( } } - return(i == lhs_len && i == rhs_len) ? 0 : rhs_len - lhs_len; + return((i == lhs_len && i == rhs_len) ? 0 : + static_cast<int>(rhs_len - lhs_len)); } /***************************************************************** diff --git a/storage/xtradb/row/row0ftsort.cc b/storage/xtradb/row/row0ftsort.cc index be62aa34a07..54f6f7bcc0f 100644 --- a/storage/xtradb/row/row0ftsort.cc +++ b/storage/xtradb/row/row0ftsort.cc @@ -872,7 +872,9 @@ func_exit: mutex_exit(&psort_info->mutex); if (UT_LIST_GET_LEN(psort_info->fts_doc_list) > 0) { - ut_ad(error != DB_SUCCESS); + /* child can exit either with error or told by parent. */ + ut_ad(error != DB_SUCCESS + || psort_info->state == FTS_PARENT_EXITING); } /* Free fts doc list in case of error. */ @@ -1194,7 +1196,7 @@ row_fts_sel_tree_propagate( sel_tree[parent] = selected; - return(parent); + return(static_cast<int>(parent)); } /*********************************************************************//** @@ -1214,8 +1216,8 @@ row_fts_sel_tree_update( ulint i; for (i = 1; i <= height; i++) { - propagated = row_fts_sel_tree_propagate( - propagated, sel_tree, mrec, offsets, index); + propagated = static_cast<ulint>(row_fts_sel_tree_propagate( + static_cast<int>(propagated), sel_tree, mrec, offsets, index)); } return(sel_tree[0]); @@ -1239,8 +1241,8 @@ row_fts_build_sel_tree_level( ulint i; ulint num_item; - start = (1 << level) - 1; - num_item = (1 << level); + start = static_cast<ulint>((1 << level) - 1); + num_item = static_cast<ulint>(1 << level); for (i = 0; i < num_item; i++) { child_left = sel_tree[(start + i) * 2 + 1]; @@ -1315,8 +1317,9 @@ row_fts_build_sel_tree( sel_tree[i + start] = i; } - for (i = treelevel - 1; i >=0; i--) { - row_fts_build_sel_tree_level(sel_tree, i, mrec, offsets, index); + for (i = static_cast<int>(treelevel) - 1; i >= 0; i--) { + row_fts_build_sel_tree_level( + sel_tree, static_cast<ulint>(i), mrec, offsets, index); } return(treelevel); @@ -1501,7 +1504,7 @@ row_fts_merge_insert( mrec[i], mrec[min_rec], offsets[i], offsets[min_rec], index, NULL) < 0) { - min_rec = i; + min_rec = static_cast<int>(i); } } } else { diff --git a/storage/xtradb/row/row0ins.cc b/storage/xtradb/row/row0ins.cc index 34e34925b9a..f8ca40fac12 100644 --- a/storage/xtradb/row/row0ins.cc +++ b/storage/xtradb/row/row0ins.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2014, 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 @@ -2995,6 +2995,10 @@ row_ins_index_entry( dtuple_t* entry, /*!< in/out: index entry to insert */ que_thr_t* thr) /*!< in: query thread */ { + DBUG_EXECUTE_IF("row_ins_index_entry_timeout", { + DBUG_SET("-d,row_ins_index_entry_timeout"); + return(DB_LOCK_WAIT);}); + if (dict_index_is_clust(index)) { return(row_ins_clust_index_entry(index, entry, thr, 0)); } else { diff --git a/storage/xtradb/row/row0log.cc b/storage/xtradb/row/row0log.cc index 3a01b5ed55a..1240cf7fcc5 100644 --- a/storage/xtradb/row/row0log.cc +++ b/storage/xtradb/row/row0log.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2011, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2011, 2014, 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 @@ -493,9 +493,8 @@ row_log_table_delete( dict_index_t* index, /*!< in/out: clustered index, S-latched or X-latched */ const ulint* offsets,/*!< in: rec_get_offsets(rec,index) */ - bool purge, /*!< in: true=purging BLOBs */ - trx_id_t trx_id) /*!< in: DB_TRX_ID of the record before - it was deleted */ + const byte* sys) /*!< in: DB_TRX_ID,DB_ROLL_PTR that should + be logged, or NULL to use those in rec */ { ulint old_pk_extra_size; ulint old_pk_size; @@ -527,22 +526,21 @@ row_log_table_delete( ut_ad(dict_index_is_clust(new_index)); ut_ad(!dict_index_is_online_ddl(new_index)); - /* Create the tuple PRIMARY KEY, DB_TRX_ID in the new_table. */ + /* Create the tuple PRIMARY KEY,DB_TRX_ID,DB_ROLL_PTR in new_table. */ if (index->online_log->same_pk) { - byte* db_trx_id; dtuple_t* tuple; ut_ad(new_index->n_uniq == index->n_uniq); - /* The PRIMARY KEY and DB_TRX_ID are in the first + /* The PRIMARY KEY and DB_TRX_ID,DB_ROLL_PTR are in the first fields of the record. */ heap = mem_heap_create( DATA_TRX_ID_LEN - + DTUPLE_EST_ALLOC(new_index->n_uniq + 1)); - old_pk = tuple = dtuple_create(heap, new_index->n_uniq + 1); + + DTUPLE_EST_ALLOC(new_index->n_uniq + 2)); + old_pk = tuple = dtuple_create(heap, new_index->n_uniq + 2); dict_index_copy_types(tuple, new_index, tuple->n_fields); dtuple_set_n_fields_cmp(tuple, new_index->n_uniq); - for (ulint i = 0; i < new_index->n_uniq; i++) { + for (ulint i = 0; i < dtuple_get_n_fields(tuple); i++) { ulint len; const void* field = rec_get_nth_field( rec, offsets, i, &len); @@ -553,42 +551,33 @@ row_log_table_delete( dfield_set_data(dfield, field, len); } - db_trx_id = static_cast<byte*>( - mem_heap_alloc(heap, DATA_TRX_ID_LEN)); - trx_write_trx_id(db_trx_id, trx_id); - - dfield_set_data(dtuple_get_nth_field(tuple, new_index->n_uniq), - db_trx_id, DATA_TRX_ID_LEN); + if (sys) { + dfield_set_data( + dtuple_get_nth_field(tuple, + new_index->n_uniq), + sys, DATA_TRX_ID_LEN); + dfield_set_data( + dtuple_get_nth_field(tuple, + new_index->n_uniq + 1), + sys + DATA_TRX_ID_LEN, DATA_ROLL_PTR_LEN); + } } else { /* The PRIMARY KEY has changed. Translate the tuple. */ - dfield_t* dfield; - - old_pk = row_log_table_get_pk(rec, index, offsets, &heap); + old_pk = row_log_table_get_pk( + rec, index, offsets, NULL, &heap); if (!old_pk) { ut_ad(index->online_log->error != DB_SUCCESS); + if (heap) { + goto func_exit; + } return; } - - /* Remove DB_ROLL_PTR. */ - ut_ad(dtuple_get_n_fields_cmp(old_pk) - == dict_index_get_n_unique(new_index)); - ut_ad(dtuple_get_n_fields(old_pk) - == dict_index_get_n_unique(new_index) + 2); - const_cast<ulint&>(old_pk->n_fields)--; - - /* Overwrite DB_TRX_ID with the old trx_id. */ - dfield = dtuple_get_nth_field(old_pk, new_index->n_uniq); - ut_ad(dfield_get_type(dfield)->mtype == DATA_SYS); - ut_ad(dfield_get_type(dfield)->prtype - == (DATA_NOT_NULL | DATA_TRX_ID)); - ut_ad(dfield_get_len(dfield) == DATA_TRX_ID_LEN); - dfield_dup(dfield, heap); - trx_write_trx_id(static_cast<byte*>(dfield->data), trx_id); } - ut_ad(dtuple_get_n_fields(old_pk) > 1); ut_ad(DATA_TRX_ID_LEN == dtuple_get_nth_field( + old_pk, old_pk->n_fields - 2)->len); + ut_ad(DATA_ROLL_PTR_LEN == dtuple_get_nth_field( old_pk, old_pk->n_fields - 1)->len); old_pk_size = rec_get_converted_size_temp( new_index, old_pk->fields, old_pk->n_fields, @@ -600,7 +589,7 @@ row_log_table_delete( /* Log enough prefix of the BLOB unless both the old and new table are in COMPACT or REDUNDANT format, which store the prefix in the clustered index record. */ - if (purge && rec_offs_any_extern(offsets) + if (rec_offs_any_extern(offsets) && (dict_table_get_format(index->table) >= UNIV_FORMAT_B || dict_table_get_format(new_table) >= UNIV_FORMAT_B)) { @@ -665,6 +654,7 @@ row_log_table_delete( index->online_log, b, mrec_size, avail_size); } +func_exit: mem_heap_free(heap); } @@ -1018,6 +1008,8 @@ row_log_table_get_pk( dict_index_t* index, /*!< in/out: clustered index, S-latched or X-latched */ const ulint* offsets,/*!< in: rec_get_offsets(rec,index) */ + byte* sys, /*!< out: DB_TRX_ID,DB_ROLL_PTR for + row_log_table_delete(), or NULL */ mem_heap_t** heap) /*!< in/out: memory heap where allocated */ { dtuple_t* tuple = NULL; @@ -1036,6 +1028,31 @@ row_log_table_get_pk( if (log->same_pk) { /* The PRIMARY KEY columns are unchanged. */ + if (sys) { + /* Store the DB_TRX_ID,DB_ROLL_PTR. */ + ulint trx_id_offs = index->trx_id_offset; + + if (!trx_id_offs) { + ulint pos = dict_index_get_sys_col_pos( + index, DATA_TRX_ID); + ulint len; + ut_ad(pos > 0); + + if (!offsets) { + offsets = rec_get_offsets( + rec, index, NULL, pos + 1, + heap); + } + + trx_id_offs = rec_get_nth_field_offs( + offsets, pos, &len); + ut_ad(len == DATA_TRX_ID_LEN); + } + + memcpy(sys, rec + trx_id_offs, + DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN); + } + return(NULL); } @@ -1145,6 +1162,20 @@ err_exit: const byte* trx_roll = rec + row_get_trx_id_offset(index, offsets); + /* Copy the fields, because the fields will be updated + or the record may be moved somewhere else in the B-tree + as part of the upcoming operation. */ + if (sys) { + memcpy(sys, trx_roll, + DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN); + trx_roll = sys; + } else { + trx_roll = static_cast<const byte*>( + mem_heap_dup( + *heap, trx_roll, + DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN)); + } + dfield_set_data(dtuple_get_nth_field(tuple, new_n_uniq), trx_roll, DATA_TRX_ID_LEN); dfield_set_data(dtuple_get_nth_field(tuple, new_n_uniq + 1), @@ -1263,10 +1294,13 @@ row_log_table_apply_convert_mrec( mem_heap_t* heap, /*!< in/out: memory heap */ trx_id_t trx_id, /*!< in: DB_TRX_ID of mrec */ dberr_t* error) /*!< out: DB_SUCCESS or + DB_MISSING_HISTORY or reason of failure */ { dtuple_t* row; + *error = DB_SUCCESS; + /* This is based on row_build(). */ if (log->add_cols) { row = dtuple_copy(log->add_cols, heap); @@ -1308,7 +1342,7 @@ row_log_table_apply_convert_mrec( dfield_t* dfield = dtuple_get_nth_field(row, col_no); ulint len; - const byte* data= NULL; + const byte* data; if (rec_offs_nth_extern(offsets, i)) { ut_ad(rec_offs_any_extern(offsets)); @@ -1328,29 +1362,26 @@ row_log_table_apply_convert_mrec( && p->second.is_freed(log->head.total)) { /* This BLOB has been freed. We must not access the row. */ - row = NULL; + *error = DB_MISSING_HISTORY; + dfield_set_data(dfield, data, len); + dfield_set_ext(dfield); + goto blob_done; } } - if (row) { - data = btr_rec_copy_externally_stored_field( - mrec, offsets, - dict_table_zip_size(index->table), - i, &len, heap); - ut_a(data); - } - + data = btr_rec_copy_externally_stored_field( + mrec, offsets, + dict_table_zip_size(index->table), + i, &len, heap); + ut_a(data); + dfield_set_data(dfield, data, len); +blob_done: rw_lock_x_unlock(dict_index_get_lock(index)); - - if (!row) { - goto func_exit; - } } else { data = rec_get_nth_field(mrec, offsets, i, &len); + dfield_set_data(dfield, data, len); } - dfield_set_data(dfield, data, len); - /* See if any columns were changed to NULL or NOT NULL. */ const dict_col_t* new_col = dict_table_get_nth_col(log->table, col_no); @@ -1379,8 +1410,6 @@ row_log_table_apply_convert_mrec( dfield_get_type(dfield))); } -func_exit: - *error = DB_SUCCESS; return(row); } @@ -1479,22 +1508,32 @@ row_log_table_apply_insert( const dtuple_t* row = row_log_table_apply_convert_mrec( mrec, dup->index, offsets, log, heap, trx_id, &error); - ut_ad(error == DB_SUCCESS || !row); - /* Handling of duplicate key error requires storing - of offending key in a record buffer. */ - ut_ad(error != DB_DUPLICATE_KEY); - - if (error != DB_SUCCESS) + switch (error) { + case DB_MISSING_HISTORY: + ut_ad(log->blobs); + /* Because some BLOBs are missing, we know that the + transaction was rolled back later (a rollback of + an insert can free BLOBs). + We can simply skip the insert: the subsequent + ROW_T_DELETE will be ignored, or a ROW_T_UPDATE will + be interpreted as ROW_T_INSERT. */ + return(DB_SUCCESS); + case DB_SUCCESS: + ut_ad(row != NULL); + break; + default: + ut_ad(0); + case DB_INVALID_NULL: + ut_ad(row == NULL); return(error); + } - if (row) { - error = row_log_table_apply_insert_low( - thr, row, trx_id, offsets_heap, heap, dup); - if (error != DB_SUCCESS) { - /* Report the erroneous row using the new - version of the table. */ - innobase_row_to_mysql(dup->table, log->table, row); - } + error = row_log_table_apply_insert_low( + thr, row, trx_id, offsets_heap, heap, dup); + if (error != DB_SUCCESS) { + /* Report the erroneous row using the new + version of the table. */ + innobase_row_to_mysql(dup->table, log->table, row); } return(error); } @@ -1613,10 +1652,11 @@ row_log_table_apply_delete( mem_heap_t* offsets_heap, /*!< in/out: memory heap that can be emptied */ mem_heap_t* heap, /*!< in/out: memory heap */ - dict_table_t* new_table, /*!< in: rebuilt table */ + const row_log_t* log, /*!< in: online log */ const row_ext_t* save_ext) /*!< in: saved external field info, or NULL */ { + dict_table_t* new_table = log->table; dict_index_t* index = dict_table_get_first_index(new_table); dtuple_t* old_pk; mtr_t mtr; @@ -1624,15 +1664,14 @@ row_log_table_apply_delete( ulint* offsets; ut_ad(rec_offs_n_fields(moffsets) - == dict_index_get_n_unique(index) + 1); + == dict_index_get_n_unique(index) + 2); ut_ad(!rec_offs_any_extern(moffsets)); /* Convert the row to a search tuple. */ - old_pk = dtuple_create(heap, index->n_uniq + 1); - dict_index_copy_types(old_pk, index, old_pk->n_fields); - dtuple_set_n_fields_cmp(old_pk, index->n_uniq); + old_pk = dtuple_create(heap, index->n_uniq); + dict_index_copy_types(old_pk, index, index->n_uniq); - for (ulint i = 0; i <= index->n_uniq; i++) { + for (ulint i = 0; i < index->n_uniq; i++) { ulint len; const void* field; field = rec_get_nth_field(mrec, moffsets, i, &len); @@ -1666,6 +1705,10 @@ flag_ok: all_done: mtr_commit(&mtr); /* The record was not found. All done. */ + /* This should only happen when an earlier + ROW_T_INSERT was skipped or + ROW_T_UPDATE was interpreted as ROW_T_DELETE + due to BLOBs having been freed by rollback. */ return(DB_SUCCESS); } @@ -1675,19 +1718,38 @@ all_done: ut_a(!rec_offs_any_null_extern(btr_pcur_get_rec(&pcur), offsets)); #endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */ - /* Only remove the record if DB_TRX_ID matches what was - buffered. */ + /* Only remove the record if DB_TRX_ID,DB_ROLL_PTR match. */ { ulint len; - const void* mrec_trx_id + const byte* mrec_trx_id = rec_get_nth_field(mrec, moffsets, trx_id_col, &len); ut_ad(len == DATA_TRX_ID_LEN); - const void* rec_trx_id + const byte* rec_trx_id = rec_get_nth_field(btr_pcur_get_rec(&pcur), offsets, trx_id_col, &len); ut_ad(len == DATA_TRX_ID_LEN); - if (memcmp(mrec_trx_id, rec_trx_id, DATA_TRX_ID_LEN)) { + + ut_ad(rec_get_nth_field(mrec, moffsets, trx_id_col + 1, &len) + == mrec_trx_id + DATA_TRX_ID_LEN); + ut_ad(len == DATA_ROLL_PTR_LEN); + ut_ad(rec_get_nth_field(btr_pcur_get_rec(&pcur), offsets, + trx_id_col + 1, &len) + == rec_trx_id + DATA_TRX_ID_LEN); + ut_ad(len == DATA_ROLL_PTR_LEN); + + if (memcmp(mrec_trx_id, rec_trx_id, + DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN)) { + /* The ROW_T_DELETE was logged for a different + PRIMARY KEY,DB_TRX_ID,DB_ROLL_PTR. + This is possible if a ROW_T_INSERT was skipped + or a ROW_T_UPDATE was interpreted as ROW_T_DELETE + because some BLOBs were missing due to + (1) rolling back the initial insert, or + (2) purging the BLOB for a later ROW_T_DELETE + (3) purging 'old values' for a later ROW_T_UPDATE + or ROW_T_DELETE. */ + ut_ad(!log->same_pk); goto all_done; } } @@ -1731,17 +1793,32 @@ row_log_table_apply_update( == dict_index_get_n_unique(index)); ut_ad(dtuple_get_n_fields(old_pk) == dict_index_get_n_unique(index) - + (dup->index->online_log->same_pk ? 0 : 2)); + + (log->same_pk ? 0 : 2)); row = row_log_table_apply_convert_mrec( mrec, dup->index, offsets, log, heap, trx_id, &error); - ut_ad(error == DB_SUCCESS || !row); - /* Handling of duplicate key error requires storing - of offending key in a record buffer. */ - ut_ad(error != DB_DUPLICATE_KEY); - - if (!row) { + switch (error) { + case DB_MISSING_HISTORY: + /* The record contained BLOBs that are now missing. */ + ut_ad(log->blobs); + /* Whether or not we are updating the PRIMARY KEY, we + know that there should be a subsequent + ROW_T_DELETE for rolling back a preceding ROW_T_INSERT, + overriding this ROW_T_UPDATE record. (*1) + + This allows us to interpret this ROW_T_UPDATE + as ROW_T_DELETE. + + When applying the subsequent ROW_T_DELETE, no matching + record will be found. */ + case DB_SUCCESS: + ut_ad(row != NULL); + break; + default: + ut_ad(0); + case DB_INVALID_NULL: + ut_ad(row == NULL); return(error); } @@ -1764,10 +1841,57 @@ row_log_table_apply_update( if (page_rec_is_infimum(btr_pcur_get_rec(&pcur)) || btr_pcur_get_low_match(&pcur) < index->n_uniq) { - ut_ad(0); - error = DB_CORRUPTION; + /* The record was not found. This should only happen + when an earlier ROW_T_INSERT or ROW_T_UPDATE was + diverted because BLOBs were freed when the insert was + later rolled back. */ + + ut_ad(log->blobs); + + if (error == DB_SUCCESS) { + /* An earlier ROW_T_INSERT could have been + skipped because of a missing BLOB, like this: + + BEGIN; + INSERT INTO t SET blob_col='blob value'; + UPDATE t SET blob_col=''; + ROLLBACK; + + This would generate the following records: + ROW_T_INSERT (referring to 'blob value') + ROW_T_UPDATE + ROW_T_UPDATE (referring to 'blob value') + ROW_T_DELETE + [ROLLBACK removes the 'blob value'] + + The ROW_T_INSERT would have been skipped + because of a missing BLOB. Now we are + executing the first ROW_T_UPDATE. + The second ROW_T_UPDATE (for the ROLLBACK) + would be interpreted as ROW_T_DELETE, because + the BLOB would be missing. + + We could probably assume that the transaction + has been rolled back and simply skip the + 'insert' part of this ROW_T_UPDATE record. + However, there might be some complex scenario + that could interfere with such a shortcut. + So, we will insert the row (and risk + introducing a bogus duplicate key error + for the ALTER TABLE), and a subsequent + ROW_T_UPDATE or ROW_T_DELETE will delete it. */ + mtr_commit(&mtr); + error = row_log_table_apply_insert_low( + thr, row, trx_id, offsets_heap, heap, dup); + } else { + /* Some BLOBs are missing, so we are interpreting + this ROW_T_UPDATE as ROW_T_DELETE (see *1). + Because the record was not found, we do nothing. */ + ut_ad(error == DB_MISSING_HISTORY); + error = DB_SUCCESS; func_exit: - mtr_commit(&mtr); + mtr_commit(&mtr); + } func_exit_committed: ut_ad(mtr.state == MTR_COMMITTED); @@ -1780,19 +1904,76 @@ func_exit_committed: return(error); } - /* Update the record. */ + /* Prepare to update (or delete) the record. */ ulint* cur_offsets = rec_get_offsets( btr_pcur_get_rec(&pcur), index, NULL, ULINT_UNDEFINED, &offsets_heap); + if (!log->same_pk) { + /* Only update the record if DB_TRX_ID,DB_ROLL_PTR match what + was buffered. */ + ulint len; + const void* rec_trx_id + = rec_get_nth_field(btr_pcur_get_rec(&pcur), + cur_offsets, index->n_uniq, &len); + ut_ad(len == DATA_TRX_ID_LEN); + ut_ad(dtuple_get_nth_field(old_pk, index->n_uniq)->len + == DATA_TRX_ID_LEN); + ut_ad(dtuple_get_nth_field(old_pk, index->n_uniq + 1)->len + == DATA_ROLL_PTR_LEN); + ut_ad(DATA_TRX_ID_LEN + static_cast<const char*>( + dtuple_get_nth_field(old_pk, + index->n_uniq)->data) + == dtuple_get_nth_field(old_pk, + index->n_uniq + 1)->data); + if (memcmp(rec_trx_id, + dtuple_get_nth_field(old_pk, index->n_uniq)->data, + DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN)) { + /* The ROW_T_UPDATE was logged for a different + DB_TRX_ID,DB_ROLL_PTR. This is possible if an + earlier ROW_T_INSERT or ROW_T_UPDATE was diverted + because some BLOBs were missing due to rolling + back the initial insert or due to purging + the old BLOB values of an update. */ + ut_ad(log->blobs); + if (error != DB_SUCCESS) { + ut_ad(error == DB_MISSING_HISTORY); + /* Some BLOBs are missing, so we are + interpreting this ROW_T_UPDATE as + ROW_T_DELETE (see *1). + Because this is a different row, + we will do nothing. */ + error = DB_SUCCESS; + } else { + /* Because the user record is missing due to + BLOBs that were missing when processing + an earlier log record, we should + interpret the ROW_T_UPDATE as ROW_T_INSERT. + However, there is a different user record + with the same PRIMARY KEY value already. */ + error = DB_DUPLICATE_KEY; + } + + goto func_exit; + } + } + + if (error != DB_SUCCESS) { + ut_ad(error == DB_MISSING_HISTORY); + ut_ad(log->blobs); + /* Some BLOBs are missing, so we are interpreting + this ROW_T_UPDATE as ROW_T_DELETE (see *1). */ + error = row_log_table_apply_delete_low( + &pcur, cur_offsets, NULL, heap, &mtr); + goto func_exit_committed; + } + dtuple_t* entry = row_build_index_entry( row, NULL, index, heap); const upd_t* update = row_upd_build_difference_binary( index, entry, btr_pcur_get_rec(&pcur), cur_offsets, false, NULL, heap); - error = DB_SUCCESS; - if (!update->n_fields) { /* Nothing to do. */ goto func_exit; @@ -1808,7 +1989,7 @@ func_exit_committed: allow purge to free any orphaned externally stored columns. */ - if (pk_updated && dup->index->online_log->same_pk) { + if (pk_updated && log->same_pk) { /* The ROW_T_UPDATE log record should only be written when the PRIMARY KEY fields of the record did not change in the old table. We @@ -2034,7 +2215,7 @@ row_log_table_apply_op( For fixed-length PRIMARY key columns, it is 0. */ mrec += extra_size; - rec_offs_set_n_fields(offsets, new_index->n_uniq + 1); + rec_offs_set_n_fields(offsets, new_index->n_uniq + 2); rec_init_offsets_temp(mrec, new_index, offsets); next_mrec = mrec + rec_offs_data_size(offsets) + ext_size; if (next_mrec > mrec_end) { @@ -2069,7 +2250,7 @@ row_log_table_apply_op( *error = row_log_table_apply_delete( thr, new_trx_id_col, mrec, offsets, offsets_heap, heap, - log->table, ext); + log, ext); break; case ROW_T_UPDATE: diff --git a/storage/xtradb/row/row0quiesce.cc b/storage/xtradb/row/row0quiesce.cc index a59a6088ad6..1d67d5a9717 100644 --- a/storage/xtradb/row/row0quiesce.cc +++ b/storage/xtradb/row/row0quiesce.cc @@ -71,7 +71,7 @@ row_quiesce_write_index_fields( } /* Include the NUL byte in the length. */ - ib_uint32_t len = strlen(field->name) + 1; + ib_uint32_t len = static_cast<ib_uint32_t>(strlen(field->name) + 1); ut_a(len > 1); mach_write_to_4(row, len); @@ -180,7 +180,7 @@ row_quiesce_write_indexes( /* Write the length of the index name. NUL byte is included in the length. */ - ib_uint32_t len = strlen(index->name) + 1; + ib_uint32_t len = static_cast<ib_uint32_t>(strlen(index->name) + 1); ut_a(len > 1); mach_write_to_4(row, len); @@ -267,7 +267,7 @@ row_quiesce_write_table( col_name = dict_table_get_col_name(table, dict_col_get_no(col)); /* Include the NUL byte in the length. */ - len = strlen(col_name) + 1; + len = static_cast<ib_uint32_t>(strlen(col_name) + 1); ut_a(len > 1); mach_write_to_4(row, len); @@ -333,7 +333,7 @@ row_quiesce_write_header( } /* The server hostname includes the NUL byte. */ - len = strlen(hostname) + 1; + len = static_cast<ib_uint32_t>(strlen(hostname) + 1); mach_write_to_4(value, len); DBUG_EXECUTE_IF("ib_export_io_write_failure_5", close(fileno(file));); @@ -351,7 +351,7 @@ row_quiesce_write_header( /* The table name includes the NUL byte. */ ut_a(table->name != 0); - len = strlen(table->name) + 1; + len = static_cast<ib_uint32_t>(strlen(table->name) + 1); /* Write the table name. */ mach_write_to_4(value, len); diff --git a/storage/xtradb/row/row0uins.cc b/storage/xtradb/row/row0uins.cc index 7b50d8b62ae..849bf096492 100644 --- a/storage/xtradb/row/row0uins.cc +++ b/storage/xtradb/row/row0uins.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2014, 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 @@ -109,8 +109,7 @@ row_undo_ins_remove_clust_rec( mem_heap_t* heap = NULL; const ulint* offsets = rec_get_offsets( rec, index, NULL, ULINT_UNDEFINED, &heap); - row_log_table_delete( - rec, index, offsets, true, node->trx->id); + row_log_table_delete(rec, index, offsets, NULL); mem_heap_free(heap); } diff --git a/storage/xtradb/row/row0umod.cc b/storage/xtradb/row/row0umod.cc index 3c70c3e662b..29252c7834a 100644 --- a/storage/xtradb/row/row0umod.cc +++ b/storage/xtradb/row/row0umod.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2014, 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 @@ -86,6 +86,8 @@ row_undo_mod_clust_low( before the update, or NULL if the table is not being rebuilt online or the PRIMARY KEY definition does not change */ + byte* sys, /*!< out: DB_TRX_ID, DB_ROLL_PTR + for row_log_table_delete() */ que_thr_t* thr, /*!< in: query thread */ mtr_t* mtr, /*!< in: mtr; must be committed before latching any further pages */ @@ -115,7 +117,7 @@ row_undo_mod_clust_low( && dict_index_is_online_ddl(btr_cur_get_index(btr_cur))) { *rebuilt_old_pk = row_log_table_get_pk( btr_cur_get_rec(btr_cur), - btr_cur_get_index(btr_cur), NULL, &heap); + btr_cur_get_index(btr_cur), NULL, sys, &heap); } else { *rebuilt_old_pk = NULL; } @@ -277,12 +279,13 @@ row_undo_mod_clust( mem_heap_t* offsets_heap = NULL; ulint* offsets = NULL; const dtuple_t* rebuilt_old_pk; + byte sys[DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN]; /* Try optimistic processing of the record, keeping changes within the index page */ err = row_undo_mod_clust_low(node, &offsets, &offsets_heap, - heap, &rebuilt_old_pk, + heap, &rebuilt_old_pk, sys, thr, &mtr, online ? BTR_MODIFY_LEAF | BTR_ALREADY_S_LATCHED : BTR_MODIFY_LEAF); @@ -296,7 +299,8 @@ row_undo_mod_clust( mtr_start(&mtr); err = row_undo_mod_clust_low( - node, &offsets, &offsets_heap, heap, &rebuilt_old_pk, + node, &offsets, &offsets_heap, + heap, &rebuilt_old_pk, sys, thr, &mtr, BTR_MODIFY_TREE); ut_ad(err == DB_SUCCESS || err == DB_OUT_OF_FILE_SPACE); } @@ -322,8 +326,7 @@ row_undo_mod_clust( break; case TRX_UNDO_UPD_DEL_REC: row_log_table_delete( - btr_pcur_get_rec(pcur), index, offsets, - true, node->trx->id); + btr_pcur_get_rec(pcur), index, offsets, sys); break; default: ut_ad(0); diff --git a/storage/xtradb/row/row0upd.cc b/storage/xtradb/row/row0upd.cc index 4cf1c604c47..3ead385c2cd 100644 --- a/storage/xtradb/row/row0upd.cc +++ b/storage/xtradb/row/row0upd.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2014, 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 @@ -1948,9 +1948,7 @@ row_upd_clust_rec_by_insert_inherit_func( data += len - BTR_EXTERN_FIELD_REF_SIZE; /* The pointer must not be zero. */ ut_a(memcmp(data, field_ref_zero, BTR_EXTERN_FIELD_REF_SIZE)); - /* The BLOB must be owned. */ - ut_a(!(data[BTR_EXTERN_LEN] & BTR_EXTERN_OWNER_FLAG)); - + data[BTR_EXTERN_LEN] &= ~BTR_EXTERN_OWNER_FLAG; data[BTR_EXTERN_LEN] |= BTR_EXTERN_INHERITED_FLAG; /* The BTR_EXTERN_INHERITED_FLAG only matters in rollback. Purge will always free the extern fields of @@ -2055,7 +2053,13 @@ err_exit: rec, offsets, entry, node->update); if (change_ownership) { - btr_pcur_store_position(pcur, mtr); + /* The blobs are disowned here, expecting the + insert down below to inherit them. But if the + insert fails, then this disown will be undone + when the operation is rolled back. */ + btr_cur_disown_inherited_fields( + btr_cur_get_page_zip(btr_cur), + rec, index, offsets, node->update, mtr); } } @@ -2081,41 +2085,6 @@ err_exit: ? UPD_NODE_INSERT_BLOB : UPD_NODE_INSERT_CLUSTERED; - if (err == DB_SUCCESS && change_ownership) { - /* Mark the non-updated fields disowned by the old record. */ - - /* NOTE: this transaction has an x-lock on the record - and therefore other transactions cannot modify the - record when we have no latch on the page. In addition, - we assume that other query threads of the same - transaction do not modify the record in the meantime. - Therefore we can assert that the restoration of the - cursor succeeds. */ - - mtr_start(mtr); - - if (!btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur, mtr)) { - ut_error; - } - - rec = btr_cur_get_rec(btr_cur); - offsets = rec_get_offsets(rec, index, offsets, - ULINT_UNDEFINED, &heap); - ut_ad(page_rec_is_user_rec(rec)); - ut_ad(rec_get_deleted_flag(rec, rec_offs_comp(offsets))); - - btr_cur_disown_inherited_fields( - btr_cur_get_page_zip(btr_cur), - rec, index, offsets, node->update, mtr); - - /* It is not necessary to call row_log_table for - this, because during online table rebuild, purge will - not free any BLOBs in the table, whether or not they - are owned by the clustered index record. */ - - mtr_commit(mtr); - } - mem_heap_free(heap); return(err); @@ -2158,7 +2127,7 @@ row_upd_clust_rec( if (dict_index_is_online_ddl(index)) { rebuilt_old_pk = row_log_table_get_pk( - btr_cur_get_rec(btr_cur), index, offsets, &heap); + btr_cur_get_rec(btr_cur), index, offsets, NULL, &heap); } /* Try optimistic updating of the record, keeping changes within diff --git a/storage/xtradb/row/row0vers.cc b/storage/xtradb/row/row0vers.cc index bde796831c6..9f1fc13ee09 100644 --- a/storage/xtradb/row/row0vers.cc +++ b/storage/xtradb/row/row0vers.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2014, 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 @@ -73,6 +73,8 @@ row_vers_impl_x_locked_low( ulint* clust_offsets; mem_heap_t* heap; + DBUG_ENTER("row_vers_impl_x_locked_low"); + ut_ad(rec_offs_validate(rec, index, offsets)); heap = mem_heap_create(1024); @@ -92,7 +94,7 @@ row_vers_impl_x_locked_low( trx_sys_get_max_trx_id()); } mem_heap_free(heap); - return(0); + DBUG_RETURN(0); } comp = page_rec_is_comp(rec); @@ -131,17 +133,37 @@ row_vers_impl_x_locked_low( clust_rec, mtr, version, clust_index, clust_offsets, heap, &prev_version); - /* Free version and clust_offsets. */ + /* The oldest visible clustered index version must not be + delete-marked, because we never start a transaction by + inserting a delete-marked record. */ + ut_ad(prev_version + || !rec_get_deleted_flag(version, comp) + || !trx_rw_is_active(trx_id, NULL)); + /* Free version and clust_offsets. */ mem_heap_free(old_heap); if (prev_version == NULL) { - /* clust_rec should be a fresh insert, because - no previous version was found or the transaction - has committed. The caller has to recheck as the - synopsis of this function states, whether trx_id - is active or not. */ + /* We reached the oldest visible version without + finding an older version of clust_rec that would + match the secondary index record. If the secondary + index record is not delete marked, then clust_rec + is considered the correct match of the secondary + index record and hence holds the implicit lock. */ + + if (rec_del) { + /* The secondary index record is del marked. + So, the implicit lock holder of clust_rec + did not modify the secondary index record yet, + and is not holding an implicit lock on it. + + This assumes that whenever a row is inserted + or updated, the leaf page record always is + created with a clear delete-mark flag. + (We never insert a delete-marked record.) */ + trx_id = 0; + } break; } @@ -237,8 +259,11 @@ row_vers_impl_x_locked_low( } } + DBUG_PRINT("info", ("Implicit lock is held by trx:%lu", + static_cast<unsigned long>(trx_id))); + mem_heap_free(heap); - return(trx_id); + DBUG_RETURN(trx_id); } /*****************************************************************//** diff --git a/storage/xtradb/srv/srv0conc.cc b/storage/xtradb/srv/srv0conc.cc index 413d5c4eab2..6c15753246a 100644 --- a/storage/xtradb/srv/srv0conc.cc +++ b/storage/xtradb/srv/srv0conc.cc @@ -271,7 +271,7 @@ srv_conc_enter_innodb_with_atomics( && sleep_in_us > srv_adaptive_max_sleep_delay) { sleep_in_us = srv_adaptive_max_sleep_delay; - srv_thread_sleep_delay = sleep_in_us; + srv_thread_sleep_delay = static_cast<ulong>(sleep_in_us); } os_thread_sleep(sleep_in_us); diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc index 56f8f4d3110..b9ed26b9c9e 100644 --- a/storage/xtradb/srv/srv0srv.cc +++ b/storage/xtradb/srv/srv0srv.cc @@ -3287,7 +3287,8 @@ srv_purge_coordinator_suspend( rw_lock_x_lock(&purge_sys->latch); - stop = (purge_sys->state == PURGE_STATE_STOP); + stop = (srv_shutdown_state == SRV_SHUTDOWN_NONE + && purge_sys->state == PURGE_STATE_STOP); if (!stop) { ut_a(purge_sys->n_stop == 0); @@ -3375,8 +3376,9 @@ DECLARE_THREAD(srv_purge_coordinator_thread)( /* If there are no records to purge or the last purge didn't purge any records then wait for activity. */ - if (purge_sys->state == PURGE_STATE_STOP - || n_total_purged == 0) { + if (srv_shutdown_state == SRV_SHUTDOWN_NONE + && (purge_sys->state == PURGE_STATE_STOP + || n_total_purged == 0)) { srv_purge_coordinator_suspend(slot, rseg_history_len); } diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc index c1c2f39aaa1..c8fbbd74344 100644 --- a/storage/xtradb/srv/srv0start.cc +++ b/storage/xtradb/srv/srv0start.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. +Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2008, Google Inc. Copyright (c) 2009, Percona Inc. @@ -162,7 +162,7 @@ UNIV_INTERN mysql_pfs_key_t srv_log_tracking_thread_key; #endif /* UNIV_PFS_THREAD */ /*********************************************************************//** -Convert a numeric string that optionally ends in G or M, to a number +Convert a numeric string that optionally ends in G or M or K, to a number containing megabytes. @return next character in string */ static @@ -186,6 +186,10 @@ srv_parse_megabytes( case 'M': case 'm': str++; break; + case 'K': case 'k': + size /= 1024; + str++; + break; default: size /= 1024 * 1024; break; @@ -1005,14 +1009,40 @@ size_check: return(DB_ERROR); } skip_size_check: + + /* This is the earliest location where we can load + the double write buffer. */ + if (i == 0) { + buf_dblwr_init_or_load_pages( + files[i], srv_data_file_names[i], true); + } + + bool retry = true; +check_first_page: check_msg = fil_read_first_page( files[i], one_opened, &flags, &space, min_flushed_lsn, max_flushed_lsn); if (check_msg) { + + if (retry) { + fsp_open_info fsp; + const ulint page_no = 0; + + retry = false; + fsp.id = 0; + fsp.filepath = srv_data_file_names[i]; + fsp.file = files[i]; + + if (fil_user_tablespace_restore_page( + &fsp, page_no)) { + goto check_first_page; + } + } + ib_logf(IB_LOG_LEVEL_ERROR, - "%s in data file %s", - check_msg, name); + "%s in data file %s", + check_msg, name); return(DB_ERROR); } @@ -2075,6 +2105,9 @@ innobase_start_or_create_for_mysql(void) return(DB_ERROR); } + recv_sys_create(); + recv_sys_init(buf_pool_get_curr_size()); + err = open_or_create_data_files(&create_new_db, #ifdef UNIV_LOG_ARCHIVE &min_arch_log_no, &max_arch_log_no, diff --git a/storage/xtradb/sync/sync0arr.cc b/storage/xtradb/sync/sync0arr.cc index 9dd0259b3f9..126cf8de0d5 100644 --- a/storage/xtradb/sync/sync0arr.cc +++ b/storage/xtradb/sync/sync0arr.cc @@ -1098,7 +1098,7 @@ sync_array_print_long_waits( os_thread_sleep(30000000); - srv_print_innodb_monitor = old_val; + srv_print_innodb_monitor = static_cast<my_bool>(old_val); fprintf(stderr, "InnoDB: ###### Diagnostic info printed" " to the standard error stream\n"); diff --git a/storage/xtradb/sync/sync0sync.cc b/storage/xtradb/sync/sync0sync.cc index d6033d9d2ab..e698b7dcf10 100644 --- a/storage/xtradb/sync/sync0sync.cc +++ b/storage/xtradb/sync/sync0sync.cc @@ -209,7 +209,10 @@ UNIV_INTERN mysql_pfs_key_t sync_thread_mutex_key; /** Global list of database mutexes (not OS mutexes) created. */ UNIV_INTERN ut_list_base_node_t mutex_list; -/** Mutex protecting the mutex_list variable */ +/** Global list of priority mutexes. A subset of mutex_list */ +UNIV_INTERN UT_LIST_BASE_NODE_T(ib_prio_mutex_t) prio_mutex_list; + +/** Mutex protecting the mutex_list and prio_mutex_list variables */ UNIV_INTERN ib_mutex_t mutex_list_mutex; #ifdef UNIV_PFS_MUTEX @@ -353,6 +356,10 @@ mutex_create_func( cmutex_name); mutex->high_priority_waiters = 0; mutex->high_priority_event = os_event_create(); + + mutex_enter(&mutex_list_mutex); + UT_LIST_ADD_FIRST(list, prio_mutex_list, mutex); + mutex_exit(&mutex_list_mutex); } /******************************************************************//** @@ -426,6 +433,10 @@ mutex_free_func( /*============*/ ib_prio_mutex_t* mutex) /*!< in: mutex */ { + mutex_enter(&mutex_list_mutex); + UT_LIST_REMOVE(list, prio_mutex_list, mutex); + mutex_exit(&mutex_list_mutex); + ut_a(mutex->high_priority_waiters == 0); os_event_free(mutex->high_priority_event); mutex_free_func(&mutex->base_mutex); @@ -1572,6 +1583,7 @@ sync_init(void) /* Init the mutex list and create the mutex to protect it. */ UT_LIST_INIT(mutex_list); + UT_LIST_INIT(prio_mutex_list); mutex_create(mutex_list_mutex_key, &mutex_list_mutex, SYNC_NO_ORDER_CHECK); #ifdef UNIV_SYNC_DEBUG @@ -1630,10 +1642,16 @@ void sync_close(void) /*===========*/ { - ib_mutex_t* mutex; + ib_mutex_t* mutex; + ib_prio_mutex_t* prio_mutex; sync_array_close(); + for (prio_mutex = UT_LIST_GET_FIRST(prio_mutex_list); prio_mutex;) { + mutex_free(prio_mutex); + prio_mutex = UT_LIST_GET_FIRST(prio_mutex_list); + } + for (mutex = UT_LIST_GET_FIRST(mutex_list); mutex != NULL; /* No op */) { diff --git a/storage/xtradb/trx/trx0trx.cc b/storage/xtradb/trx/trx0trx.cc index f29eba0bec1..f2c78bafd86 100644 --- a/storage/xtradb/trx/trx0trx.cc +++ b/storage/xtradb/trx/trx0trx.cc @@ -2044,7 +2044,8 @@ state_ok: } if (trx->mysql_thd != NULL) { - innobase_mysql_print_thd(f, trx->mysql_thd, max_query_len); + innobase_mysql_print_thd( + f, trx->mysql_thd, static_cast<uint>(max_query_len)); } } diff --git a/storage/xtradb/ut/ut0ut.cc b/storage/xtradb/ut/ut0ut.cc index f600ba1a895..15c7bb503cb 100644 --- a/storage/xtradb/ut/ut0ut.cc +++ b/storage/xtradb/ut/ut0ut.cc @@ -823,6 +823,8 @@ ut_strerr( return("FTS query exceeds result cache limit"); case DB_TEMP_FILE_WRITE_FAILURE: return("Temp file write failure"); + case DB_FTS_TOO_MANY_WORDS_IN_PHRASE: + return("Too many words in a FTS phrase or proximity search"); /* do not add default: in order to produce a warning if new code is added to the enum but not added here */ |