diff options
Diffstat (limited to 'storage/xtradb')
58 files changed, 684 insertions, 415 deletions
diff --git a/storage/xtradb/api/api0api.cc b/storage/xtradb/api/api0api.cc index 1abb0b2bdd1..55ed555ed48 100644 --- a/storage/xtradb/api/api0api.cc +++ b/storage/xtradb/api/api0api.cc @@ -398,7 +398,7 @@ ib_read_tuple( data = btr_rec_copy_externally_stored_field( copy, offsets, zip_size, i, &len, - tuple->heap, NULL); + tuple->heap); ut_a(len != UNIV_SQL_NULL); } diff --git a/storage/xtradb/btr/btr0cur.cc b/storage/xtradb/btr/btr0cur.cc index f22871deb32..e29d9091f8e 100644 --- a/storage/xtradb/btr/btr0cur.cc +++ b/storage/xtradb/btr/btr0cur.cc @@ -3991,7 +3991,6 @@ static const ib_int64_t rows_in_range_arbitrary_ret_val = 10; @param[in] mode1 search mode for range start @param[in] tuple2 range end, may also be empty tuple @param[in] mode2 search mode for range end -@param[in] trx trx @param[in] nth_attempt if the tree gets modified too much while we are trying to analyze it, then we will retry (this function will call itself, incrementing this parameter) @@ -4008,7 +4007,6 @@ btr_estimate_n_rows_in_range_low( ulint mode1, const dtuple_t* tuple2, ulint mode2, - trx_t* trx, unsigned nth_attempt) { btr_path_t path1[BTR_PATH_ARRAY_N_SLOTS]; @@ -4027,7 +4025,7 @@ btr_estimate_n_rows_in_range_low( table_n_rows = dict_table_get_n_rows(index->table); - mtr_start_trx(&mtr, trx); + mtr_start(&mtr); cursor.path_arr = path1; @@ -4049,7 +4047,7 @@ btr_estimate_n_rows_in_range_low( return (0); } - mtr_start_trx(&mtr, trx); + mtr_start(&mtr); #ifdef UNIV_DEBUG if (!strcmp(index->name, "iC")) { @@ -4144,7 +4142,7 @@ btr_estimate_n_rows_in_range_low( const ib_int64_t ret = btr_estimate_n_rows_in_range_low( index, tuple1, mode1, - tuple2, mode2, trx, + tuple2, mode2, nth_attempt + 1); return(ret); @@ -4205,7 +4203,6 @@ btr_estimate_n_rows_in_range_low( @param[in] mode1 search mode for range start @param[in] tuple2 range end, may also be empty tuple @param[in] mode2 search mode for range end -@param[in] trx trx @return estimated number of rows */ ib_int64_t btr_estimate_n_rows_in_range( @@ -4213,11 +4210,10 @@ btr_estimate_n_rows_in_range( const dtuple_t* tuple1, ulint mode1, const dtuple_t* tuple2, - ulint mode2, - trx_t* trx) + ulint mode2) { const ib_int64_t ret = btr_estimate_n_rows_in_range_low( - index, tuple1, mode1, tuple2, mode2, trx, + index, tuple1, mode1, tuple2, mode2, 1 /* first attempt */); return(ret); @@ -5757,8 +5753,7 @@ btr_copy_blob_prefix( ulint len, /*!< in: length of buf, in bytes */ ulint space_id,/*!< in: space id of the BLOB pages */ ulint page_no,/*!< in: page number of the first BLOB page */ - ulint offset, /*!< in: offset on the first BLOB page */ - trx_t* trx) /*!< in: transaction handle */ + ulint offset) /*!< in: offset on the first BLOB page */ { ulint copied_len = 0; @@ -5770,7 +5765,7 @@ btr_copy_blob_prefix( ulint part_len; ulint copy_len; - mtr_start_trx(&mtr, trx); + mtr_start(&mtr); block = buf_page_get(space_id, 0, page_no, RW_S_LATCH, &mtr); buf_block_dbg_add_level(block, SYNC_EXTERN_STORAGE); @@ -5973,8 +5968,7 @@ btr_copy_externally_stored_field_prefix_low( zero for uncompressed BLOBs */ ulint space_id,/*!< in: space id of the first BLOB page */ ulint page_no,/*!< in: page number of the first BLOB page */ - ulint offset, /*!< in: offset on the first BLOB page */ - trx_t* trx) /*!< in: transaction handle */ + ulint offset) /*!< in: offset on the first BLOB page */ { if (UNIV_UNLIKELY(len == 0)) { return(0); @@ -5985,7 +5979,7 @@ btr_copy_externally_stored_field_prefix_low( space_id, page_no, offset)); } else { return(btr_copy_blob_prefix(buf, len, space_id, - page_no, offset, trx)); + page_no, offset)); } } @@ -6006,8 +6000,7 @@ btr_copy_externally_stored_field_prefix( field containing also the reference to the external part; must be protected by a lock or a page latch */ - ulint local_len,/*!< in: length of data, in bytes */ - trx_t* trx) /*!< in: transaction handle */ + ulint local_len)/*!< in: length of data, in bytes */ { ulint space_id; ulint page_no; @@ -6046,7 +6039,7 @@ btr_copy_externally_stored_field_prefix( len - local_len, zip_size, space_id, page_no, - offset, trx)); + offset)); } /*******************************************************************//** @@ -6065,8 +6058,7 @@ btr_copy_externally_stored_field( ulint zip_size,/*!< in: nonzero=compressed BLOB page size, zero for uncompressed BLOBs */ ulint local_len,/*!< in: length of data */ - mem_heap_t* heap, /*!< in: mem heap */ - trx_t* trx) /*!< in: transaction handle */ + mem_heap_t* heap) /*!< in: mem heap */ { ulint space_id; ulint page_no; @@ -6097,8 +6089,7 @@ btr_copy_externally_stored_field( extern_len, zip_size, space_id, - page_no, offset, - trx); + page_no, offset); return(buf); } @@ -6117,8 +6108,7 @@ btr_rec_copy_externally_stored_field( zero for uncompressed BLOBs */ ulint no, /*!< in: field number */ ulint* len, /*!< out: length of the field */ - mem_heap_t* heap, /*!< in: mem heap */ - trx_t* trx) /*!< in: transaction handle */ + mem_heap_t* heap) /*!< in: mem heap */ { ulint local_len; const byte* data; @@ -6149,7 +6139,6 @@ btr_rec_copy_externally_stored_field( } return(btr_copy_externally_stored_field(len, data, - zip_size, local_len, heap, - trx)); + zip_size, local_len, heap)); } #endif /* !UNIV_HOTBACKUP */ diff --git a/storage/xtradb/btr/btr0pcur.cc b/storage/xtradb/btr/btr0pcur.cc index 0b970e1cf49..06166e1aa16 100644 --- a/storage/xtradb/btr/btr0pcur.cc +++ b/storage/xtradb/btr/btr0pcur.cc @@ -33,6 +33,7 @@ Created 2/23/1996 Heikki Tuuri #include "rem0cmp.h" #include "trx0trx.h" #include "srv0srv.h" + /**************************************************************//** Allocates memory for a persistent cursor object and initializes the cursor. @return own: persistent cursor */ @@ -511,7 +512,7 @@ btr_pcur_move_backward_from_page( mtr_commit(mtr); - mtr_start_trx(mtr, mtr->trx); + mtr_start(mtr); btr_pcur_restore_position(latch_mode2, cursor, mtr); diff --git a/storage/xtradb/buf/buf0buddy.cc b/storage/xtradb/buf/buf0buddy.cc index 2ee39c6c992..1c50e71e687 100644 --- a/storage/xtradb/buf/buf0buddy.cc +++ b/storage/xtradb/buf/buf0buddy.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 2006, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -667,7 +668,7 @@ buf_buddy_free_low( ut_ad(buf_pool->buddy_stat[i].used > 0); buf_pool->buddy_stat[i].used--; recombine: - UNIV_MEM_ASSERT_AND_ALLOC(buf, BUF_BUDDY_LOW << i); + UNIV_MEM_ALLOC(buf, BUF_BUDDY_LOW << i); if (i == BUF_BUDDY_SIZES) { mutex_exit(&buf_pool->zip_free_mutex); diff --git a/storage/xtradb/buf/buf0lru.cc b/storage/xtradb/buf/buf0lru.cc index a84f2a832f3..7bf423ed740 100644 --- a/storage/xtradb/buf/buf0lru.cc +++ b/storage/xtradb/buf/buf0lru.cc @@ -2070,7 +2070,7 @@ buf_LRU_block_free_non_file_page( ut_d(block->page.in_free_list = TRUE); mutex_exit(&buf_pool->free_list_mutex); - UNIV_MEM_ASSERT_AND_FREE(block->frame, UNIV_PAGE_SIZE); + UNIV_MEM_FREE(block->frame, UNIV_PAGE_SIZE); } /******************************************************************//** diff --git a/storage/xtradb/buf/buf0rea.cc b/storage/xtradb/buf/buf0rea.cc index 76b71550710..152536b3120 100644 --- a/storage/xtradb/buf/buf0rea.cc +++ b/storage/xtradb/buf/buf0rea.cc @@ -137,7 +137,12 @@ buf_read_page_low( ibool unzip, ib_int64_t tablespace_version, ulint offset, - trx_t* trx = NULL) + trx_t* trx, + bool should_buffer) /*!< in: whether to buffer an aio request. + AIO read ahead uses this. If you plan to + use this parameter, make sure you remember + to call os_aio_dispatch_read_array_submit() + when you're ready to commit all your requests.*/ { buf_page_t* bpage; ulint wake_later; @@ -243,14 +248,15 @@ not_to_recover: *err = _fil_io(OS_FILE_READ | wake_later | ignore_nonexistent_pages, sync, space, zip_size, offset, 0, zip_size, - frame, bpage, 0, trx); + frame, bpage, 0, trx, should_buffer); } else { ut_a(buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE); *err = _fil_io(OS_FILE_READ | wake_later | ignore_nonexistent_pages, sync, space, 0, offset, 0, UNIV_PAGE_SIZE, - frame, bpage, &bpage->write_size, trx); + frame, bpage, &bpage->write_size, trx, + should_buffer); } if (sync) { @@ -412,7 +418,7 @@ read_ahead: &err, false, ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER, space, zip_size, FALSE, - tablespace_version, i, trx); + tablespace_version, i, trx, false); switch(err) { case DB_SUCCESS: @@ -502,7 +508,7 @@ buf_read_page( switches: hence TRUE */ count = buf_read_page_low(&err, true, BUF_READ_ANY_PAGE, space_id, zip_size, FALSE, - tablespace_version, offset, trx); + tablespace_version, offset, trx, false); srv_stats.buf_pool_reads.add(count); } @@ -555,7 +561,7 @@ buf_read_page_async( | OS_AIO_SIMULATED_WAKE_LATER | BUF_READ_IGNORE_NONEXISTENT_PAGES, space, zip_size, FALSE, - tablespace_version, offset); + tablespace_version, offset, NULL, false); switch(err) { case DB_SUCCESS: @@ -848,7 +854,7 @@ buf_read_ahead_linear( &err, false, ibuf_mode, space, zip_size, FALSE, tablespace_version, - i, trx); + i, trx, true); switch(err) { case DB_SUCCESS: @@ -876,6 +882,7 @@ buf_read_ahead_linear( } } } + os_aio_dispatch_read_array_submit(); /* In simulated aio we wake the aio handler threads only after queuing all aio requests, in native aio the following call does @@ -952,7 +959,7 @@ buf_read_ibuf_merge_pages( buf_read_page_low(&err, sync && (i + 1 == n_stored), BUF_READ_ANY_PAGE, space_ids[i], zip_size, TRUE, space_versions[i], - page_nos[i], NULL); + page_nos[i], NULL, false); switch(err) { case DB_SUCCESS: @@ -1100,13 +1107,13 @@ not_to_recover: if ((i + 1 == n_stored) && sync) { buf_read_page_low(&err, true, BUF_READ_ANY_PAGE, space, zip_size, TRUE, tablespace_version, - page_nos[i], NULL); + page_nos[i], NULL, false); } else { buf_read_page_low(&err, false, BUF_READ_ANY_PAGE | OS_AIO_SIMULATED_WAKE_LATER, space, zip_size, TRUE, tablespace_version, page_nos[i], - NULL); + NULL, false); } if (err == DB_DECRYPTION_FAILED) { diff --git a/storage/xtradb/data/data0type.cc b/storage/xtradb/data/data0type.cc index 0b9e08544a5..34ca399f9b2 100644 --- a/storage/xtradb/data/data0type.cc +++ b/storage/xtradb/data/data0type.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -49,8 +50,10 @@ ulint dtype_get_at_most_n_mbchars( /*========================*/ ulint prtype, /*!< in: precise type */ - ulint mbminmaxlen, /*!< in: minimum and maximum length of - a multi-byte character */ + ulint mbminlen, /*!< in: minimum length of + a multi-byte character, in bytes */ + ulint mbmaxlen, /*!< in: maximum length of + a multi-byte character, in bytes */ ulint prefix_len, /*!< in: length of the requested prefix, in characters, multiplied by dtype_get_mbmaxlen(dtype) */ @@ -58,9 +61,6 @@ dtype_get_at_most_n_mbchars( const char* str) /*!< in: the string whose prefix length is being determined */ { - ulint mbminlen = DATA_MBMINLEN(mbminmaxlen); - ulint mbmaxlen = DATA_MBMAXLEN(mbminmaxlen); - ut_a(data_len != UNIV_SQL_NULL); ut_ad(!mbmaxlen || !(prefix_len % mbmaxlen)); diff --git a/storage/xtradb/dict/dict0mem.cc b/storage/xtradb/dict/dict0mem.cc index 125d7d78a1f..cf27caf6c28 100644 --- a/storage/xtradb/dict/dict0mem.cc +++ b/storage/xtradb/dict/dict0mem.cc @@ -2,7 +2,7 @@ Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2017, MariaDB Corporation. +Copyright (c) 2013, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -533,7 +533,8 @@ dict_mem_fill_column_struct( column->len = (unsigned int) col_len; #ifndef UNIV_HOTBACKUP dtype_get_mblen(mtype, prtype, &mbminlen, &mbmaxlen); - dict_col_set_mbminmaxlen(column, mbminlen, mbmaxlen); + column->mbminlen = mbminlen; + column->mbmaxlen = mbmaxlen; #endif /* !UNIV_HOTBACKUP */ } diff --git a/storage/xtradb/dict/dict0stats_bg.cc b/storage/xtradb/dict/dict0stats_bg.cc index e166e7df72a..884f62103f5 100644 --- a/storage/xtradb/dict/dict0stats_bg.cc +++ b/storage/xtradb/dict/dict0stats_bg.cc @@ -337,7 +337,7 @@ dict_stats_wait_bg_to_stop_using_table( unlocking/locking the data dict */ { while (!dict_stats_stop_bg(table)) { - DICT_STATS_BG_YIELD(trx); + DICT_BG_YIELD(trx); } } diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index b7ac7375d3c..0716f291a6a 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -6093,7 +6093,12 @@ _fil_io( operation for this page and if initialized we do not trim again if actual page size does not decrease. */ - trx_t* trx) + trx_t* trx, + bool should_buffer) /*!< in: whether to buffer an aio request. + AIO read ahead uses this. If you plan to + use this parameter, make sure you remember + to call os_aio_dispatch_read_array_submit() + when you're ready to commit all your requests.*/ { ulint mode; fil_space_t* space; @@ -6314,7 +6319,7 @@ _fil_io( /* Queue the aio request */ ret = os_aio(type, is_log, mode | wake_later, name, node->handle, buf, offset, len, zip_size ? zip_size : UNIV_PAGE_SIZE, node, - message, space_id, trx, write_size); + message, space_id, trx, write_size, should_buffer); #else /* In mysqlbackup do normal i/o, not aio */ diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc index 88b5ad97277..98aaf610f2a 100644 --- a/storage/xtradb/fts/fts0fts.cc +++ b/storage/xtradb/fts/fts0fts.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2011, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2016, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -26,6 +26,7 @@ Full Text Search interface #include "row0mysql.h" #include "row0upd.h" #include "dict0types.h" +#include "dict0stats_bg.h" #include "row0sel.h" #include "fts0fts.h" @@ -868,18 +869,37 @@ fts_drop_index( err = fts_drop_index_tables(trx, index); - fts_free(table); - + for(;;) { + bool retry = false; + if (index->index_fts_syncing) { + retry = true; + } + if (!retry){ + fts_free(table); + break; + } + DICT_BG_YIELD(trx); + } return(err); } - current_doc_id = table->fts->cache->next_doc_id; - first_doc_id = table->fts->cache->first_doc_id; - fts_cache_clear(table->fts->cache); - fts_cache_destroy(table->fts->cache); - table->fts->cache = fts_cache_create(table); - table->fts->cache->next_doc_id = current_doc_id; - table->fts->cache->first_doc_id = first_doc_id; + for(;;) { + bool retry = false; + if (index->index_fts_syncing) { + retry = true; + } + if (!retry){ + current_doc_id = table->fts->cache->next_doc_id; + first_doc_id = table->fts->cache->first_doc_id; + fts_cache_clear(table->fts->cache); + fts_cache_destroy(table->fts->cache); + table->fts->cache = fts_cache_create(table); + table->fts->cache->next_doc_id = current_doc_id; + table->fts->cache->first_doc_id = first_doc_id; + break; + } + DICT_BG_YIELD(trx); + } } else { fts_cache_t* cache = table->fts->cache; fts_index_cache_t* index_cache; @@ -889,9 +909,17 @@ fts_drop_index( index_cache = fts_find_index_cache(cache, index); if (index_cache != NULL) { - if (index_cache->words) { - fts_words_free(index_cache->words); - rbt_free(index_cache->words); + for(;;) { + bool retry = false; + if (index->index_fts_syncing) { + retry = true; + } + if (!retry && index_cache->words) { + fts_words_free(index_cache->words); + rbt_free(index_cache->words); + break; + } + DICT_BG_YIELD(trx); } ib_vector_remove(cache->indexes, *(void**) index_cache); @@ -1973,7 +2001,7 @@ fts_create_one_index_table( ? DATA_VARCHAR : DATA_VARMYSQL, field->col->prtype, FTS_MAX_WORD_LEN_IN_CHAR - * DATA_MBMAXLEN(field->col->mbminmaxlen)); + * field->col->mbmaxlen); dict_mem_table_add_col(new_table, heap, "first_doc_id", DATA_INT, DATA_NOT_NULL | DATA_UNSIGNED, @@ -3333,8 +3361,7 @@ fts_fetch_doc_from_rec( dict_table_zip_size(table), clust_pos, &doc->text.f_len, static_cast<mem_heap_t*>( - doc->self_heap->arg), - NULL); + doc->self_heap->arg)); } else { doc->text.f_str = (byte*) rec_get_nth_field( clust_rec, offsets, clust_pos, @@ -4568,10 +4595,16 @@ begin_sync: index_cache = static_cast<fts_index_cache_t*>( ib_vector_get(cache->indexes, i)); - if (index_cache->index->to_be_dropped) { + if (index_cache->index->to_be_dropped + || index_cache->index->table->to_be_dropped) { continue; } + index_cache->index->index_fts_syncing = true; + DBUG_EXECUTE_IF("fts_instrument_sync_sleep_drop_waits", + os_thread_sleep(10000000); + ); + error = fts_sync_index(sync, index_cache); if (error != DB_SUCCESS && !sync->interrupted) { @@ -4604,11 +4637,33 @@ begin_sync: end_sync: if (error == DB_SUCCESS && !sync->interrupted) { error = fts_sync_commit(sync); + if (error == DB_SUCCESS) { + for (i = 0; i < ib_vector_size(cache->indexes); ++i) { + fts_index_cache_t* index_cache; + index_cache = static_cast<fts_index_cache_t*>( + ib_vector_get(cache->indexes, i)); + if (index_cache->index->index_fts_syncing) { + index_cache->index->index_fts_syncing + = false; + } + } + } } else { fts_sync_rollback(sync); } rw_lock_x_lock(&cache->lock); + /* Clear fts syncing flags of any indexes incase sync is + interrupeted */ + for (i = 0; i < ib_vector_size(cache->indexes); ++i) { + fts_index_cache_t* index_cache; + index_cache = static_cast<fts_index_cache_t*>( + ib_vector_get(cache->indexes, i)); + if (index_cache->index->index_fts_syncing == true) { + index_cache->index->index_fts_syncing = false; + } + } + sync->interrupted = false; sync->in_progress = false; os_event_set(sync->event); @@ -7535,8 +7590,7 @@ fts_init_recover_doc( &doc.text.f_len, static_cast<byte*>(dfield_get_data(dfield)), zip_size, len, - static_cast<mem_heap_t*>(doc.self_heap->arg), - NULL); + static_cast<mem_heap_t*>(doc.self_heap->arg)); } else { doc.text.f_str = static_cast<byte*>( dfield_get_data(dfield)); diff --git a/storage/xtradb/fts/fts0opt.cc b/storage/xtradb/fts/fts0opt.cc index cb30122adcb..d9f96948000 100644 --- a/storage/xtradb/fts/fts0opt.cc +++ b/storage/xtradb/fts/fts0opt.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2007, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2016, MariaDB Corporation. All Rights reserved. This program is free software; you can redistribute it and/or modify it under @@ -2971,13 +2971,6 @@ fts_optimize_sync_table( { dict_table_t* table = NULL; - /* Prevent DROP INDEX etc. from running when we are syncing - cache in background. */ - if (!rw_lock_s_lock_nowait(&dict_operation_lock, __FILE__, __LINE__)) { - /* Exit when fail to get dict operation lock. */ - return; - } - table = dict_table_open_on_id(table_id, FALSE, DICT_TABLE_OP_NORMAL); if (table) { @@ -2987,8 +2980,6 @@ fts_optimize_sync_table( dict_table_close(table, FALSE, FALSE); } - - rw_lock_s_unlock(&dict_operation_lock); } /**********************************************************************//** diff --git a/storage/xtradb/fts/fts0que.cc b/storage/xtradb/fts/fts0que.cc index 358d979fff6..0b0aecaeaa2 100644 --- a/storage/xtradb/fts/fts0que.cc +++ b/storage/xtradb/fts/fts0que.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2007, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -1937,8 +1937,7 @@ fts_query_fetch_document( if (dfield_is_ext(dfield)) { data = btr_copy_externally_stored_field( &cur_len, data, phrase->zip_size, - dfield_get_len(dfield), phrase->heap, - NULL); + dfield_get_len(dfield), phrase->heap); } else { cur_len = dfield_get_len(dfield); } @@ -3656,6 +3655,7 @@ fts_query_free( if (query->intersection) { fts_query_free_doc_ids(query, query->intersection); + query->intersection = NULL; } if (query->doc_ids) { diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 37755cb9078..65ac41c26de 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -1289,6 +1289,8 @@ static SHOW_VAR innodb_status_variables[]= { (char*) &export_vars.innodb_sec_rec_cluster_reads, SHOW_LONG}, {"secondary_index_triggered_cluster_reads_avoided", (char*) &export_vars.innodb_sec_rec_cluster_reads_avoided, SHOW_LONG}, + {"buffered_aio_submitted", + (char*) &export_vars.innodb_buffered_aio_submitted, SHOW_LONG}, /* Encryption */ {"encryption_rotation_pages_read_from_cache", @@ -12321,6 +12323,7 @@ index_bad: case ROW_TYPE_DEFAULT: /* If we fell through, set row format to Compact. */ row_format = ROW_TYPE_COMPACT; + /* fall through */ case ROW_TYPE_COMPACT: break; } @@ -13710,7 +13713,7 @@ ha_innobase::records_in_range( n_rows = btr_estimate_n_rows_in_range(index, range_start, mode1, range_end, - mode2, prebuilt->trx); + mode2); } else { n_rows = HA_POS_ERROR; @@ -21081,6 +21084,13 @@ static MYSQL_SYSVAR_BOOL(print_all_deadlocks, srv_print_all_deadlocks, "Print all deadlocks to MySQL error log (off by default)", NULL, NULL, FALSE); +static MYSQL_SYSVAR_BOOL( + print_lock_wait_timeout_info, + srv_print_lock_wait_timeout_info, + PLUGIN_VAR_OPCMDARG, + "Print lock wait timeout info to MySQL error log (off by default)", + NULL, NULL, FALSE); + static MYSQL_SYSVAR_ULONG(compression_failure_threshold_pct, zip_failure_threshold_pct, PLUGIN_VAR_OPCMDARG, "If the compression failure rate of a table is greater than this number" @@ -21539,6 +21549,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(foreground_preflush), MYSQL_SYSVAR(empty_free_list_algorithm), MYSQL_SYSVAR(print_all_deadlocks), + MYSQL_SYSVAR(print_lock_wait_timeout_info), MYSQL_SYSVAR(cmp_per_index_enabled), MYSQL_SYSVAR(undo_logs), MYSQL_SYSVAR(rollback_segments), diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index b2f0d301815..2a2c466fd4f 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2017, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2013, 2018, MariaDB Corporation. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1200,8 +1200,7 @@ innobase_col_to_mysql( #ifdef UNIV_DEBUG case DATA_MYSQL: ut_ad(flen >= len); - ut_ad(DATA_MBMAXLEN(col->mbminmaxlen) - >= DATA_MBMINLEN(col->mbminmaxlen)); + ut_ad(col->mbmaxlen >= col->mbminlen); memcpy(dest, data, len); break; @@ -5917,7 +5916,47 @@ ha_innobase::commit_inplace_alter_table( break; } - DICT_STATS_BG_YIELD(trx); + DICT_BG_YIELD(trx); + } + + /* Make a concurrent Drop fts Index to wait until sync of that + fts index is happening in the background */ + for (;;) { + bool retry = false; + + for (inplace_alter_handler_ctx** pctx = ctx_array; + *pctx; pctx++) { + int count =0; + ha_innobase_inplace_ctx* ctx + = static_cast<ha_innobase_inplace_ctx*>(*pctx); + DBUG_ASSERT(new_clustered == ctx->need_rebuild()); + + if (dict_fts_index_syncing(ctx->old_table)) { + count++; + if (count == 100) { + fprintf(stderr, + "Drop index waiting for background sync" + "to finish\n"); + } + retry = true; + } + + if (new_clustered && dict_fts_index_syncing(ctx->new_table)) { + count++; + if (count == 100) { + fprintf(stderr, + "Drop index waiting for background sync" + "to finish\n"); + } + retry = true; + } + } + + if (!retry) { + break; + } + + DICT_BG_YIELD(trx); } /* Apply the changes to the data dictionary tables, for all @@ -6233,8 +6272,13 @@ foreign_fail: ut_d(dict_table_check_for_dup_indexes( ctx->new_table, CHECK_ABORTED_OK)); - ut_a(fts_check_cached_index(ctx->new_table)); +#ifdef UNIV_DEBUG + if (!(ctx->new_table->fts != NULL + && ctx->new_table->fts->cache->sync->in_progress)) { + ut_a(fts_check_cached_index(ctx->new_table)); + } +#endif if (new_clustered) { /* Since the table has been rebuilt, we remove all persistent statistics corresponding to the diff --git a/storage/xtradb/ibuf/ibuf0ibuf.cc b/storage/xtradb/ibuf/ibuf0ibuf.cc index 6925cd3abb5..52ef41edbb9 100644 --- a/storage/xtradb/ibuf/ibuf0ibuf.cc +++ b/storage/xtradb/ibuf/ibuf0ibuf.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2017, MariaDB Corporation. +Copyright (c) 2016, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/storage/xtradb/include/btr0cur.h b/storage/xtradb/include/btr0cur.h index e478b33bf8e..1b0632e2120 100644 --- a/storage/xtradb/include/btr0cur.h +++ b/storage/xtradb/include/btr0cur.h @@ -568,8 +568,7 @@ btr_estimate_n_rows_in_range( const dtuple_t* tuple1, /*!< in: range start, may also be empty tuple */ ulint mode1, /*!< in: search mode for range start */ const dtuple_t* tuple2, /*!< in: range end, may also be empty tuple */ - ulint mode2, /*!< in: search mode for range end */ - trx_t* trx); /*!< in: trx */ + ulint mode2); /*!< in: search mode for range end */ /*******************************************************************//** Estimates the number of different key values in a given index, for each n-column prefix of the index where 1 <= n <= dict_index_get_n_unique(index). @@ -704,8 +703,7 @@ btr_copy_externally_stored_field_prefix( field containing also the reference to the external part; must be protected by a lock or a page latch */ - ulint local_len,/*!< in: length of data, in bytes */ - trx_t* trx); /*!< in: transaction handle */ + ulint local_len);/*!< in: length of data, in bytes */ /*******************************************************************//** Copies an externally stored field of a record to mem heap. The clustered index record must be protected by a lock or a page latch. @@ -722,8 +720,7 @@ btr_copy_externally_stored_field( ulint zip_size,/*!< in: nonzero=compressed BLOB page size, zero for uncompressed BLOBs */ ulint local_len,/*!< in: length of data */ - mem_heap_t* heap, /*!< in: mem heap */ - trx_t* trx); /*!< in: transaction handle */ + mem_heap_t* heap); /*!< in: mem heap */ /*******************************************************************//** Copies an externally stored field of a record to mem heap. @return the field copied to heap, or NULL if the field is incomplete */ @@ -738,8 +735,7 @@ btr_rec_copy_externally_stored_field( zero for uncompressed BLOBs */ ulint no, /*!< in: field number */ ulint* len, /*!< out: length of the field */ - mem_heap_t* heap, /*!< in: mem heap */ - trx_t* trx); /*!< in: transaction handle */ + mem_heap_t* heap); /*!< in: mem heap */ /*******************************************************************//** Flags the data tuple fields that are marked as extern storage in the update vector. We use this function to remember which fields we must diff --git a/storage/xtradb/include/data0type.h b/storage/xtradb/include/data0type.h index df6b6a41c11..f3ecab5a3ba 100644 --- a/storage/xtradb/include/data0type.h +++ b/storage/xtradb/include/data0type.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2017, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -182,18 +182,7 @@ store the charset-collation number; one byte is left unused, though */ #define DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE 6 /* Maximum multi-byte character length in bytes, plus 1 */ -#define DATA_MBMAX 5 - -/* Pack mbminlen, mbmaxlen to mbminmaxlen. */ -#define DATA_MBMINMAXLEN(mbminlen, mbmaxlen) \ - ((mbmaxlen) * DATA_MBMAX + (mbminlen)) -/* Get mbminlen from mbminmaxlen. Cast the result of UNIV_EXPECT to ulint -because in GCC it returns a long. */ -#define DATA_MBMINLEN(mbminmaxlen) ((ulint) \ - UNIV_EXPECT(((mbminmaxlen) % DATA_MBMAX), \ - 1)) -/* Get mbmaxlen from mbminmaxlen. */ -#define DATA_MBMAXLEN(mbminmaxlen) ((ulint) ((mbminmaxlen) / DATA_MBMAX)) +#define DATA_MBMAX 8 /* We now support 15 bits (up to 32767) collation number */ #define MAX_CHAR_COLL_NUM 32767 @@ -220,8 +209,10 @@ ulint dtype_get_at_most_n_mbchars( /*========================*/ ulint prtype, /*!< in: precise type */ - ulint mbminmaxlen, /*!< in: minimum and maximum length of - a multi-byte character */ + ulint mbminlen, /*!< in: minimum length of + a multi-byte character, in bytes */ + ulint mbmaxlen, /*!< in: maximum length of + a multi-byte character, in bytes */ ulint prefix_len, /*!< in: length of the requested prefix, in characters, multiplied by dtype_get_mbmaxlen(dtype) */ @@ -366,19 +357,6 @@ dtype_get_mbmaxlen( /*===============*/ const dtype_t* type); /*!< in: type */ /*********************************************************************//** -Sets the minimum and maximum length of a character, in bytes. */ -UNIV_INLINE -void -dtype_set_mbminmaxlen( -/*==================*/ - dtype_t* type, /*!< in/out: type */ - ulint mbminlen, /*!< in: minimum length of a char, - in bytes, or 0 if this is not - a character type */ - ulint mbmaxlen); /*!< in: maximum length of a char, - in bytes, or 0 if this is not - a character type */ -/*********************************************************************//** Gets the padding character code for the type. @return padding character code, or ULINT_UNDEFINED if no padding specified */ UNIV_INLINE @@ -398,7 +376,9 @@ dtype_get_fixed_size_low( ulint mtype, /*!< in: main type */ ulint prtype, /*!< in: precise type */ ulint len, /*!< in: length */ - ulint mbminmaxlen, /*!< in: minimum and maximum length of a + ulint mbminlen, /*!< in: minimum length of a + multibyte character, in bytes */ + ulint mbmaxlen, /*!< in: maximum length of a multibyte character, in bytes */ ulint comp); /*!< in: nonzero=ROW_FORMAT=COMPACT */ #ifndef UNIV_HOTBACKUP @@ -412,8 +392,8 @@ dtype_get_min_size_low( ulint mtype, /*!< in: main type */ ulint prtype, /*!< in: precise type */ ulint len, /*!< in: length */ - ulint mbminmaxlen); /*!< in: minimum and maximum length of a - multibyte character */ + ulint mbminlen, /*!< in: minimum length of a character */ + ulint mbmaxlen); /*!< in: maximum length of a character */ /***********************************************************************//** Returns the maximum size of a data type. Note: types in system tables may be incomplete and return incorrect information. @@ -530,11 +510,10 @@ struct dtype_t{ the string, MySQL uses 1 or 2 bytes to store the string length) */ #ifndef UNIV_HOTBACKUP - unsigned mbminmaxlen:5; /*!< minimum and maximum length of a - character, in bytes; - DATA_MBMINMAXLEN(mbminlen,mbmaxlen); - mbminlen=DATA_MBMINLEN(mbminmaxlen); - mbmaxlen=DATA_MBMINLEN(mbminmaxlen) */ + unsigned mbminlen:3; /*!< minimum length of a character, + in bytes */ + unsigned mbmaxlen:3; /*!< maximum length of a character, + in bytes */ #endif /* !UNIV_HOTBACKUP */ }; diff --git a/storage/xtradb/include/data0type.ic b/storage/xtradb/include/data0type.ic index ff72f6ed20f..96b001e197e 100644 --- a/storage/xtradb/include/data0type.ic +++ b/storage/xtradb/include/data0type.ic @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2017, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -105,27 +105,6 @@ dtype_get_mblen( } /*********************************************************************//** -Sets the minimum and maximum length of a character, in bytes. */ -UNIV_INLINE -void -dtype_set_mbminmaxlen( -/*==================*/ - dtype_t* type, /*!< in/out: type */ - ulint mbminlen, /*!< in: minimum length of a char, - in bytes, or 0 if this is not - a character type */ - ulint mbmaxlen) /*!< in: maximum length of a char, - in bytes, or 0 if this is not - a character type */ -{ - ut_ad(mbminlen < DATA_MBMAX); - ut_ad(mbmaxlen < DATA_MBMAX); - ut_ad(mbminlen <= mbmaxlen); - - type->mbminmaxlen = DATA_MBMINMAXLEN(mbminlen, mbmaxlen); -} - -/*********************************************************************//** Compute the mbminlen and mbmaxlen members of a data type structure. */ UNIV_INLINE void @@ -137,7 +116,8 @@ dtype_set_mblen( ulint mbmaxlen; dtype_get_mblen(type->mtype, type->prtype, &mbminlen, &mbmaxlen); - dtype_set_mbminmaxlen(type, mbminlen, mbmaxlen); + type->mbminlen = mbminlen; + type->mbmaxlen = mbmaxlen; ut_ad(dtype_validate(type)); } @@ -233,8 +213,7 @@ dtype_get_mbminlen( /*===============*/ const dtype_t* type) /*!< in: type */ { - ut_ad(type); - return(DATA_MBMINLEN(type->mbminmaxlen)); + return type->mbminlen; } /*********************************************************************//** Gets the maximum length of a character, in bytes. @@ -246,8 +225,7 @@ dtype_get_mbmaxlen( /*===============*/ const dtype_t* type) /*!< in: type */ { - ut_ad(type); - return(DATA_MBMAXLEN(type->mbminmaxlen)); + return type->mbmaxlen; } /*********************************************************************//** @@ -523,8 +501,10 @@ dtype_get_fixed_size_low( ulint mtype, /*!< in: main type */ ulint prtype, /*!< in: precise type */ ulint len, /*!< in: length */ - ulint mbminmaxlen, /*!< in: minimum and maximum length of - a multibyte character, in bytes */ + ulint mbminlen, /*!< in: minimum length of a + multibyte character, in bytes */ + ulint mbmaxlen, /*!< in: maximum length of a + multibyte character, in bytes */ ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */ { switch (mtype) { @@ -565,11 +545,10 @@ dtype_get_fixed_size_low( dtype_get_charset_coll(prtype), &i_mbminlen, &i_mbmaxlen); - ut_ad(DATA_MBMINMAXLEN(i_mbminlen, i_mbmaxlen) - == mbminmaxlen); + ut_ad(i_mbminlen == mbminlen); + ut_ad(i_mbmaxlen == mbmaxlen); #endif /* UNIV_DEBUG */ - if (DATA_MBMINLEN(mbminmaxlen) - == DATA_MBMAXLEN(mbminmaxlen)) { + if (mbminlen == mbmaxlen) { return(len); } } @@ -602,8 +581,8 @@ dtype_get_min_size_low( ulint mtype, /*!< in: main type */ ulint prtype, /*!< in: precise type */ ulint len, /*!< in: length */ - ulint mbminmaxlen) /*!< in: minimum and maximum length of a - multi-byte character */ + ulint mbminlen, /*!< in: minimum length of a character */ + ulint mbmaxlen) /*!< in: maximum length of a character */ { switch (mtype) { case DATA_SYS: @@ -633,9 +612,6 @@ dtype_get_min_size_low( if (prtype & DATA_BINARY_TYPE) { return(len); } else { - ulint mbminlen = DATA_MBMINLEN(mbminmaxlen); - ulint mbmaxlen = DATA_MBMAXLEN(mbminmaxlen); - if (mbminlen == mbmaxlen) { return(len); } @@ -706,9 +682,9 @@ dtype_get_sql_null_size( { #ifndef UNIV_HOTBACKUP return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len, - type->mbminmaxlen, comp)); + type->mbminlen, type->mbmaxlen, comp)); #else /* !UNIV_HOTBACKUP */ return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len, - 0, 0)); + 0, 0, 0)); #endif /* !UNIV_HOTBACKUP */ } diff --git a/storage/xtradb/include/dict0dict.h b/storage/xtradb/include/dict0dict.h index dda8f4d2714..241ed89e36b 100644 --- a/storage/xtradb/include/dict0dict.h +++ b/storage/xtradb/include/dict0dict.h @@ -2,7 +2,7 @@ Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2017, MariaDB Corporation. +Copyright (c) 2013, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -197,18 +197,6 @@ dict_col_get_mbmaxlen( const dict_col_t* col) /*!< in: column */ MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** -Sets the minimum and maximum number of bytes per character. */ -UNIV_INLINE -void -dict_col_set_mbminmaxlen( -/*=====================*/ - dict_col_t* col, /*!< in/out: column */ - ulint mbminlen, /*!< in: minimum multi-byte - character size, in bytes */ - ulint mbmaxlen) /*!< in: minimum multi-byte - character size, in bytes */ - MY_ATTRIBUTE((nonnull)); -/*********************************************************************//** Gets the column data type. */ UNIV_INLINE void diff --git a/storage/xtradb/include/dict0dict.ic b/storage/xtradb/include/dict0dict.ic index 4db6a73bbc2..17b4adc10e2 100644 --- a/storage/xtradb/include/dict0dict.ic +++ b/storage/xtradb/include/dict0dict.ic @@ -1,7 +1,7 @@ /***************************************************************************** -Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2017, MariaDB Corporation. +Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2013, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -41,7 +41,7 @@ dict_col_get_mbminlen( /*==================*/ const dict_col_t* col) /*!< in: column */ { - return(DATA_MBMINLEN(col->mbminmaxlen)); + return col->mbminlen; } /*********************************************************************//** Gets the maximum number of bytes per character. @@ -52,25 +52,7 @@ dict_col_get_mbmaxlen( /*==================*/ const dict_col_t* col) /*!< in: column */ { - return(DATA_MBMAXLEN(col->mbminmaxlen)); -} -/*********************************************************************//** -Sets the minimum and maximum number of bytes per character. */ -UNIV_INLINE -void -dict_col_set_mbminmaxlen( -/*=====================*/ - dict_col_t* col, /*!< in/out: column */ - ulint mbminlen, /*!< in: minimum multi-byte - character size, in bytes */ - ulint mbmaxlen) /*!< in: minimum multi-byte - character size, in bytes */ -{ - ut_ad(mbminlen < DATA_MBMAX); - ut_ad(mbmaxlen < DATA_MBMAX); - ut_ad(mbminlen <= mbmaxlen); - - col->mbminmaxlen = DATA_MBMINMAXLEN(mbminlen, mbmaxlen); + return col->mbmaxlen; } /*********************************************************************//** Gets the column data type. */ @@ -87,7 +69,8 @@ dict_col_copy_type( type->mtype = col->mtype; type->prtype = col->prtype; type->len = col->len; - type->mbminmaxlen = col->mbminmaxlen; + type->mbminlen = col->mbminlen; + type->mbmaxlen = col->mbmaxlen; } #endif /* !UNIV_HOTBACKUP */ @@ -109,7 +92,8 @@ dict_col_type_assert_equal( ut_ad(col->prtype == type->prtype); //ut_ad(col->len == type->len); # ifndef UNIV_HOTBACKUP - ut_ad(col->mbminmaxlen == type->mbminmaxlen); + ut_ad(col->mbminlen == type->mbminlen); + ut_ad(col->mbmaxlen == type->mbmaxlen); # endif /* !UNIV_HOTBACKUP */ return(TRUE); @@ -127,7 +111,7 @@ dict_col_get_min_size( const dict_col_t* col) /*!< in: column */ { return(dtype_get_min_size_low(col->mtype, col->prtype, col->len, - col->mbminmaxlen)); + col->mbminlen, col->mbmaxlen)); } /***********************************************************************//** Returns the maximum size of the column. @@ -152,7 +136,7 @@ dict_col_get_fixed_size( ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */ { return(dtype_get_fixed_size_low(col->mtype, col->prtype, col->len, - col->mbminmaxlen, comp)); + col->mbminlen, col->mbmaxlen, comp)); } /***********************************************************************//** Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column. @@ -1077,6 +1061,27 @@ dict_table_x_lock_indexes( } /*********************************************************************//** +Returns true if the particular FTS index in the table is still syncing +in the background, false otherwise. +@param [in] table Table containing FTS index +@return True if sync of fts index is still going in the background */ +UNIV_INLINE +bool +dict_fts_index_syncing( + dict_table_t* table) +{ + dict_index_t* index; + + for (index = dict_table_get_first_index(table); + index != NULL; + index = dict_table_get_next_index(index)) { + if (index->index_fts_syncing) { + return(true); + } + } + return(false); +} +/*********************************************************************//** Release the exclusive locks on all index tree. */ UNIV_INLINE void diff --git a/storage/xtradb/include/dict0mem.h b/storage/xtradb/include/dict0mem.h index 2a4422fc18b..bdec503c88c 100644 --- a/storage/xtradb/include/dict0mem.h +++ b/storage/xtradb/include/dict0mem.h @@ -1,8 +1,8 @@ /***************************************************************************** -Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2017, MariaDB Corporation. +Copyright (c) 2013, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -538,11 +538,10 @@ struct dict_col_t{ the string, MySQL uses 1 or 2 bytes to store the string length) */ - unsigned mbminmaxlen:5; /*!< minimum and maximum length of a - character, in bytes; - DATA_MBMINMAXLEN(mbminlen,mbmaxlen); - mbminlen=DATA_MBMINLEN(mbminmaxlen); - mbmaxlen=DATA_MBMINLEN(mbminmaxlen) */ + unsigned mbminlen:3; /*!< minimum length of a + character, in bytes */ + unsigned mbmaxlen:3; /*!< maximum length of a + character, in bytes */ /*----------------------*/ /* End of definitions copied from dtype_t */ /* @} */ @@ -720,6 +719,8 @@ struct dict_index_t{ dict_sys->mutex. Other changes are protected by index->lock. */ dict_field_t* fields; /*!< array of field descriptions */ + bool index_fts_syncing;/*!< Whether the fts index is + still syncing in the background */ #ifndef UNIV_HOTBACKUP UT_LIST_NODE_T(dict_index_t) indexes;/*!< list of indexes of the table */ diff --git a/storage/xtradb/include/dict0stats_bg.h b/storage/xtradb/include/dict0stats_bg.h index 8f3385eb22b..66fcf7a0998 100644 --- a/storage/xtradb/include/dict0stats_bg.h +++ b/storage/xtradb/include/dict0stats_bg.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2012, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -83,7 +83,7 @@ dict_stats_defrag_pool_del( /** Yield the data dictionary latch when waiting for the background thread to stop accessing a table. @param trx transaction holding the data dictionary locks */ -#define DICT_STATS_BG_YIELD(trx) do { \ +#define DICT_BG_YIELD(trx) do { \ row_mysql_unlock_data_dictionary(trx); \ os_thread_sleep(250000); \ row_mysql_lock_data_dictionary(trx); \ diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h index 5fe2d20b4f0..9ca59a479c9 100644 --- a/storage/xtradb/include/fil0fil.h +++ b/storage/xtradb/include/fil0fil.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2017, MariaDB Corporation. +Copyright (c) 2013, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1193,12 +1193,14 @@ _fil_io( operation for this page and if initialized we do not trim again if actual page size does not decrease. */ - trx_t* trx) /*!< in: trx */ + trx_t* trx, /*!< in: trx */ + bool should_buffer) /*!< in: whether to buffer an aio request. + Only used by aio read ahead*/ __attribute__((nonnull(8))); #define fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message, write_size) \ - _fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message, write_size, NULL) + _fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message, write_size, NULL, false) /** Determine the block size of the data file. @param[in] space tablespace diff --git a/storage/xtradb/include/log0online.h b/storage/xtradb/include/log0online.h index 5c3e7d07fd9..2d1febe9b9f 100644 --- a/storage/xtradb/include/log0online.h +++ b/storage/xtradb/include/log0online.h @@ -129,7 +129,11 @@ log_online_bitmap_iterator_next( /** Struct for single bitmap file information */ struct log_online_bitmap_file_struct { - char name[FN_REFLEN]; /*!< Name with full path */ + /** Name with full path + 61 is a nice magic constant for the extra space needed for the sprintf + template in the cc file + */ + char name[FN_REFLEN+61]; /*!< Name with full path */ pfs_os_file_t file; /*!< Handle to opened file */ ib_uint64_t size; /*!< Size of the file */ os_offset_t offset; /*!< Offset of the next read, diff --git a/storage/xtradb/include/mem0mem.ic b/storage/xtradb/include/mem0mem.ic index 63e68150b61..2b4638718fd 100644 --- a/storage/xtradb/include/mem0mem.ic +++ b/storage/xtradb/include/mem0mem.ic @@ -305,8 +305,8 @@ mem_heap_free_heap_top( mem_block_set_free(block, old_top - (byte*) block); ut_ad(mem_block_get_start(block) <= mem_block_get_free(block)); - UNIV_MEM_ASSERT_W(old_top, (byte*) block + block->len - old_top); #if defined UNIV_MEM_DEBUG + UNIV_MEM_ALLOC(old_top, (byte*)block + block->len - old_top); /* In the debug version erase block from top up */ mem_erase_buf(old_top, (byte*) block + block->len - old_top); @@ -315,7 +315,7 @@ mem_heap_free_heap_top( mem_current_allocated_memory -= (total_size - size); mutex_exit(&mem_hash_mutex); #endif /* UNIV_MEM_DEBUG */ - UNIV_MEM_ALLOC(old_top, (byte*) block + block->len - old_top); + UNIV_MEM_FREE(old_top, (byte*)block + block->len - old_top); /* If free == start, we may free the block if it is not the first one */ @@ -396,11 +396,11 @@ mem_heap_free_top( /* Subtract the free field of block */ mem_block_set_free(block, mem_block_get_free(block) - MEM_SPACE_NEEDED(n)); - UNIV_MEM_ASSERT_W((byte*) block + mem_block_get_free(block), n); #ifdef UNIV_MEM_DEBUG ut_ad(mem_block_get_start(block) <= mem_block_get_free(block)); + UNIV_MEM_ALLOC((byte*) block + mem_block_get_free(block), n); /* In the debug version check the consistency, and erase field */ mem_field_erase((byte*) block + mem_block_get_free(block), n); #endif @@ -412,11 +412,7 @@ mem_heap_free_top( == mem_block_get_start(block))) { mem_heap_block_free(heap, block); } else { - /* Avoid a bogus UNIV_MEM_ASSERT_W() warning in a - subsequent invocation of mem_heap_free_top(). - Originally, this was UNIV_MEM_FREE(), to catch writes - to freed memory. */ - UNIV_MEM_ALLOC((byte*) block + mem_block_get_free(block), n); + UNIV_MEM_FREE((byte*) block + mem_block_get_free(block), n); } } diff --git a/storage/xtradb/include/mtr0mtr.h b/storage/xtradb/include/mtr0mtr.h index ef6cd61719d..42a57f1022a 100644 --- a/storage/xtradb/include/mtr0mtr.h +++ b/storage/xtradb/include/mtr0mtr.h @@ -35,7 +35,6 @@ Created 11/26/1995 Heikki Tuuri #include "ut0byte.h" #include "mtr0types.h" #include "page0types.h" -#include "trx0types.h" /* Logging modes for a mini-transaction */ #define MTR_LOG_ALL 21 /* default mode: log all operations @@ -213,22 +212,10 @@ functions). The page number parameter was originally written as 0. @{ */ Starts a mini-transaction. */ UNIV_INLINE void -mtr_start_trx( -/*======*/ - mtr_t* mtr, /*!< out: mini-transaction */ - trx_t* trx) /*!< in: transaction */ - __attribute__((nonnull (1))); -/***************************************************************//** -Starts a mini-transaction. */ -UNIV_INLINE -void mtr_start( /*======*/ mtr_t* mtr) /*!< out: mini-transaction */ -{ - mtr_start_trx(mtr, NULL); -} - MY_ATTRIBUTE((nonnull)) + MY_ATTRIBUTE((nonnull)); /***************************************************************//** Commits a mini-transaction. */ UNIV_INTERN @@ -435,7 +422,6 @@ struct mtr_t{ #ifdef UNIV_DEBUG ulint magic_n; #endif /* UNIV_DEBUG */ - trx_t* trx; /*!< transaction */ }; #ifdef UNIV_DEBUG diff --git a/storage/xtradb/include/mtr0mtr.ic b/storage/xtradb/include/mtr0mtr.ic index a6d9df09925..04c39cf7f7e 100644 --- a/storage/xtradb/include/mtr0mtr.ic +++ b/storage/xtradb/include/mtr0mtr.ic @@ -43,10 +43,9 @@ mtr_block_dirtied( Starts a mini-transaction. */ UNIV_INLINE void -mtr_start_trx( +mtr_start( /*======*/ - mtr_t* mtr, /*!< out: mini-transaction */ - trx_t* trx) /*!< in: transaction */ + mtr_t* mtr) /*!< out: mini-transaction */ { UNIV_MEM_INVALID(mtr, sizeof *mtr); @@ -59,7 +58,6 @@ mtr_start_trx( mtr->made_dirty = FALSE; mtr->n_log_recs = 0; mtr->n_freed_pages = 0; - mtr->trx = trx; ut_d(mtr->state = MTR_ACTIVE); ut_d(mtr->magic_n = MTR_MAGIC_N); diff --git a/storage/xtradb/include/os0file.h b/storage/xtradb/include/os0file.h index f69230240c5..74a32a8bfa4 100644 --- a/storage/xtradb/include/os0file.h +++ b/storage/xtradb/include/os0file.h @@ -383,10 +383,10 @@ The wrapper functions have the prefix of "innodb_". */ # define os_aio(type, is_log, mode, name, file, buf, offset, \ n, page_size, message1, message2, space_id, \ - trx, write_size) \ + trx, write_size, should_buffer) \ pfs_os_aio_func(type, is_log, mode, name, file, buf, offset, \ n, page_size, message1, message2, space_id, trx, write_size, \ - __FILE__, __LINE__) + should_buffer, __FILE__, __LINE__) # define os_file_read(file, buf, offset, n) \ pfs_os_file_read_func(file, buf, offset, n, NULL, \ @@ -457,7 +457,7 @@ to original un-instrumented file I/O APIs */ # define os_aio(type, is_log, mode, name, file, buf, offset, n, page_size, message1, \ message2, space_id, trx, write_size) \ os_aio_func(type, is_log, mode, name, file, buf, offset, n, \ - page_size, message1, message2, space_id, trx, write_size) + page_size, message1, message2, space_id, trx, write_size, should_buffer) # define os_file_read(file, buf, offset, n) \ os_file_read_func(file, buf, offset, n, NULL) @@ -939,6 +939,12 @@ pfs_os_aio_func( operation for this page and if initialized we do not trim again if actual page size does not decrease. */ + bool should_buffer, + /*!< in: Whether to buffer an aio request. + AIO read ahead uses this. If you plan to + use this parameter, make sure you remember + to call os_aio_dispatch_read_array_submit() + when you're ready to commit all your requests.*/ const char* src_file,/*!< in: file name where func invoked */ ulint src_line);/*!< in: line where the func invoked */ /*******************************************************************//** @@ -1359,11 +1365,17 @@ os_aio_func( OS_AIO_SYNC */ ulint space_id, trx_t* trx, - ulint* write_size);/*!< in/out: Actual write size initialized + ulint* write_size,/*!< in/out: Actual write size initialized after fist successfull trim operation for this page and if initialized we do not trim again if actual page size does not decrease. */ + bool should_buffer); + /*!< in: Whether to buffer an aio request. + AIO read ahead uses this. If you plan to + use this parameter, make sure you remember + to call os_aio_dispatch_read_array_submit() + when you're ready to commit all your requests.*/ /************************************************************************//** Wakes up all async i/o threads so that they know to exit themselves in shutdown. */ @@ -1547,6 +1559,10 @@ os_file_handle_error_no_exit( ibool on_error_silent);/*!< in: if TRUE then don't print any message to the log. */ +/** Submit buffered AIO requests on the given segment to the kernel. */ +UNIV_INTERN +void +os_aio_dispatch_read_array_submit(); /***********************************************************************//** Try to get number of bytes per sector from file system. diff --git a/storage/xtradb/include/os0file.ic b/storage/xtradb/include/os0file.ic index 72ac9d9dd6a..a2011da3545 100644 --- a/storage/xtradb/include/os0file.ic +++ b/storage/xtradb/include/os0file.ic @@ -258,6 +258,9 @@ pfs_os_aio_func( operation for this page and if initialized we do not trim again if actual page size does not decrease. */ + bool should_buffer, + /*!< in: whether to buffer an aio request. + Only used by aio read ahead*/ const char* src_file,/*!< in: file name where func invoked */ ulint src_line)/*!< in: line where the func invoked */ { @@ -274,7 +277,7 @@ pfs_os_aio_func( result = os_aio_func(type, is_log, mode, name, file, buf, offset, n, page_size, message1, message2, space_id, trx, - write_size); + write_size, should_buffer); register_pfs_file_io_end(locker, n); diff --git a/storage/xtradb/include/rem0rec.ic b/storage/xtradb/include/rem0rec.ic index 5811a77a48b..89f6902059d 100644 --- a/storage/xtradb/include/rem0rec.ic +++ b/storage/xtradb/include/rem0rec.ic @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -922,7 +923,7 @@ rec_offs_set_n_alloc( { ut_ad(offsets); ut_ad(n_alloc > REC_OFFS_HEADER_SIZE); - UNIV_MEM_ASSERT_AND_ALLOC(offsets, n_alloc * sizeof *offsets); + UNIV_MEM_ALLOC(offsets, n_alloc * sizeof *offsets); offsets[0] = n_alloc; } diff --git a/storage/xtradb/include/row0mysql.h b/storage/xtradb/include/row0mysql.h index 4326f1208e5..4915e7c7a31 100644 --- a/storage/xtradb/include/row0mysql.h +++ b/storage/xtradb/include/row0mysql.h @@ -591,18 +591,6 @@ void row_mysql_close(void); /*=================*/ -/*********************************************************************//** -Reassigns the table identifier of a table. -@return error code or DB_SUCCESS */ -UNIV_INTERN -dberr_t -row_mysql_table_id_reassign( -/*========================*/ - dict_table_t* table, /*!< in/out: table */ - trx_t* trx, /*!< in/out: transaction */ - table_id_t* new_id) /*!< out: new table id */ - MY_ATTRIBUTE((nonnull, warn_unused_result)); - /* A struct describing a place for an individual column in the MySQL row format which is presented to the table handler in ha_innobase. This template struct is used to speed up row transformations between diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h index e7f6350987e..6df60e0e52d 100644 --- a/storage/xtradb/include/srv0srv.h +++ b/storage/xtradb/include/srv0srv.h @@ -195,6 +195,9 @@ struct srv_stats_t { wait timeout */ ulint_ctr_1_t n_lock_max_wait_time; + /** Number of buffered aio requests submitted */ + ulint_ctr_64_t n_aio_submitted; + /** Number of times page 0 is read from tablespace */ ulint_ctr_64_t page0_read; @@ -720,6 +723,9 @@ extern ulong srv_sync_array_size; /* print all user-level transactions deadlocks to mysqld stderr */ extern my_bool srv_print_all_deadlocks; +/* print lock wait timeout info to mysqld stderr */ +extern my_bool srv_print_lock_wait_timeout_info; + extern my_bool srv_cmp_per_index_enabled; /* is encryption enabled */ @@ -1294,7 +1300,9 @@ struct export_var_t{ ib_int64_t innodb_n_rowlog_blocks_decrypted; ulint innodb_sec_rec_cluster_reads; /*!< srv_sec_rec_cluster_reads */ - ulint innodb_sec_rec_cluster_reads_avoided;/*!< srv_sec_rec_cluster_reads_avoided */ + ulint innodb_sec_rec_cluster_reads_avoided; /*!< srv_sec_rec_cluster_reads_avoided */ + + ulint innodb_buffered_aio_submitted; ulint innodb_encryption_rotation_pages_read_from_cache; ulint innodb_encryption_rotation_pages_read_from_disk; diff --git a/storage/xtradb/include/trx0rec.h b/storage/xtradb/include/trx0rec.h index ec15250ec7b..fef12548003 100644 --- a/storage/xtradb/include/trx0rec.h +++ b/storage/xtradb/include/trx0rec.h @@ -229,7 +229,7 @@ trx_undo_report_row_operation( const ulint* offsets, /*!< in: rec_get_offsets(rec) */ roll_ptr_t* roll_ptr) /*!< out: DB_ROLL_PTR to the undo log record */ - MY_ATTRIBUTE((nonnull(1,2,8), warn_unused_result)); + MY_ATTRIBUTE((nonnull(2,8), warn_unused_result)); /******************************************************************//** Copies an undo record to heap. This function can be called if we know that the undo log record exists. diff --git a/storage/xtradb/include/trx0undo.h b/storage/xtradb/include/trx0undo.h index 190308112ba..0148cc61579 100644 --- a/storage/xtradb/include/trx0undo.h +++ b/storage/xtradb/include/trx0undo.h @@ -243,13 +243,22 @@ Truncates an undo log from the end. This function is used during a rollback to free space from an undo log. */ UNIV_INTERN void -trx_undo_truncate_end( +trx_undo_truncate_end_func( /*=======================*/ - trx_t* trx, /*!< in: transaction whose undo log it is */ +#ifdef UNIV_DEBUG + const trx_t* trx, /*!< in: transaction whose undo log it is */ +#endif /* UNIV_DEBUG */ trx_undo_t* undo, /*!< in/out: undo log */ undo_no_t limit) /*!< in: all undo records with undo number >= this value should be truncated */ MY_ATTRIBUTE((nonnull)); +#ifdef UNIV_DEBUG +# define trx_undo_truncate_end(trx,undo,limit) \ + trx_undo_truncate_end_func(trx,undo,limit) +#else /* UNIV_DEBUG */ +# define trx_undo_truncate_end(trx,undo,limit) \ + trx_undo_truncate_end_func(undo,limit) +#endif /* UNIV_DEBUG */ /***********************************************************************//** Truncates an undo log from the start. This function is used during a purge diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i index 5886b078e4d..93ab71bf46c 100644 --- a/storage/xtradb/include/univ.i +++ b/storage/xtradb/include/univ.i @@ -48,7 +48,7 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_BUGFIX 36 #ifndef PERCONA_INNODB_VERSION -#define PERCONA_INNODB_VERSION 82.2 +#define PERCONA_INNODB_VERSION 83.0 #endif /* Enable UNIV_LOG_ARCHIVE in XtraDB */ @@ -691,14 +691,6 @@ typedef void* os_thread_ret_t; # define UNIV_MEM_ASSERT_W(addr, size) do {} while(0) # define UNIV_MEM_TRASH(addr, c, size) do {} while(0) #endif -#define UNIV_MEM_ASSERT_AND_FREE(addr, size) do { \ - UNIV_MEM_ASSERT_W(addr, size); \ - UNIV_MEM_FREE(addr, size); \ -} while (0) -#define UNIV_MEM_ASSERT_AND_ALLOC(addr, size) do { \ - UNIV_MEM_ASSERT_W(addr, size); \ - UNIV_MEM_ALLOC(addr, size); \ -} while (0) extern ulong srv_page_size_shift; extern ulong srv_page_size; diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc index 20e3f5adeb7..6f41e27e12c 100644 --- a/storage/xtradb/lock/lock0lock.cc +++ b/storage/xtradb/lock/lock0lock.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2017, MariaDB Corporation +Copyright (c) 2014, 2018, MariaDB Corporation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/storage/xtradb/lock/lock0wait.cc b/storage/xtradb/lock/lock0wait.cc index a0f557e18e5..da4b0301df8 100644 --- a/storage/xtradb/lock/lock0wait.cc +++ b/storage/xtradb/lock/lock0wait.cc @@ -33,6 +33,20 @@ Created 25/5/2010 Sunny Bains #include "srv0start.h" #include "ha_prototypes.h" #include "lock0priv.h" +#include "lock0iter.h" + +#include <sstream> + +extern "C" +LEX_STRING* thd_query_string(MYSQL_THD thd); + +struct blocking_trx_info { + uint64_t trx_id; + uint32_t thread_id; + int64_t query_id; +}; + +static const size_t MAX_BLOCKING_TRX_IN_REPORT = 10; #include <mysql/service_wsrep.h> @@ -187,6 +201,46 @@ lock_wait_table_reserve_slot( return(NULL); } +/** Print lock wait timeout info to stderr. It's supposed this function +is executed in trx's THD thread as it calls some non-thread-safe +functions to get some info from THD. +@param[in] trx requested trx +@param[in] blocking blocking info array +@param[in] blocking_count blocking info array size */ +void +print_lock_wait_timeout( + const trx_t &trx, + blocking_trx_info *blocking, + size_t blocking_count) +{ + std::ostringstream outs; + + outs << "Lock wait timeout info:\n"; + outs << "Requested thread id: " << + thd_get_thread_id(trx.mysql_thd) << + "\n"; + outs << "Requested trx id: " << trx.id << "\n"; + outs << "Requested query: " << + thd_query_string(trx.mysql_thd)->str << "\n"; + + outs << "Total blocking transactions count: " << + blocking_count << + "\n"; + + for (size_t i = 0; i < blocking_count; ++i) { + outs << "Blocking transaction number: " << (i + 1) << "\n"; + outs << "Blocking thread id: " << + blocking[i].thread_id << + "\n"; + outs << "Blocking query id: " << + blocking[i].query_id << + "\n"; + outs << "Blocking trx id: " << blocking[i].trx_id << "\n"; + } + ut_print_timestamp(stderr); + fprintf(stderr, " %s", outs.str().c_str()); +} + #ifdef WITH_WSREP /*********************************************************************//** check if lock timeout was for priority thread, @@ -235,6 +289,8 @@ lock_wait_suspend_thread( ulint sec; ulint ms; ulong lock_wait_timeout; + blocking_trx_info blocking[MAX_BLOCKING_TRX_IN_REPORT]; + size_t blocking_count = 0; trx = thr_get_trx(thr); @@ -411,6 +467,8 @@ lock_wait_suspend_thread( #endif /* WITH_WSREP */ trx->error_state = DB_LOCK_WAIT_TIMEOUT; + if (srv_print_lock_wait_timeout_info) + print_lock_wait_timeout(*trx, blocking, blocking_count); #ifdef WITH_WSREP } diff --git a/storage/xtradb/log/log0online.cc b/storage/xtradb/log/log0online.cc index 27382977e5c..af32237243b 100644 --- a/storage/xtradb/log/log0online.cc +++ b/storage/xtradb/log/log0online.cc @@ -479,9 +479,9 @@ log_online_make_bitmap_name( /*=========================*/ lsn_t start_lsn) /*!< in: the start LSN name part */ { - ut_snprintf(log_bmp_sys->out.name, FN_REFLEN, bmp_file_name_template, - log_bmp_sys->bmp_file_home, bmp_file_name_stem, - log_bmp_sys->out_seq_num, start_lsn); + ut_snprintf(log_bmp_sys->out.name, sizeof(log_bmp_sys->out.name), + bmp_file_name_template, log_bmp_sys->bmp_file_home, + bmp_file_name_stem, log_bmp_sys->out_seq_num, start_lsn); } /*********************************************************************//** diff --git a/storage/xtradb/mem/mem0mem.cc b/storage/xtradb/mem/mem0mem.cc index e066aff5b30..b9f190509ee 100644 --- a/storage/xtradb/mem/mem0mem.cc +++ b/storage/xtradb/mem/mem0mem.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -506,13 +507,13 @@ mem_heap_block_free( #ifndef UNIV_HOTBACKUP if (!srv_use_sys_malloc) { #ifdef UNIV_MEM_DEBUG + UNIV_MEM_ALLOC(block, len); /* In the debug version we set the memory to a random combination of hex 0xDE and 0xAD. */ - mem_erase_buf((byte*) block, len); -#else /* UNIV_MEM_DEBUG */ - UNIV_MEM_ASSERT_AND_FREE(block, len); + mem_erase_buf((byte*)block, len); #endif /* UNIV_MEM_DEBUG */ + UNIV_MEM_FREE(block, len); } if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) { @@ -526,13 +527,13 @@ mem_heap_block_free( } #else /* !UNIV_HOTBACKUP */ #ifdef UNIV_MEM_DEBUG + UNIV_MEM_ALLOC(block, len); /* In the debug version we set the memory to a random combination of hex 0xDE and 0xAD. */ - mem_erase_buf((byte*) block, len); -#else /* UNIV_MEM_DEBUG */ - UNIV_MEM_ASSERT_AND_FREE(block, len); + mem_erase_buf((byte*)block, len); #endif /* UNIV_MEM_DEBUG */ + UNIV_MEM_FREE(block, len); ut_free(block); #endif /* !UNIV_HOTBACKUP */ } diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc index 8b0fa059100..634ebb2af49 100644 --- a/storage/xtradb/os/os0file.cc +++ b/storage/xtradb/os/os0file.cc @@ -296,6 +296,16 @@ struct os_aio_array_t{ There is one such event for each possible pending IO. The size of the array is equal to n_slots. */ + struct iocb** pending; + /* Array to buffer the not-submitted aio + requests. The array length is n_slots. + It is divided into n_segments segments. + pending requests on each segment are buffered + separately.*/ + ulint* count; + /* Array of length n_segments. Each element + counts the number of not-submitted aio + request on that segment.*/ #endif /* LINUX_NATIV_AIO */ }; @@ -4276,6 +4286,13 @@ os_aio_array_create( memset(io_event, 0x0, sizeof(*io_event) * n); array->aio_events = io_event; + array->pending = static_cast<struct iocb**>( + ut_malloc(n * sizeof(struct iocb*))); + memset(array->pending, 0x0, sizeof(struct iocb*) * n); + array->count = static_cast<ulint*>( + ut_malloc(n_segments * sizeof(ulint))); + memset(array->count, 0x0, sizeof(ulint) * n_segments); + skip_native_aio: #endif /* LINUX_NATIVE_AIO */ for (ulint i = 0; i < n; i++) { @@ -4310,6 +4327,16 @@ os_aio_array_free( if (srv_use_native_aio) { ut_free(array->aio_events); ut_free(array->aio_ctx); + +#ifdef UNIV_DEBUG + for (size_t idx = 0; idx < array->n_slots; ++idx) + ut_ad(array->pending[idx] == NULL); + for (size_t idx = 0; idx < array->n_segments; ++idx) + ut_ad(array->count[idx] == 0); +#endif + + ut_free(array->pending); + ut_free(array->count); } #endif /* LINUX_NATIVE_AIO */ @@ -4957,6 +4984,83 @@ readahead requests. */ } #endif /* _WIN32 */ +/** Submit buffered AIO requests on the given segment to the kernel +(low level function). +@param acquire_mutex specifies whether to lock array mutex +*/ +static +void +os_aio_dispatch_read_array_submit_low(bool acquire_mutex MY_ATTRIBUTE((unused))) +{ + if (!srv_use_native_aio) { + return; + } +#if defined(LINUX_NATIVE_AIO) + os_aio_array_t* array = os_aio_read_array; + ulint total_submitted = 0; + if (acquire_mutex) + os_mutex_enter(array->mutex); + /* Submit aio requests buffered on all segments. */ + for (ulint i = 0; i < array->n_segments; i++) { + const int count = array->count[i]; + int offset = 0; + while (offset != count) { + struct iocb** const iocb_array = array->pending + + i * array->n_slots / array->n_segments + + offset; + const int partial_count = count - offset; + /* io_submit() returns number of successfully queued + requests or (-errno). + It returns 0 only if the number of iocb blocks passed + is also 0. */ + const int submitted = io_submit(array->aio_ctx[i], + partial_count, iocb_array); + + /* This assertion prevents infinite loop in both + debug and release modes. */ + ut_a(submitted != 0); + + if (submitted < 0) { + /* Terminating with fatal error */ + const char* errmsg = + strerror(-submitted); + ib_logf(IB_LOG_LEVEL_FATAL, + "Trying to sumbit %d aio requests, " + "io_submit() set errno to %d: %s", + partial_count, -submitted, + errmsg ? errmsg : "<unknown>"); + } + ut_ad(submitted <= partial_count); + if (submitted < partial_count) + { + ib_logf(IB_LOG_LEVEL_WARN, + "Trying to sumbit %d aio requests, " + "io_submit() submitted only %d", + partial_count, submitted); + } + offset += submitted; + } + total_submitted += count; + } + /* Reset the aio request buffer. */ + memset(array->pending, 0x0, sizeof(struct iocb*) * array->n_slots); + memset(array->count, 0x0, sizeof(ulint) * array->n_segments); + + if (acquire_mutex) + os_mutex_exit(array->mutex); + + srv_stats.n_aio_submitted.add(total_submitted); +#endif +} + +/** Submit buffered AIO requests on the given segment to the kernel. */ +UNIV_INTERN +void +os_aio_dispatch_read_array_submit() +{ + os_aio_dispatch_read_array_submit_low(true); +} + #if defined(LINUX_NATIVE_AIO) /*******************************************************************//** Dispatch an AIO request to the kernel. @@ -4966,10 +5070,11 @@ ibool os_aio_linux_dispatch( /*==================*/ os_aio_array_t* array, /*!< in: io request array. */ - os_aio_slot_t* slot) /*!< in: an already reserved slot. */ + os_aio_slot_t* slot, /*!< in: an already reserved slot. */ + bool should_buffer) /*!< in: should buffer the request + rather than submit. */ { int ret; - ulint io_ctx_index; struct iocb* iocb; ut_ad(slot != NULL); @@ -4981,9 +5086,31 @@ os_aio_linux_dispatch( The iocb struct is directly in the slot. The io_context is one per segment. */ + ulint slots_per_segment = array->n_slots / array->n_segments; iocb = &slot->control; - io_ctx_index = (slot->pos * array->n_segments) / array->n_slots; + ulint io_ctx_index = slot->pos / slots_per_segment; + if (should_buffer) { + ut_ad(array == os_aio_read_array); + os_mutex_enter(array->mutex); + /* There are array->n_slots elements in array->pending, + which is divided into array->n_segments area of equal size. + The iocb of each segment are buffered in its corresponding area + in the pending array consecutively as they come. + array->count[i] records the number of buffered aio requests + in the ith segment.*/ + ulint& count = array->count[io_ctx_index]; + ut_ad(count != slots_per_segment); + ulint n = io_ctx_index * slots_per_segment + count; + array->pending[n] = iocb; + ++count; + if (count == slots_per_segment) { + os_aio_dispatch_read_array_submit_low(false); + } + os_mutex_exit(array->mutex); + return(TRUE); + } + /* Submit the given request. */ ret = io_submit(array->aio_ctx[io_ctx_index], 1, &iocb); #if defined(UNIV_AIO_DEBUG) @@ -5046,11 +5173,17 @@ os_aio_func( OS_AIO_SYNC */ ulint space_id, trx_t* trx, - ulint* write_size)/*!< in/out: Actual write size initialized + ulint* write_size,/*!< in/out: Actual write size initialized after fist successfull trim operation for this page and if initialized we do not trim again if actual page size does not decrease. */ + bool should_buffer) + /*!< in: Whether to buffer an aio request. + AIO read ahead uses this. If you plan to + use this parameter, make sure you remember + to call os_aio_dispatch_read_array_submit() + when you're ready to commit all your requests.*/ { os_aio_array_t* array; os_aio_slot_t* slot; @@ -5168,7 +5301,8 @@ try_again: goto err_exit; #elif defined(LINUX_NATIVE_AIO) - if (!os_aio_linux_dispatch(array, slot)) { + if (!os_aio_linux_dispatch(array, slot, + should_buffer)) { goto err_exit; } #endif /* WIN_ASYNC_IO */ @@ -5192,7 +5326,7 @@ try_again: if(!ret && GetLastError() != ERROR_IO_PENDING) goto err_exit; #elif defined(LINUX_NATIVE_AIO) - if (!os_aio_linux_dispatch(array, slot)) { + if (!os_aio_linux_dispatch(array, slot, false)) { goto err_exit; } #endif /* WIN_ASYNC_IO */ diff --git a/storage/xtradb/page/page0page.cc b/storage/xtradb/page/page0page.cc index 800f76e1532..fc93eebd445 100644 --- a/storage/xtradb/page/page0page.cc +++ b/storage/xtradb/page/page0page.cc @@ -2839,7 +2839,7 @@ page_warn_strict_checksum( ulint space_id, ulint page_no) { - srv_checksum_algorithm_t curr_algo_nonstrict; + srv_checksum_algorithm_t curr_algo_nonstrict = srv_checksum_algorithm_t(); switch (curr_algo) { case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32: curr_algo_nonstrict = SRV_CHECKSUM_ALGORITHM_CRC32; diff --git a/storage/xtradb/rem/rem0rec.cc b/storage/xtradb/rem/rem0rec.cc index c62e8c90434..2314f110312 100644 --- a/storage/xtradb/rem/rem0rec.cc +++ b/storage/xtradb/rem/rem0rec.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2017, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -865,13 +865,10 @@ rec_get_converted_size_comp_prefix_low( if (fixed_len) { #ifdef UNIV_DEBUG - ulint mbminlen = DATA_MBMINLEN(col->mbminmaxlen); - ulint mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen); - ut_ad(len <= fixed_len); - ut_ad(!mbmaxlen || len >= mbminlen - * (fixed_len / mbmaxlen)); + ut_ad(!col->mbmaxlen || len >= col->mbminlen + * (fixed_len / col->mbmaxlen)); /* dict_index_add_col() should guarantee this */ ut_ad(!field->prefix_len @@ -1259,14 +1256,10 @@ rec_convert_dtuple_to_rec_comp( it is 128 or more, or when the field is stored externally. */ if (fixed_len) { #ifdef UNIV_DEBUG - ulint mbminlen = DATA_MBMINLEN( - ifield->col->mbminmaxlen); - ulint mbmaxlen = DATA_MBMAXLEN( - ifield->col->mbminmaxlen); - ut_ad(len <= fixed_len); - ut_ad(!mbmaxlen || len >= mbminlen - * (fixed_len / mbmaxlen)); + ut_ad(!ifield->col->mbmaxlen + || len >= ifield->col->mbminlen + * (fixed_len / ifield->col->mbmaxlen)); ut_ad(!dfield_is_ext(field)); #endif /* UNIV_DEBUG */ } else if (dfield_is_ext(field)) { diff --git a/storage/xtradb/row/row0ext.cc b/storage/xtradb/row/row0ext.cc index ad852577ad2..32b78391d6a 100644 --- a/storage/xtradb/row/row0ext.cc +++ b/storage/xtradb/row/row0ext.cc @@ -78,8 +78,7 @@ row_ext_cache_fill( crashed during the execution of btr_free_externally_stored_field(). */ ext->len[i] = btr_copy_externally_stored_field_prefix( - buf, ext->max_len, zip_size, field, f_len, - NULL); + buf, ext->max_len, zip_size, field, f_len); } } } diff --git a/storage/xtradb/row/row0ftsort.cc b/storage/xtradb/row/row0ftsort.cc index 0f9c15f6a69..bd57685b71c 100644 --- a/storage/xtradb/row/row0ftsort.cc +++ b/storage/xtradb/row/row0ftsort.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2010, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, 2017, MariaDB Corporation. +Copyright (c) 2015, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -106,8 +106,9 @@ row_merge_create_fts_sort_index( field->col->prtype = idx_field->col->prtype | DATA_NOT_NULL; field->col->mtype = charset == &my_charset_latin1 ? DATA_VARCHAR : DATA_VARMYSQL; - field->col->mbminmaxlen = idx_field->col->mbminmaxlen; - field->col->len = HA_FT_MAXCHARLEN * DATA_MBMAXLEN(field->col->mbminmaxlen); + field->col->mbminlen = idx_field->col->mbminlen; + field->col->mbmaxlen = idx_field->col->mbmaxlen; + field->col->len = HA_FT_MAXCHARLEN * field->col->mbmaxlen; field->fixed_len = 0; @@ -150,7 +151,8 @@ row_merge_create_fts_sort_index( field->col->prtype = DATA_NOT_NULL | DATA_BINARY_TYPE; - field->col->mbminmaxlen = 0; + field->col->mbminlen = 0; + field->col->mbmaxlen = 0; /* The third field is on the word's position in the original doc */ field = dict_index_get_nth_field(new_index, 2); @@ -162,7 +164,8 @@ row_merge_create_fts_sort_index( field->col->len = 4 ; field->fixed_len = 4; field->col->prtype = DATA_NOT_NULL; - field->col->mbminmaxlen = 0; + field->col->mbminlen = 0; + field->col->mbmaxlen = 0; return(new_index); } @@ -540,7 +543,8 @@ row_merge_fts_doc_tokenize( field->type.mtype = DATA_INT; field->type.prtype = DATA_NOT_NULL | DATA_BINARY_TYPE; field->type.len = len; - field->type.mbminmaxlen = 0; + field->type.mbminlen = 0; + field->type.mbmaxlen = 0; cur_len += len; dfield_dup(field, buf->heap); @@ -559,7 +563,8 @@ row_merge_fts_doc_tokenize( field->type.mtype = DATA_INT; field->type.prtype = DATA_NOT_NULL; field->type.len = len; - field->type.mbminmaxlen = 0; + field->type.mbminlen = 0; + field->type.mbmaxlen = 0; cur_len += len; dfield_dup(field, buf->heap); @@ -709,8 +714,7 @@ loop: doc.text.f_str = btr_copy_externally_stored_field( &doc.text.f_len, data, - zip_size, data_len, blob_heap, - NULL); + zip_size, data_len, blob_heap); } else { doc.text.f_str = data; doc.text.f_len = data_len; diff --git a/storage/xtradb/row/row0import.cc b/storage/xtradb/row/row0import.cc index 3efc2a30037..f0035302852 100644 --- a/storage/xtradb/row/row0import.cc +++ b/storage/xtradb/row/row0import.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, 2017, MariaDB Corporation. +Copyright (c) 2015, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1259,7 +1259,8 @@ row_import::match_table_columns( err = DB_ERROR; } - if (cfg_col->mbminmaxlen != col->mbminmaxlen) { + if (cfg_col->mbminlen != col->mbminlen + || cfg_col->mbmaxlen != col->mbmaxlen) { ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH, @@ -2877,7 +2878,9 @@ row_import_read_columns( col->len = mach_read_from_4(ptr); ptr += sizeof(ib_uint32_t); - col->mbminmaxlen = mach_read_from_4(ptr); + ulint mbminmaxlen = mach_read_from_4(ptr); + col->mbmaxlen = mbminmaxlen / 5; + col->mbminlen = mbminmaxlen % 5; ptr += sizeof(ib_uint32_t); col->ind = mach_read_from_4(ptr); diff --git a/storage/xtradb/row/row0ins.cc b/storage/xtradb/row/row0ins.cc index f653a4df77d..472be8ad848 100644 --- a/storage/xtradb/row/row0ins.cc +++ b/storage/xtradb/row/row0ins.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2017, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -571,7 +571,8 @@ row_ins_cascade_calc_update_vec( if (!dfield_is_null(&ufield->new_val) && dtype_get_at_most_n_mbchars( - col->prtype, col->mbminmaxlen, + col->prtype, + col->mbminlen, col->mbmaxlen, col->len, ufield_len, static_cast<char*>( @@ -1330,7 +1331,7 @@ row_ins_foreign_check_on_constraint( row_mysql_freeze_data_dictionary(thr_get_trx(thr)); - mtr_start_trx(mtr, trx); + mtr_start(mtr); /* Restore pcur position */ @@ -1358,7 +1359,7 @@ nonstandard_exit_func: btr_pcur_store_position(pcur, mtr); mtr_commit(mtr); - mtr_start_trx(mtr, trx); + mtr_start(mtr); btr_pcur_restore_position(BTR_SEARCH_LEAF, pcur, mtr); @@ -1571,7 +1572,7 @@ run_again: } } - mtr_start_trx(&mtr, trx); + mtr_start(&mtr); /* Store old value on n_fields_cmp */ @@ -2390,7 +2391,7 @@ row_ins_clust_index_entry_low( search_mode = mode; } - mtr_start_trx(&mtr, thr_get_trx(thr)); + mtr_start(&mtr); if (mode == BTR_MODIFY_LEAF && dict_index_is_online_ddl(index)) { @@ -2628,10 +2629,9 @@ Starts a mini-transaction and checks if the index will be dropped. @return true if the index is to be dropped */ static MY_ATTRIBUTE((nonnull, warn_unused_result)) bool -row_ins_sec_mtr_start_trx_and_check_if_aborted( +row_ins_sec_mtr_start_and_check_if_aborted( /*=======================================*/ mtr_t* mtr, /*!< out: mini-transaction */ - trx_t* trx, /*!< in: transaction handle */ dict_index_t* index, /*!< in/out: secondary index */ bool check, /*!< in: whether to check */ ulint search_mode) @@ -2639,7 +2639,7 @@ row_ins_sec_mtr_start_trx_and_check_if_aborted( { ut_ad(!dict_index_is_clust(index)); - mtr_start_trx(mtr, trx); + mtr_start(mtr); if (!check) { return(false); @@ -2697,14 +2697,13 @@ row_ins_sec_index_entry_low( ulint n_unique; mtr_t mtr; ulint* offsets = NULL; - trx_t* trx = thr_get_trx(thr); ut_ad(!dict_index_is_clust(index)); ut_ad(mode == BTR_MODIFY_LEAF || mode == BTR_MODIFY_TREE); cursor.thr = thr; ut_ad(thr_get_trx(thr)->id); - mtr_start_trx(&mtr, trx); + mtr_start(&mtr); /* If running with fake_changes mode on then avoid using insert buffer and also switch from modify to search so that code takes only s-latch @@ -2766,7 +2765,7 @@ row_ins_sec_index_entry_low( if (err != DB_SUCCESS) { if (err == DB_DECRYPTION_FAILED) { - ib_push_warning(trx->mysql_thd, + ib_push_warning(thr_get_trx(thr)->mysql_thd, DB_DECRYPTION_FAILED, "Table %s is encrypted but encryption service or" " used key_id is not available. " @@ -2802,8 +2801,8 @@ row_ins_sec_index_entry_low( DEBUG_SYNC_C("row_ins_sec_index_unique"); - if (row_ins_sec_mtr_start_trx_and_check_if_aborted( - &mtr, trx, index, check, search_mode)) { + if (row_ins_sec_mtr_start_and_check_if_aborted( + &mtr, index, check, search_mode)) { goto func_exit; } @@ -2837,8 +2836,8 @@ row_ins_sec_index_entry_low( return(err); } - if (row_ins_sec_mtr_start_trx_and_check_if_aborted( - &mtr, trx, index, check, search_mode)) { + if (row_ins_sec_mtr_start_and_check_if_aborted( + &mtr, index, check, search_mode)) { goto func_exit; } @@ -3147,7 +3146,7 @@ row_ins_index_entry_set_vals( = dict_field_get_col(ind_field); len = dtype_get_at_most_n_mbchars( - col->prtype, col->mbminmaxlen, + col->prtype, col->mbminlen, col->mbmaxlen, ind_field->prefix_len, len, static_cast<const char*>( diff --git a/storage/xtradb/row/row0log.cc b/storage/xtradb/row/row0log.cc index 82fde841f39..040fb37ee30 100644 --- a/storage/xtradb/row/row0log.cc +++ b/storage/xtradb/row/row0log.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2017, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1064,7 +1064,7 @@ row_log_table_get_pk_col( mem_heap_alloc(heap, field_len)); len = btr_copy_externally_stored_field_prefix( - blob_field, field_len, zip_size, field, len, NULL); + blob_field, field_len, zip_size, field, len); if (len >= max_len + 1) { return(DB_TOO_BIG_INDEX_COL); } @@ -1183,7 +1183,7 @@ row_log_table_get_pk( dict_field_t* ifield; dfield_t* dfield; ulint prtype; - ulint mbminmaxlen; + ulint mbminlen, mbmaxlen; ifield = dict_index_get_nth_field(new_index, new_i); dfield = dtuple_get_nth_field(tuple, new_i); @@ -1212,7 +1212,8 @@ err_exit: goto func_exit; } - mbminmaxlen = col->mbminmaxlen; + mbminlen = col->mbminlen; + mbmaxlen = col->mbmaxlen; prtype = col->prtype; } else { /* No matching column was found in the old @@ -1222,7 +1223,8 @@ err_exit: dfield_copy(dfield, dtuple_get_nth_field( log->add_cols, col_no)); - mbminmaxlen = dfield->type.mbminmaxlen; + mbminlen = dfield->type.mbminlen; + mbmaxlen = dfield->type.mbmaxlen; prtype = dfield->type.prtype; } @@ -1231,7 +1233,7 @@ err_exit: if (ifield->prefix_len) { ulint len = dtype_get_at_most_n_mbchars( - prtype, mbminmaxlen, + prtype, mbminlen, mbmaxlen, ifield->prefix_len, dfield_get_len(dfield), static_cast<const char*>( @@ -1455,7 +1457,7 @@ row_log_table_apply_convert_mrec( data = btr_rec_copy_externally_stored_field( mrec, offsets, dict_table_zip_size(index->table), - i, &len, heap, NULL); + i, &len, heap); ut_a(data); dfield_set_data(dfield, data, len); blob_done: diff --git a/storage/xtradb/row/row0merge.cc b/storage/xtradb/row/row0merge.cc index cbcc3cc62f3..d9585818577 100644 --- a/storage/xtradb/row/row0merge.cc +++ b/storage/xtradb/row/row0merge.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2005, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2017, MariaDB Corporation. +Copyright (c) 2014, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -268,8 +268,8 @@ row_merge_buf_redundant_convert( mem_heap_t* heap, trx_t* trx) { - ut_ad(DATA_MBMINLEN(field->type.mbminmaxlen) == 1); - ut_ad(DATA_MBMAXLEN(field->type.mbminmaxlen) > 1); + ut_ad(field->type.mbminlen == 1); + ut_ad(field->type.mbmaxlen > 1); byte* buf = (byte*) mem_heap_alloc(heap, len); ulint field_len = row_field->len; @@ -285,7 +285,7 @@ row_merge_buf_redundant_convert( field_ref_zero, BTR_EXTERN_FIELD_REF_SIZE)); byte* data = btr_copy_externally_stored_field( - &ext_len, field_data, zip_size, field_len, heap, trx); + &ext_len, field_data, zip_size, field_len, heap); ut_ad(ext_len < len); @@ -396,7 +396,8 @@ row_merge_buf_add( field->type.mtype = ifield->col->mtype; field->type.prtype = ifield->col->prtype; - field->type.mbminmaxlen = DATA_MBMINMAXLEN(0, 0); + field->type.mbminlen = 0; + field->type.mbmaxlen = 0; field->type.len = ifield->col->len; } else { row_field = dtuple_get_nth_field(row, col_no); @@ -531,7 +532,7 @@ row_merge_buf_add( if (ifield->prefix_len) { len = dtype_get_at_most_n_mbchars( col->prtype, - col->mbminmaxlen, + col->mbminlen, col->mbmaxlen, ifield->prefix_len, len, static_cast<char*>(dfield_get_data(field))); @@ -546,8 +547,7 @@ row_merge_buf_add( fixed_len = ifield->fixed_len; if (fixed_len && !dict_table_is_comp(index->table) - && DATA_MBMINLEN(col->mbminmaxlen) - != DATA_MBMAXLEN(col->mbminmaxlen)) { + && col->mbminlen != col->mbmaxlen) { /* CHAR in ROW_FORMAT=REDUNDANT is always fixed-length, but in the temporary file it is variable-length for variable-length character @@ -557,14 +557,11 @@ row_merge_buf_add( if (fixed_len) { #ifdef UNIV_DEBUG - ulint mbminlen = DATA_MBMINLEN(col->mbminmaxlen); - ulint mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen); - /* len should be between size calcualted base on mbmaxlen and mbminlen */ ut_ad(len <= fixed_len); - ut_ad(!mbmaxlen || len >= mbminlen - * (fixed_len / mbmaxlen)); + ut_ad(!col->mbmaxlen || len >= col->mbminlen + * (fixed_len / col->mbmaxlen)); ut_ad(!dfield_is_ext(field)); #endif /* UNIV_DEBUG */ @@ -2626,7 +2623,7 @@ row_merge_copy_blobs( BLOB pointers are read (row_merge_read_clustered_index()) and dereferenced (below). */ data = btr_rec_copy_externally_stored_field( - mrec, offsets, zip_size, i, &len, heap, NULL); + mrec, offsets, zip_size, i, &len, heap); /* Because we have locked the table, any records written by incomplete transactions must have been rolled back already. There must not be any incomplete diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc index 43f4d4bcdd3..549a19799b3 100644 --- a/storage/xtradb/row/row0mysql.cc +++ b/storage/xtradb/row/row0mysql.cc @@ -1,7 +1,7 @@ /***************************************************************************** -Copyright (c) 2000, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, 2017, MariaDB Corporation. +Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2015, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -58,6 +58,7 @@ Created 9/17/2000 Heikki Tuuri #include "btr0sea.h" #include "btr0defragment.h" #include "fil0fil.h" +#include "srv0srv.h" #include "fil0crypt.h" #include "ibuf0ibuf.h" #include "fts0fts.h" @@ -1998,7 +1999,7 @@ row_unlock_for_mysql( trx_id_t rec_trx_id; mtr_t mtr; - mtr_start_trx(&mtr, trx); + mtr_start(&mtr); /* Restore the cursor position and find the record */ @@ -2888,7 +2889,7 @@ func_exit: /*********************************************************************//** Reassigns the table identifier of a table. @return error code or DB_SUCCESS */ -UNIV_INTERN +static dberr_t row_mysql_table_id_reassign( /*========================*/ @@ -3585,7 +3586,7 @@ row_truncate_table_for_mysql( index = dict_table_get_next_index(index); } while (index); - mtr_start_trx(&mtr, trx); + mtr_start(&mtr); fsp_header_init(space_id, FIL_IBD_FILE_INITIAL_SIZE, &mtr); mtr_commit(&mtr); @@ -3614,7 +3615,7 @@ row_truncate_table_for_mysql( sys_index = dict_table_get_first_index(dict_sys->sys_indexes); dict_index_copy_types(tuple, sys_index, 1); - mtr_start_trx(&mtr, trx); + mtr_start(&mtr); btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, BTR_MODIFY_LEAF, &pcur, &mtr); for (;;) { @@ -3661,7 +3662,7 @@ row_truncate_table_for_mysql( a page in this mini-transaction, and the rest of this loop could latch another index page. */ mtr_commit(&mtr); - mtr_start_trx(&mtr, trx); + mtr_start(&mtr); btr_pcur_restore_position(BTR_MODIFY_LEAF, &pcur, &mtr); } @@ -4003,6 +4004,16 @@ row_drop_table_for_mysql( ut_ad(!table->fts->add_wq); ut_ad(lock_trx_has_sys_table_locks(trx) == 0); + for (;;) { + bool retry = false; + if (dict_fts_index_syncing(table)) { + retry = true; + } + if (!retry) { + break; + } + DICT_BG_YIELD(trx); + } row_mysql_unlock_data_dictionary(trx); fts_optimize_remove_table(table); row_mysql_lock_data_dictionary(trx); diff --git a/storage/xtradb/row/row0quiesce.cc b/storage/xtradb/row/row0quiesce.cc index 6c4e6adb96c..53b4040f74e 100644 --- a/storage/xtradb/row/row0quiesce.cc +++ b/storage/xtradb/row/row0quiesce.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2017, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -237,7 +237,11 @@ row_quiesce_write_table( mach_write_to_4(ptr, col->len); ptr += sizeof(ib_uint32_t); - mach_write_to_4(ptr, col->mbminmaxlen); + /* FIXME: This will not work if mbminlen>4. + This field is also redundant, because the lengths + are a property of the character set encoding, which + in turn is encodedin prtype above. */ + mach_write_to_4(ptr, col->mbmaxlen * 5 + col->mbminlen); ptr += sizeof(ib_uint32_t); mach_write_to_4(ptr, col->ind); diff --git a/storage/xtradb/row/row0row.cc b/storage/xtradb/row/row0row.cc index 96d25e15777..9bf9e7182ca 100644 --- a/storage/xtradb/row/row0row.cc +++ b/storage/xtradb/row/row0row.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -173,7 +174,7 @@ row_build_index_entry_low( /* If a column prefix index, take only the prefix. */ if (ind_field->prefix_len) { len = dtype_get_at_most_n_mbchars( - col->prtype, col->mbminmaxlen, + col->prtype, col->mbminlen, col->mbmaxlen, ind_field->prefix_len, len, static_cast<char*>(dfield_get_data(dfield))); dfield_set_len(dfield, len); @@ -588,7 +589,8 @@ row_build_row_ref( dfield_set_len(dfield, dtype_get_at_most_n_mbchars( dtype->prtype, - dtype->mbminmaxlen, + dtype->mbminlen, + dtype->mbmaxlen, clust_col_prefix_len, len, (char*) field)); } @@ -702,7 +704,8 @@ notfound: dfield_set_len(dfield, dtype_get_at_most_n_mbchars( dtype->prtype, - dtype->mbminmaxlen, + dtype->mbminlen, + dtype->mbmaxlen, clust_col_prefix_len, len, (char*) field)); } diff --git a/storage/xtradb/row/row0sel.cc b/storage/xtradb/row/row0sel.cc index 6131129d0a6..03ae6822fb7 100644 --- a/storage/xtradb/row/row0sel.cc +++ b/storage/xtradb/row/row0sel.cc @@ -2,7 +2,7 @@ Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. -Copyright (c) 2015, 2017, MariaDB Corporation. +Copyright (c) 2015, 2018, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -98,8 +98,10 @@ row_sel_sec_rec_is_for_blob( /*========================*/ ulint mtype, /*!< in: main type */ ulint prtype, /*!< in: precise type */ - ulint mbminmaxlen, /*!< in: minimum and maximum length of - a multi-byte character */ + ulint mbminlen, /*!< in: minimum length of + a character, in bytes */ + ulint mbmaxlen, /*!< in: maximum length of + a character, in bytes */ const byte* clust_field, /*!< in: the locally stored part of the clustered index column, including the BLOB pointer; the clustered @@ -138,8 +140,7 @@ row_sel_sec_rec_is_for_blob( len = btr_copy_externally_stored_field_prefix(buf, prefix_len, zip_size, - clust_field, clust_len, - NULL); + clust_field, clust_len); if (UNIV_UNLIKELY(len == 0)) { /* The BLOB was being deleted as the server crashed. @@ -150,7 +151,7 @@ row_sel_sec_rec_is_for_blob( return(FALSE); } - len = dtype_get_at_most_n_mbchars(prtype, mbminmaxlen, + len = dtype_get_at_most_n_mbchars(prtype, mbminlen, mbmaxlen, prefix_len, len, (const char*) buf); return(!cmp_data_data(mtype, prtype, buf, len, sec_field, sec_len)); @@ -234,14 +235,14 @@ row_sel_sec_rec_is_for_clust_rec( } len = dtype_get_at_most_n_mbchars( - col->prtype, col->mbminmaxlen, + col->prtype, col->mbminlen, col->mbmaxlen, ifield->prefix_len, len, (char*) clust_field); if (rec_offs_nth_extern(clust_offs, clust_pos) && len < sec_len) { if (!row_sel_sec_rec_is_for_blob( col->mtype, col->prtype, - col->mbminmaxlen, + col->mbminlen, col->mbmaxlen, clust_field, clust_len, sec_field, sec_len, ifield->prefix_len, @@ -458,7 +459,7 @@ row_sel_fetch_columns( data = btr_rec_copy_externally_stored_field( rec, offsets, dict_table_zip_size(index->table), - field_no, &len, heap, NULL); + field_no, &len, heap); /* data == NULL means that the externally stored field was not @@ -1406,7 +1407,7 @@ table_loop: /* Open a cursor to index, or restore an open cursor position */ - mtr_start_trx(&mtr, thr_get_trx(thr)); + mtr_start(&mtr); if (consistent_read && plan->unique_search && !plan->pcur_is_open && !plan->must_get_clust @@ -1447,7 +1448,7 @@ table_loop: plan_reset_cursor(plan); mtr_commit(&mtr); - mtr_start_trx(&mtr, thr_get_trx(thr)); + mtr_start(&mtr); } if (search_latch_locked) { @@ -2828,7 +2829,7 @@ row_sel_store_mysql_field_func( data = btr_rec_copy_externally_stored_field( rec, offsets, dict_table_zip_size(prebuilt->table), - field_no, &len, heap, NULL); + field_no, &len, heap); if (UNIV_UNLIKELY(!data)) { /* The externally stored field was not written @@ -3933,7 +3934,7 @@ row_search_for_mysql( } } - mtr_start_trx(&mtr, trx); + mtr_start(&mtr); /*-------------------------------------------------------------*/ /* PHASE 2: Try fast adaptive hash index search if possible */ @@ -5159,7 +5160,7 @@ next_rec: mtr_commit(&mtr); mtr_has_extra_clust_latch = FALSE; - mtr_start_trx(&mtr, trx); + mtr_start(&mtr); if (sel_restore_position_for_mysql(&same_user_rec, BTR_SEARCH_LEAF, pcur, moves_up, &mtr)) { @@ -5226,7 +5227,7 @@ lock_table_wait: /* It was a lock wait, and it ended */ thr->lock_state = QUE_THR_LOCK_NOLOCK; - mtr_start_trx(&mtr, trx); + mtr_start(&mtr); /* Table lock waited, go try to obtain table lock again */ diff --git a/storage/xtradb/row/row0umod.cc b/storage/xtradb/row/row0umod.cc index 2e5cc14bfe1..bb2fc536616 100644 --- a/storage/xtradb/row/row0umod.cc +++ b/storage/xtradb/row/row0umod.cc @@ -269,7 +269,7 @@ row_undo_mod_clust( pcur = &node->pcur; index = btr_cur_get_index(btr_pcur_get_btr_cur(pcur)); - mtr_start_trx(&mtr, thr_get_trx(thr)); + mtr_start(&mtr); online = dict_index_is_online_ddl(index); if (online) { @@ -298,7 +298,7 @@ row_undo_mod_clust( /* We may have to modify tree structure: do a pessimistic descent down the index tree */ - mtr_start_trx(&mtr, thr_get_trx(thr)); + mtr_start(&mtr); err = row_undo_mod_clust_low( node, &offsets, &offsets_heap, @@ -350,7 +350,7 @@ row_undo_mod_clust( if (err == DB_SUCCESS && node->rec_type == TRX_UNDO_UPD_DEL_REC) { - mtr_start_trx(&mtr, thr_get_trx(thr)); + mtr_start(&mtr); /* It is not necessary to call row_log_table, because the record is delete-marked and would thus @@ -363,7 +363,7 @@ row_undo_mod_clust( /* We may have to modify tree structure: do a pessimistic descent down the index tree */ - mtr_start_trx(&mtr, thr_get_trx(thr)); + mtr_start(&mtr); err = row_undo_mod_remove_clust_low(node, thr, &mtr, BTR_MODIFY_TREE); @@ -410,7 +410,7 @@ row_undo_mod_del_mark_or_remove_sec_low( enum row_search_result search_result; log_free_check(); - mtr_start_trx(&mtr, thr_get_trx(thr)); + mtr_start(&mtr); if (mode == BTR_MODIFY_TREE && index->space == IBUF_SPACE_ID && !dict_index_is_unique(index)) { @@ -471,7 +471,7 @@ row_undo_mod_del_mark_or_remove_sec_low( which cannot be purged yet, requires its existence. If some requires, we should delete mark the record. */ - mtr_start_trx(&mtr_vers, thr_get_trx(thr)); + mtr_start(&mtr_vers); success = btr_pcur_restore_position(BTR_SEARCH_LEAF, &(node->pcur), &mtr_vers); @@ -587,7 +587,7 @@ row_undo_mod_del_unmark_sec_and_undo_update( ut_ad(trx->id); log_free_check(); - mtr_start_trx(&mtr, thr_get_trx(thr)); + mtr_start(&mtr); if (mode == BTR_MODIFY_TREE && index->space == IBUF_SPACE_ID && !dict_index_is_unique(index)) { diff --git a/storage/xtradb/row/row0upd.cc b/storage/xtradb/row/row0upd.cc index 113d2f10fc2..9ac72f8d068 100644 --- a/storage/xtradb/row/row0upd.cc +++ b/storage/xtradb/row/row0upd.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -261,7 +262,7 @@ row_upd_check_references_constraints( DEBUG_SYNC_C("foreign_constraint_check_for_update"); - mtr_start_trx(mtr, trx); + mtr_start(mtr); if (trx->dict_operation_lock_mode == 0) { got_s_lock = TRUE; @@ -1155,7 +1156,7 @@ row_upd_ext_fetch( byte* buf = static_cast<byte*>(mem_heap_alloc(heap, *len)); *len = btr_copy_externally_stored_field_prefix( - buf, *len, zip_size, data, local_len, NULL); + buf, *len, zip_size, data, local_len); /* We should never update records containing a half-deleted BLOB. */ ut_a(*len); @@ -1207,7 +1208,7 @@ row_upd_index_replace_new_col_val( } len = dtype_get_at_most_n_mbchars(col->prtype, - col->mbminmaxlen, + col->mbminlen, col->mbmaxlen, field->prefix_len, len, (const char*) data); @@ -1855,7 +1856,7 @@ row_upd_sec_index_entry( } #endif /* UNIV_DEBUG */ - mtr_start_trx(&mtr, trx); + mtr_start(&mtr); if (*index->name == TEMP_INDEX_PREFIX) { /* The index->online_status may change if the @@ -2398,7 +2399,7 @@ row_upd_clust_rec( /* We may have to modify the tree structure: do a pessimistic descent down the index tree */ - mtr_start_trx(mtr, thr_get_trx(thr)); + mtr_start(mtr); /* NOTE: this transaction has an s-lock or x-lock on the record and therefore other transactions cannot modify the record when we have no @@ -2613,7 +2614,7 @@ row_upd_clust_step( /* We have to restore the cursor to its position */ - mtr_start_trx(&mtr, thr_get_trx(thr)); + mtr_start(&mtr); /* If the restoration does not succeed, then the same transaction has deleted the record on which the cursor was, @@ -2686,7 +2687,7 @@ row_upd_clust_step( mtr_commit(&mtr); - mtr_start_trx(&mtr, thr_get_trx(thr)); + mtr_start(&mtr); success = btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur, &mtr); diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc index 65a15b15aec..b0bf526a47e 100644 --- a/storage/xtradb/srv/srv0srv.cc +++ b/storage/xtradb/srv/srv0srv.cc @@ -83,7 +83,6 @@ Created 10/8/1995 Heikki Tuuri ibool innobase_get_slow_log(); #ifdef WITH_WSREP -extern int wsrep_debug; extern int wsrep_trx_is_aborting(void *thd_ptr); #endif /* The following counter is incremented whenever there is some user activity @@ -479,6 +478,9 @@ UNIV_INTERN my_bool srv_print_all_deadlocks = FALSE; /* Produce a stacktrace on long semaphore wait */ UNIV_INTERN my_bool srv_use_stacktrace = FALSE; +/** Print lock wait timeout info to mysqld stderr */ +my_bool srv_print_lock_wait_timeout_info = FALSE; + /** Enable INFORMATION_SCHEMA.innodb_cmp_per_index */ UNIV_INTERN my_bool srv_cmp_per_index_enabled = FALSE; @@ -2137,6 +2139,9 @@ srv_export_innodb_status(void) scrub_stat.page_split_failures_unknown; } + export_vars.innodb_buffered_aio_submitted = + srv_stats.n_aio_submitted; + mutex_exit(&srv_innodb_monitor_mutex); } diff --git a/storage/xtradb/trx/trx0rec.cc b/storage/xtradb/trx/trx0rec.cc index e295e7e05ca..dc9b0829925 100644 --- a/storage/xtradb/trx/trx0rec.cc +++ b/storage/xtradb/trx/trx0rec.cc @@ -467,7 +467,7 @@ trx_undo_page_fetch_ext( { /* Fetch the BLOB. */ ulint ext_len = btr_copy_externally_stored_field_prefix( - ext_buf, prefix_len, zip_size, field, *len, NULL); + ext_buf, prefix_len, zip_size, field, *len); /* BLOBs should always be nonempty. */ ut_a(ext_len); /* Append the BLOB pointer to the prefix. */ @@ -1268,7 +1268,7 @@ trx_undo_report_row_operation( rseg = trx->rseg; - mtr_start_trx(&mtr, trx); + mtr_start(&mtr); mutex_enter(&trx->undo_mutex); /* If the undo log is not assigned yet, assign one */ @@ -1345,7 +1345,7 @@ trx_undo_report_row_operation( latches, such as SYNC_FSP and SYNC_FSP_PAGE. */ mtr_commit(&mtr); - mtr_start_trx(&mtr, trx); + mtr_start(&mtr); mutex_enter(&rseg->mutex); trx_undo_free_last_page(trx, undo, &mtr); @@ -1382,7 +1382,7 @@ trx_undo_report_row_operation( /* We have to extend the undo log by one page */ ut_ad(++loop_count < 2); - mtr_start_trx(&mtr, trx); + mtr_start(&mtr); /* When we add a page to an undo log, this is analogous to a pessimistic insert in a B-tree, and we must reserve the diff --git a/storage/xtradb/trx/trx0undo.cc b/storage/xtradb/trx/trx0undo.cc index 24d14e06080..0d5a0f55f0d 100644 --- a/storage/xtradb/trx/trx0undo.cc +++ b/storage/xtradb/trx/trx0undo.cc @@ -1070,9 +1070,11 @@ Truncates an undo log from the end. This function is used during a rollback to free space from an undo log. */ UNIV_INTERN void -trx_undo_truncate_end( +trx_undo_truncate_end_func( /*=======================*/ - trx_t* trx, /*!< in: transaction whose undo log it is */ +#ifdef UNIV_DEBUG + const trx_t* trx, /*!< in: transaction whose undo log it is */ +#endif /* UNIV_DEBUG */ trx_undo_t* undo, /*!< in: undo log */ undo_no_t limit) /*!< in: all undo records with undo number >= this value should be truncated */ @@ -1087,7 +1089,7 @@ trx_undo_truncate_end( ut_ad(mutex_own(&(trx->rseg->mutex))); for (;;) { - mtr_start_trx(&mtr, trx); + mtr_start(&mtr); trunc_here = NULL; @@ -1774,7 +1776,7 @@ trx_undo_assign_undo( ut_ad(mutex_own(&(trx->undo_mutex))); - mtr_start_trx(&mtr, trx); + mtr_start(&mtr); mutex_enter(&rseg->mutex); |