diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2019-07-25 15:31:11 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2019-07-25 15:31:11 +0300 |
commit | fdef9f9b8960479919285d6aec0bb30d27fa4723 (patch) | |
tree | f358b0f34305572ddf5b4fd2466c3a09ba37c7db /storage/innobase | |
parent | 55d8ff0de8168d3b7d465644dc93dca01f53f4f6 (diff) | |
parent | a7e9395f9de0cc19cf79064f5df796d98ec19762 (diff) | |
download | mariadb-git-fdef9f9b8960479919285d6aec0bb30d27fa4723.tar.gz |
Merge 10.2 into 10.3
Diffstat (limited to 'storage/innobase')
43 files changed, 297 insertions, 782 deletions
diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index 2c00c4480ff..4513a63049d 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -145,8 +145,7 @@ SET(INNOBASE_SOURCES ut/ut0rnd.cc ut/ut0ut.cc ut/ut0vec.cc - ut/ut0wqueue.cc - ut/ut0timer.cc) + ut/ut0wqueue.cc) MYSQL_ADD_PLUGIN(innobase ${INNOBASE_SOURCES} STORAGE_ENGINE MODULE_OUTPUT_NAME ha_innodb diff --git a/storage/innobase/btr/btr0defragment.cc b/storage/innobase/btr/btr0defragment.cc index 21e954efa54..08dde6d2ae8 100644 --- a/storage/innobase/btr/btr0defragment.cc +++ b/storage/innobase/btr/btr0defragment.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (C) 2013, 2014 Facebook, Inc. All Rights Reserved. +Copyright (C) 2012, 2014 Facebook, Inc. All Rights Reserved. Copyright (C) 2014, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -36,7 +36,6 @@ Modified 30/07/2014 Jan Lindström jan.lindstrom@mariadb.com #include "ibuf0ibuf.h" #include "lock0lock.h" #include "srv0start.h" -#include "ut0timer.h" #include <list> @@ -100,8 +99,7 @@ Initialize defragmentation. */ void btr_defragment_init() { - srv_defragment_interval = ut_microseconds_to_timer( - (ulonglong) (1000000.0 / srv_defragment_frequency)); + srv_defragment_interval = 1000000000ULL / srv_defragment_frequency; mutex_create(LATCH_ID_BTR_DEFRAGMENT_MUTEX, &btr_defragment_mutex); } @@ -731,7 +729,7 @@ DECLARE_THREAD(btr_defragment_thread)(void*) } pcur = item->pcur; - ulonglong now = ut_timer_now(); + ulonglong now = my_interval_timer(); ulonglong elapsed = now - item->last_processed; if (elapsed < srv_defragment_interval) { @@ -741,11 +739,12 @@ DECLARE_THREAD(btr_defragment_thread)(void*) defragmentation of all indices queue up on a single thread, it's likely other indices that follow this one don't need to sleep again. */ - os_thread_sleep(((ulint)ut_timer_to_microseconds( - srv_defragment_interval - elapsed))); + os_thread_sleep(static_cast<ulint> + ((srv_defragment_interval - elapsed) + / 1000)); } - now = ut_timer_now(); + now = my_interval_timer(); mtr_start(&mtr); cursor = btr_pcur_get_btr_cur(pcur); index = btr_cur_get_index(cursor); diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 293f32bcab0..b8ee5140dd0 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -1983,7 +1983,7 @@ buf_pool_init_instance( buf_pool->zip_hash = hash_create(2 * buf_pool->curr_size); - buf_pool->last_printout_time = ut_time(); + buf_pool->last_printout_time = time(NULL); } /* 2. Initialize flushing fields -------------------------------- */ @@ -2822,7 +2822,7 @@ buf_pool_resize() buf_resize_status("Withdrawing blocks to be shrunken."); - ib_time_t withdraw_started = ut_time(); + time_t withdraw_started = time(NULL); ulint message_interval = 60; ulint retry_interval = 1; @@ -2848,8 +2848,10 @@ withdraw_retry: /* abort buffer pool load */ buf_load_abort(); + const time_t current_time = time(NULL); + if (should_retry_withdraw - && ut_difftime(ut_time(), withdraw_started) >= message_interval) { + && difftime(current_time, withdraw_started) >= message_interval) { if (message_interval > 900) { message_interval = 1800; @@ -2865,8 +2867,7 @@ withdraw_retry: trx = UT_LIST_GET_NEXT(trx_list, trx)) { if (trx->state != TRX_STATE_NOT_STARTED && trx->mysql_thd != NULL - && ut_difftime(withdraw_started, - trx->start_time) > 0) { + && withdraw_started > trx->start_time) { if (!found) { ib::warn() << "The following trx might hold" @@ -2879,13 +2880,13 @@ withdraw_retry: } lock_trx_print_wait_and_mvcc_state( - stderr, trx); + stderr, trx, current_time); } } mutex_exit(&trx_sys.mutex); lock_mutex_exit(); - withdraw_started = ut_time(); + withdraw_started = current_time; } if (should_retry_withdraw) { @@ -6351,7 +6352,7 @@ void buf_refresh_io_stats( buf_pool_t* buf_pool) { - buf_pool->last_printout_time = ut_time(); + buf_pool->last_printout_time = time(NULL); buf_pool->old_stat = buf_pool->stat; } diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index d7343fbd9ed..fffeafbdf8c 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -2441,7 +2441,7 @@ page_cleaner_flush_pages_recommendation( if (prev_lsn == 0) { /* First time around. */ prev_lsn = cur_lsn; - prev_time = ut_time(); + prev_time = time(NULL); return(0); } @@ -2451,7 +2451,7 @@ page_cleaner_flush_pages_recommendation( sum_pages += last_pages_in; - time_t curr_time = ut_time(); + time_t curr_time = time(NULL); double time_elapsed = difftime(curr_time, prev_time); /* We update our variables every srv_flushing_avg_loops diff --git a/storage/innobase/dict/dict0defrag_bg.cc b/storage/innobase/dict/dict0defrag_bg.cc index f1ea8ae30d2..73f55cc8667 100644 --- a/storage/innobase/dict/dict0defrag_bg.cc +++ b/storage/innobase/dict/dict0defrag_bg.cc @@ -238,7 +238,6 @@ dict_stats_save_defrag_summary( dict_index_t* index) /*!< in: index */ { dberr_t ret=DB_SUCCESS; - lint now = (lint) ut_time(); if (dict_index_is_ibuf(index)) { return DB_SUCCESS; @@ -247,7 +246,7 @@ dict_stats_save_defrag_summary( rw_lock_x_lock(&dict_operation_lock); mutex_enter(&dict_sys->mutex); - ret = dict_stats_save_index_stat(index, now, "n_pages_freed", + ret = dict_stats_save_index_stat(index, time(NULL), "n_pages_freed", index->stat_defrag_n_pages_freed, NULL, "Number of pages freed during" @@ -278,7 +277,7 @@ dict_stats_save_defrag_stats( return dict_stats_report_error(index->table, true); } - lint now = (lint) ut_time(); + const time_t now = time(NULL); mtr_t mtr; ulint n_leaf_pages; ulint n_leaf_reserved; diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index 1b8f4931553..0310f275196 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -960,7 +960,7 @@ dict_stats_update_transient( table->stat_sum_of_other_index_sizes = sum_of_index_sizes - index->stat_index_size; - table->stats_last_recalc = ut_time(); + table->stats_last_recalc = time(NULL); table->stat_modified_counter = 0; @@ -2271,7 +2271,7 @@ dict_stats_update_persistent( += index->stat_index_size; } - table->stats_last_recalc = ut_time(); + table->stats_last_recalc = time(NULL); table->stat_modified_counter = 0; @@ -2300,7 +2300,7 @@ rolled back only in the case of error, but not freed. dberr_t dict_stats_save_index_stat( dict_index_t* index, - ib_time_t last_update, + time_t last_update, const char* stat_name, ib_uint64_t stat_value, ib_uint64_t* sample_size, @@ -2429,7 +2429,6 @@ dict_stats_save( const index_id_t* only_for_index) { pars_info_t* pinfo; - ib_time_t now; dberr_t ret; dict_table_t* table; char db_utf8[MAX_DB_UTF8_LEN]; @@ -2448,7 +2447,7 @@ dict_stats_save( dict_fs2utf8(table->name.m_name, db_utf8, sizeof(db_utf8), table_utf8, sizeof(table_utf8)); - now = ut_time(); + const time_t now = time(NULL); rw_lock_x_lock(&dict_operation_lock); mutex_enter(&dict_sys->mutex); diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc index c387d35dfd4..812c5c539f5 100644 --- a/storage/innobase/dict/dict0stats_bg.cc +++ b/storage/innobase/dict/dict0stats_bg.cc @@ -393,14 +393,14 @@ dict_stats_process_entry_from_recalc_pool() mutex_exit(&dict_sys->mutex); - /* ut_time() could be expensive, the current function + /* time() could be expensive, the current function is called once every time a table has been changed more than 10% and on a system with lots of small tables, this could become hot. If we find out that this is a problem, then the check below could eventually be replaced with something else, though a time interval is the natural approach. */ - if (ut_difftime(ut_time(), table->stats_last_recalc) + if (difftime(time(NULL), table->stats_last_recalc) < MIN_RECALC_INTERVAL) { /* Stats were (re)calculated not long ago. To avoid diff --git a/storage/innobase/eval/eval0eval.cc b/storage/innobase/eval/eval0eval.cc index fc16b9defb5..577157d2eb9 100644 --- a/storage/innobase/eval/eval0eval.cc +++ b/storage/innobase/eval/eval0eval.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2019, 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 @@ -814,7 +815,7 @@ eval_predefined( dfield_get_data(que_node_get_val(arg1))); } else if (func == PARS_SYSDATE_TOKEN) { - int_val = (lint) ut_time(); + int_val = (lint) time(NULL); } else { eval_predefined_2(func_node); diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index e9b7c7b45c4..ba29c65145e 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -74,8 +74,8 @@ ulong fts_min_token_size; // FIXME: testing -static ib_time_t elapsed_time = 0; -static ulint n_nodes = 0; +static time_t elapsed_time; +static ulint n_nodes; #ifdef FTS_CACHE_SIZE_DEBUG /** The cache size permissible lower limit (1K) */ @@ -194,15 +194,13 @@ FTS auxiliary INDEX table and clear the cache at the end. @param[in,out] sync sync state @param[in] unlock_cache whether unlock cache lock when write node @param[in] wait whether wait when a sync is in progress -@param[in] has_dict whether has dict operation lock @return DB_SUCCESS if all OK */ static dberr_t fts_sync( fts_sync_t* sync, bool unlock_cache, - bool wait, - bool has_dict); + bool wait); /****************************************************************//** Release all resources help by the words rb tree e.g., the node ilist. */ @@ -3399,7 +3397,7 @@ fts_add_doc_from_tuple( if (cache->total_size > fts_max_cache_size / 5 || fts_need_sync) { - fts_sync(cache->sync, true, false, false); + fts_sync(cache->sync, true, false); } mtr_start(&mtr); @@ -3577,7 +3575,7 @@ fts_add_doc_by_id( DBUG_EXECUTE_IF( "fts_instrument_sync_debug", - fts_sync(cache->sync, true, true, false); + fts_sync(cache->sync, true, true); ); DEBUG_SYNC_C("fts_instrument_sync_request"); @@ -3850,7 +3848,7 @@ fts_write_node( pars_info_t* info; dberr_t error; ib_uint32_t doc_count; - ib_time_t start_time; + time_t start_time; doc_id_t last_doc_id; doc_id_t first_doc_id; char table_name[MAX_FULL_NAME_LEN]; @@ -3899,9 +3897,9 @@ fts_write_node( " :last_doc_id, :doc_count, :ilist);"); } - start_time = ut_time(); + start_time = time(NULL); error = fts_eval_sql(trx, *graph); - elapsed_time += ut_time() - start_time; + elapsed_time += time(NULL) - start_time; ++n_nodes; return(error); @@ -4078,7 +4076,7 @@ fts_sync_begin( n_nodes = 0; elapsed_time = 0; - sync->start_time = ut_time(); + sync->start_time = time(NULL); sync->trx = trx_create(); trx_start_internal(sync->trx); @@ -4217,7 +4215,7 @@ fts_sync_commit( if (fts_enable_diag_print && elapsed_time) { ib::info() << "SYNC for table " << sync->table->name << ": SYNC time: " - << (ut_time() - sync->start_time) + << (time(NULL) - sync->start_time) << " secs: elapsed " << (double) n_nodes / elapsed_time << " ins/sec"; @@ -4287,15 +4285,13 @@ FTS auxiliary INDEX table and clear the cache at the end. @param[in,out] sync sync state @param[in] unlock_cache whether unlock cache lock when write node @param[in] wait whether wait when a sync is in progress -@param[in] has_dict whether has dict operation lock @return DB_SUCCESS if all OK */ static dberr_t fts_sync( fts_sync_t* sync, bool unlock_cache, - bool wait, - bool has_dict) + bool wait) { if (srv_read_only_mode) { return DB_READ_ONLY; @@ -4328,12 +4324,6 @@ fts_sync( DEBUG_SYNC_C("fts_sync_begin"); fts_sync_begin(sync); - /* When sync in background, we hold dict operation lock - to prevent DDL like DROP INDEX, etc. */ - if (has_dict) { - sync->trx->dict_operation_lock_mode = RW_S_LATCH; - } - begin_sync: if (cache->total_size > fts_max_cache_size) { /* Avoid the case: sync never finish when @@ -4424,16 +4414,9 @@ end_sync: /** Run SYNC on the table, i.e., write out data from the cache to the FTS auxiliary INDEX table and clear the cache at the end. @param[in,out] table fts table -@param[in] unlock_cache whether unlock cache when write node @param[in] wait whether wait for existing sync to finish -@param[in] has_dict whether has dict operation lock @return DB_SUCCESS on success, error code on failure. */ -dberr_t -fts_sync_table( - dict_table_t* table, - bool unlock_cache, - bool wait, - bool has_dict) +dberr_t fts_sync_table(dict_table_t* table, bool wait) { dberr_t err = DB_SUCCESS; @@ -4441,8 +4424,7 @@ fts_sync_table( if (table->space && table->fts->cache && !dict_table_is_corrupted(table)) { - err = fts_sync(table->fts->cache->sync, - unlock_cache, wait, has_dict); + err = fts_sync(table->fts->cache->sync, !wait, wait); } return(err); diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc index a0c63f83276..fa1e4ceb44b 100644 --- a/storage/innobase/fts/fts0opt.cc +++ b/storage/innobase/fts/fts0opt.cc @@ -58,7 +58,7 @@ static os_event_t fts_opt_shutdown_event = NULL; static const ulint FTS_WORD_NODES_INIT_SIZE = 64; /** Last time we did check whether system need a sync */ -static ib_time_t last_check_sync_time; +static time_t last_check_sync_time; /** FTS optimize thread message types. */ enum fts_msg_type_t { @@ -180,12 +180,11 @@ struct fts_slot_t { ulint deleted; /*!< Number of doc ids deleted since the last time this table was optimized */ - ib_time_t last_run; /*!< Time last run completed */ + /** time(NULL) of completing fts_optimize_table_bk() */ + time_t last_run; - ib_time_t completed; /*!< Optimize finish time */ - - ib_time_t interval_time; /*!< Minimum time to wait before - optimizing the table again. */ + /** time(NULL) of latest successful fts_optimize_table() */ + time_t completed; }; /** A table remove message for the FTS optimize thread. */ @@ -217,8 +216,8 @@ char fts_enable_diag_print; /** ZLib compressed block size.*/ static ulint FTS_ZIP_BLOCK_SIZE = 1024; -/** The amount of time optimizing in a single pass, in milliseconds. */ -static ib_time_t fts_optimize_time_limit = 0; +/** The amount of time optimizing in a single pass, in seconds. */ +static ulint fts_optimize_time_limit; /** It's defined in fts0fts.cc */ extern const char* fts_common_tables[]; @@ -1530,7 +1529,7 @@ fts_optimize_compact( /*=================*/ fts_optimize_t* optim, /*!< in: optimize state data */ dict_index_t* index, /*!< in: current FTS being optimized */ - ib_time_t start_time) /*!< in: optimize start time */ + time_t start_time) /*!< in: optimize start time */ { ulint i; dberr_t error = DB_SUCCESS; @@ -1563,8 +1562,11 @@ fts_optimize_compact( /* Free the word that was optimized. */ fts_word_free(word); + ulint interval = ulint(time(NULL) - start_time); + if (fts_optimize_time_limit > 0 - && (ut_time() - start_time) > fts_optimize_time_limit) { + && (lint(interval) < 0 + || interval > fts_optimize_time_limit)) { optim->done = TRUE; } @@ -1624,7 +1626,7 @@ fts_optimize_get_index_start_time( /*==============================*/ trx_t* trx, /*!< in: transaction */ dict_index_t* index, /*!< in: FTS index */ - ib_time_t* start_time) /*!< out: time in secs */ + time_t* start_time) /*!< out: time in secs */ { return(fts_config_get_index_ulint( trx, index, FTS_OPTIMIZE_START_TIME, @@ -1640,7 +1642,7 @@ fts_optimize_set_index_start_time( /*==============================*/ trx_t* trx, /*!< in: transaction */ dict_index_t* index, /*!< in: FTS index */ - ib_time_t start_time) /*!< in: start time */ + time_t start_time) /*!< in: start time */ { return(fts_config_set_index_ulint( trx, index, FTS_OPTIMIZE_START_TIME, @@ -1656,7 +1658,7 @@ fts_optimize_get_index_end_time( /*============================*/ trx_t* trx, /*!< in: transaction */ dict_index_t* index, /*!< in: FTS index */ - ib_time_t* end_time) /*!< out: time in secs */ + time_t* end_time) /*!< out: time in secs */ { return(fts_config_get_index_ulint( trx, index, FTS_OPTIMIZE_END_TIME, (ulint*) end_time)); @@ -1671,7 +1673,7 @@ fts_optimize_set_index_end_time( /*============================*/ trx_t* trx, /*!< in: transaction */ dict_index_t* index, /*!< in: FTS index */ - ib_time_t end_time) /*!< in: end time */ + time_t end_time) /*!< in: end time */ { return(fts_config_set_index_ulint( trx, index, FTS_OPTIMIZE_END_TIME, (ulint) end_time)); @@ -1734,22 +1736,23 @@ fts_optimize_free( Get the max time optimize should run in millisecs. @return max optimize time limit in millisecs. */ static -ib_time_t +ulint fts_optimize_get_time_limit( /*========================*/ trx_t* trx, /*!< in: transaction */ fts_table_t* fts_table) /*!< in: aux table */ { - ib_time_t time_limit = 0; + ulint time_limit = 0; fts_config_get_ulint( trx, fts_table, - FTS_OPTIMIZE_LIMIT_IN_SECS, (ulint*) &time_limit); + FTS_OPTIMIZE_LIMIT_IN_SECS, &time_limit); + /* FIXME: This is returning milliseconds, while the variable + is being stored and interpreted as seconds! */ return(time_limit * 1000); } - /**********************************************************************//** Run OPTIMIZE on the given table. Note: this can take a very long time (hours). */ @@ -1762,7 +1765,6 @@ fts_optimize_words( fts_string_t* word) /*!< in: the starting word to optimize */ { fts_fetch_t fetch; - ib_time_t start_time; que_t* graph = NULL; CHARSET_INFO* charset = optim->fts_index_table.charset; @@ -1772,7 +1774,7 @@ fts_optimize_words( fts_optimize_time_limit = fts_optimize_get_time_limit( optim->trx, &optim->fts_common_table); - start_time = ut_time(); + const time_t start_time = time(NULL); /* Setup the callback to use for fetching the word ilist etc. */ fetch.read_arg = optim->words; @@ -1858,7 +1860,7 @@ fts_optimize_index_completed( dberr_t error; byte buf[sizeof(ulint)]; #ifdef FTS_OPTIMIZE_DEBUG - ib_time_t end_time = ut_time(); + time_t end_time = time(NULL); error = fts_optimize_set_index_end_time(optim->trx, index, end_time); #endif @@ -2249,8 +2251,8 @@ fts_optimize_indexes( dict_index_t* index; #ifdef FTS_OPTIMIZE_DEBUG - ib_time_t end_time; - ib_time_t start_time; + time_t end_time; + time_t start_time; /* Get the start and end optimize times for this index. */ error = fts_optimize_get_index_start_time( @@ -2270,14 +2272,14 @@ fts_optimize_indexes( /* Start time will be 0 only for the first time or after completing the optimization of all FTS indexes. */ if (start_time == 0) { - start_time = ut_time(); + start_time = time(NULL); error = fts_optimize_set_index_start_time( optim->trx, index, start_time); } /* Check if this index needs to be optimized or not. */ - if (ut_difftime(end_time, start_time) < 0) { + if (difftime(end_time, start_time) < 0) { error = fts_optimize_index(optim, index); if (error != DB_SUCCESS) { @@ -2349,7 +2351,7 @@ fts_optimize_reset_start_time( for (uint i = 0; i < ib_vector_size(fts->indexes); ++i) { dict_index_t* index; - ib_time_t start_time = 0; + time_t start_time = 0; /* Reset the start time to 0 for this index. */ error = fts_optimize_set_index_start_time( @@ -2378,11 +2380,13 @@ fts_optimize_table_bk( /*==================*/ fts_slot_t* slot) /*!< in: table to optimiza */ { - dberr_t error; + const time_t now = time(NULL); + const ulint interval = ulint(now - slot->last_run); /* Avoid optimizing tables that were optimized recently. */ if (slot->last_run > 0 - && (ut_time() - slot->last_run) < slot->interval_time) { + && lint(interval) >= 0 + && interval < FTS_OPTIMIZE_INTERVAL_IN_SECS) { return(DB_SUCCESS); } @@ -2390,12 +2394,19 @@ fts_optimize_table_bk( dict_table_t* table = dict_table_open_on_id( slot->table_id, FALSE, DICT_TABLE_OP_NORMAL); - if (table && fil_table_accessible(table) + if (!table) { + slot->last_run = now; + return DB_SUCCESS; + } + + dberr_t error; + + if (fil_table_accessible(table) && table->fts && table->fts->cache && table->fts->cache->deleted >= FTS_OPTIMIZE_THRESHOLD) { error = fts_optimize_table(table); - slot->last_run = ut_time(); + slot->last_run = time(NULL); if (error == DB_SUCCESS) { slot->running = false; @@ -2403,7 +2414,7 @@ fts_optimize_table_bk( } } else { /* Note time this run completed. */ - slot->last_run = ut_time(); + slot->last_run = now; error = DB_SUCCESS; } @@ -2653,7 +2664,6 @@ static bool fts_optimize_new_table(dict_table_t* table) slot->table_id = table->id; slot->running = false; - slot->interval_time = FTS_OPTIMIZE_INTERVAL_IN_SECS; return(TRUE); } @@ -2689,37 +2699,23 @@ Calculate how many tables in fts_slots need to be optimized. @return no. of tables to optimize */ static ulint fts_optimize_how_many() { - ulint i; - ib_time_t delta; - ulint n_tables = 0; - ib_time_t current_time; - - current_time = ut_time(); + ulint n_tables = 0; + const time_t current_time = time(NULL); - for (i = 0; i < ib_vector_size(fts_slots); ++i) { + for (ulint i = 0; i < ib_vector_size(fts_slots); ++i) { const fts_slot_t* slot = static_cast<const fts_slot_t*>( ib_vector_get_const(fts_slots, i)); if (slot->table_id == 0) { continue; } - if (!slot->running) { - ut_a(slot->completed <= current_time); - - delta = current_time - slot->completed; + const time_t end = slot->running + ? slot->last_run : slot->completed; + ulint interval = ulint(current_time - end); - /* Skip slots that have been optimized recently. */ - if (delta >= slot->interval_time) { - ++n_tables; - } - } else { - ut_a(slot->last_run <= current_time); - - delta = current_time - slot->last_run; - - if (delta > slot->interval_time) { - ++n_tables; - } + if (lint(interval) < 0 + || interval >= FTS_OPTIMIZE_INTERVAL_IN_SECS) { + ++n_tables; } } @@ -2731,14 +2727,15 @@ Check if the total memory used by all FTS table exceeds the maximum limit. @return true if a sync is needed, false otherwise */ static bool fts_is_sync_needed() { - ulint total_memory = 0; - double time_diff = difftime(ut_time(), last_check_sync_time); + ulint total_memory = 0; + const time_t now = time(NULL); + double time_diff = difftime(now, last_check_sync_time); - if (fts_need_sync || time_diff < 5) { + if (fts_need_sync || (time_diff >= 0 && time_diff < 5)) { return(false); } - last_check_sync_time = ut_time(); + last_check_sync_time = now; for (ulint i = 0; i < ib_vector_size(fts_slots); ++i) { const fts_slot_t* slot = static_cast<const fts_slot_t*>( @@ -2776,7 +2773,7 @@ static void fts_optimize_sync_table(table_id_t table_id) table_id, FALSE, DICT_TABLE_OP_NORMAL)) { if (fil_table_accessible(table) && table->fts && table->fts->cache) { - fts_sync_table(table, true, false, false); + fts_sync_table(table, false); } dict_table_close(table, FALSE, FALSE); @@ -2969,7 +2966,7 @@ fts_optimize_init(void) table_vector.clear(); fts_opt_shutdown_event = os_event_create(0); - last_check_sync_time = ut_time(); + last_check_sync_time = time(NULL); os_thread_create(fts_optimize_thread, fts_optimize_wq, NULL); } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 23ec1b6cada..e877de68bba 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -100,7 +100,6 @@ this program; if not, write to the Free Software Foundation, Inc., #include "row0trunc.h" #include "row0upd.h" #include "fil0crypt.h" -#include "ut0timer.h" #include "srv0mon.h" #include "srv0srv.h" #include "srv0start.h" @@ -1680,18 +1679,6 @@ thd_trx_is_auto_commit( && thd_is_select(thd)); } -extern "C" time_t thd_start_time(const THD* thd); - -/******************************************************************//** -Get the thread start time. -@return the thread start time in seconds since the epoch. */ -ulint thd_start_time_in_secs(THD*) -{ - // FIXME: This function should be added to the server code. - //return(thd_start_time(thd)); - return(ulint(ut_time())); -} - /** Enter InnoDB engine after checking the max number of user threads allowed, else the thread is put into sleep. @param[in,out] prebuilt row prebuilt handler */ @@ -14446,7 +14433,7 @@ ha_innobase::optimize( if (innodb_optimize_fulltext_only) { if (m_prebuilt->table->fts && m_prebuilt->table->fts->cache && m_prebuilt->table->space) { - fts_sync_table(m_prebuilt->table, false, true, false); + fts_sync_table(m_prebuilt->table); fts_optimize_table(m_prebuilt->table); } try_alter = false; @@ -18142,8 +18129,7 @@ innodb_defragment_frequency_update(THD*, st_mysql_sys_var*, void*, const void* save) { srv_defragment_frequency = (*static_cast<const uint*>(save)); - srv_defragment_interval = ut_microseconds_to_timer( - (ulonglong) (1000000.0 / srv_defragment_frequency)); + srv_defragment_interval = 1000000000ULL / srv_defragment_frequency; } static inline char *my_strtok_r(char *str, const char *delim, char **saveptr) @@ -20757,7 +20743,7 @@ innobase_rename_vc_templ( given col_no. @param[in] foreign foreign key information @param[in] update updated parent vector. -@param[in] col_no column position of the table +@param[in] col_no base column position of the child table to check @return updated field from the parent update vector, else NULL */ static dfield_t* @@ -20773,6 +20759,10 @@ innobase_get_field_from_update_vector( ulint prefix_col_no; for (ulint i = 0; i < foreign->n_fields; i++) { + if (dict_index_get_nth_col_no(foreign->foreign_index, i) + != col_no) { + continue; + } parent_col_no = dict_index_get_nth_col_no(parent_index, i); parent_field_no = dict_table_get_nth_col_pos( @@ -20782,8 +20772,7 @@ innobase_get_field_from_update_vector( upd_field_t* parent_ufield = &update->fields[j]; - if (parent_ufield->field_no == parent_field_no - && parent_col_no == col_no) { + if (parent_ufield->field_no == parent_field_no) { return(&parent_ufield->new_val); } } diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 3aedad5a87a..093e8cac4b2 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -1775,7 +1775,7 @@ struct dict_table_t { unsigned stat_initialized:1; /** Timestamp of last recalc of the stats. */ - ib_time_t stats_last_recalc; + time_t stats_last_recalc; /** The two bits below are set in the 'stat_persistent' member. They have the following meaning: diff --git a/storage/innobase/include/dict0stats.h b/storage/innobase/include/dict0stats.h index 1a5047605ca..98956412ae2 100644 --- a/storage/innobase/include/dict0stats.h +++ b/storage/innobase/include/dict0stats.h @@ -203,7 +203,7 @@ rolled back only in the case of error, but not freed. dberr_t dict_stats_save_index_stat( dict_index_t* index, - ib_time_t last_update, + time_t last_update, const char* stat_name, ib_uint64_t stat_value, ib_uint64_t* sample_size, diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h index b3ea718b14a..b38658f281e 100644 --- a/storage/innobase/include/fts0fts.h +++ b/storage/innobase/include/fts0fts.h @@ -782,16 +782,9 @@ fts_drop_orphaned_tables(void); /** Run SYNC on the table, i.e., write out data from the cache to the FTS auxiliary INDEX table and clear the cache at the end. @param[in,out] table fts table -@param[in] unlock_cache whether unlock cache when write node -@param[in] wait whether wait for existing sync to finish -@param[in] has_dict whether has dict operation lock +@param[in] wait whether to wait for existing sync to finish @return DB_SUCCESS on success, error code on failure. */ -dberr_t -fts_sync_table( - dict_table_t* table, - bool unlock_cache, - bool wait, - bool has_dict); +dberr_t fts_sync_table(dict_table_t* table, bool wait = true); /****************************************************************//** Free the query graph but check whether dict_sys->mutex is already diff --git a/storage/innobase/include/fts0types.h b/storage/innobase/include/fts0types.h index 26f18cc3d1d..a08a60b9e95 100644 --- a/storage/innobase/include/fts0types.h +++ b/storage/innobase/include/fts0types.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2017, 2019, 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 @@ -123,7 +123,8 @@ struct fts_sync_t { doc_id_t max_doc_id; /*!< The doc id at which the cache was noted as being full, we use this to set the upper_limit field */ - ib_time_t start_time; /*!< SYNC start time */ + time_t start_time; /*!< SYNC start time; only used if + fts_enable_diag_print */ bool in_progress; /*!< flag whether sync is in progress.*/ bool unlock_cache; /*!< flag whether unlock cache when write fts node */ diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h index c4f3124a9f8..d94ca26fc0a 100644 --- a/storage/innobase/include/ha_prototypes.h +++ b/storage/innobase/include/ha_prototypes.h @@ -361,14 +361,6 @@ thd_trx_is_auto_commit( /*===================*/ THD* thd); /*!< in: thread handle, or NULL */ -/******************************************************************//** -Get the thread start time. -@return the thread start time in seconds since the epoch. */ -ulint -thd_start_time_in_secs( -/*===================*/ - THD* thd); /*!< in: thread handle, or NULL */ - /*****************************************************************//** A wrapper function of innobase_convert_name(), convert a table name to the MySQL system_charset_info (UTF-8) and quote it if needed. diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index 0481ecab3a2..91ee6b07c40 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, 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 @@ -566,11 +566,10 @@ lock_print_info_summary( /** Prints transaction lock wait and MVCC state. @param[in,out] file file where to print -@param[in] trx transaction */ +@param[in] trx transaction +@param[in] now current time */ void -lock_trx_print_wait_and_mvcc_state( - FILE* file, - const trx_t* trx); +lock_trx_print_wait_and_mvcc_state(FILE* file, const trx_t* trx, time_t now); /*********************************************************************//** Prints info of locks for each transaction. This function assumes that the diff --git a/storage/innobase/include/lock0types.h b/storage/innobase/include/lock0types.h index bdd03c49554..cb04afdf9db 100644 --- a/storage/innobase/include/lock0types.h +++ b/storage/innobase/include/lock0types.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2018, MariaDB Corporation. +Copyright (c) 2018, 2019, 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 @@ -190,10 +190,14 @@ struct ib_lock_t lock. The link node in a singly linked list, used during hashing. */ - /* Statistics for how long lock has been held and time - how long this lock had to be waited before it was granted */ - time_t requested_time; /*!< Lock request time */ - ulint wait_time; /*!< Time waited this lock or 0 */ + /** time(NULL) of the lock request creation. + Used for computing wait_time and diagnostics only. + Note: bogus durations may be reported + when the system time is adjusted! */ + time_t requested_time; + /** Cumulated wait time in seconds. + Note: may be bogus when the system time is adjusted! */ + ulint wait_time; union { lock_table_t tab_lock;/*!< table lock */ diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h index 927e04ce04e..a4f8aab4e02 100644 --- a/storage/innobase/include/log0recv.h +++ b/storage/innobase/include/log0recv.h @@ -250,7 +250,7 @@ struct recv_sys_t{ /*!< the LSN of a MLOG_CHECKPOINT record, or 0 if none was parsed */ /** the time when progress was last reported */ - ib_time_t progress_time; + time_t progress_time; mem_heap_t* heap; /*!< memory heap of log records and file addresses*/ hash_table_t* addr_hash;/*!< hash table of file addresses of pages */ @@ -275,7 +275,7 @@ struct recv_sys_t{ @param[in] time the current time @return whether progress should be reported (the last report was at least 15 seconds ago) */ - bool report(ib_time_t time) + bool report(time_t time) { if (time - progress_time < 15) { return false; diff --git a/storage/innobase/include/srv0mon.h b/storage/innobase/include/srv0mon.h index 6e2c359517d..049f437fa9b 100644 --- a/storage/innobase/include/srv0mon.h +++ b/storage/innobase/include/srv0mon.h @@ -63,9 +63,9 @@ create the internal counter ID in "monitor_id_t". */ /** Structure containing the actual values of a monitor counter. */ struct monitor_value_t { - ib_time_t mon_start_time; /*!< Start time of monitoring */ - ib_time_t mon_stop_time; /*!< Stop time of monitoring */ - ib_time_t mon_reset_time; /*!< Time counter resetted */ + time_t mon_start_time; /*!< Start time of monitoring */ + time_t mon_stop_time; /*!< Stop time of monitoring */ + time_t mon_reset_time; /*!< Time of resetting the counter */ mon_type_t mon_value; /*!< Current counter Value */ mon_type_t mon_max_value; /*!< Current Max value */ mon_type_t mon_min_value; /*!< Current Min value */ diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 61b3e6fea3f..d1596764bd1 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -1086,10 +1086,14 @@ struct srv_slot_t{ ibool suspended; /*!< TRUE if the thread is waiting for the event of this slot */ - ib_time_t suspend_time; /*!< time when the thread was - suspended. Initialized by - lock_wait_table_reserve_slot() - for lock wait */ + /** time(NULL) when the thread was suspended. + FIXME: Use my_interval_timer() or similar, to avoid bogus + timeouts in lock_wait_check_and_cancel() or lock_wait_suspend_thread() + when the system time is adjusted to the past! + + FIXME: This is duplicating trx_lock_t::wait_started, + which is being used for diagnostic purposes only. */ + time_t suspend_time; ulong wait_timeout; /*!< wait time that if exceeded the thread will be timed out. Initialized by diff --git a/storage/innobase/include/trx0i_s.h b/storage/innobase/include/trx0i_s.h index 97fb0a7cdaa..65c7d321597 100644 --- a/storage/innobase/include/trx0i_s.h +++ b/storage/innobase/include/trx0i_s.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2017, 2019, 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 @@ -127,12 +127,12 @@ struct i_s_trx_row_t { trx_id_t trx_id; /*!< transaction identifier */ const char* trx_state; /*!< transaction state from trx_get_que_state_str() */ - ib_time_t trx_started; /*!< trx_t::start_time */ + time_t trx_started; /*!< trx_t::start_time */ const i_s_locks_row_t* requested_lock_row; /*!< pointer to a row in innodb_locks if trx is waiting, or NULL */ - ib_time_t trx_wait_started; /*!< trx_t::wait_started */ + time_t trx_wait_started; /*!< trx_t->lock.wait_started */ uintmax_t trx_weight; /*!< TRX_WEIGHT() */ ulint trx_mysql_thread_id; /*!< thd_get_thread_id() */ const char* trx_query; /*!< MySQL statement being diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 46d1ea7efe4..e537bf80fe2 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -918,10 +918,11 @@ public: on dict_operation_lock. Protected by dict_operation_lock. */ - time_t start_time; /*!< time the state last time became - TRX_STATE_ACTIVE */ - ib_uint64_t start_time_micro; /*!< start time of transaction in - microseconds */ + /** wall-clock time of the latest transition to TRX_STATE_ACTIVE; + used for diagnostic purposes only */ + time_t start_time; + /** microsecond_interval_timer() of transaction start */ + ulonglong start_time_micro; lsn_t commit_lsn; /*!< lsn at the time of the commit */ table_id_t table_id; /*!< Table to drop iff dict_operation == TRX_DICT_OP_TABLE, or 0. */ diff --git a/storage/innobase/include/ut0timer.h b/storage/innobase/include/ut0timer.h deleted file mode 100644 index 376af3cf0ef..00000000000 --- a/storage/innobase/include/ut0timer.h +++ /dev/null @@ -1,67 +0,0 @@ -/***************************************************************************** - -Copyright (c) 2013, 2014, Facebook, Inc. All Rights Reserved. -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 -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA - -*****************************************************************************/ - -/********************************************************************//** -@file include/ut0timer.h -Timer routines - -Created 30/07/2014 Jan Lindström jan.lindstrom@skysql.com -modified from https://github.com/facebook/mysql-5.6/commit/c75a413edeb96eb99bf11d7269bdfea06f96d6b6 -*************************************************************************/ -#ifndef ut0timer_h -#define ut0timer_h - -#include "univ.i" - -/* Current timer stats */ -extern struct my_timer_unit_info ut_timer; - -/**************************************************************//** -Function pointer to point selected timer function. -@return timer current value */ -extern ulonglong (*ut_timer_now)(void); - -/**************************************************************//** -Sets up the data required for use of my_timer_* functions. -Selects the best timer by high frequency, and tight resolution. -Points my_timer_now() to the selected timer function. -Initializes my_timer struct to contain the info for selected timer.*/ -UNIV_INTERN -void ut_init_timer(void); - -/**************************************************************//** -Convert native timer units in a ulonglong into microseconds in a double -@return time in microseconds */ -UNIV_INLINE -double -ut_timer_to_microseconds( -/*=====================*/ - ulonglong when); /*!< in: time where to calculate */ -/**************************************************************//** -Convert microseconds in a double to native timer units in a ulonglong -@return time in microseconds */ -UNIV_INLINE -ulonglong -ut_microseconds_to_timer( -/*=====================*/ - ulonglong when); /*!< in: time where to calculate */ - -#include "ut0timer.ic" - -#endif diff --git a/storage/innobase/include/ut0timer.ic b/storage/innobase/include/ut0timer.ic deleted file mode 100644 index 26cf0bd2fbe..00000000000 --- a/storage/innobase/include/ut0timer.ic +++ /dev/null @@ -1,56 +0,0 @@ -/***************************************************************************** - -Copyright (c) 2013, 2014, Facebook, Inc. All Rights Reserved. -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 -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA - -*****************************************************************************/ - -/********************************************************************//** -@file include/ut0timer.ic -Timer routines - -Created 30/07/2014 Jan Lindström jan.lindstrom@skysql.com -modified from https://github.com/facebook/mysql-5.6/commit/c75a413edeb96eb99bf11d7269bdfea06f96d6b6 -*************************************************************************/ - -/**************************************************************//** -Convert native timer units in a ulonglong into microseconds in a double -@return time in microseconds */ -UNIV_INLINE -double -ut_timer_to_microseconds( -/*=====================*/ - ulonglong when) /*!< in: time where to calculate */ -{ - double ret = (double)(when); - ret *= 1000000.0; - ret /= (double)(ut_timer.frequency); - return ret; -} - -/**************************************************************//** -Convert microseconds in a double to native timer units in a ulonglong -@return time in microseconds */ -UNIV_INLINE -ulonglong -ut_microseconds_to_timer( -/*=====================*/ - ulonglong when) /*!< in: time where to calculate */ -{ - double ret = (double)when; - ret *= (double)(ut_timer.frequency); - ret /= 1000000.0; - return (ulonglong)ret; -} diff --git a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h index 876eea596cf..4b285cf718c 100644 --- a/storage/innobase/include/ut0ut.h +++ b/storage/innobase/include/ut0ut.h @@ -51,9 +51,6 @@ Created 1/20/1994 Heikki Tuuri /** Index name prefix in fast index creation, as a string constant */ #define TEMP_INDEX_PREFIX_STR "\377" -/** Time stamp */ -typedef time_t ib_time_t; - #define ut_max std::max #define ut_min std::min @@ -156,26 +153,6 @@ store the given number of bits. #define UT_BITS_IN_BYTES(b) (((b) + 7) / 8) /**********************************************************//** -Returns system time. We do not specify the format of the time returned: -the only way to manipulate it is to use the function ut_difftime. -@return system time */ -ib_time_t -ut_time(void); -/*=========*/ - -/**********************************************************//** -Returns system time. -Upon successful completion, the value 0 is returned; otherwise the -value -1 is returned and the global variable errno is set to indicate the -error. -@return 0 on success, -1 otherwise */ -int -ut_usectime( -/*========*/ - ulint* sec, /*!< out: seconds since the Epoch */ - ulint* ms); /*!< out: microseconds since the Epoch+*sec */ - -/**********************************************************//** Returns the number of milliseconds since some epoch. The value may wrap around. It should only be used for heuristic purposes. @@ -183,25 +160,6 @@ purposes. ulint ut_time_ms(void); /*============*/ - -/**********************************************************//** -Returns the number of milliseconds since some epoch. The -value may wrap around. It should only be used for heuristic -purposes. -@return ms since epoch */ -ulint -ut_time_ms(void); -/*============*/ - -/**********************************************************//** -Returns the difference of two times in seconds. -@return time2 - time1 expressed in seconds */ -double -ut_difftime( -/*========*/ - ib_time_t time2, /*!< in: time */ - ib_time_t time1); /*!< in: time */ - #endif /* !UNIV_INNOCHECKSUM */ /** Determines if a number is zero or a power of two. diff --git a/storage/innobase/include/ut0wqueue.h b/storage/innobase/include/ut0wqueue.h index 008ea2a70dd..6a096a36894 100644 --- a/storage/innobase/include/ut0wqueue.h +++ b/storage/innobase/include/ut0wqueue.h @@ -84,7 +84,7 @@ ib_wqueue_timedwait( /*================*/ /* out: work item or NULL on timeout*/ ib_wqueue_t* wq, /* in: work queue */ - ib_time_t wait_in_usecs); /* in: wait time in micro seconds */ + ulint wait_in_usecs); /* in: wait time in micro seconds */ /******************************************************************** Return first item on work queue or NULL if queue is empty diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 1448c59dd1f..0f71f372323 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -72,44 +72,39 @@ extern "C" void thd_rpl_deadlock_check(MYSQL_THD thd, MYSQL_THD other_thd); extern "C" int thd_need_wait_reports(const MYSQL_THD thd); extern "C" int thd_need_ordering_with(const MYSQL_THD thd, const MYSQL_THD other_thd); -/** Print info of a table lock. +/** Pretty-print a table lock. @param[in,out] file output stream @param[in] lock table lock */ -static -void -lock_table_print(FILE* file, const lock_t* lock); +static void lock_table_print(FILE* file, const lock_t* lock); -/** Print info of a record lock. +/** Pretty-print a record lock. @param[in,out] file output stream -@param[in] lock record lock */ -static -void -lock_rec_print(FILE* file, const lock_t* lock); +@param[in] lock record lock +@param[in,out] mtr mini-transaction for accessing the record */ +static void lock_rec_print(FILE* file, const lock_t* lock, mtr_t& mtr); /** Deadlock checker. */ class DeadlockChecker { public: - /** Checks if a joining lock request results in a deadlock. If - a deadlock is found this function will resolve the deadlock - by choosing a victim transaction and rolling it back. It - will attempt to resolve all deadlocks. The returned transaction - id will be the joining transaction id or 0 if some other - transaction was chosen as a victim and rolled back or no - deadlock found. - - @param lock lock the transaction is requesting - @param trx transaction requesting the lock - - @return id of transaction chosen as victim or 0 */ - static const trx_t* check_and_resolve( - const lock_t* lock, - trx_t* trx); + /** Check if a joining lock request results in a deadlock. + If a deadlock is found, we will resolve the deadlock by + choosing a victim transaction and rolling it back. + We will attempt to resolve all deadlocks. + + @param[in] lock the lock request + @param[in,out] trx transaction requesting the lock + + @return trx if it was chosen as victim + @retval NULL if another victim was chosen, + or there is no deadlock (any more) */ + static const trx_t* check_and_resolve(const lock_t* lock, trx_t* trx); private: /** Do a shallow copy. Default destructor OK. @param trx the start transaction (start node) @param wait_lock lock that a transaction wants - @param mark_start visited node counter */ + @param mark_start visited node counter + @param report_waiters whether to call thd_rpl_deadlock_check() */ DeadlockChecker( const trx_t* trx, const lock_t* wait_lock, @@ -751,11 +746,12 @@ lock_rec_has_to_wait( thread, we need to look at trx ordering and lock types */ if (wsrep_thd_is_BF(trx->mysql_thd, FALSE) && wsrep_thd_is_BF(lock2->trx->mysql_thd, TRUE)) { + mtr_t mtr; if (wsrep_debug) { ib::info() << "BF-BF lock conflict, locking: " << for_locking; - lock_rec_print(stderr, lock2); + lock_rec_print(stderr, lock2, mtr); ib::info() << " SQL1: " << wsrep_thd_query(trx->mysql_thd) << " SQL2: " @@ -780,7 +776,7 @@ lock_rec_has_to_wait( << wsrep_thd_conflict_state( lock2->trx->mysql_thd, FALSE); - lock_rec_print(stderr, lock2); + lock_rec_print(stderr, lock2, mtr); ib::info() << " SQL1: " << wsrep_thd_query(trx->mysql_thd) << " SQL2: " @@ -1100,6 +1096,7 @@ wsrep_kill_victim( my_bool bf_this = wsrep_thd_is_BF(trx->mysql_thd, FALSE); my_bool bf_other = wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE); + mtr_t mtr; if ((bf_this && !bf_other) || (bf_this && bf_other && wsrep_trx_order_before( @@ -1131,7 +1128,7 @@ wsrep_kill_victim( ib::info() << "*** WAITING FOR THIS LOCK TO BE GRANTED:"; if (lock_get_type(lock) == LOCK_REC) { - lock_rec_print(stderr, lock); + lock_rec_print(stderr, lock, mtr); } else { lock_table_print(stderr, lock); } @@ -1297,6 +1294,7 @@ wsrep_print_wait_locks( lock_t* c_lock) /* conflicting lock to print */ { if (wsrep_debug && c_lock->trx->lock.wait_lock != c_lock) { + mtr_t mtr; ib::info() << "WSREP: c_lock != wait lock"; ib::info() << " SQL: " << wsrep_thd_query(c_lock->trx->mysql_thd); @@ -1304,13 +1302,14 @@ wsrep_print_wait_locks( if (lock_get_type_low(c_lock) & LOCK_TABLE) { lock_table_print(stderr, c_lock); } else { - lock_rec_print(stderr, c_lock); + lock_rec_print(stderr, c_lock, mtr); } if (lock_get_type_low(c_lock->trx->lock.wait_lock) & LOCK_TABLE) { lock_table_print(stderr, c_lock->trx->lock.wait_lock); } else { - lock_rec_print(stderr, c_lock->trx->lock.wait_lock); + lock_rec_print(stderr, c_lock->trx->lock.wait_lock, + mtr); } } } @@ -1523,11 +1522,7 @@ If only one of them is a wait lock, it has lower priority. If either is a high priority transaction, the lock has higher priority. Otherwise, the one with an older transaction has higher priority. @returns true if lock1 has higher priority, false otherwise. */ -static -bool -has_higher_priority( - lock_t *lock1, - lock_t *lock2) +static bool has_higher_priority(lock_t *lock1, lock_t *lock2) { if (lock1 == NULL) { return false; @@ -1734,10 +1729,7 @@ lock_rec_enqueue_waiting( lock_prdt_set_prdt(lock, prdt); } - if ( -#ifdef UNIV_DEBUG - const trx_t* victim = -#endif + if (ut_d(const trx_t* victim =) DeadlockChecker::check_and_resolve(lock, trx)) { ut_ad(victim == trx); lock_reset_lock_and_trx_wait(lock); @@ -1761,7 +1753,7 @@ lock_rec_enqueue_waiting( trx->lock.que_state = TRX_QUE_LOCK_WAIT; trx->lock.was_chosen_as_deadlock_victim = false; - trx->lock.wait_started = ut_time(); + trx->lock.wait_started = time(NULL); ut_a(que_thr_stop(thr)); @@ -2071,12 +2063,13 @@ lock_rec_has_to_wait_in_queue( if (wsrep_thd_is_BF(wait_lock->trx->mysql_thd, FALSE) && wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE)) { if (wsrep_debug) { + mtr_t mtr; ib::info() << "WSREP: waiting BF trx: " << ib::hex(wait_lock->trx->id) << " query: " << wsrep_thd_query(wait_lock->trx->mysql_thd); - lock_rec_print(stderr, wait_lock); + lock_rec_print(stderr, wait_lock, mtr); ib::info() << "WSREP: do not wait another BF trx: " << ib::hex(lock->trx->id) << " query: " << wsrep_thd_query(lock->trx->mysql_thd); - lock_rec_print(stderr, lock); + lock_rec_print(stderr, lock, mtr); } /* don't wait for another BF lock */ continue; @@ -3774,7 +3767,7 @@ lock_table_enqueue_waiting( ); const trx_t* victim_trx = - DeadlockChecker::check_and_resolve(lock, trx); + DeadlockChecker::check_and_resolve(lock, trx); if (victim_trx != 0) { ut_ad(victim_trx == trx); @@ -3795,7 +3788,7 @@ lock_table_enqueue_waiting( trx->lock.que_state = TRX_QUE_LOCK_WAIT; - trx->lock.wait_started = ut_time(); + trx->lock.wait_started = time(NULL); trx->lock.was_chosen_as_deadlock_victim = false; ut_a(que_thr_stop(thr)); @@ -4433,20 +4426,14 @@ lock_table_print(FILE* file, const lock_t* lock) putc('\n', file); } -/** Print info of a record lock. +/** Pretty-print a record lock. @param[in,out] file output stream -@param[in] lock record lock */ -static -void -lock_rec_print(FILE* file, const lock_t* lock) +@param[in] lock record lock +@param[in,out] mtr mini-transaction for accessing the record */ +static void lock_rec_print(FILE* file, const lock_t* lock, mtr_t& mtr) { ulint space; ulint page_no; - mtr_t mtr; - mem_heap_t* heap = NULL; - ulint offsets_[REC_OFFS_NORMAL_SIZE]; - ulint* offsets = offsets_; - rec_offs_init(offsets_); ut_ad(lock_mutex_own()); ut_a(lock_get_type_low(lock) == LOCK_REC); @@ -4486,13 +4473,16 @@ lock_rec_print(FILE* file, const lock_t* lock) fputs(" waiting", file); } - mtr_start(&mtr); - putc('\n', file); - const buf_block_t* block; + mem_heap_t* heap = NULL; + ulint offsets_[REC_OFFS_NORMAL_SIZE]; + ulint* offsets = offsets_; + rec_offs_init(offsets_); - block = buf_page_try_get(page_id_t(space, page_no), &mtr); + mtr.start(); + const buf_block_t* block = buf_page_try_get(page_id_t(space, page_no), + &mtr); for (ulint i = 0; i < lock_rec_get_n_bits(lock); ++i) { @@ -4521,9 +4511,9 @@ lock_rec_print(FILE* file, const lock_t* lock) putc('\n', file); } - mtr_commit(&mtr); + mtr.commit(); - if (heap) { + if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } } @@ -4626,11 +4616,10 @@ lock_print_info_summary( /** Prints transaction lock wait and MVCC state. @param[in,out] file file where to print -@param[in] trx transaction */ +@param[in] trx transaction +@param[in] now current time */ void -lock_trx_print_wait_and_mvcc_state( - FILE* file, - const trx_t* trx) +lock_trx_print_wait_and_mvcc_state(FILE* file, const trx_t* trx, time_t now) { fprintf(file, "---"); @@ -4650,10 +4639,11 @@ lock_trx_print_wait_and_mvcc_state( fprintf(file, "------- TRX HAS BEEN WAITING %lu SEC" " FOR THIS LOCK TO BE GRANTED:\n", - (ulong) difftime(ut_time(), trx->lock.wait_started)); + (ulong) difftime(now, trx->lock.wait_started)); if (lock_get_type_low(trx->lock.wait_lock) == LOCK_REC) { - lock_rec_print(file, trx->lock.wait_lock); + mtr_t mtr; + lock_rec_print(file, trx->lock.wait_lock, mtr); } else { lock_table_print(file, trx->lock.wait_lock); } @@ -4671,6 +4661,7 @@ lock_trx_print_locks( FILE* file, /*!< in/out: File to write */ const trx_t* trx) /*!< in: current transaction */ { + mtr_t mtr; uint32_t i= 0; /* Iterate over the transaction's locks. */ for (lock_t *lock = UT_LIST_GET_FIRST(trx->lock.trx_locks); @@ -4678,7 +4669,7 @@ lock_trx_print_locks( lock = UT_LIST_GET_NEXT(trx_locks, lock)) { if (lock_get_type_low(lock) == LOCK_REC) { - lock_rec_print(file, lock); + lock_rec_print(file, lock, mtr); } else { ut_ad(lock_get_type_low(lock) & LOCK_TABLE); @@ -4699,20 +4690,21 @@ lock_trx_print_locks( /** Functor to display all transactions */ struct lock_print_info { - lock_print_info(FILE* file) : file(file) {} + lock_print_info(FILE* file, time_t now) : file(file), now(now) {} void operator()(const trx_t* trx) const { ut_ad(mutex_own(&trx_sys.mutex)); if (trx == purge_sys.query->trx) return; - lock_trx_print_wait_and_mvcc_state(file, trx); + lock_trx_print_wait_and_mvcc_state(file, trx, now); if (trx->will_lock && srv_print_innodb_lock_monitor) lock_trx_print_locks(file, trx); } FILE* const file; + const time_t now; }; /*********************************************************************//** @@ -4727,9 +4719,10 @@ lock_print_info_all_transactions( ut_ad(lock_mutex_own()); fprintf(file, "LIST OF TRANSACTIONS FOR EACH SESSION:\n"); + const time_t now = time(NULL); mutex_enter(&trx_sys.mutex); - ut_list_map(trx_sys.trx_list, lock_print_info(file)); + ut_list_map(trx_sys.trx_list, lock_print_info(file, now)); mutex_exit(&trx_sys.mutex); lock_mutex_exit(); @@ -6642,10 +6635,11 @@ DeadlockChecker::print(const lock_t* lock) ut_ad(lock_mutex_own()); if (lock_get_type_low(lock) == LOCK_REC) { - lock_rec_print(lock_latest_err_file, lock); + mtr_t mtr; + lock_rec_print(lock_latest_err_file, lock, mtr); if (srv_print_all_deadlocks) { - lock_rec_print(stderr, lock); + lock_rec_print(stderr, lock, mtr); } } else { lock_table_print(lock_latest_err_file, lock); @@ -6940,7 +6934,7 @@ DeadlockChecker::search() @param trx transaction rolled back @param lock lock trx wants */ void -DeadlockChecker::rollback_print(const trx_t* trx, const lock_t* lock) +DeadlockChecker::rollback_print(const trx_t* trx, const lock_t* lock) { ut_ad(lock_mutex_own()); @@ -6980,16 +6974,17 @@ DeadlockChecker::trx_rollback() trx_mutex_exit(trx); } -/** Checks if a joining lock request results in a deadlock. If a deadlock is -found this function will resolve the deadlock by choosing a victim transaction -and rolling it back. It will attempt to resolve all deadlocks. The returned -transaction id will be the joining transaction instance or NULL if some other -transaction was chosen as a victim and rolled back or no deadlock found. +/** Check if a joining lock request results in a deadlock. +If a deadlock is found, we will resolve the deadlock by +choosing a victim transaction and rolling it back. +We will attempt to resolve all deadlocks. -@param[in] lock lock the transaction is requesting -@param[in,out] trx transaction requesting the lock +@param[in] lock the lock request +@param[in,out] trx transaction requesting the lock -@return transaction instanace chosen as victim or 0 */ +@return trx if it was chosen as victim +@retval NULL if another victim was chosen, +or there is no deadlock (any more) */ const trx_t* DeadlockChecker::check_and_resolve(const lock_t* lock, trx_t* trx) { diff --git a/storage/innobase/lock/lock0wait.cc b/storage/innobase/lock/lock0wait.cc index 13134feb6dc..75e93aed561 100644 --- a/storage/innobase/lock/lock0wait.cc +++ b/storage/innobase/lock/lock0wait.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2018, MariaDB Corporation. +Copyright (c) 2014, 2019, 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,7 +58,7 @@ lock_wait_table_print(void) (ulong) slot->in_use, (ulong) slot->suspended, slot->wait_timeout, - (ulong) difftime(ut_time(), slot->suspend_time)); + (ulong) difftime(time(NULL), slot->suspend_time)); } } @@ -155,7 +155,7 @@ lock_wait_table_reserve_slot( os_event_reset(slot->event); slot->suspended = TRUE; - slot->suspend_time = ut_time(); + slot->suspend_time = time(NULL); slot->wait_timeout = wait_timeout; if (slot == lock_sys.last_slot) { @@ -231,13 +231,8 @@ lock_wait_suspend_thread( user OS thread */ { srv_slot_t* slot; - double wait_time; trx_t* trx; ibool was_declared_inside_innodb; - int64_t start_time = 0; - int64_t finish_time; - ulint sec; - ulint ms; ulong lock_wait_timeout; trx = thr_get_trx(thr); @@ -283,15 +278,12 @@ lock_wait_suspend_thread( lock_wait_mutex_exit(); trx_mutex_exit(trx); + ulonglong start_time = 0; + if (thr->lock_state == QUE_THR_LOCK_ROW) { srv_stats.n_lock_wait_count.inc(); srv_stats.n_lock_wait_current_count.inc(); - - if (ut_usectime(&sec, &ms) == -1) { - start_time = -1; - } else { - start_time = int64_t(sec) * 1000000 + int64_t(ms); - } + start_time = my_interval_timer(); } ulint lock_type = ULINT_UNDEFINED; @@ -371,28 +363,23 @@ lock_wait_suspend_thread( row_mysql_freeze_data_dictionary(trx); } - wait_time = ut_difftime(ut_time(), slot->suspend_time); + double wait_time = difftime(time(NULL), slot->suspend_time); /* Release the slot for others to use */ lock_wait_table_release_slot(slot); if (thr->lock_state == QUE_THR_LOCK_ROW) { - int64_t diff_time; - if (start_time == -1 || ut_usectime(&sec, &ms) == -1) { - finish_time = -1; - diff_time = 0; - } else { - finish_time = int64_t(sec) * 1000000 + int64_t(ms); - diff_time = std::max<int64_t>( - 0, finish_time - start_time); - srv_stats.n_lock_wait_time.add(diff_time); + const ulonglong finish_time = my_interval_timer(); + if (finish_time >= start_time) { + const ulint diff_time = static_cast<ulint> + ((finish_time - start_time) / 1000); + srv_stats.n_lock_wait_time.add(diff_time); /* Only update the variable if we successfully retrieved the start and finish times. See Bug#36819. */ - if (ulint(diff_time) > lock_sys.n_lock_max_wait_time) { - lock_sys.n_lock_max_wait_time - = ulint(diff_time); + if (diff_time > lock_sys.n_lock_max_wait_time) { + lock_sys.n_lock_max_wait_time = diff_time; } /* Record the lock wait time for this thread */ thd_storage_lock_wait(trx->mysql_thd, diff_time); @@ -468,19 +455,12 @@ lock_wait_check_and_cancel( const srv_slot_t* slot) /*!< in: slot reserved by a user thread when the wait started */ { - trx_t* trx; - double wait_time; - ib_time_t suspend_time = slot->suspend_time; - ut_ad(lock_wait_mutex_own()); - ut_ad(slot->in_use); - ut_ad(slot->suspended); - wait_time = ut_difftime(ut_time(), suspend_time); - - trx = thr_get_trx(slot->thr); + double wait_time = difftime(time(NULL), slot->suspend_time); + trx_t* trx = thr_get_trx(slot->thr); if (trx_is_interrupted(trx) || (slot->wait_timeout < 100000000 @@ -515,7 +495,6 @@ lock_wait_check_and_cancel( trx_mutex_exit(trx); } - } /*********************************************************************//** diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 3bc2f57a325..ec538042d37 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -856,7 +856,7 @@ recv_sys_init() recv_sys->buf_size = RECV_PARSING_BUF_SIZE; recv_sys->addr_hash = hash_create(size / 512); - recv_sys->progress_time = ut_time(); + recv_sys->progress_time = time(NULL); recv_max_page_lsn = 0; /* Call the constructor for recv_sys_t::dblwr member */ @@ -1000,7 +1000,7 @@ fail: } } - if (recv_sys->report(ut_time())) { + if (recv_sys->report(time(NULL))) { ib::info() << "Read redo log up to LSN=" << *start_lsn; service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL, "Read redo log up to LSN=" LSN_PF, @@ -2152,7 +2152,7 @@ skip_log: mtr.discard_modifications(); mtr.commit(); - ib_time_t time = ut_time(); + time_t now = time(NULL); mutex_enter(&recv_sys->mutex); @@ -2165,7 +2165,7 @@ skip_log: ut_a(recv_sys->n_addrs > 0); if (ulint n = --recv_sys->n_addrs) { - if (recv_sys->report(time)) { + if (recv_sys->report(now)) { ib::info() << "To recover: " << n << " pages from log"; service_manager_extend_timeout( INNODB_EXTEND_TIMEOUT_INTERVAL, "To recover: " ULINTPF " pages from log", n); diff --git a/storage/innobase/os/os0event.cc b/storage/innobase/os/os0event.cc index bd7a66a0744..f1d7b2ed337 100644 --- a/storage/innobase/os/os0event.cc +++ b/storage/innobase/os/os0event.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 2013, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2019, 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 @@ -25,13 +26,11 @@ Created 2012-09-23 Sunny Bains #include "os0event.h" #include "ut0mutex.h" +#include <my_sys.h> #ifdef _WIN32 #include <windows.h> #include <synchapi.h> -#endif /* _WIN32 */ - -#ifdef _WIN32 /** Native condition variable. */ typedef CONDITION_VARIABLE os_cond_t; #else @@ -358,21 +357,9 @@ os_event::wait_time_low( struct timespec abstime; if (time_in_usec != OS_SYNC_INFINITE_TIME) { - struct timeval tv; - int ret; - ulint sec; - ulint usec; - - ret = ut_usectime(&sec, &usec); - ut_a(ret == 0); - - tv.tv_sec = sec; - tv.tv_usec = usec; - - tv.tv_usec += time_in_usec; - - abstime.tv_sec = tv.tv_sec + tv.tv_usec / 1000000; - abstime.tv_nsec = tv.tv_usec % 1000000 * 1000; + ulonglong usec = ulonglong(time_in_usec) + my_hrtime().val; + abstime.tv_sec = usec / 1000000; + abstime.tv_nsec = (usec % 1000000) * 1000; } else { abstime.tv_nsec = 999999999; abstime.tv_sec = (time_t) ULINT_MAX; diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 744bb7bc756..dace9b54a0b 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -6006,7 +6006,7 @@ AIO::start( os_aio_validate(); - os_last_printout = ut_time(); + os_last_printout = time(NULL); if (srv_use_native_aio) { return(true); @@ -6262,7 +6262,7 @@ AIO::reserve_slot( } slot->is_reserved = true; - slot->reservation_time = ut_time(); + slot->reservation_time = time(NULL); slot->m1 = m1; slot->m2 = m2; slot->file = file; @@ -7072,7 +7072,7 @@ private: { ulint age; - age = (ulint) difftime(ut_time(), slot->reservation_time); + age = (ulint) difftime(time(NULL), slot->reservation_time); if ((age >= 2 && age > m_oldest) || (age >= 2 @@ -7474,7 +7474,7 @@ os_aio_print(FILE* file) AIO::print_all(file); putc('\n', file); - current_time = ut_time(); + current_time = time(NULL); time_elapsed = 0.001 + difftime(current_time, os_last_printout); fprintf(file, @@ -7540,7 +7540,7 @@ os_aio_refresh_stats() os_bytes_read_since_printout = 0; - os_last_printout = ut_time(); + os_last_printout = time(NULL); } /** Checks that all slots in the system have been freed, that is, there are diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 3e7fe26db6e..0c8d8ed369d 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -2863,8 +2863,7 @@ wait_again: if (max_doc_id && err == DB_SUCCESS) { /* Sync fts cache for other fts indexes to keep all fts indexes consistent in sync_doc_id. */ - err = fts_sync_table(const_cast<dict_table_t*>(new_table), - false, true, false); + err = fts_sync_table(const_cast<dict_table_t*>(new_table)); if (err == DB_SUCCESS) { fts_update_next_doc_id(NULL, new_table, max_doc_id); diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index a7f1d4bcc77..d1e7735886b 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -1680,8 +1680,9 @@ DECLARE_THREAD(srv_monitor_thread)(void*) pfs_register_thread(srv_monitor_thread_key); #endif /* UNIV_PFS_THREAD */ - srv_last_monitor_time = ut_time(); - last_monitor_time = ut_time(); + current_time = time(NULL); + srv_last_monitor_time = current_time; + last_monitor_time = current_time; mutex_skipped = 0; last_srv_print_monitor = srv_print_innodb_monitor; loop: @@ -1692,12 +1693,12 @@ loop: os_event_wait_time_low(srv_monitor_event, 5000000, sig_count); - current_time = ut_time(); + current_time = time(NULL); time_elapsed = difftime(current_time, last_monitor_time); if (time_elapsed > 15) { - last_monitor_time = ut_time(); + last_monitor_time = current_time; if (srv_print_innodb_monitor) { /* Reset mutex_skipped counter everytime @@ -2037,20 +2038,16 @@ static void srv_shutdown_print_master_pending( /*==============================*/ - ib_time_t* last_print_time, /*!< last time the function + time_t* last_print_time, /*!< last time the function print the message */ ulint n_tables_to_drop, /*!< number of tables to be dropped */ ulint n_bytes_merged) /*!< number of change buffer just merged */ { - ib_time_t current_time; - double time_elapsed; - - current_time = ut_time(); - time_elapsed = ut_difftime(current_time, *last_print_time); + time_t current_time = time(NULL); - if (time_elapsed > 60) { + if (difftime(current_time, *last_print_time) > 60) { *last_print_time = current_time; if (n_tables_to_drop) { @@ -2128,7 +2125,7 @@ void srv_master_do_active_tasks(void) /*============================*/ { - ib_time_t cur_time = ut_time(); + time_t cur_time = time(NULL); ulonglong counter_time = microsecond_interval_timer(); /* First do the tasks that we are suppose to do at each @@ -2304,7 +2301,7 @@ srv_shutdown(bool ibuf_merge) { ulint n_bytes_merged = 0; ulint n_tables_to_drop; - ib_time_t now = ut_time(); + time_t now = time(NULL); do { ut_ad(!srv_read_only_mode); @@ -2443,10 +2440,10 @@ static bool srv_purge_should_exit() if (history_size) { #if defined HAVE_SYSTEMD && !defined EMBEDDED_LIBRARY - static ib_time_t progress_time; - ib_time_t time = ut_time(); - if (time - progress_time >= 15) { - progress_time = time; + static time_t progress_time; + time_t now = time(NULL); + if (now - progress_time >= 15) { + progress_time = now; service_manager_extend_timeout( INNODB_EXTEND_TIMEOUT_INTERVAL, "InnoDB: to purge " ULINTPF " transactions", diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 47eaccb6573..2fb1bc4b6e2 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -47,7 +47,6 @@ Created 2/16/1996 Heikki Tuuri #include "row0ftsort.h" #include "ut0mem.h" -#include "ut0timer.h" #include "mem0mem.h" #include "data0data.h" #include "data0type.h" @@ -2520,36 +2519,6 @@ skip_monitors: return(DB_SUCCESS); } -#if 0 -/******************************************************************** -Sync all FTS cache before shutdown */ -static -void -srv_fts_close(void) -/*===============*/ -{ - dict_table_t* table; - - for (table = UT_LIST_GET_FIRST(dict_sys->table_LRU); - table; table = UT_LIST_GET_NEXT(table_LRU, table)) { - fts_t* fts = table->fts; - - if (fts != NULL) { - fts_sync_table(table); - } - } - - for (table = UT_LIST_GET_FIRST(dict_sys->table_non_LRU); - table; table = UT_LIST_GET_NEXT(table_LRU, table)) { - fts_t* fts = table->fts; - - if (fts != NULL) { - fts_sync_table(table); - } - } -} -#endif - /** Shut down background threads that can generate undo log. */ void srv_shutdown_bg_undo_sources() { diff --git a/storage/innobase/sync/sync0arr.cc b/storage/innobase/sync/sync0arr.cc index dce2d596710..352e93a4392 100644 --- a/storage/innobase/sync/sync0arr.cc +++ b/storage/innobase/sync/sync0arr.cc @@ -2,7 +2,7 @@ Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. -Copyright (c) 2013, 2018, MariaDB Corporation. +Copyright (c) 2013, 2019, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -119,8 +119,10 @@ struct sync_cell_t { has not been signalled in the period between the reset and wait call. */ - time_t reservation_time;/*!< time when the thread reserved - the wait cell */ + /** time(NULL) when the wait cell was reserved. + FIXME: sync_array_print_long_waits_low() may display bogus + warnings when the system time is adjusted to the past! */ + time_t reservation_time; }; /* NOTE: It is allowed for a thread to wait for an event allocated for @@ -375,7 +377,7 @@ sync_array_reserve_cell( cell->thread_id = os_thread_get_curr_id(); - cell->reservation_time = ut_time(); + cell->reservation_time = time(NULL); /* Make sure the event is reset and also store the value of signal_count at which the event was reset. */ diff --git a/storage/innobase/trx/trx0i_s.cc b/storage/innobase/trx/trx0i_s.cc index 0168de8980d..a39fb5d2e95 100644 --- a/storage/innobase/trx/trx0i_s.cc +++ b/storage/innobase/trx/trx0i_s.cc @@ -456,7 +456,7 @@ fill_trx_row( ut_ad(lock_mutex_own()); row->trx_id = trx_get_id_for_print(trx); - row->trx_started = (ib_time_t) trx->start_time; + row->trx_started = trx->start_time; row->trx_state = trx_get_que_state_str(trx); row->requested_lock_row = requested_lock_row; ut_ad(requested_lock_row == NULL @@ -465,7 +465,7 @@ fill_trx_row( if (trx->lock.wait_lock != NULL) { ut_a(requested_lock_row != NULL); - row->trx_wait_started = (ib_time_t) trx->lock.wait_started; + row->trx_wait_started = trx->lock.wait_started; } else { ut_a(requested_lock_row == NULL); row->trx_wait_started = 0; diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc index 838b4291e58..b6206c9b3be 100644 --- a/storage/innobase/trx/trx0purge.cc +++ b/storage/innobase/trx/trx0purge.cc @@ -137,7 +137,8 @@ purge_graph_build() trx_t* trx = trx_create(); ut_ad(!trx->id); - trx->start_time = ut_time(); + trx->start_time = time(NULL); + trx->start_time_micro = microsecond_interval_timer(); trx->state = TRX_STATE_ACTIVE; trx->op_info = "purge trx"; diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc index 4247dd1c005..65aa454808f 100644 --- a/storage/innobase/trx/trx0roll.cc +++ b/storage/innobase/trx/trx0roll.cc @@ -729,9 +729,9 @@ static my_bool trx_roll_count_callback(rw_trx_hash_element_t *element, /** Report progress when rolling back a row of a recovered transaction. */ void trx_roll_report_progress() { - ib_time_t time = ut_time(); + time_t now = time(NULL); mutex_enter(&recv_sys->mutex); - bool report = recv_sys->report(time); + bool report = recv_sys->report(now); mutex_exit(&recv_sys->mutex); if (report) { diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 1706ff2dbbd..89ac734652e 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -605,7 +605,8 @@ trx_resurrect_table_locks( */ static void trx_resurrect(trx_undo_t *undo, trx_rseg_t *rseg, - ib_time_t start_time, uint64_t *rows_to_undo, + time_t start_time, ulonglong start_time_micro, + uint64_t *rows_to_undo, bool is_old_insert) { trx_state_t state; @@ -657,6 +658,7 @@ static void trx_resurrect(trx_undo_t *undo, trx_rseg_t *rseg, trx->id= undo->trx_id; trx->is_recovered= true; trx->start_time= start_time; + trx->start_time_micro= start_time_micro; if (undo->dict_operation) { @@ -697,7 +699,8 @@ trx_lists_init_at_db_start() /* Look from the rollback segments if there exist undo logs for transactions. */ - const ib_time_t start_time = ut_time(); + const time_t start_time = time(NULL); + const ulonglong start_time_micro= microsecond_interval_timer(); uint64_t rows_to_undo = 0; for (ulint i = 0; i < TRX_SYS_N_RSEGS; ++i) { @@ -716,8 +719,8 @@ trx_lists_init_at_db_start() undo = UT_LIST_GET_FIRST(rseg->old_insert_list); while (undo) { trx_undo_t* next = UT_LIST_GET_NEXT(undo_list, undo); - trx_resurrect(undo, rseg, start_time, &rows_to_undo, - true); + trx_resurrect(undo, rseg, start_time, start_time_micro, + &rows_to_undo, true); undo = next; } @@ -728,6 +731,7 @@ trx_lists_init_at_db_start() trx_t *trx = trx_sys.find(0, undo->trx_id, false); if (!trx) { trx_resurrect(undo, rseg, start_time, + start_time_micro, &rows_to_undo, false); } else { ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE) || @@ -985,14 +989,10 @@ trx_start_low( } } - if (trx->mysql_thd != NULL) { - trx->start_time = thd_start_time_in_secs(trx->mysql_thd); - trx->start_time_micro = thd_query_start_micro(trx->mysql_thd); - - } else { - trx->start_time = ut_time(); - trx->start_time_micro = 0; - } + trx->start_time = time(NULL); + trx->start_time_micro = trx->mysql_thd + ? thd_query_start_micro(trx->mysql_thd) + : microsecond_interval_timer(); ut_a(trx->error_state == DB_SUCCESS); @@ -1227,7 +1227,7 @@ trx_update_mod_tables_timestamp( { /* consider using trx->start_time if calling time() is too expensive here */ - time_t now = ut_time(); + const time_t now = time(NULL); trx_mod_tables_t::const_iterator end = trx->mod_tables.end(); diff --git a/storage/innobase/ut/ut0timer.cc b/storage/innobase/ut/ut0timer.cc deleted file mode 100644 index 9aefcafebc6..00000000000 --- a/storage/innobase/ut/ut0timer.cc +++ /dev/null @@ -1,90 +0,0 @@ -/***************************************************************************** - -Copyright (c) 2013, 2014, Facebook, Inc. All Rights Reserved. -Copyright (c) 2014, SkySQL Ab. All Rights Reserved. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA - -*****************************************************************************/ - -/********************************************************************//** -@file ut/ut0timer.cc -Timer rountines - -Created 30/07/2014 Jan Lindström jan.lindstrom@skysql.com -modified from https://github.com/facebook/mysql-5.6/commit/c75a413edeb96eb99bf11d7269bdfea06f96d6b6 -*************************************************************************/ - -#include "data0type.h" -#include <my_rdtsc.h> -#include <ut0timer.h> - -/**************************************************************//** -Initial timer definition -@return 0 */ -static -ulonglong -ut_timer_none(void) -/*===============*/ -{ - return 0; -} - -/**************************************************************//** -Function pointer to point selected timer function. -@return timer current value */ -ulonglong (*ut_timer_now)(void) = &ut_timer_none; - -struct my_timer_unit_info ut_timer; -extern MYSQL_PLUGIN_IMPORT MY_TIMER_INFO sys_timer_info; - -/**************************************************************//** -Sets up the data required for use of my_timer_* functions. -Selects the best timer by high frequency, and tight resolution. -Points my_timer_now() to the selected timer function. -Initializes my_timer struct to contain the info for selected timer.*/ -UNIV_INTERN -void -ut_init_timer(void) -/*===============*/ -{ - if (sys_timer_info.cycles.frequency > 1000000 && - sys_timer_info.cycles.resolution == 1) { - ut_timer = sys_timer_info.cycles; - ut_timer_now = &my_timer_cycles; - } else if (sys_timer_info.nanoseconds.frequency > 1000000 && - sys_timer_info.nanoseconds.resolution == 1) { - ut_timer = sys_timer_info.nanoseconds; - ut_timer_now = &my_timer_nanoseconds; - } else if (sys_timer_info.microseconds.frequency >= 1000000 && - sys_timer_info.microseconds.resolution == 1) { - ut_timer = sys_timer_info.microseconds; - ut_timer_now = &my_timer_microseconds; - - } else if (sys_timer_info.milliseconds.frequency >= 1000 && - sys_timer_info.milliseconds.resolution == 1) { - ut_timer = sys_timer_info.milliseconds; - ut_timer_now = &my_timer_milliseconds; - } else if (sys_timer_info.ticks.frequency >= 1000 && - /* Will probably be false */ - sys_timer_info.ticks.resolution == 1) { - ut_timer = sys_timer_info.ticks; - ut_timer_now = &my_timer_ticks; - } else { - /* None are acceptable, so leave it as "None", and fill in struct */ - ut_timer.frequency = 1; /* Avoid div-by-zero */ - ut_timer.overhead = 0; /* Since it doesn't do anything */ - ut_timer.resolution = 10; /* Another sign it's bad */ - ut_timer.routine = 0; /* None */ - } -} diff --git a/storage/innobase/ut/ut0ut.cc b/storage/innobase/ut/ut0ut.cc index de12ab0cc11..0d6e9c45aec 100644 --- a/storage/innobase/ut/ut0ut.cc +++ b/storage/innobase/ut/ut0ut.cc @@ -39,112 +39,6 @@ Created 5/11/1994 Heikki Tuuri #include "log.h" #include "my_cpu.h" -#ifdef _WIN32 -typedef VOID(WINAPI *time_fn)(LPFILETIME); -static time_fn ut_get_system_time_as_file_time = GetSystemTimeAsFileTime; - -/*****************************************************************//** -NOTE: The Windows epoch starts from 1601/01/01 whereas the Unix -epoch starts from 1970/1/1. For selection of constant see: -http://support.microsoft.com/kb/167296/ */ -#define WIN_TO_UNIX_DELTA_USEC 11644473600000000LL - - -/*****************************************************************//** -This is the Windows version of gettimeofday(2). -@return 0 if all OK else -1 */ -static -int -ut_gettimeofday( -/*============*/ - struct timeval* tv, /*!< out: Values are relative to Unix epoch */ - void* tz) /*!< in: not used */ -{ - FILETIME ft; - int64_t tm; - - if (!tv) { - errno = EINVAL; - return(-1); - } - - ut_get_system_time_as_file_time(&ft); - - tm = (int64_t) ft.dwHighDateTime << 32; - tm |= ft.dwLowDateTime; - - ut_a(tm >= 0); /* If tm wraps over to negative, the quotient / 10 - does not work */ - - tm /= 10; /* Convert from 100 nsec periods to usec */ - - /* If we don't convert to the Unix epoch the value for - struct timeval::tv_sec will overflow.*/ - tm -= WIN_TO_UNIX_DELTA_USEC; - - tv->tv_sec = (long) (tm / 1000000L); - tv->tv_usec = (long) (tm % 1000000L); - - return(0); -} -#else -/** An alias for gettimeofday(2). On Microsoft Windows, we have to -reimplement this function. */ -#define ut_gettimeofday gettimeofday -#endif - -/**********************************************************//** -Returns system time. We do not specify the format of the time returned: -the only way to manipulate it is to use the function ut_difftime. -@return system time */ -ib_time_t -ut_time(void) -/*=========*/ -{ - return(time(NULL)); -} - - -/**********************************************************//** -Returns system time. -Upon successful completion, the value 0 is returned; otherwise the -value -1 is returned and the global variable errno is set to indicate the -error. -@return 0 on success, -1 otherwise */ -int -ut_usectime( -/*========*/ - ulint* sec, /*!< out: seconds since the Epoch */ - ulint* ms) /*!< out: microseconds since the Epoch+*sec */ -{ - struct timeval tv; - int ret; - int errno_gettimeofday; - int i; - - for (i = 0; i < 10; i++) { - - ret = ut_gettimeofday(&tv, NULL); - - if (ret == -1) { - errno_gettimeofday = errno; - ib::error() << "gettimeofday(): " - << strerror(errno_gettimeofday); - os_thread_sleep(100000); /* 0.1 sec */ - errno = errno_gettimeofday; - } else { - break; - } - } - - if (ret != -1) { - *sec = (ulint) tv.tv_sec; - *ms = (ulint) tv.tv_usec; - } - - return(ret); -} - /**********************************************************//** Returns the number of milliseconds since some epoch. The value may wrap around. It should only be used for heuristic @@ -156,19 +50,6 @@ ut_time_ms(void) { return static_cast<ulint>(my_interval_timer() / 1000000); } - -/**********************************************************//** -Returns the difference of two times in seconds. -@return time2 - time1 expressed in seconds */ -double -ut_difftime( -/*========*/ - ib_time_t time2, /*!< in: time */ - ib_time_t time1) /*!< in: time */ -{ - return(difftime(time2, time1)); -} - #endif /* !UNIV_INNOCHECKSUM */ /**********************************************************//** diff --git a/storage/innobase/ut/ut0wqueue.cc b/storage/innobase/ut/ut0wqueue.cc index 4697aa2fc46..026431695ed 100644 --- a/storage/innobase/ut/ut0wqueue.cc +++ b/storage/innobase/ut/ut0wqueue.cc @@ -135,7 +135,7 @@ ib_wqueue_timedwait( /*================*/ /* out: work item or NULL on timeout*/ ib_wqueue_t* wq, /* in: work queue */ - ib_time_t wait_in_usecs) /* in: wait time in micro seconds */ + ulint wait_in_usecs) /* in: wait time in micro seconds */ { ib_list_node_t* node = NULL; |