From 1fcd8db7765719f24692a6ef39afdc75337c44b2 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 31 Aug 2021 12:02:31 +0200 Subject: [PATCH 1/9] MDEV-26511 - Do not change purge thread count during bootstrap Apparently, in bootstrap this could crash when creating new THDs --- storage/innobase/srv/srv0srv.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index 2a42d51676166..685e4f19aa206 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -2139,7 +2139,7 @@ ulint srv_get_task_queue_length() void srv_purge_shutdown() { if (purge_sys.enabled()) { - if (!srv_fast_shutdown) + if (!srv_fast_shutdown && !opt_bootstrap) srv_update_purge_thread_count(innodb_purge_threads_MAX); while(!srv_purge_should_exit()) { ut_a(!purge_sys.paused()); From 4362ed1b6f7dcf84f5b34276fad0a5eb27222971 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 31 Aug 2021 13:48:00 +0300 Subject: [PATCH 2/9] MDEV-25691 fixup: Avoid MDL acquisition in purge row_purge_remove_clust_if_poss_low(): When dict_table_open_on_id() is being invoked with the data dictionary locked, it will not actually acquire MDL. Remove the MDL that became dead code in commit c366845a0b5c08285c958cf1500b3b7906ecf8d4. --- storage/innobase/row/row0purge.cc | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc index d07288a9e237e..082bf69476cd5 100644 --- a/storage/innobase/row/row0purge.cc +++ b/storage/innobase/row/row0purge.cc @@ -108,7 +108,6 @@ row_purge_remove_clust_if_poss_low( dict_index_t* index = dict_table_get_first_index(node->table); table_id_t table_id = 0; index_id_t index_id = 0; - MDL_ticket* mdl_ticket = nullptr; dict_table_t *table = nullptr; pfs_os_file_t f = OS_FILE_CLOSED; @@ -117,8 +116,7 @@ row_purge_remove_clust_if_poss_low( purge_sys.check_stop_FTS(); dict_sys.mutex_lock(); table = dict_table_open_on_id( - table_id, true, DICT_TABLE_OP_OPEN_ONLY_IF_CACHED, - node->purge_thd, &mdl_ticket); + table_id, true, DICT_TABLE_OP_OPEN_ONLY_IF_CACHED); if (!table) { dict_sys.mutex_unlock(); } else if (table->n_rec_locks) { @@ -143,8 +141,7 @@ row_purge_remove_clust_if_poss_low( mtr.commit(); close_and_exit: if (table) { - dict_table_close(table, true, false, - node->purge_thd, mdl_ticket); + dict_table_close(table, true, false); dict_sys.mutex_unlock(); } return success; @@ -175,16 +172,8 @@ row_purge_remove_clust_if_poss_low( table->space = nullptr; table->file_unreadable = true; } - table = nullptr; dict_sys.mutex_unlock(); - if (!mdl_ticket); - else if (MDL_context* mdl_context = - static_cast( - thd_mdl_context(node-> - purge_thd))) { - mdl_context->release_lock(mdl_ticket); - mdl_ticket = nullptr; - } + table = nullptr; } f = fil_delete_tablespace(space_id); } @@ -192,8 +181,7 @@ row_purge_remove_clust_if_poss_low( mtr.commit(); if (table) { - dict_table_close(table, true, false, - node->purge_thd, mdl_ticket); + dict_table_close(table, true, false); dict_sys.mutex_unlock(); table = nullptr; } From 2e08b6d78c004471224e3ef0bd9e6c9bf56eff80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 31 Aug 2021 13:48:10 +0300 Subject: [PATCH 3/9] MDEV-24258 preparation: Remove dict_sys.freeze() and unfreeze() This will essentially make dict_sys.latch a mutex (it is only acquired in exclusive mode). The subsequent commit will merge dict_sys.mutex into dict_sys.latch and reintroduce dict_sys.freeze() for those cases where we currently acquire only dict_sys.latch but not dict_sys.mutex. The case where both are acquired will be mapped to dict_sys.lock(). i_s_sys_tables_fill_table_stats(): Invoke dict_sys.prevent_eviction() and the new function dict_sys.allow_eviction() to avoid table eviction while a row in INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS is being produced. Reviewed by: Thirunarayanan Balathandayuthapani --- storage/innobase/handler/i_s.cc | 36 +++++++++++++++------------- storage/innobase/include/dict0dict.h | 32 +++++++++++++++---------- storage/innobase/row/row0upd.cc | 4 ++-- 3 files changed, 40 insertions(+), 32 deletions(-) diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 9acfad100d0c2..a84d8266b092e 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -5095,9 +5095,8 @@ i_s_sys_tables_fill_table_stats( DBUG_RETURN(0); } - dict_sys.freeze(); - dict_sys.mutex_lock(); - mtr_start(&mtr); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_tables); @@ -5110,33 +5109,36 @@ i_s_sys_tables_fill_table_stats( this SYS_TABLES record */ err_msg = i_s_sys_tables_rec(pcur, nullptr, &table_rec); - ulint ref_count = table_rec ? table_rec->get_ref_count() : 0; - dict_sys.mutex_unlock(); - - if (table_rec != NULL) { - ut_ad(err_msg == NULL); + if (UNIV_LIKELY(!err_msg)) { + bool evictable = dict_sys.prevent_eviction(table_rec); + ulint ref_count = table_rec->get_ref_count(); + dict_sys.unlock(); i_s_dict_fill_sys_tablestats(thd, table_rec, ref_count, tables->table); + if (!evictable) { + table_rec = nullptr; + } } else { - ut_ad(err_msg != NULL); + ut_ad(!table_rec); + dict_sys.unlock(); push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_CANT_FIND_SYSTEM_REC, "%s", err_msg); } - dict_sys.unfreeze(); - /* Get the next record */ - dict_sys.freeze(); - dict_sys.mutex_lock(); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); + + if (table_rec) { + dict_sys.allow_eviction(table_rec); + } - mtr_start(&mtr); rec = dict_getnext_system(&pcur, &mtr); } - mtr_commit(&mtr); - dict_sys.mutex_unlock(); - dict_sys.unfreeze(); + mtr.commit(); + dict_sys.unlock(); DBUG_RETURN(0); } diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 3c0e93edc8ff7..6f5d2377b07a4 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -1527,17 +1527,28 @@ class dict_sys_t } #endif - /** Move a table to the non-LRU list from the LRU list. */ - void prevent_eviction(dict_table_t *table) + /** Move a table to the non-LRU list from the LRU list. + @return whether the table was evictable */ + bool prevent_eviction(dict_table_t *table) { ut_ad(find(table)); - if (table->can_be_evicted) - { - table->can_be_evicted= false; - UT_LIST_REMOVE(table_LRU, table); - UT_LIST_ADD_LAST(table_non_LRU, table); - } + if (!table->can_be_evicted) + return false; + table->can_be_evicted= false; + UT_LIST_REMOVE(table_LRU, table); + UT_LIST_ADD_LAST(table_non_LRU, table); + return true; } + /** Move a table from the non-LRU list to the LRU list. */ + void allow_eviction(dict_table_t *table) + { + ut_ad(find(table)); + ut_ad(!table->can_be_evicted); + table->can_be_evicted= true; + UT_LIST_REMOVE(table_non_LRU, table); + UT_LIST_ADD_LAST(table_LRU, table); + } + /** Acquire a reference to a cached table. */ inline void acquire(dict_table_t *table); @@ -1582,11 +1593,6 @@ class dict_sys_t latch.wr_unlock(); } - /** Prevent modifications of the data dictionary */ - void freeze() { latch.rd_lock(SRW_LOCK_CALL); ut_ad(!latch_ex); } - /** Allow modifications of the data dictionary */ - void unfreeze() { ut_ad(!latch_ex); latch.rd_unlock(); } - /** Estimate the used memory occupied by the data dictionary table and index objects. @return number of bytes occupied */ diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index ee88ee7a4a673..db666cc5b28fb 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -162,7 +162,7 @@ wsrep_row_upd_index_is_foreign( /* No MDL protects dereferencing the members of table->foreign_set. */ const bool no_lock= !trx->dict_operation_lock_mode; if (no_lock) - dict_sys.freeze(); + dict_sys.mutex_lock(); auto end= table->foreign_set.end(); const bool is_referenced= end != @@ -170,7 +170,7 @@ wsrep_row_upd_index_is_foreign( [index](const dict_foreign_t* f) {return f->foreign_index == index;}); if (no_lock) - dict_sys.unfreeze(); + dict_sys.mutex_unlock(); return is_referenced; } From 82b7c561b7919fa24e3d24b3f04a16046e24374f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 31 Aug 2021 13:51:35 +0300 Subject: [PATCH 4/9] MDEV-24258 Merge dict_sys.mutex into dict_sys.latch In the parent commit, dict_sys.latch could theoretically have been replaced with a mutex. But, we can do better and merge dict_sys.mutex into dict_sys.latch. Generally, every occurrence of dict_sys.mutex_lock() will be replaced with dict_sys.lock(). The PERFORMANCE_SCHEMA instrumentation for dict_sys_mutex will be removed along with dict_sys.mutex. The dict_sys.latch will remain instrumented as dict_operation_lock. Some use of dict_sys.lock() will be replaced with dict_sys.freeze(), which we will reintroduce for the new shared mode. Most notably, concurrent table lookups are possible as long as the tables are present in the dict_sys cache. In particular, this will allow more concurrency among InnoDB purge workers. Because dict_sys.mutex will no longer 'throttle' the threads that purge InnoDB transaction history, a performance degradation may be observed unless innodb_purge_threads=1. The table cache eviction policy will become FIFO-like, similar to what happened to fil_system.LRU in commit 45ed9dd957eebc7fc84feb2509f4aa6baa908a95. The name of the list dict_sys.table_LRU will become somewhat misleading; that list contains tables that may be evicted, even though the eviction policy no longer is least-recently-used but first-in-first-out. (Note: Tables can never be evicted as long as locks exist on them or the tables are in use by some thread.) As demonstrated by the test perfschema.sxlock_func, there will be less contention on dict_sys.latch, because some previous use of exclusive latches will be replaced with shared latches. fts_parse_sql_no_dict_lock(): Replaced with pars_sql(). fts_get_table_name_prefix(): Merged to fts_optimize_create(). dict_stats_update_transient_for_index(): Deduplicated some code. ha_innobase::info_low(), dict_stats_stop_bg(): Use a combination of dict_sys.latch and table->stats_mutex_lock() to cover the changes of BG_STAT_SHOULD_QUIT, because the flag is being read in dict_stats_update_persistent() while not holding dict_sys.latch. row_discard_tablespace_for_mysql(): Protect stats_bg_flag by exclusive dict_sys.latch, like most other code does. row_quiesce_table_has_fts_index(): Remove unnecessary mutex acquisition. FLUSH TABLES...FOR EXPORT is protected by MDL. row_import::set_root_by_heuristic(): Remove unnecessary mutex acquisition. ALTER TABLE...IMPORT TABLESPACE is protected by MDL. row_ins_sec_index_entry_low(): Replace a call to dict_set_corrupted_index_cache_only(). Reads of index->type were not really protected by dict_sys.mutex, and writes (flagging an index corrupted) should be extremely rare. dict_stats_process_entry_from_defrag_pool(): Only freeze the dictionary, do not lock it exclusively. dict_stats_wait_bg_to_stop_using_table(), DICT_BG_YIELD: Remove trx. We can simply invoke dict_sys.unlock() and dict_sys.lock() directly. dict_acquire_mdl_shared(): Assert that dict_sys.latch is only held in shared more, not exclusive mode. Only acquire it in exclusive mode if the table needs to be loaded to the cache. dict_sys_t::acquire(): Remove. Relocating elements in dict_sys.table_LRU would require holding an exclusive latch, which we want to avoid for performance reasons. dict_sys_t::allow_eviction(): Add the table first to dict_sys.table_LRU, to compensate for the removal of dict_sys_t::acquire(). This function is only invoked by INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS. dict_table_open_on_id(), dict_table_open_on_name(): If dict_locked=false, try to acquire dict_sys.latch in shared mode. Only acquire the latch in exclusive mode if the table is not found in the cache. Reviewed by: Thirunarayanan Balathandayuthapani --- .../suite/perfschema/r/sxlock_func.result | 2 +- .../suite/perfschema/t/sxlock_func.test | 2 + storage/innobase/btr/btr0sea.cc | 12 +- storage/innobase/dict/dict0boot.cc | 6 +- storage/innobase/dict/dict0crea.cc | 32 +- storage/innobase/dict/dict0defrag_bg.cc | 75 ++-- storage/innobase/dict/dict0dict.cc | 392 +++++++++--------- storage/innobase/dict/dict0load.cc | 51 ++- storage/innobase/dict/dict0stats.cc | 46 +- storage/innobase/dict/dict0stats_bg.cc | 34 +- storage/innobase/dict/drop.cc | 8 +- storage/innobase/fil/fil0fil.cc | 2 +- storage/innobase/fts/fts0fts.cc | 45 +- storage/innobase/fts/fts0opt.cc | 26 +- storage/innobase/fts/fts0sql.cc | 59 +-- storage/innobase/handler/ha_innodb.cc | 68 ++- storage/innobase/handler/handler0alter.cc | 67 ++- storage/innobase/handler/i_s.cc | 126 +++--- storage/innobase/include/dict0dict.h | 114 ++--- storage/innobase/include/dict0dict.ic | 4 +- storage/innobase/include/dict0load.h | 9 +- storage/innobase/include/dict0mem.h | 9 +- storage/innobase/include/dict0stats.ic | 4 +- storage/innobase/include/dict0stats_bg.h | 28 +- storage/innobase/include/fil0fil.h | 2 +- storage/innobase/include/fts0fts.h | 4 +- storage/innobase/include/fts0priv.h | 20 +- storage/innobase/include/log0log.h | 2 +- storage/innobase/include/log0log.ic | 2 +- storage/innobase/include/que0que.h | 4 +- storage/innobase/include/univ.i | 1 - storage/innobase/lock/lock0lock.cc | 4 +- storage/innobase/pars/pars0pars.cc | 2 +- storage/innobase/pars/pars0sym.cc | 2 +- storage/innobase/que/que0que.cc | 20 +- storage/innobase/row/row0import.cc | 6 - storage/innobase/row/row0ins.cc | 4 +- storage/innobase/row/row0merge.cc | 10 +- storage/innobase/row/row0mysql.cc | 19 +- storage/innobase/row/row0purge.cc | 10 +- storage/innobase/row/row0quiesce.cc | 4 - storage/innobase/row/row0uins.cc | 26 +- storage/innobase/row/row0umod.cc | 6 +- storage/innobase/row/row0upd.cc | 4 +- storage/innobase/srv/srv0srv.cc | 4 +- storage/innobase/trx/trx0trx.cc | 4 +- 46 files changed, 653 insertions(+), 728 deletions(-) diff --git a/mysql-test/suite/perfschema/r/sxlock_func.result b/mysql-test/suite/perfschema/r/sxlock_func.result index 943f2c9301b34..8f4c2fdcecebc 100644 --- a/mysql-test/suite/perfschema/r/sxlock_func.result +++ b/mysql-test/suite/perfschema/r/sxlock_func.result @@ -35,10 +35,10 @@ SELECT DISTINCT event_name FROM performance_schema.events_waits_history_long WHERE event_name LIKE 'wait/synch/rwlock/innodb/%' AND event_name NOT IN ('wait/synch/rwlock/innodb/btr_search_latch', +'wait/synch/rwlock/innodb/dict_operation_lock', 'wait/synch/rwlock/innodb/trx_purge_latch') ORDER BY event_name; event_name -wait/synch/rwlock/innodb/dict_operation_lock wait/synch/rwlock/innodb/fil_space_latch wait/synch/rwlock/innodb/lock_latch SELECT event_name FROM performance_schema.events_waits_history_long diff --git a/mysql-test/suite/perfschema/t/sxlock_func.test b/mysql-test/suite/perfschema/t/sxlock_func.test index b8852c51ccb43..c628158c9ead6 100644 --- a/mysql-test/suite/perfschema/t/sxlock_func.test +++ b/mysql-test/suite/perfschema/t/sxlock_func.test @@ -42,11 +42,13 @@ commit; drop table t1; # Make sure some rw-lock operations have been executed +# (there will only occasionally be waits on some rw-locks) SELECT DISTINCT event_name FROM performance_schema.events_waits_history_long WHERE event_name LIKE 'wait/synch/rwlock/innodb/%' AND event_name NOT IN ('wait/synch/rwlock/innodb/btr_search_latch', + 'wait/synch/rwlock/innodb/dict_operation_lock', 'wait/synch/rwlock/innodb/trx_purge_latch') ORDER BY event_name; diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc index a5e22fa0c2af8..6fb4a01951a2a 100644 --- a/storage/innobase/btr/btr0sea.cc +++ b/storage/innobase/btr/btr0sea.cc @@ -230,12 +230,12 @@ void btr_search_disable() { dict_table_t* table; - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); btr_search_x_lock_all(); if (!btr_search_enabled) { - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); btr_search_x_unlock_all(); return; } @@ -256,7 +256,7 @@ void btr_search_disable() btr_search_disable_ref_count(table); } - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); /* Set all block->index = NULL. */ buf_pool.clear_hash_index(); @@ -1263,7 +1263,7 @@ void btr_search_drop_page_hash_index(buf_block_t* block) ut_ad(page_is_leaf(block->frame)); /* We must not dereference block->index here, because it could be freed - if (index->table->n_ref_count == 0). + if (!index->table->get_ref_count() && !dict_sys.frozen()). Determine the ahi_slot based on the block contents. */ const index_id_t index_id @@ -1436,10 +1436,8 @@ void btr_search_drop_page_hash_when_freed(const page_id_t page_id) /* In all our callers, the table handle should be open, or we should be in the process of dropping the table (preventing eviction). */ -#ifdef SAFE_MUTEX DBUG_ASSERT(block->index->table->get_ref_count() - || dict_sys.mutex_is_locked()); -#endif /* SAFE_MUTEX */ + || dict_sys.locked()); btr_search_drop_page_hash_index(block); } } diff --git a/storage/innobase/dict/dict0boot.cc b/storage/innobase/dict/dict0boot.cc index 2792f71376d61..e6a46699f02e7 100644 --- a/storage/innobase/dict/dict0boot.cc +++ b/storage/innobase/dict/dict0boot.cc @@ -225,7 +225,7 @@ dict_boot(void) heap = mem_heap_create(450); - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); /* Get the dictionary header */ const byte* dict_hdr = &dict_hdr_get(&mtr)->frame[DICT_HDR]; @@ -413,10 +413,10 @@ dict_boot(void) dict_load_sys_table(dict_sys.sys_columns); dict_load_sys_table(dict_sys.sys_indexes); dict_load_sys_table(dict_sys.sys_fields); - dict_sys.mutex_unlock(); + dict_sys.unlock(); dict_sys.load_sys_tables(); } else { - dict_sys.mutex_unlock(); + dict_sys.unlock(); } return(err); diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc index 70d9e2bb0227d..c293ab302a355 100644 --- a/storage/innobase/dict/dict0crea.cc +++ b/storage/innobase/dict/dict0crea.cc @@ -343,7 +343,7 @@ dict_build_table_def_step( que_thr_t* thr, /*!< in: query thread */ tab_node_t* node) /*!< in: table create node */ { - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); dict_table_t* table = node->table; ut_ad(!table->is_temporary()); ut_ad(!table->space); @@ -403,7 +403,7 @@ dict_build_v_col_def_step( Based on an index object, this function builds the entry to be inserted in the SYS_INDEXES system table. @return the tuple which should be inserted */ -static +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dtuple_t* dict_create_sys_indexes_tuple( /*==========================*/ @@ -416,7 +416,7 @@ dict_create_sys_indexes_tuple( dfield_t* dfield; byte* ptr; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); ut_ad(index); ut_ad(index->table->space || !UT_LIST_GET_LEN(index->table->indexes) || index->table->file_unreadable); @@ -646,7 +646,7 @@ dict_build_index_def_step( dtuple_t* row; trx_t* trx; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); trx = thr_get_trx(thr); @@ -691,7 +691,7 @@ dict_build_index_def( dict_index_t* index, /*!< in/out: index */ trx_t* trx) /*!< in/out: InnoDB transaction handle */ { - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); ut_ad((UT_LIST_GET_LEN(table->indexes) > 0) || dict_index_is_clust(index)); @@ -734,7 +734,7 @@ dict_create_index_tree_step( dict_index_t* index; dtuple_t* search_tuple; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); index = node->index; @@ -803,7 +803,7 @@ dict_create_index_tree_in_mem( { mtr_t mtr; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); ut_ad(!(index->type & DICT_FTS)); mtr_start(&mtr); @@ -833,7 +833,7 @@ uint32_t dict_drop_index_tree(btr_pcur_t *pcur, trx_t *trx, mtr_t *mtr) { rec_t *rec= btr_pcur_get_rec(pcur); - ut_d(if (trx) dict_sys.assert_locked()); + ut_ad(!trx || dict_sys.locked()); ut_ad(!dict_table_is_comp(dict_sys.sys_indexes)); btr_pcur_store_position(pcur, mtr); @@ -995,7 +995,7 @@ dict_create_table_step( trx_t* trx; ut_ad(thr); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); trx = thr_get_trx(thr); @@ -1171,7 +1171,7 @@ dict_create_index_step( trx_t* trx; ut_ad(thr); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); trx = thr_get_trx(thr); @@ -1319,7 +1319,7 @@ bool dict_sys_t::load_sys_tables() { ut_ad(!srv_any_background_activity()); bool mismatch= false; - mutex_lock(); + lock(SRW_LOCK_CALL); if (!(sys_foreign= load_table(SYS_TABLE[SYS_FOREIGN], DICT_ERR_IGNORE_FK_NOKEY))); else if (UT_LIST_GET_LEN(sys_foreign->indexes) == 3 && @@ -1354,7 +1354,7 @@ bool dict_sys_t::load_sys_tables() mismatch= true; ib::error() << "Invalid definition of SYS_VIRTUAL"; } - mutex_unlock(); + unlock(); return mismatch; } @@ -1453,13 +1453,13 @@ dberr_t dict_sys_t::create_or_check_sys_tables() trx->free(); srv_file_per_table= srv_file_per_table_backup; - mutex_lock(); + lock(SRW_LOCK_CALL); if (sys_foreign); else if (!(sys_foreign= load_table(SYS_TABLE[SYS_FOREIGN]))) { tablename= SYS_TABLE[SYS_FOREIGN].data(); load_fail: - mutex_unlock(); + unlock(); ib::error() << "Failed to CREATE TABLE " << tablename; return DB_TABLE_NOT_FOUND; } @@ -1484,7 +1484,7 @@ dberr_t dict_sys_t::create_or_check_sys_tables() else prevent_eviction(sys_virtual); - mutex_unlock(); + unlock(); return DB_SUCCESS; } @@ -1877,7 +1877,7 @@ dict_create_add_foreigns_to_dictionary( const dict_table_t* table, trx_t* trx) { - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); if (!dict_sys.sys_foreign) { diff --git a/storage/innobase/dict/dict0defrag_bg.cc b/storage/innobase/dict/dict0defrag_bg.cc index 4be6a28882ea8..44cc4289a672c 100644 --- a/storage/innobase/dict/dict0defrag_bg.cc +++ b/storage/innobase/dict/dict0defrag_bg.cc @@ -145,7 +145,7 @@ dict_stats_defrag_pool_del( { ut_a((table && !index) || (!table && index)); ut_ad(!srv_read_only_mode); - dict_sys.assert_locked(); + ut_ad(dict_sys.frozen()); mysql_mutex_lock(&defrag_pool_mutex); @@ -170,45 +170,34 @@ dict_stats_defrag_pool_del( /*****************************************************************//** Get the first index that has been added for updating persistent defrag stats and eventually save its stats. */ -static -void -dict_stats_process_entry_from_defrag_pool() +static void dict_stats_process_entry_from_defrag_pool() { - table_id_t table_id; - index_id_t index_id; - - ut_ad(!srv_read_only_mode); - - /* pop the first index from the auto defrag pool */ - if (!dict_stats_defrag_pool_get(&table_id, &index_id)) { - /* no index in defrag pool */ - return; - } - - dict_table_t* table; - - dict_sys.mutex_lock(); - - /* If the table is no longer cached, we've already lost the in - memory stats so there's nothing really to write to disk. */ - table = dict_table_open_on_id(table_id, TRUE, - DICT_TABLE_OP_OPEN_ONLY_IF_CACHED); - - dict_index_t* index = table && !table->corrupted - ? dict_table_find_index_on_id(table, index_id) - : NULL; - - if (!index || index->is_corrupted()) { - if (table) { - dict_table_close(table, TRUE, FALSE); - } - dict_sys.mutex_unlock(); - return; - } - - dict_sys.mutex_unlock(); - dict_stats_save_defrag_stats(index); - dict_table_close(table, FALSE, FALSE); + table_id_t table_id; + index_id_t index_id; + + ut_ad(!srv_read_only_mode); + + /* pop the first index from the auto defrag pool */ + if (!dict_stats_defrag_pool_get(&table_id, &index_id)) + /* no index in defrag pool */ + return; + + dict_sys.freeze(SRW_LOCK_CALL); + + /* If the table is no longer cached, we've already lost the in + memory stats so there's nothing really to write to disk. */ + dict_table_t *table= dict_sys.find_table(table_id); + dict_index_t *index= table && table->corrupted + ? nullptr : dict_table_find_index_on_id(table, index_id); + const bool save= index && !index->is_corrupted(); + if (save) + table->acquire(); + dict_sys.unfreeze(); + if (save) + { + dict_stats_save_defrag_stats(index); + table->release(); + } } /*****************************************************************//** @@ -237,7 +226,7 @@ dict_stats_save_defrag_summary( return DB_SUCCESS; } - dict_sys_lock(); + dict_sys.lock(SRW_LOCK_CALL); ret = dict_stats_save_index_stat(index, time(NULL), "n_pages_freed", index->stat_defrag_n_pages_freed, @@ -246,7 +235,7 @@ dict_stats_save_defrag_summary( " last defragmentation run.", NULL); - dict_sys_unlock(); + dict_sys.unlock(); return (ret); } @@ -331,7 +320,7 @@ dict_stats_save_defrag_stats( return DB_SUCCESS; } - dict_sys_lock(); + dict_sys.lock(SRW_LOCK_CALL); ret = dict_stats_save_index_stat(index, now, "n_page_split", index->stat_defrag_n_page_split, NULL, @@ -361,6 +350,6 @@ dict_stats_save_defrag_stats( NULL); end: - dict_sys_unlock(); + dict_sys.unlock(); return ret; } diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 2ab5f9a07c94e..400cda111fe03 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -86,7 +86,7 @@ const span dict_sys_t::SYS_TABLE[]= /** Diagnostic message for exceeding the mutex_lock_wait() timeout */ const char dict_sys_t::fatal_msg[]= - "innodb_fatal_semaphore_wait_threshold was exceeded for dict_sys.mutex. " + "innodb_fatal_semaphore_wait_threshold was exceeded for dict_sys.latch. " "Please refer to " "https://mariadb.com/kb/en/how-to-produce-a-full-stack-trace-for-mysqld/"; @@ -272,11 +272,10 @@ dict_table_try_drop_aborted( /**********************************************************************//** When opening a table, try to drop any indexes after an aborted index creation. -Release the dict_sys.mutex. */ +Invoke dict_sys.unlock(). */ static void -dict_table_try_drop_aborted_and_mutex_exit( -/*=======================================*/ +dict_table_try_drop_aborted_and_unlock( dict_table_t* table, /*!< in: table (may be NULL) */ ibool try_drop) /*!< in: FALSE if should try to drop indexes whose online creation @@ -292,11 +291,11 @@ dict_table_try_drop_aborted_and_mutex_exit( was aborted. */ table_id_t table_id = table->id; - dict_sys.mutex_unlock(); + dict_sys.unlock(); dict_table_try_drop_aborted(table, table_id, 1); } else { - dict_sys.mutex_unlock(); + dict_sys.unlock(); } } @@ -317,10 +316,10 @@ dict_table_close( MDL_ticket* mdl) { if (!dict_locked) { - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); } - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); ut_a(table->get_ref_count() > 0); const bool last_handle = table->release(); @@ -330,8 +329,9 @@ dict_table_close( if they have been manually modified. We reset table->stat_initialized only if table reference count is 0 because we do not want too frequent stats re-reads (e.g. in other cases than FLUSH TABLE). */ - if (last_handle && strchr(table->name.m_name, '/') != NULL - && dict_stats_is_persistent_enabled(table)) { + if (last_handle + && dict_stats_is_persistent_enabled(table) + && strchr(table->name.m_name, '/')) { table->stats_mutex_lock(); dict_stats_deinit(table); @@ -347,7 +347,7 @@ dict_table_close( && table->drop_aborted && dict_table_get_first_index(table); - dict_sys.mutex_unlock(); + dict_sys.unlock(); /* dict_table_try_drop_aborted() can generate undo logs. So it should be avoided after shutdown of background @@ -691,7 +691,7 @@ dict_index_get_nth_field_pos( } /** Parse the table file name into table name and database name. -@tparam dict_locked whether dict_sys.mutex is being held +@tparam dict_locked whether dict_sys.lock() was called @param[in,out] db_name database name buffer @param[in,out] tbl_name table name buffer @param[out] db_name_len database name length @@ -706,8 +706,8 @@ bool dict_table_t::parse_name(char (&db_name)[NAME_LEN + 1], char tbl_buf[MAX_TABLE_NAME_LEN + 1]; if (!dict_locked) - dict_sys.mutex_lock(); /* protect against renaming */ - dict_sys.assert_locked(); + dict_sys.freeze(SRW_LOCK_CALL); /* protect against renaming */ + ut_ad(dict_sys.frozen()); const size_t db_len= name.dblen(); ut_ad(db_len <= MAX_DATABASE_NAME_LEN); @@ -726,7 +726,7 @@ bool dict_table_t::parse_name(char (&db_name)[NAME_LEN + 1], tbl_buf[tbl_len]= 0; if (!dict_locked) - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); *db_name_len= filename_to_tablename(db_buf, db_name, MAX_DATABASE_NAME_LEN + 1, true); @@ -766,13 +766,14 @@ dict_acquire_mdl_shared(dict_table_t *table, if (trylock) { - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); db_len= dict_get_db_name_len(table->name.m_name); - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); } else { - dict_sys.assert_locked(); + ut_ad(dict_sys.frozen()); + ut_ad(!dict_sys.locked()); db_len= dict_get_db_name_len(table->name.m_name); } @@ -795,7 +796,6 @@ dict_acquire_mdl_shared(dict_table_t *table, retry: if (!unaccessible && (!table->is_readable() || table->corrupted)) { -is_unaccessible: if (*mdl) { mdl_context->release_lock(*mdl); @@ -811,10 +811,12 @@ dict_acquire_mdl_shared(dict_table_t *table, return nullptr; if (!trylock) - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); + { MDL_request request; - MDL_REQUEST_INIT(&request,MDL_key::TABLE, db_buf, tbl_buf, MDL_SHARED, MDL_EXPLICIT); + MDL_REQUEST_INIT(&request,MDL_key::TABLE, db_buf, tbl_buf, MDL_SHARED, + MDL_EXPLICIT); if (trylock ? mdl_context->try_acquire_lock(&request) : mdl_context->acquire_lock(&request, @@ -828,19 +830,37 @@ dict_acquire_mdl_shared(dict_table_t *table, return nullptr; } else + { *mdl= request.ticket; + if (trylock && !*mdl) + return nullptr; + } } - if (!trylock) - dict_sys.mutex_lock(); - else if (!*mdl) - return nullptr; - - table= dict_table_open_on_id(table_id, !trylock, table_op); + dict_sys.freeze(SRW_LOCK_CALL); + table= dict_sys.find_table(table_id); + if (table) + table->acquire(); + if (!table && table_op != DICT_TABLE_OP_OPEN_ONLY_IF_CACHED) + { + dict_sys.unfreeze(); + dict_sys.lock(SRW_LOCK_CALL); + table= dict_load_table_on_id(table_id, + table_op == DICT_TABLE_OP_LOAD_TABLESPACE + ? DICT_ERR_IGNORE_RECOVER_LOCK + : DICT_ERR_IGNORE_FK_NOKEY); + if (table) + table->acquire(); + dict_sys.unlock(); + dict_sys.freeze(SRW_LOCK_CALL); + } - if (!table) + if (!table || !table->is_accessible()) { - /* The table was dropped. */ + table= nullptr; +return_without_mdl: + if (trylock) + dict_sys.unfreeze(); if (*mdl) { mdl_context->release_lock(*mdl); @@ -849,21 +869,13 @@ dict_acquire_mdl_shared(dict_table_t *table, return nullptr; } - if (!table->is_accessible()) - goto is_unaccessible; - size_t db1_len, tbl1_len; if (!table->parse_name(db_buf1, tbl_buf1, &db1_len, &tbl1_len)) { /* The table was renamed to #sql prefix. Release MDL (if any) for the old name and return. */ - if (*mdl) - { - mdl_context->release_lock(*mdl); - *mdl= nullptr; - } - return table; + goto return_without_mdl; } if (*mdl) @@ -871,7 +883,11 @@ dict_acquire_mdl_shared(dict_table_t *table, if (db_len == db1_len && tbl_len == tbl1_len && !memcmp(db_buf, db_buf1, db_len) && !memcmp(tbl_buf, tbl_buf1, tbl_len)) + { + if (trylock) + dict_sys.unfreeze(); return table; + } /* The table was renamed. Release MDL for the old name and try to acquire MDL for the new name. */ @@ -887,8 +903,10 @@ dict_acquire_mdl_shared(dict_table_t *table, goto retry; } -template dict_table_t* -dict_acquire_mdl_shared(dict_table_t*,THD*,MDL_ticket**,dict_table_op_t); +template dict_table_t* dict_acquire_mdl_shared +(dict_table_t*,THD*,MDL_ticket**,dict_table_op_t); +template dict_table_t* dict_acquire_mdl_shared +(dict_table_t*,THD*,MDL_ticket**,dict_table_op_t); /** Look up a table by numeric identifier. @param[in] table_id table identifier @@ -902,34 +920,47 @@ dict_table_open_on_id(table_id_t table_id, bool dict_locked, dict_table_op_t table_op, THD *thd, MDL_ticket **mdl) { - if (!dict_locked) { - dict_sys.mutex_lock(); - } - - dict_sys.assert_locked(); - - dict_table_t* table = dict_table_open_on_id_low( - table_id, - table_op == DICT_TABLE_OP_LOAD_TABLESPACE - ? DICT_ERR_IGNORE_RECOVER_LOCK - : DICT_ERR_IGNORE_FK_NOKEY, - table_op == DICT_TABLE_OP_OPEN_ONLY_IF_CACHED); + if (!dict_locked) + dict_sys.freeze(SRW_LOCK_CALL); - if (table) { - dict_sys.acquire(table); - } + dict_table_t *table= dict_sys.find_table(table_id); - if (!dict_locked) { - if (thd) { - table = dict_acquire_mdl_shared( - table, thd, mdl, table_op); - } + if (table) + { + table->acquire(); + if (thd && !dict_locked) + table= dict_acquire_mdl_shared(table, thd, mdl, table_op); + } + else if (table_op != DICT_TABLE_OP_OPEN_ONLY_IF_CACHED) + { + if (!dict_locked) + { + dict_sys.unfreeze(); + dict_sys.lock(SRW_LOCK_CALL); + } + table= dict_load_table_on_id(table_id, + table_op == DICT_TABLE_OP_LOAD_TABLESPACE + ? DICT_ERR_IGNORE_RECOVER_LOCK + : DICT_ERR_IGNORE_FK_NOKEY); + if (table) + table->acquire(); + if (!dict_locked) + { + dict_sys.unlock(); + if (table && thd) + { + dict_sys.freeze(SRW_LOCK_CALL); + table= dict_acquire_mdl_shared(table, thd, mdl, table_op); + dict_sys.unfreeze(); + } + return table; + } + } - dict_table_try_drop_aborted_and_mutex_exit( - table, table_op == DICT_TABLE_OP_DROP_ORPHAN); - } + if (!dict_locked) + dict_sys.unfreeze(); - return table; + return table; } /********************************************************************//** @@ -991,8 +1022,6 @@ void dict_sys_t::create() UT_LIST_INIT(table_LRU, &dict_table_t::table_LRU); UT_LIST_INIT(table_non_LRU, &dict_table_t::table_LRU); - mysql_mutex_init(dict_sys_mutex_key, &mutex, nullptr); - const ulint hash_size = buf_pool_get_curr_size() / (DICT_POOL_PER_TABLE_HASH * UNIV_WORD_SIZE); @@ -1013,27 +1042,17 @@ void dict_sys_t::create() } -/** Acquire a reference to a cached table. */ -inline void dict_sys_t::acquire(dict_table_t *table) -{ - ut_ad(dict_sys.find(table)); - if (table->can_be_evicted) - { - UT_LIST_REMOVE(table_LRU, table); - UT_LIST_ADD_FIRST(table_LRU, table); - } - - table->acquire(); -} - -void dict_sys_t::mutex_lock_wait() +void dict_sys_t::lock_wait(SRW_LOCK_ARGS(const char *file, unsigned line)) { ulonglong now= my_hrtime_coarse().val, old= 0; - if (mutex_wait_start.compare_exchange_strong + if (latch_ex_wait_start.compare_exchange_strong (old, now, std::memory_order_relaxed, std::memory_order_relaxed)) { - mysql_mutex_lock(&mutex); - mutex_wait_start.store(0, std::memory_order_relaxed); + latch.wr_lock(SRW_LOCK_ARGS(file, line)); + latch_ex_wait_start.store(0, std::memory_order_relaxed); + ut_ad(!latch_readers); + ut_ad(!latch_ex); + ut_d(latch_ex= true); return; } @@ -1047,32 +1066,36 @@ void dict_sys_t::mutex_lock_wait() if (waited > threshold / 4) ib::warn() << "A long wait (" << waited - << " seconds) was observed for dict_sys.mutex"; - mysql_mutex_lock(&mutex); + << " seconds) was observed for dict_sys.latch"; + latch.wr_lock(SRW_LOCK_ARGS(file, line)); + ut_ad(!latch_readers); + ut_ad(!latch_ex); + ut_d(latch_ex= true); } -#ifdef HAVE_PSI_MUTEX_INTERFACE -/** Acquire the mutex */ -void dict_sys_t::mutex_lock() +#ifdef UNIV_PFS_RWLOCK +ATTRIBUTE_NOINLINE void dict_sys_t::unlock() { - if (mysql_mutex_trylock(&mutex)) - mutex_lock_wait(); + ut_ad(latch_ex); + ut_ad(!latch_readers); + ut_d(latch_ex= false); + latch.wr_unlock(); } -/** Release the mutex */ -void dict_sys_t::mutex_unlock() { mysql_mutex_unlock(&mutex); } -#endif +ATTRIBUTE_NOINLINE void dict_sys_t::freeze(const char *file, unsigned line) +{ + latch.rd_lock(file, line); + ut_ad(!latch_ex); + ut_d(latch_readers++); +} -/** Lock the data dictionary cache. */ -void dict_sys_t::lock(SRW_LOCK_ARGS(const char *file, unsigned line)) +ATTRIBUTE_NOINLINE void dict_sys_t::unfreeze() { - ut_ad(this == &dict_sys); - ut_ad(is_initialised()); - latch.wr_lock(SRW_LOCK_ARGS(file, line)); ut_ad(!latch_ex); - ut_d(latch_ex= true); - mutex_lock(); + ut_ad(latch_readers--); + latch.rd_unlock(); } +#endif /* UNIV_PFS_RWLOCK */ /**********************************************************************//** Returns a table object and increment its open handle count. @@ -1092,58 +1115,58 @@ dict_table_open_on_name( ignore_err) /*!< in: error to be ignored when loading a table definition */ { - dict_table_t* table; - DBUG_ENTER("dict_table_open_on_name"); - DBUG_PRINT("dict_table_open_on_name", ("table: '%s'", table_name)); - - if (!dict_locked) { - dict_sys.mutex_lock(); - } - - ut_ad(table_name); - table = dict_sys.load_table({table_name, strlen(table_name)}, - ignore_err); - - if (table) { - ut_ad(table->cached); - - /* If table is encrypted or corrupted */ - if (!(ignore_err & ~DICT_ERR_IGNORE_FK_NOKEY) - && !table->is_readable()) { - /* Make life easy for drop table. */ - dict_sys.prevent_eviction(table); - - if (table->corrupted) { - - ib::error() << "Table " << table->name - << " is corrupted. Please " - "drop the table and recreate."; - if (!dict_locked) { - dict_sys.mutex_unlock(); - } - - DBUG_RETURN(NULL); - } + dict_table_t *table; + DBUG_ENTER("dict_table_open_on_name"); + DBUG_PRINT("dict_table_open_on_name", ("table: '%s'", table_name)); - dict_sys.acquire(table); + const span name{table_name, strlen(table_name)}; - if (!dict_locked) { - dict_sys.mutex_unlock(); - } + if (!dict_locked) + { + dict_sys.freeze(SRW_LOCK_CALL); + table= dict_sys.find_table(name); + if (table) + { + ut_ad(table->cached); + if (!(ignore_err & ~DICT_ERR_IGNORE_FK_NOKEY) && + !table->is_readable() && table->corrupted) + { + ib::error() << "Table " << table->name + << " is corrupted. Please drop the table and recreate."; + dict_sys.unfreeze(); + DBUG_RETURN(nullptr); + } + table->acquire(); + dict_sys.unfreeze(); + DBUG_RETURN(table); + } + dict_sys.unfreeze(); + dict_sys.lock(SRW_LOCK_CALL); + } - DBUG_RETURN(table); - } + table= dict_sys.load_table(name, ignore_err); - dict_sys.acquire(table); - } + if (table) + { + ut_ad(table->cached); + if (!(ignore_err & ~DICT_ERR_IGNORE_FK_NOKEY) && + !table->is_readable() && table->corrupted) + { + ib::error() << "Table " << table->name + << " is corrupted. Please drop the table and recreate."; + if (!dict_locked) + dict_sys.unlock(); + DBUG_RETURN(nullptr); + } - ut_ad(dict_lru_validate()); + table->acquire(); + } - if (!dict_locked) { - dict_table_try_drop_aborted_and_mutex_exit(table, try_drop); - } + ut_ad(dict_lru_validate()); + if (!dict_locked) + dict_table_try_drop_aborted_and_unlock(table, try_drop); - DBUG_RETURN(table); + DBUG_RETURN(table); } /**********************************************************************//** @@ -1252,7 +1275,7 @@ inline void dict_sys_t::add(dict_table_t* table) @return whether the table can be evicted */ static bool dict_table_can_be_evicted(dict_table_t *table) { - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); ut_a(table->can_be_evicted); ut_a(table->foreign_set.empty()); ut_a(table->referenced_set.empty()); @@ -1423,8 +1446,8 @@ dict_table_find_index_on_id( } /**********************************************************************//** -Looks for an index with the given id. NOTE that we do not reserve -the dictionary mutex: this function is for emergency purposes like +Looks for an index with the given id. NOTE that we do not acquire +dict_sys.latch: this function is for emergency purposes like printing info of a corrupt database page! @return index or NULL if not found in cache */ dict_index_t* @@ -1540,7 +1563,7 @@ dict_table_rename_in_cache( ulint fold; char old_name[MAX_FULL_NAME_LEN + 1]; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); /* store the old/current name to an automatic variable */ const size_t old_name_len = strlen(table->name.m_name); @@ -1864,7 +1887,7 @@ dict_table_change_id_in_cache( dict_table_t* table, /*!< in/out: table object already in cache */ table_id_t new_id) /*!< in: new id to set */ { - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); ut_ad(!table->is_temporary()); @@ -1943,7 +1966,7 @@ void dict_sys_t::remove(dict_table_t* table, bool lru, bool keep) and free the index pages. */ trx_t* trx = trx_create(); - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); /* Mimic row_mysql_lock_data_dictionary(). */ trx->dict_operation_lock_mode = RW_X_LATCH; @@ -2033,7 +2056,7 @@ dict_index_add_to_cache( ulint n_ord; ulint i; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); ut_ad(index->n_def == index->n_fields); ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); ut_ad(!dict_index_is_online_ddl(index)); @@ -2161,7 +2184,7 @@ dict_index_remove_from_cache_low( ut_ad(table && index); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); ut_ad(table->id); #ifdef BTR_CUR_HASH_ADAPT ut_ad(!index->freed()); @@ -2243,7 +2266,7 @@ dict_index_find_cols( const dict_table_t* table = index->table; ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); for (ulint i = 0; i < index->n_fields; i++) { ulint j; @@ -2512,7 +2535,7 @@ dict_index_build_internal_clust( ut_ad(index->is_primary()); ut_ad(!index->has_virtual()); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); /* Create a new index object with certainly enough fields */ new_index = dict_mem_index_create(index->table, index->name, @@ -2667,7 +2690,7 @@ dict_index_build_internal_non_clust( ut_ad(table && index); ut_ad(!dict_index_is_clust(index)); ut_ad(!dict_index_is_ibuf(index)); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); /* The clustered index should be the first in the list of indexes */ clust_index = UT_LIST_GET_FIRST(table->indexes); @@ -2761,7 +2784,7 @@ dict_index_build_internal_fts( dict_index_t* new_index; ut_ad(index->type == DICT_FTS); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); /* Create a new index */ new_index = dict_mem_index_create(index->table, index->name, @@ -2813,7 +2836,7 @@ dict_foreign_remove_from_cache( /*===========================*/ dict_foreign_t* foreign) /*!< in, own: foreign constraint */ { - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); ut_a(foreign); if (foreign->referenced_table != NULL) { @@ -2838,7 +2861,7 @@ dict_foreign_find( dict_table_t* table, /*!< in: table object */ dict_foreign_t* foreign) /*!< in: foreign constraint */ { - dict_sys.assert_locked(); + ut_ad(dict_sys.frozen()); ut_ad(dict_foreign_set_validate(table->foreign_set)); ut_ad(dict_foreign_set_validate(table->referenced_set)); @@ -2892,7 +2915,7 @@ dict_foreign_find_index( /*!< out: index where error happened */ { - dict_sys.assert_locked(); + ut_ad(dict_sys.frozen()); if (error) { *error = FK_INDEX_NOT_FOUND; @@ -2990,7 +3013,7 @@ dict_foreign_add_to_cache( DBUG_ENTER("dict_foreign_add_to_cache"); DBUG_PRINT("dict_foreign_add_to_cache", ("id: %s", foreign->id)); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); for_table = dict_sys.find_table( {foreign->foreign_table_name_lookup, @@ -3637,7 +3660,7 @@ dict_foreign_parse_drop_constraints( ptr = str; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); loop: ptr = dict_scan_to(ptr, "DROP"); @@ -3739,14 +3762,14 @@ dict_foreign_parse_drop_constraints( /**********************************************************************//** Returns an index object if it is found in the dictionary cache. -Assumes that dict_sys.mutex is already being held. +Assumes that dict_sys.latch is already being held. @return index, NULL if not found */ dict_index_t* dict_index_get_if_in_cache_low( /*===========================*/ index_id_t index_id) /*!< in: index id */ { - dict_sys.assert_locked(); + ut_ad(dict_sys.frozen()); return(dict_index_find_on_id_low(index_id)); } @@ -3766,11 +3789,11 @@ dict_index_get_if_in_cache( return(NULL); } - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); index = dict_index_get_if_in_cache_low(index_id); - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); return(index); } @@ -4056,7 +4079,7 @@ dict_print_info_on_foreign_keys( dict_foreign_t* foreign; std::string str; - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); for (dict_foreign_set::iterator it = table->foreign_set.begin(); it != table->foreign_set.end(); @@ -4123,7 +4146,7 @@ dict_print_info_on_foreign_keys( } } - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); return str; } @@ -4221,7 +4244,7 @@ dict_set_corrupted( row_mysql_lock_data_dictionary(trx); } - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); ut_ad(!dict_table_is_comp(dict_sys.sys_tables)); ut_ad(!dict_table_is_comp(dict_sys.sys_indexes)); @@ -4309,7 +4332,7 @@ dict_set_corrupted_index_cache_only( { ut_ad(index != NULL); ut_ad(index->table != NULL); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); ut_ad(!dict_table_is_comp(dict_sys.sys_tables)); ut_ad(!dict_table_is_comp(dict_sys.sys_indexes)); @@ -4343,13 +4366,13 @@ dict_index_set_merge_threshold( ut_ad(!dict_table_is_comp(dict_sys.sys_tables)); ut_ad(!dict_table_is_comp(dict_sys.sys_indexes)); - dict_sys_lock(); - heap = mem_heap_create(sizeof(dtuple_t) + 2 * (sizeof(dfield_t) + sizeof(que_fork_t) + sizeof(upd_node_t) + sizeof(upd_t) + 12)); - mtr_start(&mtr); + mtr.start(); + + dict_sys.lock(SRW_LOCK_CALL); sys_index = UT_LIST_GET_FIRST(dict_sys.sys_indexes->indexes); @@ -4387,7 +4410,7 @@ dict_index_set_merge_threshold( mtr_commit(&mtr); mem_heap_free(heap); - dict_sys_unlock(); + dict_sys.unlock(); } #ifdef UNIV_DEBUG @@ -4419,14 +4442,14 @@ void dict_set_merge_threshold_all_debug( uint merge_threshold_all) { - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); dict_set_merge_threshold_list_debug( &dict_sys.table_LRU, merge_threshold_all); dict_set_merge_threshold_list_debug( &dict_sys.table_non_LRU, merge_threshold_all); - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); } #endif /* UNIV_DEBUG */ @@ -4544,7 +4567,7 @@ dict_table_check_for_dup_indexes( const dict_index_t* index1; const dict_index_t* index2; - dict_sys.assert_locked(); + ut_ad(dict_sys.frozen()); /* The primary index _must_ exist */ ut_a(UT_LIST_GET_LEN(table->indexes) > 0); @@ -4656,7 +4679,7 @@ void dict_sys_t::resize() { ut_ad(this == &dict_sys); ut_ad(is_initialised()); - mutex_lock(); + lock(SRW_LOCK_CALL); /* all table entries are in table_LRU and table_non_LRU lists */ table_hash.free(); @@ -4694,7 +4717,7 @@ void dict_sys_t::resize() HASH_INSERT(dict_table_t, id_hash, id_hash, id_fold, table); } - mutex_unlock(); + unlock(); } /** Close the data dictionary cache on shutdown. */ @@ -4703,10 +4726,10 @@ void dict_sys_t::close() ut_ad(this == &dict_sys); if (!is_initialised()) return; - mutex_lock(); + lock(SRW_LOCK_CALL); - /* Free the hash elements. We don't remove them from the table - because we are going to destroy the table anyway. */ + /* Free the hash elements. We don't remove them from table_hash + because we are invoking table_hash.free() below. */ for (ulint i= table_hash.n_cells; i--; ) while (dict_table_t *table= static_cast (HASH_GET_FIRST(&table_hash, i))) @@ -4721,8 +4744,7 @@ void dict_sys_t::close() /* No temporary tables should exist at this point. */ temp_id_hash.free(); - mutex_unlock(); - mysql_mutex_destroy(&mutex); + unlock(); latch.destroy(); mysql_mutex_destroy(&dict_foreign_err_mutex); @@ -4747,7 +4769,7 @@ dict_lru_validate(void) { dict_table_t* table; - dict_sys.assert_locked(); + ut_ad(dict_sys.frozen()); for (table = UT_LIST_GET_FIRST(dict_sys.table_LRU); table != NULL; diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index db11f4ff00359..74275b77bb035 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -509,7 +509,7 @@ dict_sys_tables_rec_check( const byte* field; ulint len; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); if (rec_get_deleted_flag(rec, 0)) { return("delete-marked record in SYS_TABLES"); @@ -828,7 +828,7 @@ static ulint dict_check_sys_tables() DBUG_ENTER("dict_check_sys_tables"); - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); mtr_start(&mtr); @@ -934,7 +934,7 @@ void dict_check_tablespaces_and_store_max_id() DBUG_ENTER("dict_check_tablespaces_and_store_max_id"); - dict_sys_lock(); + dict_sys.lock(SRW_LOCK_CALL); /* Initialize the max space_id from sys header */ mtr.start(); @@ -949,7 +949,7 @@ void dict_check_tablespaces_and_store_max_id() max_space_id = dict_check_sys_tables(); fil_set_max_space_id_if_bigger(max_space_id); - dict_sys_unlock(); + dict_sys.unlock(); DBUG_VOID_RETURN; } @@ -1237,7 +1237,7 @@ dict_load_columns( mtr_t mtr; ulint n_skipped = 0; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); mtr_start(&mtr); @@ -1351,7 +1351,7 @@ dict_load_virtual_one_col( mtr_t mtr; ulint skipped = 0; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); if (v_col->num_base == 0) { return; @@ -1581,7 +1581,7 @@ dict_load_fields( mtr_t mtr; dberr_t error; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); mtr_start(&mtr); @@ -1811,7 +1811,7 @@ dict_load_indexes( mtr_t mtr; dberr_t error = DB_SUCCESS; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); mtr_start(&mtr); @@ -2122,7 +2122,7 @@ dict_save_data_dir_path( dict_table_t* table, /*!< in/out: table */ const char* filepath) /*!< in: filepath of tablespace */ { - dict_sys.assert_locked(); + ut_ad(dict_sys.frozen()); ut_a(DICT_TF_HAS_DATA_DIR(table->flags)); ut_a(!table->data_dir_path); @@ -2145,20 +2145,17 @@ dict_save_data_dir_path( } } -/** Make sure the data_dir_path is saved in dict_table_t if needed. -@param[in] table Table object -@param[in] dict_mutex_own true if dict_sys.mutex is owned already */ -void -dict_get_and_save_data_dir_path( - dict_table_t* table, - bool dict_mutex_own) +/** Make sure the data_file_name is saved in dict_table_t if needed. +@param[in,out] table Table object +@param[in] dict_locked dict_sys.frozen() */ +void dict_get_and_save_data_dir_path(dict_table_t* table, bool dict_locked) { ut_ad(!table->is_temporary()); ut_ad(!table->space || table->space->id == table->space_id); if (!table->data_dir_path && table->space_id && table->space) { - if (!dict_mutex_own) { - dict_sys.mutex_lock(); + if (!dict_locked) { + dict_sys.freeze(SRW_LOCK_CALL); } table->flags |= 1 << DICT_TF_POS_DATA_DIR @@ -2176,8 +2173,8 @@ dict_get_and_save_data_dir_path( & ((1U << DICT_TF_BITS) - 1); } - if (!dict_mutex_own) { - dict_sys.mutex_unlock(); + if (!dict_locked) { + dict_sys.unfreeze(); } } } @@ -2288,7 +2285,7 @@ static dict_table_t *dict_load_table_one(const span &name, DBUG_PRINT("dict_load_table_one", ("table: %.*s", name.size(), name.data())); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); heap = mem_heap_create(32000); @@ -2544,10 +2541,10 @@ dict_load_table_on_id( ulint len; mtr_t mtr; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); /* NOTE that the operation of this function is protected by - the dictionary mutex, and therefore no deadlocks can occur + dict_sys.latch, and therefore no deadlocks can occur with other dictionary operations. */ mtr.start(); @@ -2627,7 +2624,7 @@ dict_load_sys_table( { mem_heap_t* heap; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); heap = mem_heap_create(1000); @@ -2662,7 +2659,7 @@ dict_load_foreign_cols( mtr_t mtr; size_t id_len; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); id_len = strlen(foreign->id); @@ -2804,7 +2801,7 @@ dict_load_foreign( DBUG_PRINT("dict_load_foreign", ("id: '%s', check_recursive: %d", id, check_recursive)); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); id_len = strlen(id); @@ -2977,7 +2974,7 @@ dict_load_foreigns( DBUG_ENTER("dict_load_foreigns"); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); if (!dict_sys.sys_foreign || !dict_sys.sys_foreign_cols) { if (ignore_err & DICT_ERR_IGNORE_FK_NOKEY) { diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index eb2f06ab31eae..ee72d7db3cdf1 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -326,7 +326,6 @@ static bool innodb_index_stats_not_found_reported; Checks whether a table exists and whether it has the given structure. The table must have the same number of columns with the same names and types. The order of the columns does not matter. -The caller must own the dictionary mutex. dict_table_schema_check() @{ @return DB_SUCCESS if the table exists and contains the necessary columns */ static @@ -478,21 +477,16 @@ dict_table_schema_check( Checks whether the persistent statistics storage exists and that all tables have the proper structure. @return true if exists and all tables are ok */ -static -bool -dict_stats_persistent_storage_check( -/*================================*/ - bool caller_has_dict_sys_mutex) /*!< in: true if the caller - owns dict_sys.mutex */ +static bool dict_stats_persistent_storage_check(bool dict_already_locked) { char errstr[512]; dberr_t ret; - if (!caller_has_dict_sys_mutex) { - dict_sys.mutex_lock(); + if (!dict_already_locked) { + dict_sys.lock(SRW_LOCK_CALL); } - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); /* first check table_stats */ ret = dict_table_schema_check(&table_stats_schema, errstr, @@ -503,8 +497,8 @@ dict_stats_persistent_storage_check( sizeof(errstr)); } - if (!caller_has_dict_sys_mutex) { - dict_sys.mutex_unlock(); + if (!dict_already_locked) { + dict_sys.unlock(); } if (ret != DB_SUCCESS && ret != DB_STATS_DO_NOT_EXIST) { @@ -530,7 +524,7 @@ only in the case of error, but not freed. static dberr_t dict_stats_exec_sql(pars_info_t *pinfo, const char* sql, trx_t *trx) { - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); if (!dict_stats_persistent_storage_check(true)) { @@ -1014,7 +1008,7 @@ dict_table_t* dict_stats_snapshot_create( dict_table_t* table) { - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); dict_stats_assert_initialized(table); @@ -1035,7 +1029,7 @@ dict_stats_snapshot_create( t->stats_sample_pages = table->stats_sample_pages; t->stats_bg_flag = table->stats_bg_flag; - dict_sys.mutex_unlock(); + dict_sys.unlock(); return(t); } @@ -1074,14 +1068,13 @@ dict_stats_update_transient_for_index( Initialize some bogus index cardinality statistics, so that the data can be queried in various means, also via secondary indexes. */ +dummy_empty: index->table->stats_mutex_lock(); dict_stats_empty_index(index, false); index->table->stats_mutex_unlock(); #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG } else if (ibuf_debug && !dict_index_is_clust(index)) { - index->table->stats_mutex_lock(); - dict_stats_empty_index(index, false); - index->table->stats_mutex_unlock(); + goto dummy_empty; #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ } else { mtr_t mtr; @@ -1102,10 +1095,7 @@ dict_stats_update_transient_for_index( switch (size) { case ULINT_UNDEFINED: - index->table->stats_mutex_lock(); - dict_stats_empty_index(index, false); - index->table->stats_mutex_unlock(); - return; + goto dummy_empty; case 0: /* The root node of the tree is a leaf */ size = 1; @@ -2586,7 +2576,7 @@ dict_stats_save_index_stat( char db_utf8[MAX_DB_UTF8_LEN]; char table_utf8[MAX_TABLE_UTF8_LEN]; - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); dict_fs2utf8(index->table->name.m_name, db_utf8, sizeof(db_utf8), table_utf8, sizeof(table_utf8)); @@ -2722,7 +2712,7 @@ dict_stats_save( trx_t* trx = trx_create(); trx_start_internal(trx); trx->dict_operation_lock_mode = RW_X_LATCH; - dict_sys_lock(); + dict_sys.lock(SRW_LOCK_CALL); pinfo = pars_info_create(); @@ -2764,7 +2754,7 @@ dict_stats_save( trx->rollback(); free_and_exit: trx->dict_operation_lock_mode = 0; - dict_sys_unlock(); + dict_sys.unlock(); trx->free(); dict_stats_snapshot_free(table); return ret; @@ -3634,7 +3624,7 @@ dberr_t dict_stats_delete_from_table_stats(const char *database_name, { pars_info_t* pinfo; - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); pinfo = pars_info_create(); @@ -3661,7 +3651,7 @@ dberr_t dict_stats_delete_from_index_stats(const char *database_name, { pars_info_t* pinfo; - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); pinfo = pars_info_create(); @@ -3690,7 +3680,7 @@ dberr_t dict_stats_delete_from_index_stats(const char *database_name, { pars_info_t* pinfo; - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); pinfo = pars_info_create(); diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc index dbaff373ac4b8..209a2f33ba9c9 100644 --- a/storage/innobase/dict/dict0stats_bg.cc +++ b/storage/innobase/dict/dict0stats_bg.cc @@ -146,8 +146,6 @@ schedule new estimates for table and index statistics to be calculated. void dict_stats_update_if_needed_func(dict_table_t *table) #endif { - dict_sys.assert_not_locked(); - if (UNIV_UNLIKELY(!table->stat_initialized)) { /* The table may have been evicted from dict_sys and reloaded internally by InnoDB for FOREIGN KEY @@ -258,7 +256,7 @@ dict_stats_recalc_pool_del( const dict_table_t* table) /*!< in: table to remove */ { ut_ad(!srv_read_only_mode); - dict_sys.assert_locked(); + ut_ad(dict_sys.frozen()); mysql_mutex_lock(&recalc_pool_mutex); @@ -280,23 +278,13 @@ dict_stats_recalc_pool_del( /*****************************************************************//** Wait until background stats thread has stopped using the specified table. -The caller must have locked the data dictionary using -row_mysql_lock_data_dictionary() and this function may unlock it temporarily -and restore the lock before it exits. The background stats thread is guaranteed not to start using the specified -table after this function returns and before the caller unlocks the data -dictionary because it sets the BG_STAT_IN_PROGRESS bit in table->stats_bg_flag -under dict_sys.mutex. */ -void -dict_stats_wait_bg_to_stop_using_table( -/*===================================*/ - dict_table_t* table, /*!< in/out: table */ - trx_t* trx) /*!< in/out: transaction to use for - unlocking/locking the data dict */ +table after this function returns and before the caller releases +dict_sys.latch. */ +void dict_stats_wait_bg_to_stop_using_table(dict_table_t *table) { - while (!dict_stats_stop_bg(table)) { - DICT_BG_YIELD(trx); - } + while (!dict_stats_stop_bg(table)) + DICT_BG_YIELD; } /*****************************************************************//** @@ -347,7 +335,7 @@ static bool dict_stats_process_entry_from_recalc_pool() dict_table_t* table; - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); table = dict_table_open_on_id(table_id, TRUE, DICT_TABLE_OP_NORMAL); @@ -362,13 +350,13 @@ static bool dict_stats_process_entry_from_recalc_pool() if (!table->is_accessible()) { dict_table_close(table, TRUE, FALSE); no_table: - dict_sys.mutex_unlock(); + dict_sys.unlock(); goto next_table_id; } table->stats_bg_flag |= BG_STAT_IN_PROGRESS; - dict_sys.mutex_unlock(); + dict_sys.unlock(); /* time() could be expensive, the current function is called once every time a table has been changed more than 10% and @@ -393,13 +381,13 @@ static bool dict_stats_process_entry_from_recalc_pool() ret = true; } - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); table->stats_bg_flag = BG_STAT_NONE; dict_table_close(table, TRUE, FALSE); - dict_sys.mutex_unlock(); + dict_sys.unlock(); return ret; } diff --git a/storage/innobase/dict/drop.cc b/storage/innobase/dict/drop.cc index b2aab6992bbd3..bb0af50c4c284 100644 --- a/storage/innobase/dict/drop.cc +++ b/storage/innobase/dict/drop.cc @@ -78,7 +78,7 @@ before transaction commit and must be rolled back explicitly are as follows: @return error code */ dberr_t trx_t::drop_table_foreign(const table_name_t &name) { - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); ut_ad(state == TRX_STATE_ACTIVE); ut_ad(dict_operation); ut_ad(dict_operation_lock_mode == RW_X_LATCH); @@ -116,7 +116,7 @@ dberr_t trx_t::drop_table_foreign(const table_name_t &name) @return error code */ dberr_t trx_t::drop_table_statistics(const table_name_t &name) { - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); ut_ad(dict_operation_lock_mode == RW_X_LATCH); if (strstr(name.m_name, "/" TEMP_FILE_PREFIX_INNODB) || @@ -143,7 +143,7 @@ dberr_t trx_t::drop_table_statistics(const table_name_t &name) @return error code */ dberr_t trx_t::drop_table(const dict_table_t &table) { - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); ut_ad(state == TRX_STATE_ACTIVE); ut_ad(dict_operation); ut_ad(dict_operation_lock_mode == RW_X_LATCH); @@ -235,7 +235,7 @@ void trx_t::commit(std::vector &deleted) commit_persist(); if (dict_operation) { - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); for (const auto &p : mod_tables) { if (p.second.is_dropped()) diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 0d4aa4901f8ec..94f9df63149ae 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -2098,7 +2098,7 @@ to the .err log. This function is used to open a tablespace when we start mysqld after the dictionary has been booted, and also in IMPORT TABLESPACE. NOTE that we assume this operation is used either at the database startup -or under the protection of the dictionary mutex, so that two users cannot +or under the protection of dict_sys.latch, so that two users cannot race here. This operation does not leave the file associated with the tablespace open, but closes it after we have looked at the space id in it. diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 7b6ca04827139..40a8c270a253b 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -159,6 +159,7 @@ const fts_index_selector_t fts_index_selector[] = { /** Default config values for FTS indexes on a table. */ static const char* fts_config_table_insert_values_sql = + "PROCEDURE P() IS\n" "BEGIN\n" "\n" "INSERT INTO $config_table VALUES('" @@ -174,7 +175,8 @@ static const char* fts_config_table_insert_values_sql = FTS_TOTAL_DELETED_COUNT "', '0');\n" "" /* Note: 0 == FTS_TABLE_STATE_RUNNING */ "INSERT INTO $config_table VALUES ('" - FTS_TABLE_STATE "', '0');\n"; + FTS_TABLE_STATE "', '0');\n" + "END;\n"; /** FTS tokenize parmameter for plugin parser */ struct fts_tokenize_param_t { @@ -185,9 +187,9 @@ struct fts_tokenize_param_t { /** Free a query graph */ void fts_que_graph_free(que_t *graph) { - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); que_graph_free(graph); - dict_sys.mutex_unlock(); + dict_sys.unlock(); } /** Run SYNC on the table, i.e., write out data from the cache to the @@ -455,7 +457,7 @@ fts_load_user_stopword( fts_stopword_t* stopword_info) /*!< in: Stopword info */ { if (!fts->dict_locked) { - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); } /* Validate the user table existence in the right format */ @@ -464,7 +466,7 @@ fts_load_user_stopword( if (!stopword_info->charset) { cleanup: if (!fts->dict_locked) { - dict_sys.mutex_unlock(); + dict_sys.unlock(); } return ret; @@ -489,8 +491,9 @@ fts_load_user_stopword( pars_info_bind_function(info, "my_func", fts_read_stopword, stopword_info); - que_t* graph = fts_parse_sql_no_dict_lock( + que_t* graph = pars_sql( info, + "PROCEDURE P() IS\n" "DECLARE FUNCTION my_func;\n" "DECLARE CURSOR c IS" " SELECT value" @@ -504,7 +507,8 @@ fts_load_user_stopword( " EXIT;\n" " END IF;\n" "END LOOP;\n" - "CLOSE c;"); + "CLOSE c;" + "END;\n"); for (;;) { dberr_t error = fts_eval_sql(trx, graph); @@ -882,7 +886,7 @@ fts_drop_index( } /****************************************************************//** -Free the query graph but check whether dict_sys.mutex is already +Free the query graph but check whether dict_sys.latch is already held */ void fts_que_graph_free_check_lock( @@ -904,15 +908,15 @@ fts_que_graph_free_check_lock( } if (!has_dict) { - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); } - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); que_graph_free(graph); if (!has_dict) { - dict_sys.mutex_unlock(); + dict_sys.unlock(); } } @@ -1551,19 +1555,19 @@ static dberr_t fts_lock_table(trx_t *trx, const char *table_name) { dberr_t err= lock_table_for_trx(table, trx, LOCK_X); /* Wait for purge threads to stop using the table. */ - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); for (uint n= 15; table->get_ref_count() > 1; ) { - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); if (!--n) { err= DB_LOCK_WAIT_TIMEOUT; goto fail; } std::this_thread::sleep_for(std::chrono::milliseconds(50)); - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); } - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); fail: table->release(); return err; @@ -1905,7 +1909,7 @@ fts_create_common_tables( fts_get_table_name(&fts_table, fts_name, true); pars_info_bind_id(info, "config_table", fts_name); - graph = fts_parse_sql_no_dict_lock( + graph = pars_sql( info, fts_config_table_insert_values_sql); error = fts_eval_sql(trx, graph); @@ -2049,8 +2053,7 @@ fts_create_index_tables(trx_t* trx, const dict_index_t* index, table_id_t id) dict_table_t* new_table; /* Create the FTS auxiliary tables that are specific - to an FTS index. We need to preserve the table_id %s - which fts_parse_sql_no_dict_lock() will fill in for us. */ + to an FTS index. */ fts_table.suffix = fts_get_suffix(i); new_table = fts_create_one_index_table( @@ -6038,8 +6041,6 @@ fts_init_index( fts_cache_t* cache = table->fts->cache; bool need_init = false; - dict_sys.assert_not_locked(); - /* First check cache->get_docs is initialized */ if (!has_cache_lock) { mysql_mutex_lock(&cache->lock); @@ -6103,9 +6104,9 @@ fts_init_index( } if (need_init) { - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); /* Register the table with the optimize thread. */ fts_optimize_add_table(table); - dict_sys.mutex_unlock(); + dict_sys.unlock(); } } diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc index 6417994783280..2fcbf9b28e34f 100644 --- a/storage/innobase/fts/fts0opt.cc +++ b/storage/innobase/fts/fts0opt.cc @@ -1603,8 +1603,21 @@ fts_optimize_create( optim->fts_index_table.table = table; /* The common prefix for all this parent table's aux tables. */ - optim->name_prefix = fts_get_table_name_prefix( - &optim->fts_common_table); + char table_id[FTS_AUX_MIN_TABLE_ID_LENGTH]; + const size_t table_id_len = 1 + + size_t(fts_get_table_id(&optim->fts_common_table, table_id)); + dict_sys.freeze(SRW_LOCK_CALL); + /* Include the separator as well. */ + const size_t dbname_len = table->name.dblen() + 1; + ut_ad(dbname_len > 1); + const size_t prefix_name_len = dbname_len + 4 + table_id_len; + char* prefix_name = static_cast( + ut_malloc_nokey(prefix_name_len)); + memcpy(prefix_name, table->name.m_name, dbname_len); + dict_sys.unfreeze(); + memcpy(prefix_name + dbname_len, "FTS_", 4); + memcpy(prefix_name + dbname_len + 4, table_id, table_id_len); + optim->name_prefix =prefix_name; return(optim); } @@ -2589,7 +2602,6 @@ fts_optimize_remove_table( if (table->fts->in_queue) { - dict_sys.assert_not_locked(); fts_msg_t *msg= fts_optimize_create_msg(FTS_MSG_DEL_TABLE, nullptr); pthread_cond_t cond; pthread_cond_init(&cond, nullptr); @@ -2937,7 +2949,7 @@ fts_optimize_init(void) /* Add fts tables to fts_slots which could be skipped during dict_load_table_one() because fts_optimize_thread wasn't even started. */ - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); for (dict_table_t* table = UT_LIST_GET_FIRST(dict_sys.table_LRU); table != NULL; table = UT_LIST_GET_NEXT(table_LRU, table)) { @@ -2952,7 +2964,7 @@ fts_optimize_init(void) fts_optimize_new_table(table); table->fts->in_queue = true; } - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); pthread_cond_init(&fts_opt_shutdown_cond, nullptr); last_check_sync_time = time(NULL); @@ -2966,13 +2978,13 @@ fts_optimize_shutdown() /* If there is an ongoing activity on dictionary, such as srv_master_evict_from_table_cache(), wait for it */ - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); mysql_mutex_lock(&fts_optimize_wq->mutex); /* Tells FTS optimizer system that we are exiting from optimizer thread, message send their after will not be processed */ fts_opt_start_shutdown = true; - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); /* We tell the OPTIMIZE thread to switch to state done, we can't delete the work queue here because the add thread needs diff --git a/storage/innobase/fts/fts0sql.cc b/storage/innobase/fts/fts0sql.cc index 2d41776eb1228..1970f6f584feb 100644 --- a/storage/innobase/fts/fts0sql.cc +++ b/storage/innobase/fts/fts0sql.cc @@ -84,46 +84,23 @@ fts_get_table_id( return(len); } -/** Construct the name of an internal FTS table for the given table. -@param[in] fts_table metadata on fulltext-indexed table -@param[in] dict_locked whether dict_sys.mutex is being held -@return the prefix, must be freed with ut_free() */ -char* fts_get_table_name_prefix(const fts_table_t* fts_table) -{ - char table_id[FTS_AUX_MIN_TABLE_ID_LENGTH]; - const size_t table_id_len = size_t(fts_get_table_id(fts_table, - table_id)) + 1; - dict_sys.mutex_lock(); - /* Include the separator as well. */ - const size_t dbname_len = fts_table->table->name.dblen() + 1; - ut_ad(dbname_len > 1); - const size_t prefix_name_len = dbname_len + 4 + table_id_len; - char* prefix_name = static_cast( - ut_malloc_nokey(prefix_name_len)); - memcpy(prefix_name, fts_table->table->name.m_name, dbname_len); - dict_sys.mutex_unlock(); - memcpy(prefix_name + dbname_len, "FTS_", 4); - memcpy(prefix_name + dbname_len + 4, table_id, table_id_len); - return prefix_name; -} - /** Construct the name of an internal FTS table for the given table. @param[in] fts_table metadata on fulltext-indexed table @param[out] table_name a name up to MAX_FULL_NAME_LEN -@param[in] dict_locked whether dict_sys.mutex is being held */ +@param[in] dict_locked whether dict_sys.latch is being held */ void fts_get_table_name(const fts_table_t* fts_table, char* table_name, bool dict_locked) { if (!dict_locked) { - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); } - dict_sys.assert_locked(); + ut_ad(dict_sys.frozen()); /* Include the separator as well. */ const size_t dbname_len = fts_table->table->name.dblen() + 1; ut_ad(dbname_len > 1); memcpy(table_name, fts_table->table->name.m_name, dbname_len); if (!dict_locked) { - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); } memcpy(table_name += dbname_len, "FTS_", 4); table_name += 4; @@ -153,14 +130,14 @@ fts_parse_sql( if (!dict_locked) { /* The InnoDB SQL parser is not re-entrant. */ - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); } graph = pars_sql(info, str); ut_a(graph); if (!dict_locked) { - dict_sys.mutex_unlock(); + dict_sys.unlock(); } ut_free(str); @@ -168,30 +145,6 @@ fts_parse_sql( return(graph); } -/******************************************************************//** -Parse an SQL string. -@return query graph */ -que_t* -fts_parse_sql_no_dict_lock( -/*=======================*/ - pars_info_t* info, /*!< in: info struct, or NULL */ - const char* sql) /*!< in: SQL string to evaluate */ -{ - char* str; - que_t* graph; - - dict_sys.assert_locked(); - - str = ut_str3cat(fts_sql_begin, sql, fts_sql_end); - - graph = pars_sql(info, str); - ut_a(graph); - - ut_free(str); - - return(graph); -} - /******************************************************************//** Evaluate an SQL query graph. @return DB_SUCCESS or error code */ diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 1485e8aa0df29..0a57b847d14ee 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -503,7 +503,6 @@ static mysql_pfs_key_t pending_checkpoint_mutex_key; # ifdef UNIV_PFS_MUTEX mysql_pfs_key_t buf_pool_mutex_key; mysql_pfs_key_t dict_foreign_err_mutex_key; -mysql_pfs_key_t dict_sys_mutex_key; mysql_pfs_key_t fil_system_mutex_key; mysql_pfs_key_t flush_list_mutex_key; mysql_pfs_key_t fts_cache_mutex_key; @@ -545,7 +544,6 @@ static PSI_mutex_info all_innodb_mutexes[] = { PSI_KEY(pending_checkpoint_mutex), PSI_KEY(buf_pool_mutex), PSI_KEY(dict_foreign_err_mutex), - PSI_KEY(dict_sys_mutex), PSI_KEY(recalc_pool_mutex), PSI_KEY(fil_system_mutex), PSI_KEY(flush_list_mutex), @@ -5497,7 +5495,7 @@ is done when the table first opened. @param[in,out] s_templ InnoDB template structure @param[in] add_v new virtual columns added along with add index call -@param[in] locked true if dict_sys mutex is held */ +@param[in] locked true if dict_sys.latch is held */ void innobase_build_v_templ( const TABLE* table, @@ -5520,12 +5518,18 @@ innobase_build_v_templ( ut_ad(n_v_col > 0); if (!locked) { - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); } +#if 0 + /* This does not (need to) hold for ctx->new_table in + alter_rebuild_apply_log() */ + ut_ad(dict_sys.locked()); +#endif + if (s_templ->vtempl) { if (!locked) { - dict_sys.mutex_unlock(); + dict_sys.unlock(); } DBUG_VOID_RETURN; } @@ -5631,7 +5635,7 @@ innobase_build_v_templ( } if (!locked) { - dict_sys.mutex_unlock(); + dict_sys.unlock(); } s_templ->db_name = table->s->db.str; @@ -5919,7 +5923,7 @@ ha_innobase::open(const char* name, int, uint) key_used_on_scan = m_primary_key; if (ib_table->n_v_cols) { - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); if (ib_table->vc_templ == NULL) { ib_table->vc_templ = UT_NEW_NOKEY(dict_vcol_templ_t()); innobase_build_v_templ( @@ -5927,7 +5931,7 @@ ha_innobase::open(const char* name, int, uint) true); } - dict_sys.mutex_unlock(); + dict_sys.unlock(); } if (!check_index_consistency(table, ib_table)) { @@ -9853,7 +9857,7 @@ wsrep_append_foreign_key( foreign->referenced_table : foreign->foreign_table)) { WSREP_DEBUG("pulling %s table into cache", (referenced) ? "referenced" : "foreign"); - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); if (referenced) { foreign->referenced_table = @@ -9888,7 +9892,7 @@ wsrep_append_foreign_key( TRUE, FALSE); } } - dict_sys.mutex_unlock(); + dict_sys.unlock(); } if ( !((referenced) ? @@ -13016,9 +13020,9 @@ create_table_info_t::create_table_update_dict() DBUG_RETURN(-1); } - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); fts_optimize_add_table(innobase_table); - dict_sys.mutex_unlock(); + dict_sys.unlock(); } if (const Field* ai = m_form->found_next_number_field) { @@ -13277,12 +13281,12 @@ ha_innobase::discard_or_import_tablespace( btr_cur_instant_init(). */ table_id_t id = m_prebuilt->table->id; ut_ad(id); - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); dict_table_close(m_prebuilt->table, TRUE, FALSE); dict_sys.remove(m_prebuilt->table); m_prebuilt->table = dict_table_open_on_id(id, TRUE, DICT_TABLE_OP_NORMAL); - dict_sys.mutex_unlock(); + dict_sys.unlock(); if (!m_prebuilt->table) { err = DB_TABLE_NOT_FOUND; } else { @@ -13673,7 +13677,7 @@ int ha_innobase::truncate() } row_mysql_lock_data_dictionary(trx); - dict_stats_wait_bg_to_stop_using_table(ib_table, trx); + dict_stats_wait_bg_to_stop_using_table(ib_table); /* Wait for purge threads to stop using the table. */ for (uint n = 15; ib_table->get_ref_count() > 1; ) { if (!--n) { @@ -14303,8 +14307,6 @@ ha_innobase::info_low( DEBUG_SYNC_C("ha_innobase_info_low"); - dict_sys.assert_not_locked(); - /* If we are forcing recovery at a high level, we will suppress statistics calculation on tables, because that may crash the server if an index is badly corrupted. */ @@ -14335,13 +14337,11 @@ ha_innobase::info_low( if (dict_stats_is_persistent_enabled(ib_table)) { if (is_analyze) { - row_mysql_lock_data_dictionary( - m_prebuilt->trx); + dict_sys.lock(SRW_LOCK_CALL); dict_stats_recalc_pool_del(ib_table); dict_stats_wait_bg_to_stop_using_table( - ib_table, m_prebuilt->trx); - row_mysql_unlock_data_dictionary( - m_prebuilt->trx); + ib_table); + dict_sys.unlock(); opt = DICT_STATS_RECALC_PERSISTENT; } else { /* This is e.g. 'SHOW INDEXES', fetch @@ -14355,10 +14355,12 @@ ha_innobase::info_low( ret = dict_stats_update(ib_table, opt); if (opt == DICT_STATS_RECALC_PERSISTENT) { - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); + ib_table->stats_mutex_lock(); ib_table->stats_bg_flag &= byte(~BG_STAT_SHOULD_QUIT); - dict_sys.mutex_unlock(); + ib_table->stats_mutex_unlock(); + dict_sys.unfreeze(); } if (ret != DB_SUCCESS) { @@ -15160,10 +15162,7 @@ get_foreign_key_info( /* Load referenced table to update FK referenced key name. */ if (foreign->referenced_table == NULL) { - dict_table_t* ref_table; - - dict_sys.assert_locked(); - ref_table = dict_table_open_on_name( + dict_table_t* ref_table = dict_table_open_on_name( foreign->referenced_table_name_lookup, TRUE, FALSE, DICT_ERR_IGNORE_NONE); @@ -15217,7 +15216,7 @@ ha_innobase::get_foreign_key_list( m_prebuilt->trx->op_info = "getting list of foreign keys"; - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); for (dict_foreign_set::iterator it = m_prebuilt->table->foreign_set.begin(); @@ -15234,7 +15233,7 @@ ha_innobase::get_foreign_key_list( } } - dict_sys.mutex_unlock(); + dict_sys.unlock(); m_prebuilt->trx->op_info = ""; @@ -15255,7 +15254,7 @@ ha_innobase::get_parent_foreign_key_list( m_prebuilt->trx->op_info = "getting list of referencing foreign keys"; - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); for (dict_foreign_set::iterator it = m_prebuilt->table->referenced_set.begin(); @@ -15272,7 +15271,7 @@ ha_innobase::get_parent_foreign_key_list( } } - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); m_prebuilt->trx->op_info = ""; @@ -19803,9 +19802,8 @@ TABLE* innobase_init_vc_templ(dict_table_t* table) DBUG_RETURN(NULL); } - dict_sys.mutex_lock(); - innobase_build_v_templ(mysql_table, table, table->vc_templ, NULL, true); - dict_sys.mutex_unlock(); + innobase_build_v_templ(mysql_table, table, table->vc_templ, NULL, + false); DBUG_RETURN(mysql_table); } diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 97d56671fe967..e7b01a4f72be3 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -486,7 +486,7 @@ inline bool dict_table_t::instant_column(const dict_table_t& table, DBUG_ASSERT(table.n_cols + table.n_dropped() >= n_cols + n_dropped()); DBUG_ASSERT(!table.persistent_autoinc || persistent_autoinc == table.persistent_autoinc); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); { const char* end = table.col_names; @@ -731,7 +731,7 @@ inline void dict_table_t::rollback_instant( const char* old_v_col_names, const ulint* col_map) { - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); if (cols == old_cols) { /* Alter fails before instant operation happens. @@ -2639,7 +2639,7 @@ innobase_init_foreign( ulint referenced_num_field) /*!< in: number of referenced columns */ { - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); if (constraint_name) { ulint db_len; @@ -3043,7 +3043,7 @@ innobase_get_foreign_key_info( add_fk[num_fk] = dict_mem_foreign_create(); - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); referenced_table_name = dict_get_referenced_table( table->name.m_name, @@ -3059,11 +3059,9 @@ innobase_get_foreign_key_info( referenced_table = NULL;); if (!referenced_table && trx->check_foreigns) { - dict_sys.mutex_unlock(); my_error(ER_FK_CANNOT_OPEN_PARENT, MYF(0), fk_key->ref_table.str); - - goto err_exit; + goto err_exit_unlock; } if (fk_key->ref_columns.elements > 0) { @@ -3092,12 +3090,11 @@ innobase_get_foreign_key_info( /* Check whether there exist such index in the the index create clause */ if (!referenced_index) { - dict_sys.mutex_unlock(); my_error(ER_FK_NO_INDEX_PARENT, MYF(0), fk_key->name.str ? fk_key->name.str : "", fk_key->ref_table.str); - goto err_exit; + goto err_exit_unlock; } } else { ut_a(!trx->check_foreigns); @@ -3107,10 +3104,9 @@ innobase_get_foreign_key_info( } else { /* Not possible to add a foreign key without a referenced column */ - dict_sys.mutex_unlock(); my_error(ER_CANNOT_ADD_FOREIGN, MYF(0), fk_key->ref_table.str); - goto err_exit; + goto err_exit_unlock; } if (!innobase_init_foreign( @@ -3119,15 +3115,14 @@ innobase_get_foreign_key_info( num_col, referenced_table_name, referenced_table, referenced_index, referenced_column_names, referenced_num_col)) { - dict_sys.mutex_unlock(); my_error( ER_DUP_CONSTRAINT_NAME, MYF(0), "FOREIGN KEY", add_fk[num_fk]->id); - goto err_exit; + goto err_exit_unlock; } - dict_sys.mutex_unlock(); + dict_sys.unlock(); correct_option = innobase_set_foreign_key_option( add_fk[num_fk], fk_key); @@ -3158,6 +3153,8 @@ innobase_get_foreign_key_info( *n_add_fk = num_fk; DBUG_RETURN(true); +err_exit_unlock: + dict_sys.unlock(); err_exit: for (ulint i = 0; i <= num_fk; i++) { if (add_fk[i]) { @@ -4073,7 +4070,7 @@ online_retry_drop_indexes_low( dict_table_t* table, /*!< in/out: table */ trx_t* trx) /*!< in/out: transaction */ { - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); ut_ad(trx->dict_operation); @@ -4129,9 +4126,9 @@ online_retry_drop_indexes( trx->free(); } - ut_d(dict_sys.mutex_lock()); + ut_d(dict_sys.freeze(SRW_LOCK_CALL)); ut_d(dict_table_check_for_dup_indexes(table, CHECK_ALL_COMPLETE)); - ut_d(dict_sys.mutex_unlock()); + ut_d(dict_sys.unfreeze()); ut_ad(!table->drop_aborted); } @@ -4212,7 +4209,7 @@ innobase_check_foreigns_low( bool drop) { dict_foreign_t* foreign; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); /* Check if any FOREIGN KEY constraints are defined on this column. */ @@ -4811,7 +4808,7 @@ innobase_update_gis_column_type( DBUG_ASSERT(trx->dict_operation); ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); info = pars_info_create(); @@ -6327,7 +6324,7 @@ prepare_inplace_alter_table_dict( at least until checking ut_ad(user_table->n_ref_count == 1) below. XXX what may happen if bg stats opens the table after we have unlocked data dictionary below? */ - dict_stats_wait_bg_to_stop_using_table(user_table, ctx->trx); + dict_stats_wait_bg_to_stop_using_table(user_table); ut_d(stats_wait = true); online_retry_drop_indexes_low(ctx->new_table, ctx->trx); @@ -7056,7 +7053,7 @@ prepare_inplace_alter_table_dict( if (fts_index) { ut_ad(ctx->trx->dict_operation); ut_ad(ctx->trx->dict_operation_lock_mode == RW_X_LATCH); - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); DICT_TF2_FLAG_SET(ctx->new_table, DICT_TF2_FTS); if (ctx->need_rebuild()) { @@ -7342,7 +7339,7 @@ rename_index_try( trx_t* trx) { DBUG_ENTER("rename_index_try"); - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); pars_info_t* pinfo; @@ -7400,7 +7397,7 @@ void innobase_rename_index_cache(dict_index_t* index, const char* new_name) { DBUG_ENTER("innobase_rename_index_cache"); - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); size_t old_name_len = strlen(index->name); size_t new_name_len = strlen(new_name); @@ -7559,10 +7556,10 @@ ha_innobase::prepare_inplace_alter_table( } #endif /* UNIV_DEBUG */ - ut_d(dict_sys.mutex_lock()); + ut_d(dict_sys.freeze(SRW_LOCK_CALL)); ut_d(dict_table_check_for_dup_indexes( m_prebuilt->table, CHECK_ABORTED_OK)); - ut_d(dict_sys.mutex_unlock()); + ut_d(dict_sys.unfreeze()); if (!(ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE)) { /* Nothing to do */ @@ -8507,10 +8504,10 @@ ha_innobase::inplace_alter_table( KEY* dup_key; all_done: case DB_SUCCESS: - ut_d(dict_sys.mutex_lock()); + ut_d(dict_sys.freeze(SRW_LOCK_CALL)); ut_d(dict_table_check_for_dup_indexes( m_prebuilt->table, CHECK_PARTIAL_OK)); - ut_d(dict_sys.mutex_unlock()); + ut_d(dict_sys.unfreeze()); /* prebuilt->table->n_ref_count can be anything here, given that we hold at most a shared lock on the table. */ goto ok_exit; @@ -8571,7 +8568,7 @@ innobase_online_rebuild_log_free( dict_table_t* table) { dict_index_t* clust_index = dict_table_get_first_index(table); - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); clust_index->lock.x_lock(SRW_LOCK_CALL); if (clust_index->online_log) { @@ -8776,10 +8773,10 @@ inline bool rollback_inplace_alter_table(Alter_inplace_info *ha_alter_info, purge_sys.resume_FTS(); if (ctx->old_table->fts) { - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); ut_ad(fts_check_cached_index(ctx->old_table)); fts_optimize_add_table(ctx->old_table); - dict_sys.mutex_unlock(); + dict_sys.unlock(); } goto free_and_exit; } @@ -8850,7 +8847,7 @@ innobase_drop_foreign_try( DBUG_ASSERT(trx->dict_operation); ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); /* Drop the constraint from the data dictionary. */ static const char sql[] = @@ -8906,7 +8903,7 @@ innobase_rename_column_try( DBUG_ASSERT(trx->dict_operation); ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); if (ctx.need_rebuild()) { goto rename_foreign; @@ -9224,7 +9221,7 @@ innobase_rename_or_enlarge_column_try( DBUG_ASSERT(trx->dict_operation); ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); ulint n_base; @@ -9650,7 +9647,7 @@ innobase_update_foreign_cache( DBUG_ENTER("innobase_update_foreign_cache"); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); user_table = ctx->old_table; @@ -10958,7 +10955,7 @@ ha_innobase::commit_inplace_alter_table( break; } - DICT_BG_YIELD(trx); + DICT_BG_YIELD; } /* Apply the changes to the data dictionary tables, for all diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index a84d8266b092e..ae9aa95339eb8 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -1335,12 +1335,12 @@ i_s_cmp_per_index_fill_low( RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); /* Create a snapshot of the stats so we do not bump into lock - order violations with dict_sys.mutex below. */ + order violations with dict_sys.latch below. */ mysql_mutex_lock(&page_zip_stat_per_index_mutex); page_zip_stat_per_index_t snap (page_zip_stat_per_index); mysql_mutex_unlock(&page_zip_stat_per_index_mutex); - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); page_zip_stat_per_index_t::iterator iter; ulint i; @@ -1393,18 +1393,18 @@ i_s_cmp_per_index_fill_low( status = 1; break; } - /* Release and reacquire the dict mutex to allow other + /* Release and reacquire the dict_sys.latch to allow other threads to proceed. This could eventually result in the contents of INFORMATION_SCHEMA.innodb_cmp_per_index being inconsistent, but it is an acceptable compromise. */ if (i == 1000) { - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); i = 0; - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); } } - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); if (reset) { page_zip_reset_stat_per_index(); @@ -3973,7 +3973,7 @@ i_s_innodb_buffer_page_fill( if (page_info->page_type == I_S_PAGE_TYPE_INDEX) { bool ret = false; - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); const dict_index_t* index = dict_index_get_if_in_cache_low( @@ -3998,7 +3998,7 @@ i_s_innodb_buffer_page_fill( system_charset_info); } - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); OK(ret); @@ -4476,7 +4476,7 @@ i_s_innodb_buf_page_lru_fill( if (page_info->page_type == I_S_PAGE_TYPE_INDEX) { bool ret = false; - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); const dict_index_t* index = dict_index_get_if_in_cache_low( @@ -4501,7 +4501,7 @@ i_s_innodb_buf_page_lru_fill( system_charset_info); } - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); OK(ret); @@ -4854,8 +4854,8 @@ i_s_sys_tables_fill_table( DBUG_RETURN(0); } - dict_sys.mutex_lock(); - mtr_start(&mtr); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); for (const rec_t *rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_tables); @@ -4871,7 +4871,7 @@ i_s_sys_tables_fill_table( information from SYS_TABLES row */ err_msg = i_s_sys_tables_rec(pcur, rec, &table_rec); mtr.commit(); - dict_sys.mutex_unlock(); + dict_sys.unlock(); if (!err_msg) { i_s_dict_fill_sys_tables(thd, table_rec, @@ -4887,12 +4887,12 @@ i_s_sys_tables_fill_table( } /* Get the next record */ - dict_sys.mutex_lock(); mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); } mtr.commit(); - dict_sys.mutex_unlock(); + dict_sys.unlock(); DBUG_RETURN(0); } @@ -5129,7 +5129,6 @@ i_s_sys_tables_fill_table_stats( /* Get the next record */ mtr.start(); dict_sys.lock(SRW_LOCK_CALL); - if (table_rec) { dict_sys.allow_eviction(table_rec); } @@ -5331,7 +5330,7 @@ i_s_sys_indexes_fill_table( } heap = mem_heap_create(1000); - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); mtr_start(&mtr); /* Start scan the SYS_INDEXES table */ @@ -5352,8 +5351,8 @@ i_s_sys_indexes_fill_table( rec, DICT_FLD__SYS_INDEXES__SPACE, &space_id); space_id = space_id == 4 ? mach_read_from_4(field) : ULINT_UNDEFINED; - mtr_commit(&mtr); - dict_sys.mutex_unlock(); + mtr.commit(); + dict_sys.unlock(); if (!err_msg) { if (int err = i_s_dict_fill_sys_indexes( @@ -5371,13 +5370,13 @@ i_s_sys_indexes_fill_table( mem_heap_empty(heap); /* Get the next record */ - dict_sys.mutex_lock(); - mtr_start(&mtr); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); rec = dict_getnext_system(&pcur, &mtr); } - mtr_commit(&mtr); - dict_sys.mutex_unlock(); + mtr.commit(); + dict_sys.unlock(); mem_heap_free(heap); DBUG_RETURN(0); @@ -5550,8 +5549,8 @@ i_s_sys_columns_fill_table( } heap = mem_heap_create(1000); - dict_sys.mutex_lock(); - mtr_start(&mtr); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_columns); @@ -5567,8 +5566,8 @@ i_s_sys_columns_fill_table( &table_id, &col_name, &nth_v_col); - mtr_commit(&mtr); - dict_sys.mutex_unlock(); + mtr.commit(); + dict_sys.unlock(); if (!err_msg) { i_s_dict_fill_sys_columns(thd, table_id, col_name, @@ -5583,17 +5582,18 @@ i_s_sys_columns_fill_table( mem_heap_empty(heap); /* Get the next record */ - dict_sys.mutex_lock(); - mtr_start(&mtr); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); rec = dict_getnext_system(&pcur, &mtr); } - mtr_commit(&mtr); - dict_sys.mutex_unlock(); + mtr.commit(); + dict_sys.unlock(); mem_heap_free(heap); DBUG_RETURN(0); } + /*******************************************************************//** Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_columns @return 0 on success */ @@ -5743,8 +5743,8 @@ i_s_sys_virtual_fill_table( DBUG_RETURN(0); } - dict_sys.mutex_lock(); - mtr_start(&mtr); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_virtual); @@ -5758,8 +5758,8 @@ i_s_sys_virtual_fill_table( &table_id, &pos, &base_pos); - mtr_commit(&mtr); - dict_sys.mutex_unlock(); + mtr.commit(); + dict_sys.unlock(); if (!err_msg) { i_s_dict_fill_sys_virtual(thd, table_id, pos, base_pos, @@ -5771,13 +5771,13 @@ i_s_sys_virtual_fill_table( } /* Get the next record */ - dict_sys.mutex_lock(); - mtr_start(&mtr); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); rec = dict_getnext_system(&pcur, &mtr); } - mtr_commit(&mtr); - dict_sys.mutex_unlock(); + mtr.commit(); + dict_sys.unlock(); DBUG_RETURN(0); } @@ -5929,13 +5929,13 @@ i_s_sys_fields_fill_table( } heap = mem_heap_create(1000); - dict_sys.mutex_lock(); - mtr_start(&mtr); + mtr.start(); /* will save last index id so that we know whether we move to the next index. This is used to calculate prefix length */ last_id = 0; + dict_sys.lock(SRW_LOCK_CALL); rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_fields); while (rec) { @@ -5949,8 +5949,8 @@ i_s_sys_fields_fill_table( err_msg = dict_process_sys_fields_rec(heap, rec, &field_rec, &pos, &index_id, last_id); - mtr_commit(&mtr); - dict_sys.mutex_unlock(); + mtr.commit(); + dict_sys.unlock(); if (!err_msg) { i_s_dict_fill_sys_fields(thd, index_id, &field_rec, @@ -5965,13 +5965,13 @@ i_s_sys_fields_fill_table( mem_heap_empty(heap); /* Get the next record */ - dict_sys.mutex_lock(); - mtr_start(&mtr); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); rec = dict_getnext_system(&pcur, &mtr); } - mtr_commit(&mtr); - dict_sys.mutex_unlock(); + mtr.commit(); + dict_sys.unlock(); mem_heap_free(heap); DBUG_RETURN(0); @@ -6132,8 +6132,8 @@ i_s_sys_foreign_fill_table( } heap = mem_heap_create(1000); - dict_sys.mutex_lock(); - mtr_start(&mtr); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_foreign); @@ -6145,8 +6145,8 @@ i_s_sys_foreign_fill_table( a SYS_FOREIGN row */ err_msg = dict_process_sys_foreign_rec(heap, rec, &foreign_rec); - mtr_commit(&mtr); - dict_sys.mutex_unlock(); + mtr.commit(); + dict_sys.unlock(); if (!err_msg) { i_s_dict_fill_sys_foreign(thd, &foreign_rec, @@ -6160,13 +6160,13 @@ i_s_sys_foreign_fill_table( mem_heap_empty(heap); /* Get the next record */ - mtr_start(&mtr); - dict_sys.mutex_lock(); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); rec = dict_getnext_system(&pcur, &mtr); } - mtr_commit(&mtr); - dict_sys.mutex_unlock(); + mtr.commit(); + dict_sys.unlock(); mem_heap_free(heap); DBUG_RETURN(0); @@ -6325,8 +6325,8 @@ i_s_sys_foreign_cols_fill_table( } heap = mem_heap_create(1000); - dict_sys.mutex_lock(); - mtr_start(&mtr); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_foreign_cols); @@ -6341,8 +6341,8 @@ i_s_sys_foreign_cols_fill_table( err_msg = dict_process_sys_foreign_col_rec( heap, rec, &name, &for_col_name, &ref_col_name, &pos); - mtr_commit(&mtr); - dict_sys.mutex_unlock(); + mtr.commit(); + dict_sys.unlock(); if (!err_msg) { i_s_dict_fill_sys_foreign_cols( @@ -6357,13 +6357,13 @@ i_s_sys_foreign_cols_fill_table( mem_heap_empty(heap); /* Get the next record */ - dict_sys.mutex_lock(); - mtr_start(&mtr); + mtr.start(); + dict_sys.lock(SRW_LOCK_CALL); rec = dict_getnext_system(&pcur, &mtr); } - mtr_commit(&mtr); - dict_sys.mutex_unlock(); + mtr.commit(); + dict_sys.unlock(); mem_heap_free(heap); DBUG_RETURN(0); diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 6f5d2377b07a4..1842650f1f62f 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -934,8 +934,8 @@ dict_table_copy_types( const dict_table_t* table) /*!< in: table */ MY_ATTRIBUTE((nonnull)); /**********************************************************************//** -Looks for an index with the given id. NOTE that we do not reserve -the dictionary mutex: this function is for emergency purposes like +Looks for an index with the given id. NOTE that we do not acquire +dict_sys.latch: this function is for emergency purposes like printing info of a corrupt database page! @return index or NULL if not found from cache */ dict_index_t* @@ -1146,7 +1146,6 @@ dict_field_get_col( /**********************************************************************//** Returns an index object if it is found in the dictionary cache. -Assumes that dict_sys.mutex is already being held. @return index, NULL if not found */ dict_index_t* dict_index_get_if_in_cache_low( @@ -1352,13 +1351,12 @@ extern mysql_mutex_t dict_foreign_err_mutex; /** InnoDB data dictionary cache */ class dict_sys_t { - /** The my_hrtime_coarse().val of the oldest mutex_lock_wait() start, or 0 */ - std::atomic mutex_wait_start; + /** The my_hrtime_coarse().val of the oldest lock_wait() start, or 0 */ + std::atomic latch_ex_wait_start; /** @brief the data dictionary rw-latch protecting dict_sys - Table create, drop, etc. reserve this in X-mode (along with - acquiring dict_sys.mutex); implicit or + Table create, drop, etc. reserve this in X-mode; implicit or backround operations that are not fully covered by MDL (rollback, foreign key checks) reserve this in S-mode. @@ -1368,11 +1366,9 @@ class dict_sys_t #ifdef UNIV_DEBUG /** whether latch is being held in exclusive mode (by any thread) */ bool latch_ex; + /** number of S-latch holders */ + Atomic_counter latch_readers; #endif - /** Mutex protecting dict_sys. Whenever latch is acquired - exclusively, also the mutex will be acquired. - FIXME: merge the mutex and the latch, once MDEV-23484 has been fixed */ - mysql_mutex_t mutex; public: /** Indexes of SYS_TABLE[] */ enum @@ -1429,7 +1425,7 @@ class dict_sys_t /** The synchronization interval of row_id */ static constexpr size_t ROW_ID_WRITE_MARGIN= 256; public: - /** Diagnostic message for exceeding the mutex_lock_wait() timeout */ + /** Diagnostic message for exceeding the lock_wait() timeout */ static const char fatal_msg[]; /** @return A new value for GEN_CLUST_INDEX(DB_ROW_ID) */ @@ -1457,7 +1453,7 @@ class dict_sys_t (should only happen during the rollback of CREATE...SELECT) */ dict_table_t *acquire_temporary_table(table_id_t id) { - mysql_mutex_assert_owner(&mutex); + ut_ad(frozen()); dict_table_t *table; ulint fold = ut_fold_ull(id); HASH_SEARCH(id_hash, &temp_id_hash, fold, dict_table_t*, table, @@ -1477,7 +1473,7 @@ class dict_sys_t @retval nullptr if not cached */ dict_table_t *find_table(table_id_t id) { - mysql_mutex_assert_owner(&mutex); + ut_ad(frozen()); dict_table_t *table; ulint fold= ut_fold_ull(id); HASH_SEARCH(id_hash, &table_id_hash, fold, dict_table_t*, table, @@ -1511,7 +1507,7 @@ class dict_sys_t { ut_ad(table); ut_ad(table->can_be_evicted == in_lru); - mysql_mutex_assert_owner(&mutex); + ut_ad(frozen()); for (const dict_table_t* t= in_lru ? table_LRU.start : table_non_LRU.start; t; t = UT_LIST_GET_NEXT(table_LRU, t)) { @@ -1531,6 +1527,7 @@ class dict_sys_t @return whether the table was evictable */ bool prevent_eviction(dict_table_t *table) { + ut_d(locked()); ut_ad(find(table)); if (!table->can_be_evicted) return false; @@ -1542,56 +1539,78 @@ class dict_sys_t /** Move a table from the non-LRU list to the LRU list. */ void allow_eviction(dict_table_t *table) { + ut_d(locked()); ut_ad(find(table)); ut_ad(!table->can_be_evicted); table->can_be_evicted= true; UT_LIST_REMOVE(table_non_LRU, table); - UT_LIST_ADD_LAST(table_LRU, table); + UT_LIST_ADD_FIRST(table_LRU, table); } - /** Acquire a reference to a cached table. */ - inline void acquire(dict_table_t *table); - - /** Assert that the mutex is locked */ - void assert_locked() const { mysql_mutex_assert_owner(&mutex); } - /** Assert that the mutex is not locked */ - void assert_not_locked() const { mysql_mutex_assert_not_owner(&mutex); } -#ifdef SAFE_MUTEX - bool mutex_is_locked() const { return mysql_mutex_is_owner(&mutex); } +#ifdef UNIV_DEBUG + /** @return whether any thread (not necessarily the current thread) + is holding the latch; that is, this check may return false + positives */ + bool frozen() const { return latch_readers || locked(); } + /** @return whether any thread (not necessarily the current thread) + is holding the exclusive latch; that is, this check may return false + positives */ + bool locked() const { return latch_ex; } #endif private: - /** Acquire the mutex */ - ATTRIBUTE_NOINLINE void mutex_lock_wait(); + /** Acquire the exclusive latch */ + ATTRIBUTE_NOINLINE + void lock_wait(SRW_LOCK_ARGS(const char *file, unsigned line)); public: - /** @return the my_hrtime_coarse().val of the oldest mutex_lock_wait() start, + /** @return the my_hrtime_coarse().val of the oldest lock_wait() start, assuming that requests are served on a FIFO basis */ ulonglong oldest_wait() const - { return mutex_wait_start.load(std::memory_order_relaxed); } + { return latch_ex_wait_start.load(std::memory_order_relaxed); } -#ifdef HAVE_PSI_MUTEX_INTERFACE - /** Acquire the mutex */ - ATTRIBUTE_NOINLINE void mutex_lock(); - /** Release the mutex */ - ATTRIBUTE_NOINLINE void mutex_unlock(); -#else - /** Acquire the mutex */ - void mutex_lock() { if (mysql_mutex_trylock(&mutex)) mutex_lock_wait(); } - - /** Release the mutex */ - void mutex_unlock() { mysql_mutex_unlock(&mutex); } -#endif - - /** Lock the data dictionary cache. */ - void lock(SRW_LOCK_ARGS(const char *file, unsigned line)); + /** Exclusively lock the dictionary cache. */ + void lock(SRW_LOCK_ARGS(const char *file, unsigned line)) + { + if (latch.wr_lock_try()) + { + ut_ad(!latch_readers); + ut_ad(!latch_ex); + ut_d(latch_ex= true); + } + else + lock_wait(SRW_LOCK_ARGS(file, line)); + } +#ifdef UNIV_PFS_RWLOCK + /** Unlock the data dictionary cache. */ + ATTRIBUTE_NOINLINE void unlock(); + /** Acquire a shared lock on the dictionary cache. */ + ATTRIBUTE_NOINLINE void freeze(const char *file, unsigned line); + /** Release a shared lock on the dictionary cache. */ + ATTRIBUTE_NOINLINE void unfreeze(); +#else /** Unlock the data dictionary cache. */ void unlock() { ut_ad(latch_ex); + ut_ad(!latch_readers); ut_d(latch_ex= false); - mutex_unlock(); latch.wr_unlock(); } + /** Acquire a shared lock on the dictionary cache. */ + void freeze() + { + latch.rd_lock(); + ut_ad(!latch_ex); + ut_d(latch_readers++); + } + /** Release a shared lock on the dictionary cache. */ + void unfreeze() + { + ut_ad(!latch_ex); + ut_ad(latch_readers--); + latch.rd_unlock(); + } +#endif /** Estimate the used memory occupied by the data dictionary table and index objects. @@ -1621,7 +1640,7 @@ class dict_sys_t @retval nullptr if not found */ dict_table_t *find_table(const span &name) const { - assert_locked(); + ut_ad(frozen()); for (dict_table_t *table= static_cast (HASH_GET_FIRST(&table_hash, table_hash.calc_hash (my_crc32c(0, name.data(), name.size())))); @@ -1650,9 +1669,6 @@ class dict_sys_t /** the data dictionary cache */ extern dict_sys_t dict_sys; -#define dict_sys_lock() dict_sys.lock(SRW_LOCK_CALL) -#define dict_sys_unlock() dict_sys.unlock() - /*********************************************************************//** Converts a database and table name from filesystem encoding (e.g. d@i1b/a@q1b@1Kc, same format as used in dict_table_t::name) in two diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic index a494eefdc3260..a98ca38d9b31e 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2020, MariaDB Corporation. +Copyright (c) 2013, 2021, 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 @@ -1141,7 +1141,7 @@ dict_table_is_file_per_table( /** Acquire the table handle. */ inline void dict_table_t::acquire() { - dict_sys.assert_locked(); + ut_ad(dict_sys.frozen()); n_ref_count++; } diff --git a/storage/innobase/include/dict0load.h b/storage/innobase/include/dict0load.h index 591dd30f2115e..072773694a9d7 100644 --- a/storage/innobase/include/dict0load.h +++ b/storage/innobase/include/dict0load.h @@ -53,12 +53,9 @@ We also scan the biggest space id, and store it to fil_system. */ void dict_check_tablespaces_and_store_max_id(); /** Make sure the data_file_name is saved in dict_table_t if needed. -@param[in] table Table object -@param[in] dict_mutex_own true if dict_sys.mutex is owned already */ -void -dict_get_and_save_data_dir_path( - dict_table_t* table, - bool dict_mutex_own); +@param[in,out] table Table object +@param[in] dict_locked dict_sys.frozen() */ +void dict_get_and_save_data_dir_path(dict_table_t* table, bool dict_locked); /***********************************************************************//** Loads a table object based on the table id. diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 82bb2b29b65b7..45747c255654c 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -1026,8 +1026,7 @@ struct dict_index_t { /*!< enum online_index_status. Transitions from ONLINE_INDEX_COMPLETE (to ONLINE_INDEX_CREATION) are protected - by dict_sys.latch and - dict_sys.mutex. Other changes are + by dict_sys.latch. Other changes are protected by index->lock. */ unsigned uncommitted:1; /*!< a flag that is set for secondary indexes @@ -1935,7 +1934,7 @@ struct dict_table_t { inline size_t get_overflow_field_local_len() const; /** Parse the table file name into table name and database name. - @tparam dict_locked whether dict_sys.mutex is being held + @tparam dict_locked whether dict_sys.lock() was called @param[in,out] db_name database name buffer @param[in,out] tbl_name table name buffer @param[out] db_name_len database name length @@ -2178,7 +2177,7 @@ struct dict_table_t { dict_foreign_set referenced_set; /** Statistics for query optimization. Mostly protected by - dict_sys.mutex. @{ */ + dict_sys.latch and stats_mutex_lock(). @{ */ /** TRUE if statistics have been calculated the first time after database startup or table creation. */ @@ -2260,7 +2259,7 @@ struct dict_table_t { /** The state of the background stats thread wrt this table. See BG_STAT_NONE, BG_STAT_IN_PROGRESS and BG_STAT_SHOULD_QUIT. - Writes are covered by dict_sys.mutex. Dirty reads are possible. */ + Writes are covered by dict_sys.latch and stats_mutex_lock(). */ byte stats_bg_flag; bool stats_error_printed; diff --git a/storage/innobase/include/dict0stats.ic b/storage/innobase/include/dict0stats.ic index 6859240425331..e49153eb099cf 100644 --- a/storage/innobase/include/dict0stats.ic +++ b/storage/innobase/include/dict0stats.ic @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, 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 @@ -75,7 +75,7 @@ dict_stats_is_persistent_enabled(const dict_table_t* table) + dict_stats_update(DICT_STATS_RECALC_TRANSIENT) on a table that has just been PS-enabled. This is acceptable. Avoiding this would mean that we would have to - protect the stat_persistent with dict_sys.mutex like the + hold dict_sys.latch or stats_mutex_lock() like for accessing the other ::stat_ members which would be too big performance penalty, especially when this function is called from dict_stats_update_if_needed(). */ diff --git a/storage/innobase/include/dict0stats_bg.h b/storage/innobase/include/dict0stats_bg.h index e9318a0116db3..0d5982b231af0 100644 --- a/storage/innobase/include/dict0stats_bg.h +++ b/storage/innobase/include/dict0stats_bg.h @@ -50,10 +50,10 @@ dict_stats_recalc_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_BG_YIELD(trx) do { \ - row_mysql_unlock_data_dictionary(trx); \ +#define DICT_BG_YIELD do { \ + dict_sys.unlock(); \ std::this_thread::sleep_for(std::chrono::milliseconds(250)); \ - row_mysql_lock_data_dictionary(trx); \ + dict_sys.lock(SRW_LOCK_CALL); \ } while (0) /*****************************************************************//** @@ -67,31 +67,27 @@ dict_stats_stop_bg( dict_table_t* table) /*!< in/out: table */ { ut_ad(!srv_read_only_mode); - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); if (!(table->stats_bg_flag & BG_STAT_IN_PROGRESS)) { return(true); } + /* In dict_stats_update_persistent() this flag is being read + while holding the mutex, not dict_sys.latch. */ + table->stats_mutex_lock(); table->stats_bg_flag |= BG_STAT_SHOULD_QUIT; + table->stats_mutex_unlock(); return(false); } /*****************************************************************//** Wait until background stats thread has stopped using the specified table. -The caller must have locked the data dictionary using -row_mysql_lock_data_dictionary() and this function may unlock it temporarily -and restore the lock before it exits. The background stats thread is guaranteed not to start using the specified -table after this function returns and before the caller unlocks the data -dictionary because it sets the BG_STAT_IN_PROGRESS bit in table->stats_bg_flag -under dict_sys.mutex. */ -void -dict_stats_wait_bg_to_stop_using_table( -/*===================================*/ - dict_table_t* table, /*!< in/out: table */ - trx_t* trx); /*!< in/out: transaction to use for - unlocking/locking the data dict */ +table after this function returns and before the caller releases +dict_sys.latch. */ +void dict_stats_wait_bg_to_stop_using_table(dict_table_t *table); + /*****************************************************************//** Initialize global variables needed for the operation of dict_stats_thread(). Must be called before dict_stats task is started. */ diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index 9fd0b076520d0..445a80853208c 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -1660,7 +1660,7 @@ right in it. If does not succeed, prints an error message to the .err log. This function is used to open a tablespace when we start up mysqld, and also in IMPORT TABLESPACE. NOTE that we assume this operation is used either at the database startup -or under the protection of the dictionary mutex, so that two users cannot +or under the protection of dict_sys.latch, so that two users cannot race here. This operation does not leave the file associated with the tablespace open, but closes it after we have looked at the space id in it. diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h index 95b5131a526f2..0fb01dd850ee7 100644 --- a/storage/innobase/include/fts0fts.h +++ b/storage/innobase/include/fts0fts.h @@ -318,7 +318,7 @@ class fts_t { /** Whether the ADDED table record sync-ed after crash recovery */ unsigned added_synced:1; - /** Whether the table holds dict_sys.mutex */ + /** Whether the table holds dict_sys.latch */ unsigned dict_locked:1; /** Work queue for scheduling jobs for the FTS 'Add' thread, or NULL @@ -741,7 +741,7 @@ FTS auxiliary INDEX table and clear the cache at the end. dberr_t fts_sync_table(dict_table_t* table, bool wait = true); /****************************************************************//** -Free the query graph but check whether dict_sys.mutex is already +Free the query graph but check whether dict_sys.latch is already held */ void fts_que_graph_free_check_lock( diff --git a/storage/innobase/include/fts0priv.h b/storage/innobase/include/fts0priv.h index fbe2acdc712a0..a8647b4dd1d31 100644 --- a/storage/innobase/include/fts0priv.h +++ b/storage/innobase/include/fts0priv.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, 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 @@ -135,7 +135,7 @@ fts_eval_sql( /** Construct the name of an internal FTS table for the given table. @param[in] fts_table metadata on fulltext-indexed table @param[out] table_name a name up to MAX_FULL_NAME_LEN -@param[in] dict_locked whether dict_sys.mutex is being held */ +@param[in] dict_locked whether dict_sys.latch is being held */ void fts_get_table_name(const fts_table_t* fts_table, char* table_name, bool dict_locked = false) MY_ATTRIBUTE((nonnull)); @@ -295,16 +295,6 @@ fts_trx_table_id_cmp( #define fts_sql_commit(trx) trx_commit_for_mysql(trx) #define fts_sql_rollback(trx) (trx)->rollback() /******************************************************************//** -Parse an SQL string. %s is replaced with the table's id. Don't acquire -the dict mutex -@return query graph */ -que_t* -fts_parse_sql_no_dict_lock( -/*=======================*/ - pars_info_t* info, /*!< in: parser info */ - const char* sql) /*!< in: SQL string to evaluate */ - MY_ATTRIBUTE((nonnull(2), malloc, warn_unused_result)); -/******************************************************************//** Get value from config table. The caller must ensure that enough space is allocated for value to hold the column contents @return DB_SUCCESS or error code */ @@ -469,12 +459,6 @@ fts_get_table_id( FTS_AUX_MIN_TABLE_ID_LENGTH bytes long */ MY_ATTRIBUTE((nonnull, warn_unused_result)); -/** Construct the name of an internal FTS table for the given table. -@param[in] fts_table metadata on fulltext-indexed table -@param[in] dict_locked whether dict_sys.mutex is being held -@return the prefix, must be freed with ut_free() */ -char* fts_get_table_name_prefix(const fts_table_t* fts_table) - MY_ATTRIBUTE((nonnull, malloc, warn_unused_result)); /******************************************************************//** Add node positions. */ void diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h index ca792f9e43989..a651a56e8a0c8 100644 --- a/storage/innobase/include/log0log.h +++ b/storage/innobase/include/log0log.h @@ -77,7 +77,7 @@ log_reserve_and_write_fast( Checks if there is need for a log buffer flush or a new checkpoint, and does this if yes. Any database operation should call this when it has modified more than about 4 pages. NOTE that this function may only be called when the -OS thread owns no synchronization objects except the dictionary mutex. */ +OS thread owns no synchronization objects except dict_sys.latch. */ UNIV_INLINE void log_free_check(void); diff --git a/storage/innobase/include/log0log.ic b/storage/innobase/include/log0log.ic index aebe511d659d6..c29c0bfa55feb 100644 --- a/storage/innobase/include/log0log.ic +++ b/storage/innobase/include/log0log.ic @@ -294,7 +294,7 @@ log_reserve_and_write_fast( Checks if there is need for a log buffer flush or a new checkpoint, and does this if yes. Any database operation should call this when it has modified more than about 4 pages. NOTE that this function may only be called when the -OS thread owns no synchronization objects except the dictionary mutex. */ +OS thread owns no synchronization objects except dict_sys.latch. */ UNIV_INLINE void log_free_check(void) diff --git a/storage/innobase/include/que0que.h b/storage/innobase/include/que0que.h index 1a30ea45194ab..d81c77e3d36bf 100644 --- a/storage/innobase/include/que0que.h +++ b/storage/innobase/include/que0que.h @@ -207,9 +207,9 @@ que_eval_sql( /*=========*/ pars_info_t* info, /*!< in: info struct, or NULL */ const char* sql, /*!< in: SQL string */ - bool reserve_dict_mutex, + bool lock_dict, /*!< in: whether to acquire/release - dict_sys.mutex around call to pars_sql. */ + dict_sys.latch around call to pars_sql(). */ trx_t* trx); /*!< in: trx */ /**********************************************************************//** diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index eb32e91298d66..88f0b2d185be0 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -537,7 +537,6 @@ typedef unsigned int mysql_pfs_key_t; # ifdef UNIV_PFS_MUTEX extern mysql_pfs_key_t buf_pool_mutex_key; extern mysql_pfs_key_t dict_foreign_err_mutex_key; -extern mysql_pfs_key_t dict_sys_mutex_key; extern mysql_pfs_key_t fil_system_mutex_key; extern mysql_pfs_key_t flush_list_mutex_key; extern mysql_pfs_key_t fts_cache_mutex_key; diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index dccad0f3442da..f3f5ce4237268 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -3846,7 +3846,7 @@ void lock_release(trx_t *trx) #if defined SAFE_MUTEX && defined UNIV_DEBUG if (to_evict.empty()) return; - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); LockMutexGuard g{SRW_LOCK_CALL}; for (const table_id_t id : to_evict) { @@ -3854,7 +3854,7 @@ void lock_release(trx_t *trx) if (!table->get_ref_count() && !UT_LIST_GET_LEN(table->locks)) dict_sys.remove(table, true); } - dict_sys.mutex_unlock(); + dict_sys.unlock(); #endif } diff --git a/storage/innobase/pars/pars0pars.cc b/storage/innobase/pars/pars0pars.cc index 74c33b0cd9cf0..d49e5668aa13b 100644 --- a/storage/innobase/pars/pars0pars.cc +++ b/storage/innobase/pars/pars0pars.cc @@ -1973,7 +1973,7 @@ pars_sql( heap = mem_heap_create(16000); /* Currently, the parser is not reentrant: */ - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); pars_sym_tab_global = sym_tab_create(heap); diff --git a/storage/innobase/pars/pars0sym.cc b/storage/innobase/pars/pars0sym.cc index b65021a375aab..d68e352e795bb 100644 --- a/storage/innobase/pars/pars0sym.cc +++ b/storage/innobase/pars/pars0sym.cc @@ -67,7 +67,7 @@ sym_tab_free_private( sym_node_t* sym; func_node_t* func; - dict_sys.assert_locked(); + ut_ad(dict_sys.locked()); for (sym = UT_LIST_GET_FIRST(sym_tab->sym_list); sym != NULL; diff --git a/storage/innobase/que/que0que.cc b/storage/innobase/que/que0que.cc index d97466a92194c..074f8c54e2413 100644 --- a/storage/innobase/que/que0que.cc +++ b/storage/innobase/que/que0que.cc @@ -748,9 +748,9 @@ que_eval_sql( /*=========*/ pars_info_t* info, /*!< in: info struct, or NULL */ const char* sql, /*!< in: SQL string */ - bool reserve_dict_mutex, + bool lock_dict, /*!< in: whether to acquire/release - dict_sys.mutex around call to pars_sql. */ + dict_sys.latch around call to pars_sql(). */ trx_t* trx) /*!< in: trx */ { que_thr_t* thr; @@ -761,14 +761,14 @@ que_eval_sql( ut_a(trx->error_state == DB_SUCCESS); - if (reserve_dict_mutex) { - dict_sys.mutex_lock(); + if (lock_dict) { + dict_sys.lock(SRW_LOCK_CALL); } graph = pars_sql(info, sql); - if (reserve_dict_mutex) { - dict_sys.mutex_unlock(); + if (lock_dict) { + dict_sys.unlock(); } graph->trx = trx; @@ -778,14 +778,14 @@ que_eval_sql( que_run_threads(thr); - if (reserve_dict_mutex) { - dict_sys.mutex_lock(); + if (lock_dict) { + dict_sys.lock(SRW_LOCK_CALL); } que_graph_free(graph); - if (reserve_dict_mutex) { - dict_sys.mutex_unlock(); + if (lock_dict) { + dict_sys.unlock(); } DBUG_RETURN(trx->error_state); diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 710e1910d1bdc..0d380405e5d86 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -1446,8 +1446,6 @@ row_import::set_root_by_heuristic() UNIV_NOTHROW " the tablespace has " << m_n_indexes << " indexes"; } - dict_sys.mutex_lock(); - ulint i = 0; dberr_t err = DB_SUCCESS; @@ -1487,8 +1485,6 @@ row_import::set_root_by_heuristic() UNIV_NOTHROW } } - dict_sys.mutex_unlock(); - return(err); } @@ -4211,8 +4207,6 @@ row_import_for_mysql( } /* Open the tablespace so that we can access via the buffer pool. - We set the 2nd param (fix_dict = true) here because we already - have locked dict_sys.latch and dict_sys.mutex. The tablespace is initially opened as a temporary one, because we will not be writing any redo log for it before we have invoked fil_space_t::set_imported() to declare it a persistent tablespace. */ diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 3d1f07093fd66..eb5a3cc91b82f 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -3040,9 +3040,7 @@ row_ins_sec_index_entry_low( if (!index->is_committed()) { ut_ad(!thr_get_trx(thr) ->dict_operation_lock_mode); - dict_sys.mutex_lock(); - dict_set_corrupted_index_cache_only(index); - dict_sys.mutex_unlock(); + index->type |= DICT_CORRUPT; /* Do not return any error to the caller. The duplicate will be reported by ALTER TABLE or CREATE UNIQUE INDEX. diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index c6bd09e43fde0..459f0db39971b 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -3680,7 +3680,7 @@ row_merge_drop_index_dict( ut_ad(!srv_read_only_mode); ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); ut_ad(trx->dict_operation); - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); info = pars_info_create(); pars_info_add_ull_literal(info, "indexid", index_id); @@ -3742,7 +3742,7 @@ row_merge_drop_indexes_dict( ut_ad(!srv_read_only_mode); ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); ut_ad(trx->dict_operation); - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); /* It is possible that table->n_ref_count > 1 when locked=TRUE. In this case, all code that should have an open @@ -3815,7 +3815,7 @@ row_merge_drop_indexes( ut_ad(!srv_read_only_mode); ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); ut_ad(trx->dict_operation); - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); index = dict_table_get_first_index(table); ut_ad(dict_index_is_clust(index)); @@ -3900,7 +3900,7 @@ row_merge_drop_indexes( index->lock.x_unlock(); DEBUG_SYNC_C("merge_drop_index_after_abort"); - /* covered by dict_sys.mutex */ + /* covered by dict_sys.latch */ MONITOR_INC(MONITOR_BACKGROUND_DROP_INDEX); /* fall through */ case ONLINE_INDEX_ABORTED: @@ -3967,7 +3967,7 @@ row_merge_drop_indexes( break; case ONLINE_INDEX_ABORTED: case ONLINE_INDEX_ABORTED_DROPPED: - /* covered by dict_sys.mutex */ + /* covered by dict_sys.latch */ MONITOR_DEC(MONITOR_BACKGROUND_DROP_INDEX); } diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index a5c8f7047b6d6..b38ce54b6cad9 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -1421,7 +1421,8 @@ row_insert_for_mysql( srv_stats.n_rows_inserted.inc(size_t(trx->id)); } - /* Not protected by dict_sys.mutex for performance + /* Not protected by dict_sys.latch or table->stats_mutex_lock() + for performance reasons, we would rather get garbage in stat_n_rows (which is just an estimate anyway) than protecting the following code with a latch. */ @@ -1758,7 +1759,8 @@ row_update_for_mysql(row_prebuilt_t* prebuilt) ut_ad(is_delete == (node->is_delete == PLAIN_DELETE)); if (is_delete) { - /* Not protected by dict_sys.mutex for performance + /* Not protected by dict_sys.latch + or prebuilt->table->stats_mutex_lock() for performance reasons, we would rather get garbage in stat_n_rows (which is just an estimate anyway) than protecting the following code with a latch. */ @@ -2105,7 +2107,8 @@ row_update_cascade_for_mysql( bool stats; if (node->is_delete == PLAIN_DELETE) { - /* Not protected by dict_sys.mutex for + /* Not protected by dict_sys.latch + or node->table->stats_mutex_lock() for performance reasons, we would rather get garbage in stat_n_rows (which is just an estimate anyway) than @@ -2181,7 +2184,7 @@ row_create_table_for_mysql( que_thr_t* thr; dberr_t err; - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); DEBUG_SYNC_C("create_table"); @@ -2256,7 +2259,7 @@ row_create_index_for_mysql( ulint len; dict_table_t* table = index->table; - ut_d(dict_sys.assert_locked()); + ut_ad(dict_sys.locked()); for (i = 0; i < index->n_def; i++) { /* Check that prefix_len and actual length @@ -2545,7 +2548,6 @@ dberr_t row_discard_tablespace_for_mysql(dict_table_t *table, trx_t *trx) if (err != DB_SUCCESS) { rollback: - table->stats_bg_flag= BG_STAT_NONE; if (fts_exist) { purge_sys.resume_FTS(); @@ -2557,17 +2559,18 @@ dberr_t row_discard_tablespace_for_mysql(dict_table_t *table, trx_t *trx) } row_mysql_lock_data_dictionary(trx); - dict_stats_wait_bg_to_stop_using_table(table, trx); + dict_stats_wait_bg_to_stop_using_table(table); trx->op_info = "discarding tablespace"; trx->dict_operation= true; - /* Serialize data dictionary operations with dictionary mutex: + /* We serialize data dictionary operations with dict_sys.latch: this is to avoid deadlocks during data dictionary operations */ err= row_discard_tablespace_foreign_key_checks(trx, table); if (err != DB_SUCCESS) { + table->stats_bg_flag= BG_STAT_NONE; row_mysql_unlock_data_dictionary(trx); goto rollback; } diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc index 082bf69476cd5..7e10dcdfe9c8a 100644 --- a/storage/innobase/row/row0purge.cc +++ b/storage/innobase/row/row0purge.cc @@ -114,11 +114,11 @@ row_purge_remove_clust_if_poss_low( if (table_id) { retry: purge_sys.check_stop_FTS(); - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); table = dict_table_open_on_id( table_id, true, DICT_TABLE_OP_OPEN_ONLY_IF_CACHED); if (!table) { - dict_sys.mutex_unlock(); + dict_sys.unlock(); } else if (table->n_rec_locks) { for (dict_index_t* ind = UT_LIST_GET_FIRST( table->indexes); ind; @@ -142,7 +142,7 @@ row_purge_remove_clust_if_poss_low( close_and_exit: if (table) { dict_table_close(table, true, false); - dict_sys.mutex_unlock(); + dict_sys.unlock(); } return success; } @@ -172,7 +172,7 @@ row_purge_remove_clust_if_poss_low( table->space = nullptr; table->file_unreadable = true; } - dict_sys.mutex_unlock(); + dict_sys.unlock(); table = nullptr; } f = fil_delete_tablespace(space_id); @@ -182,7 +182,7 @@ row_purge_remove_clust_if_poss_low( if (table) { dict_table_close(table, true, false); - dict_sys.mutex_unlock(); + dict_sys.unlock(); table = nullptr; } diff --git a/storage/innobase/row/row0quiesce.cc b/storage/innobase/row/row0quiesce.cc index 74c7b9b35fcf9..04de3465dcfd4 100644 --- a/storage/innobase/row/row0quiesce.cc +++ b/storage/innobase/row/row0quiesce.cc @@ -486,8 +486,6 @@ row_quiesce_table_has_fts_index( { bool exists = false; - dict_sys.mutex_lock(); - for (const dict_index_t* index = UT_LIST_GET_FIRST(table->indexes); index != 0; index = UT_LIST_GET_NEXT(indexes, index)) { @@ -498,8 +496,6 @@ row_quiesce_table_has_fts_index( } } - dict_sys.mutex_unlock(); - return(exists); } diff --git a/storage/innobase/row/row0uins.cc b/storage/innobase/row/row0uins.cc index 704c067fc435e..2c7408c950a71 100644 --- a/storage/innobase/row/row0uins.cc +++ b/storage/innobase/row/row0uins.cc @@ -182,7 +182,7 @@ row_undo_ins_remove_clust_rec( lock_release_on_rollback(node->trx, table); if (!dict_locked) { - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); } if (table->release()) { dict_sys.remove(table); @@ -192,7 +192,7 @@ row_undo_ins_remove_clust_rec( table->file_unreadable = true; } if (!dict_locked) { - dict_sys.mutex_unlock(); + dict_sys.unlock(); } table = nullptr; if (!mdl_ticket); @@ -432,9 +432,9 @@ static bool row_undo_ins_parse_undo_rec(undo_node_t* node, bool dict_locked) node->table = dict_table_open_on_id(table_id, dict_locked, DICT_TABLE_OP_NORMAL); } else if (!dict_locked) { - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); node->table = dict_sys.acquire_temporary_table(table_id); - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); } else { node->table = dict_sys.acquire_temporary_table(table_id); } @@ -642,21 +642,19 @@ row_undo_ins( log_free_check(); - if (node->table->id == DICT_INDEXES_ID) { - ut_ad(!node->table->is_temporary()); - if (!dict_locked) { - dict_sys.mutex_lock(); - } + if (!dict_locked && node->table->id == DICT_INDEXES_ID) { + dict_sys.lock(SRW_LOCK_CALL); err = row_undo_ins_remove_clust_rec(node); - if (!dict_locked) { - dict_sys.mutex_unlock(); - } + dict_sys.unlock(); } else { + ut_ad(node->table->id != DICT_INDEXES_ID + || !node->table->is_temporary()); err = row_undo_ins_remove_clust_rec(node); } if (err == DB_SUCCESS && node->table->stat_initialized) { - /* Not protected by dict_sys.mutex for + /* Not protected by dict_sys.latch + or table->stats_mutex_lock() for performance reasons, we would rather get garbage in stat_n_rows (which is just an estimate anyway) than protecting the following code with a latch. */ @@ -665,7 +663,7 @@ row_undo_ins( /* Do not attempt to update statistics when executing ROLLBACK in the InnoDB SQL interpreter, because in that case we would - already be holding dict_sys.mutex, which + already be holding dict_sys.latch, which would be acquired when updating statistics. */ if (!dict_locked) { dict_stats_update_if_needed(node->table, diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc index ba675c927ebc0..5039df2e1a61a 100644 --- a/storage/innobase/row/row0umod.cc +++ b/storage/innobase/row/row0umod.cc @@ -1215,9 +1215,9 @@ static bool row_undo_mod_parse_undo_rec(undo_node_t* node, bool dict_locked) node->table = dict_table_open_on_id(table_id, dict_locked, DICT_TABLE_OP_NORMAL); } else if (!dict_locked) { - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); node->table = dict_sys.acquire_temporary_table(table_id); - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); } else { node->table = dict_sys.acquire_temporary_table(table_id); } @@ -1391,7 +1391,7 @@ row_undo_mod( /* Do not attempt to update statistics when executing ROLLBACK in the InnoDB SQL interpreter, because in that case we would - already be holding dict_sys.mutex, which + already be holding dict_sys.latch, which would be acquired when updating statistics. */ if (update_statistics && !dict_locked) { dict_stats_update_if_needed(node->table, diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index db666cc5b28fb..7261636a9eeb8 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -162,7 +162,7 @@ wsrep_row_upd_index_is_foreign( /* No MDL protects dereferencing the members of table->foreign_set. */ const bool no_lock= !trx->dict_operation_lock_mode; if (no_lock) - dict_sys.mutex_lock(); + dict_sys.freeze(SRW_LOCK_CALL); auto end= table->foreign_set.end(); const bool is_referenced= end != @@ -170,7 +170,7 @@ wsrep_row_upd_index_is_foreign( [index](const dict_foreign_t* f) {return f->foreign_index == index;}); if (no_lock) - dict_sys.mutex_unlock(); + dict_sys.unfreeze(); return is_referenced; } diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index 88cf5c0396a2d..80a412a85bf59 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -1297,7 +1297,7 @@ void srv_monitor_task(void*) || waited == threshold / 2 || waited == threshold / 4 * 3) { ib::warn() << "Long wait (" << waited - << " seconds) for dict_sys.mutex"; + << " seconds) for dict_sys.latch"; } } } @@ -1371,8 +1371,6 @@ void purge_sys_t::stop_SYS() /** Stop purge during FLUSH TABLES FOR EXPORT */ void purge_sys_t::stop() { - dict_sys.assert_not_locked(); - for (;;) { latch.wr_lock(SRW_LOCK_CALL); diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 4a6c7ed42a021..4f01de111832f 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -604,10 +604,10 @@ trx_resurrect_table_locks( if (dict_table_t* table = dict_table_open_on_id( p.first, FALSE, DICT_TABLE_OP_LOAD_TABLESPACE)) { if (!table->is_readable()) { - dict_sys.mutex_lock(); + dict_sys.lock(SRW_LOCK_CALL); dict_table_close(table, TRUE, FALSE); dict_sys.remove(table); - dict_sys.mutex_unlock(); + dict_sys.unlock(); continue; } From 6a2cd6f4b406cc3167799f589af1b96c4cd6943c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 31 Aug 2021 13:54:06 +0300 Subject: [PATCH 5/9] MDEV-19505 Do not hold mutex while calling que_graph_free() sym_tab_free_private(): Do not call dict_table_close(), but simply invoke dict_table_t::release(), which we can do without locking the whole dictionary cache. (Note: On user tables it may still be necessary to invoke dict_table_close(), so that InnoDB persistent statistics will be deinitialized as expected.) fts_check_corrupt(), row_fts_merge_insert(): Invoke aux_table->release() to simplify the code. This is never a user table. fts_que_graph_free(), fts_que_graph_free_check_lock(): Replaced with que_graph_free(). Reviewed by: Thirunarayanan Balathandayuthapani --- storage/innobase/fts/fts0config.cc | 6 +-- storage/innobase/fts/fts0fts.cc | 75 +++++------------------------- storage/innobase/fts/fts0opt.cc | 18 +++---- storage/innobase/fts/fts0que.cc | 18 +++---- storage/innobase/handler/i_s.cc | 2 +- storage/innobase/include/fts0fts.h | 13 ------ storage/innobase/pars/pars0sym.cc | 5 +- storage/innobase/row/row0ftsort.cc | 2 +- 8 files changed, 36 insertions(+), 103 deletions(-) diff --git a/storage/innobase/fts/fts0config.cc b/storage/innobase/fts/fts0config.cc index 09cce53f8db91..4566224e171c7 100644 --- a/storage/innobase/fts/fts0config.cc +++ b/storage/innobase/fts/fts0config.cc @@ -119,7 +119,7 @@ fts_config_get_value( trx->op_info = "getting FTS config value"; error = fts_eval_sql(trx, graph); - fts_que_graph_free(graph); + que_graph_free(graph); return(error); } @@ -226,7 +226,7 @@ fts_config_set_value( error = fts_eval_sql(trx, graph); - fts_que_graph_free_check_lock(fts_table, NULL, graph); + que_graph_free(graph); n_rows_updated = trx->undo_no - undo_no; @@ -252,7 +252,7 @@ fts_config_set_value( error = fts_eval_sql(trx, graph); - fts_que_graph_free_check_lock(fts_table, NULL, graph); + que_graph_free(graph); } return(error); diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 40a8c270a253b..fd2f689825a4c 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -184,14 +184,6 @@ struct fts_tokenize_param_t { ulint add_pos; /*!< Added position for tokens */ }; -/** Free a query graph */ -void fts_que_graph_free(que_t *graph) -{ - dict_sys.lock(SRW_LOCK_CALL); - que_graph_free(graph); - dict_sys.unlock(); -} - /** 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] sync sync state @@ -885,41 +877,6 @@ fts_drop_index( return(err); } -/****************************************************************//** -Free the query graph but check whether dict_sys.latch is already -held */ -void -fts_que_graph_free_check_lock( -/*==========================*/ - fts_table_t* fts_table, /*!< in: FTS table */ - const fts_index_cache_t*index_cache, /*!< in: FTS index cache */ - que_t* graph) /*!< in: query graph */ -{ - bool has_dict = FALSE; - - if (fts_table && fts_table->table) { - ut_ad(fts_table->table->fts); - - has_dict = fts_table->table->fts->dict_locked; - } else if (index_cache) { - ut_ad(index_cache->index->table->fts); - - has_dict = index_cache->index->table->fts->dict_locked; - } - - if (!has_dict) { - dict_sys.lock(SRW_LOCK_CALL); - } - - ut_ad(dict_sys.locked()); - - que_graph_free(graph); - - if (!has_dict) { - dict_sys.unlock(); - } -} - /****************************************************************//** Create an FTS index cache. */ CHARSET_INFO* @@ -1067,18 +1024,14 @@ fts_cache_clear( if (index_cache->ins_graph[j] != NULL) { - fts_que_graph_free_check_lock( - NULL, index_cache, - index_cache->ins_graph[j]); + que_graph_free(index_cache->ins_graph[j]); index_cache->ins_graph[j] = NULL; } if (index_cache->sel_graph[j] != NULL) { - fts_que_graph_free_check_lock( - NULL, index_cache, - index_cache->sel_graph[j]); + que_graph_free(index_cache->sel_graph[j]); index_cache->sel_graph[j] = NULL; } @@ -2608,7 +2561,7 @@ fts_cmp_set_sync_doc_id( error = fts_eval_sql(trx, graph); - fts_que_graph_free_check_lock(&fts_table, NULL, graph); + que_graph_free(graph); // FIXME: We need to retry deadlock errors if (error != DB_SUCCESS) { @@ -2724,7 +2677,7 @@ fts_update_sync_doc_id( error = fts_eval_sql(trx, graph); - fts_que_graph_free_check_lock(&fts_table, NULL, graph); + que_graph_free(graph); if (local_trx) { if (UNIV_LIKELY(error == DB_SUCCESS)) { @@ -2866,7 +2819,7 @@ fts_delete( error = fts_eval_sql(trx, graph); - fts_que_graph_free(graph); + que_graph_free(graph); } else { pars_info_free(info); } @@ -3741,7 +3694,7 @@ fts_doc_fetch_by_doc_id( trx->free(); if (!get_doc) { - fts_que_graph_free(graph); + que_graph_free(graph); } return(error); @@ -3870,7 +3823,7 @@ fts_sync_add_deleted_cache( error = fts_eval_sql(sync->trx, graph); } - fts_que_graph_free(graph); + que_graph_free(graph); return(error); } @@ -4169,18 +4122,14 @@ fts_sync_rollback( if (index_cache->ins_graph[j] != NULL) { - fts_que_graph_free_check_lock( - NULL, index_cache, - index_cache->ins_graph[j]); + que_graph_free(index_cache->ins_graph[j]); index_cache->ins_graph[j] = NULL; } if (index_cache->sel_graph[j] != NULL) { - fts_que_graph_free_check_lock( - NULL, index_cache, - index_cache->sel_graph[j]); + que_graph_free(index_cache->sel_graph[j]); index_cache->sel_graph[j] = NULL; } @@ -4744,7 +4693,7 @@ fts_get_docs_clear( ut_a(get_doc->index_cache); - fts_que_graph_free(get_doc->get_document_graph); + que_graph_free(get_doc->get_document_graph); get_doc->get_document_graph = NULL; } } @@ -4892,7 +4841,7 @@ fts_get_rows_count( } } - fts_que_graph_free(graph); + que_graph_free(graph); trx->free(); @@ -4992,7 +4941,7 @@ fts_savepoint_free( /* The default savepoint name must be NULL. */ if (ftt->docs_added_graph) { - fts_que_graph_free(ftt->docs_added_graph); + que_graph_free(ftt->docs_added_graph); } /* NOTE: We are responsible for free'ing the node */ diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc index 2fcbf9b28e34f..7f7c23aee8fff 100644 --- a/storage/innobase/fts/fts0opt.cc +++ b/storage/innobase/fts/fts0opt.cc @@ -892,7 +892,7 @@ fts_index_fetch_words( } } - fts_que_graph_free(graph); + que_graph_free(graph); /* Check if max word to fetch is exceeded */ if (optim->zip->n_words >= n_words) { @@ -1005,7 +1005,7 @@ fts_table_fetch_doc_ids( error = fts_eval_sql(trx, graph); fts_sql_commit(trx); - fts_que_graph_free(graph); + que_graph_free(graph); if (error == DB_SUCCESS) { ib_vector_sort(doc_ids->doc_ids, fts_doc_id_cmp); @@ -1459,7 +1459,7 @@ fts_optimize_write_word( " when deleting a word from the FTS index."; } - fts_que_graph_free(graph); + que_graph_free(graph); graph = NULL; /* Even if the operation needs to be rolled back and redone, @@ -1491,7 +1491,7 @@ fts_optimize_write_word( } if (graph != NULL) { - fts_que_graph_free(graph); + que_graph_free(graph); } return(error); @@ -1829,7 +1829,7 @@ fts_optimize_words( charset, word->f_str, word->f_len) && graph) { - fts_que_graph_free(graph); + que_graph_free(graph); graph = NULL; } } @@ -1848,7 +1848,7 @@ fts_optimize_words( } if (graph != NULL) { - fts_que_graph_free(graph); + que_graph_free(graph); } } @@ -2081,7 +2081,7 @@ fts_optimize_purge_deleted_doc_ids( } } - fts_que_graph_free(graph); + que_graph_free(graph); return(error); } @@ -2118,7 +2118,7 @@ fts_optimize_purge_deleted_doc_id_snapshot( graph = fts_parse_sql(NULL, info, fts_end_delete_sql); error = fts_eval_sql(optim->trx, graph); - fts_que_graph_free(graph); + que_graph_free(graph); return(error); } @@ -2186,7 +2186,7 @@ fts_optimize_create_deleted_doc_id_snapshot( error = fts_eval_sql(optim->trx, graph); - fts_que_graph_free(graph); + que_graph_free(graph); if (error != DB_SUCCESS) { fts_sql_rollback(optim->trx); diff --git a/storage/innobase/fts/fts0que.cc b/storage/innobase/fts/fts0que.cc index 594faf971adfa..ee9c291b02a23 100644 --- a/storage/innobase/fts/fts0que.cc +++ b/storage/innobase/fts/fts0que.cc @@ -1193,7 +1193,7 @@ fts_query_difference( query->error = error; } - fts_que_graph_free(graph); + que_graph_free(graph); } /* The size can't increase. */ @@ -1317,7 +1317,7 @@ fts_query_intersect( query->error = error; } - fts_que_graph_free(graph); + que_graph_free(graph); if (query->error == DB_SUCCESS) { /* Make the intesection (rb tree) the current doc id @@ -1437,7 +1437,7 @@ fts_query_union( query->error = error; } - fts_que_graph_free(graph); + que_graph_free(graph); if (query->error == DB_SUCCESS) { @@ -2331,7 +2331,7 @@ fts_query_total_docs_containing_term( } } - fts_que_graph_free(graph); + que_graph_free(graph); return(error); } @@ -2413,7 +2413,7 @@ fts_query_terms_in_document( } } - fts_que_graph_free(graph); + que_graph_free(graph); return(error); } @@ -2504,7 +2504,7 @@ fts_query_is_in_proximity_range( /* Free the prepared statement. */ if (get_doc.get_document_graph) { - fts_que_graph_free(get_doc.get_document_graph); + que_graph_free(get_doc.get_document_graph); get_doc.get_document_graph = NULL; } @@ -2594,7 +2594,7 @@ fts_query_search_phrase( func_exit: /* Free the prepared statement. */ if (get_doc.get_document_graph) { - fts_que_graph_free(get_doc.get_document_graph); + que_graph_free(get_doc.get_document_graph); get_doc.get_document_graph = NULL; } @@ -2809,7 +2809,7 @@ fts_query_phrase_search( query->error = error; } - fts_que_graph_free(graph); + que_graph_free(graph); graph = NULL; fts_query_cache(query, token); @@ -3786,7 +3786,7 @@ fts_query_free( { if (query->read_nodes_graph) { - fts_que_graph_free(query->read_nodes_graph); + que_graph_free(query->read_nodes_graph); } if (query->root) { diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index ae9aa95339eb8..9e84e9443811c 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -2964,7 +2964,7 @@ i_s_fts_index_table_fill_selected( } } - fts_que_graph_free(graph); + que_graph_free(graph); trx->free(); diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h index 0fb01dd850ee7..4918b3d5747a4 100644 --- a/storage/innobase/include/fts0fts.h +++ b/storage/innobase/include/fts0fts.h @@ -377,9 +377,6 @@ extern ulong fts_min_token_size; need a sync to free some memory */ extern bool fts_need_sync; -/** Free a query graph */ -void fts_que_graph_free(que_t *graph); - /******************************************************************//** Create a FTS cache. */ fts_cache_t* @@ -740,16 +737,6 @@ FTS auxiliary INDEX table and clear the cache at the end. @return DB_SUCCESS on success, error code on failure. */ dberr_t fts_sync_table(dict_table_t* table, bool wait = true); -/****************************************************************//** -Free the query graph but check whether dict_sys.latch is already -held */ -void -fts_que_graph_free_check_lock( -/*==========================*/ - fts_table_t* fts_table, /*!< in: FTS table */ - const fts_index_cache_t*index_cache, /*!< in: FTS index cache */ - que_t* graph); /*!< in: query graph */ - /****************************************************************//** Create an FTS index cache. */ CHARSET_INFO* diff --git a/storage/innobase/pars/pars0sym.cc b/storage/innobase/pars/pars0sym.cc index d68e352e795bb..035415849a732 100644 --- a/storage/innobase/pars/pars0sym.cc +++ b/storage/innobase/pars/pars0sym.cc @@ -67,8 +67,6 @@ sym_tab_free_private( sym_node_t* sym; func_node_t* func; - ut_ad(dict_sys.locked()); - for (sym = UT_LIST_GET_FIRST(sym_tab->sym_list); sym != NULL; sym = UT_LIST_GET_NEXT(sym_list, sym)) { @@ -76,8 +74,7 @@ sym_tab_free_private( /* Close the tables opened in pars_retrieve_table_def(). */ if (sym->token_type == SYM_TABLE_REF_COUNTED) { - - dict_table_close(sym->table, TRUE, FALSE); + sym->table->release(); sym->table = NULL; sym->resolved = FALSE; diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc index 1cae41c8987ac..e22b08346ccf0 100644 --- a/storage/innobase/row/row0ftsort.cc +++ b/storage/innobase/row/row0ftsort.cc @@ -1637,7 +1637,7 @@ row_fts_merge_insert( aux_table = dict_table_open_on_name(aux_table_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE); ut_ad(aux_table != NULL); - dict_table_close(aux_table, FALSE, FALSE); + aux_table->release(); aux_index = dict_table_get_first_index(aux_table); ut_ad(!aux_index->is_instant()); From 094de71742fbed4d49d38017d56f13100050c747 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 31 Aug 2021 13:54:20 +0300 Subject: [PATCH 6/9] MDEV-25919 preparation: Various cleanup que_eval_sql(): Remove the parameter lock_dict. The only caller with lock_dict=true was dict_stats_exec_sql(), which will now explicitly invoke dict_sys.lock() and dict_sys.unlock() by itself. row_import_cleanup(): Do not unnecessarily lock the dictionary. Concurrent access to the table during ALTER TABLE...IMPORT TABLESPACE is prevented by MDL and the fact that there cannot exist any undo log or change buffer records that would refer to the table or tablespace. row_import_for_mysql(): Do not unnecessarily lock the dictionary while accessing fil_system. Thanks to MDL_EXCLUSIVE that was acquired by the SQL layer, only one IMPORT may be in effect for the table name. row_quiesce_set_state(): Do not unnecessarily lock the dictionary. The dict_table_t::quiesce state is documented to be protected by all index latches, which we are acquiring. dict_table_close(): Introduce a simpler variant with fewer parameters. dict_table_close(): Reduce the amount of calls. We can simply invoke dict_table_t::release() on startup or in DDL operations, or when the table is inaccessible. In none of these cases, there is no need to invalidate the InnoDB persistent statistics. pars_info_t::graph_owns_us: Remove (unused). pars_info_free(): Define inline. fts_delete(), trx_t::evict_table(), row_prebuilt_free(), row_rename_table_for_mysql(): Simplify. row_mysql_lock_data_dictionary(): Remove some references; use dict_sys.lock() and dict_sys.unlock() instead. row_mysql_lock_table(): Remove. Use lock_table_for_trx() instead. ha_innobase::check_if_supported_inplace_alter(), row_create_table_for_mysql(): Simply assert dict_sys.sys_tables_exist(). In commit 49e2c8f0a6fefdeac50925f758090d6bd099768d and commit 1bd681c8b3c5213ce1f7976940a7dc38b48a0d39 srv_start() actually guarantees that the system tables will exist, or the server is in read-only mode, or startup will fail. Reviewed by: Thirunarayanan Balathandayuthapani --- storage/innobase/dict/dict0crea.cc | 8 +- storage/innobase/dict/dict0dict.cc | 38 +++++---- storage/innobase/dict/dict0stats.cc | 10 +-- storage/innobase/dict/dict0stats_bg.cc | 6 +- storage/innobase/dict/drop.cc | 6 +- storage/innobase/fts/fts0fts.cc | 42 ++++------ storage/innobase/handler/ha_innodb.cc | 53 ++++++------- storage/innobase/handler/handler0alter.cc | 61 ++++++--------- storage/innobase/include/dict0dict.h | 20 ++--- storage/innobase/include/fts0fts.h | 6 +- storage/innobase/include/pars0pars.h | 12 +-- storage/innobase/include/que0que.h | 3 - storage/innobase/include/row0mysql.h | 21 +---- storage/innobase/pars/pars0pars.cc | 16 +--- storage/innobase/que/que0que.cc | 21 +---- storage/innobase/row/row0import.cc | 27 ++----- storage/innobase/row/row0ins.cc | 4 +- storage/innobase/row/row0merge.cc | 10 +-- storage/innobase/row/row0mysql.cc | 93 +++-------------------- storage/innobase/row/row0quiesce.cc | 4 - storage/innobase/row/row0upd.cc | 8 +- storage/innobase/trx/trx0trx.cc | 11 ++- 22 files changed, 153 insertions(+), 327 deletions(-) diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc index c293ab302a355..eafc9bf78146a 100644 --- a/storage/innobase/dict/dict0crea.cc +++ b/storage/innobase/dict/dict0crea.cc @@ -1403,7 +1403,7 @@ dberr_t dict_sys_t::create_or_check_sys_tables() " ON SYS_FOREIGN (FOR_NAME);\n" "CREATE INDEX REF_IND" " ON SYS_FOREIGN (REF_NAME);\n" - "END;\n", false, trx); + "END;\n", trx); if (UNIV_UNLIKELY(error != DB_SUCCESS)) { tablename= SYS_TABLE[SYS_FOREIGN].data(); @@ -1425,7 +1425,7 @@ dberr_t dict_sys_t::create_or_check_sys_tables() " FOR_COL_NAME CHAR, REF_COL_NAME CHAR);\n" "CREATE UNIQUE CLUSTERED INDEX ID_IND" " ON SYS_FOREIGN_COLS (ID, POS);\n" - "END;\n", false, trx); + "END;\n", trx); if (UNIV_UNLIKELY(error != DB_SUCCESS)) { tablename= SYS_TABLE[SYS_FOREIGN_COLS].data(); @@ -1440,7 +1440,7 @@ dberr_t dict_sys_t::create_or_check_sys_tables() "SYS_VIRTUAL(TABLE_ID BIGINT,POS INT,BASE_POS INT);\n" "CREATE UNIQUE CLUSTERED INDEX BASE_IDX" " ON SYS_VIRTUAL(TABLE_ID, POS, BASE_POS);\n" - "END;\n", false, trx); + "END;\n", trx); if (UNIV_UNLIKELY(error != DB_SUCCESS)) { tablename= SYS_TABLE[SYS_VIRTUAL].data(); @@ -1504,7 +1504,7 @@ dict_foreign_eval_sql( dberr_t error; FILE* ef = dict_foreign_err_file; - error = que_eval_sql(info, sql, FALSE, trx); + error = que_eval_sql(info, sql, trx); if (error == DB_DUPLICATE_KEY) { mysql_mutex_lock(&dict_foreign_err_mutex); diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 400cda111fe03..13b71c9a8b68b 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -299,6 +299,25 @@ dict_table_try_drop_aborted_and_unlock( } } +/** Decrement the count of open handles */ +void dict_table_close(dict_table_t *table) +{ + if (dict_stats_is_persistent_enabled(table) && + strchr(table->name.m_name, '/')) + { + dict_sys.freeze(SRW_LOCK_CALL); + if (table->release()) + { + table->stats_mutex_lock(); + dict_stats_deinit(table); + table->stats_mutex_unlock(); + } + dict_sys.unfreeze(); + } + else + table->release(); +} + /** Decrements the count of open handles of a table. @param[in,out] table table @param[in] dict_locked data dictionary locked @@ -4223,12 +4242,7 @@ void dict_set_encrypted_by_space(const fil_space_t* space) /**********************************************************************//** Flags an index corrupted both in the data dictionary cache and in the SYS_INDEXES */ -void -dict_set_corrupted( -/*===============*/ - dict_index_t* index, /*!< in/out: index */ - trx_t* trx, /*!< in/out: transaction */ - const char* ctx) /*!< in: context */ +void dict_set_corrupted(dict_index_t *index, const char *ctx, bool dict_locked) { mem_heap_t* heap; mtr_t mtr; @@ -4238,10 +4252,9 @@ dict_set_corrupted( byte* buf; const char* status; btr_cur_t cursor; - bool locked = RW_X_LATCH == trx->dict_operation_lock_mode; - if (!locked) { - row_mysql_lock_data_dictionary(trx); + if (!dict_locked) { + dict_sys.lock(SRW_LOCK_CALL); } ut_ad(dict_sys.locked()); @@ -4311,14 +4324,13 @@ dict_set_corrupted( } mtr_commit(&mtr); - mem_heap_empty(heap); + mem_heap_free(heap); ib::error() << status << " corruption of " << index->name << " in table " << index->table->name << " in " << ctx; - mem_heap_free(heap); func_exit: - if (!locked) { - row_mysql_unlock_data_dictionary(trx); + if (!dict_locked) { + dict_sys.unlock(); } } diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index ee72d7db3cdf1..9c4d87f3feaac 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -533,13 +533,13 @@ dberr_t dict_stats_exec_sql(pars_info_t *pinfo, const char* sql, trx_t *trx) } if (trx) - return que_eval_sql(pinfo, sql, FALSE, trx); + return que_eval_sql(pinfo, sql, trx); trx= trx_create(); trx_start_internal(trx); trx->dict_operation_lock_mode= RW_X_LATCH; - dberr_t err= que_eval_sql(pinfo, sql, FALSE, trx); + dberr_t err= que_eval_sql(pinfo, sql, trx); if (err == DB_SUCCESS) trx->commit(); @@ -3255,7 +3255,7 @@ dict_stats_fetch_from_ps( "fetch_index_stats_step", dict_stats_fetch_index_stats_step, &index_fetch_arg); - + dict_sys.lock(SRW_LOCK_CALL); /* FIXME: remove this */ ret = que_eval_sql(pinfo, "PROCEDURE FETCH_STATS () IS\n" "found INT;\n" @@ -3309,9 +3309,9 @@ dict_stats_fetch_from_ps( "END LOOP;\n" "CLOSE index_stats_cur;\n" - "END;", - TRUE, trx); + "END;", trx); /* pinfo is freed by que_eval_sql() */ + dict_sys.unlock(); trx_commit_for_mysql(trx); diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc index 209a2f33ba9c9..23b00bb8e2385 100644 --- a/storage/innobase/dict/dict0stats_bg.cc +++ b/storage/innobase/dict/dict0stats_bg.cc @@ -348,7 +348,7 @@ static bool dict_stats_process_entry_from_recalc_pool() ut_ad(!table->is_temporary()); if (!table->is_accessible()) { - dict_table_close(table, TRUE, FALSE); + table->release(); no_table: dict_sys.unlock(); goto next_table_id; @@ -382,12 +382,10 @@ static bool dict_stats_process_entry_from_recalc_pool() } dict_sys.lock(SRW_LOCK_CALL); - table->stats_bg_flag = BG_STAT_NONE; - dict_table_close(table, TRUE, FALSE); - dict_sys.unlock(); + return ret; } diff --git a/storage/innobase/dict/drop.cc b/storage/innobase/dict/drop.cc index bb0af50c4c284..f837798ab8f0a 100644 --- a/storage/innobase/dict/drop.cc +++ b/storage/innobase/dict/drop.cc @@ -108,7 +108,7 @@ dberr_t trx_t::drop_table_foreign(const table_name_t &name) " DELETE FROM SYS_FOREIGN WHERE ID=fid;\n" "END LOOP;\n" "CLOSE fk;\n" - "END;\n", FALSE, this); + "END;\n", this); } /** Try to drop the statistics for a persistent table. @@ -182,7 +182,7 @@ dberr_t trx_t::drop_table(const dict_table_t &table) "BEGIN\n" "DELETE FROM SYS_VIRTUAL" " WHERE TABLE_ID=:id;\n" - "END;\n", FALSE, this)) + "END;\n", this)) return err; } @@ -224,7 +224,7 @@ dberr_t trx_t::drop_table(const dict_table_t &table) "END LOOP;\n" "CLOSE idx;\n" - "END;\n", FALSE, this); + "END;\n", this); } /** Commit the transaction, possibly after drop_table(). diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index fd2f689825a4c..1d0d9b7148900 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -1593,8 +1593,7 @@ dberr_t fts_lock_tables(trx_t *trx, const dict_table_t &table) } /** Drops the common ancillary tables needed for supporting an FTS index -on the given table. row_mysql_lock_data_dictionary must have been called -before this. +on the given table. @param trx transaction to drop fts common table @param fts_table table with an FTS index @param rename whether to rename before dropping @@ -1653,8 +1652,7 @@ dberr_t fts_drop_index_tables(trx_t *trx, const dict_index_t &index) /****************************************************************//** Drops FTS ancillary tables needed for supporting an FTS index -on the given table. row_mysql_lock_data_dictionary must have been called -before this. +on the given table. @return DB_SUCCESS or error code */ static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t @@ -1795,8 +1793,7 @@ fts_create_one_common_table( } /** Creates the common auxiliary tables needed for supporting an FTS index -on the given table. row_mysql_lock_data_dictionary must have been called -before this. +on the given table. The following tables are created. CREATE TABLE $FTS_PREFIX_DELETED (doc_id BIGINT UNSIGNED, UNIQUE CLUSTERED INDEX on doc_id) @@ -1974,8 +1971,7 @@ fts_create_one_index_table( } /** Creates the column specific ancillary tables needed for supporting an -FTS index on the given table. row_mysql_lock_data_dictionary must have -been called before this. +FTS index on the given table. All FTS AUX Index tables have the following schema. CREAT TABLE $FTS_PREFIX_INDEX_[1-6]( @@ -2754,7 +2750,6 @@ fts_delete( { que_t* graph; fts_table_t fts_table; - dberr_t error = DB_SUCCESS; doc_id_t write_doc_id; dict_table_t* table = ftt->table; doc_id_t doc_id = row->doc_id; @@ -2765,7 +2760,7 @@ fts_delete( /* we do not index Documents whose Doc ID value is 0 */ if (doc_id == FTS_NULL_DOC_ID) { ut_ad(!DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID)); - return(error); + return DB_SUCCESS; } ut_a(row->state == FTS_DELETE || row->state == FTS_MODIFY); @@ -2800,29 +2795,20 @@ fts_delete( } /* Note the deleted document for OPTIMIZE to purge. */ - if (error == DB_SUCCESS) { - char table_name[MAX_FULL_NAME_LEN]; + char table_name[MAX_FULL_NAME_LEN]; - trx->op_info = "adding doc id to FTS DELETED"; + trx->op_info = "adding doc id to FTS DELETED"; - info->graph_owns_us = TRUE; + fts_table.suffix = "DELETED"; - fts_table.suffix = "DELETED"; - - fts_get_table_name(&fts_table, table_name); - pars_info_bind_id(info, "deleted", table_name); - - graph = fts_parse_sql( - &fts_table, - info, - "BEGIN INSERT INTO $deleted VALUES (:doc_id);"); + fts_get_table_name(&fts_table, table_name); + pars_info_bind_id(info, "deleted", table_name); - error = fts_eval_sql(trx, graph); + graph = fts_parse_sql(&fts_table, info, + "BEGIN INSERT INTO $deleted VALUES (:doc_id);"); - que_graph_free(graph); - } else { - pars_info_free(info); - } + dberr_t error = fts_eval_sql(trx, graph); + que_graph_free(graph); /* Increment the total deleted count, this is used to calculate the number of documents indexed. */ diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 0a57b847d14ee..96a9012e1cbf4 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1339,7 +1339,7 @@ static void innodb_drop_database(handlerton*, char *path) trx_t *trx= innobase_trx_allocate(current_thd); retry: - row_mysql_lock_data_dictionary(trx); + dict_sys.lock(SRW_LOCK_CALL); for (auto i= dict_sys.table_id_hash.n_cells; i--; ) { @@ -1350,7 +1350,7 @@ static void innodb_drop_database(handlerton*, char *path) if (!strncmp(table->name.m_name, namebuf, len) && !dict_stats_stop_bg(table)) { - row_mysql_unlock_data_dictionary(trx); + dict_sys.unlock(); std::this_thread::sleep_for(std::chrono::milliseconds(250)); goto retry; } @@ -1385,6 +1385,7 @@ static void innodb_drop_database(handlerton*, char *path) } } + trx->dict_operation_lock_mode= RW_X_LATCH; trx_start_for_ddl(trx); uint errors= 0; char db[NAME_LEN + 1]; @@ -1467,7 +1468,7 @@ static void innodb_drop_database(handlerton*, char *path) ? innodb_drop_database_fk : innodb_drop_database_ignore_fk, &report); pars_info_add_str_literal(pinfo, "db", namebuf); - err= que_eval_sql(pinfo, drop_database, false, trx); + err= que_eval_sql(pinfo, drop_database, trx); if (err == DB_SUCCESS && report.violated) err= DB_CANNOT_DROP_CONSTRAINT; } @@ -1940,7 +1941,7 @@ static int innodb_check_version(handlerton *hton, const char *path, { const trx_id_t trx_id= table->def_trx_id; DBUG_ASSERT(trx_id <= create_id); - dict_table_close(table, false, false); + dict_table_close(table); DBUG_PRINT("info", ("create_id: %llu trx_id: %llu", create_id, trx_id)); DBUG_RETURN(create_id != trx_id); } @@ -3197,7 +3198,7 @@ static bool innobase_query_caching_table_check( bool allow = innobase_query_caching_table_check_low(table, trx); - dict_table_close(table, FALSE, FALSE); + dict_table_close(table); if (allow) { /* If the isolation level is high, assign a read view for the @@ -5858,7 +5859,7 @@ ha_innobase::open(const char* name, int, uint) or force recovery can still use it, but not others. */ ib_table->file_unreadable = true; ib_table->corrupted = true; - dict_table_close(ib_table, FALSE, FALSE); + ib_table->release(); set_my_errno(ENOENT); DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); } @@ -5905,7 +5906,7 @@ ha_innobase::open(const char* name, int, uint) ret_err = HA_ERR_DECRYPTION_FAILED; } - dict_table_close(ib_table, FALSE, FALSE); + ib_table->release(); DBUG_RETURN(ret_err); } } @@ -6219,7 +6220,7 @@ ha_innobase::close() { DBUG_ENTER("ha_innobase::close"); - row_prebuilt_free(m_prebuilt, FALSE); + row_prebuilt_free(m_prebuilt); if (m_upd_buf != NULL) { ut_ad(m_upd_buf_size != 0); @@ -13016,7 +13017,7 @@ create_table_info_t::create_table_update_dict() /* Load server stopword into FTS cache */ if (m_flags2 & DICT_TF2_FTS) { if (!innobase_fts_load_stopword(innobase_table, NULL, m_thd)) { - dict_table_close(innobase_table, FALSE, FALSE); + innobase_table->release(); DBUG_RETURN(-1); } @@ -13067,7 +13068,7 @@ create_table_info_t::create_table_update_dict() innobase_parse_hint_from_comment(m_thd, innobase_table, m_form->s); - dict_table_close(innobase_table, FALSE, FALSE); + dict_table_close(innobase_table); DBUG_RETURN(0); } @@ -13217,10 +13218,8 @@ ha_innobase::discard_or_import_tablespace( trx_start_if_not_started(m_prebuilt->trx, true); /* Obtain an exclusive lock on the table. */ - dberr_t err = row_mysql_lock_table( - m_prebuilt->trx, m_prebuilt->table, LOCK_X, - discard ? "setting table lock for DISCARD TABLESPACE" - : "setting table lock for IMPORT TABLESPACE"); + dberr_t err = lock_table_for_trx(m_prebuilt->table, + m_prebuilt->trx, LOCK_X); if (err != DB_SUCCESS) { /* unable to lock the table: do nothing */ @@ -13282,7 +13281,7 @@ ha_innobase::discard_or_import_tablespace( table_id_t id = m_prebuilt->table->id; ut_ad(id); dict_sys.lock(SRW_LOCK_CALL); - dict_table_close(m_prebuilt->table, TRUE, FALSE); + m_prebuilt->table->release(); dict_sys.remove(m_prebuilt->table); m_prebuilt->table = dict_table_open_on_id(id, TRUE, DICT_TABLE_OP_NORMAL); @@ -13627,7 +13626,7 @@ int ha_innobase::truncate() info.options|= HA_LEX_CREATE_TMP_TABLE; btr_drop_temporary_table(*ib_table); m_prebuilt->table = nullptr; - row_prebuilt_free(m_prebuilt, false); + row_prebuilt_free(m_prebuilt); m_prebuilt = nullptr; my_free(m_upd_buf); m_upd_buf = nullptr; @@ -13742,7 +13741,7 @@ int ha_innobase::truncate() m_prebuilt->stored_select_lock_type = stored_lock; m_prebuilt->table->update_time = update_time; - row_prebuilt_free(prebuilt, false); + row_prebuilt_free(prebuilt); my_free(upd_buf); } else { /* Revert to the old table. */ @@ -14837,8 +14836,7 @@ ha_innobase::check( index = dict_table_get_first_index(m_prebuilt->table); if (!index->is_corrupted()) { - dict_set_corrupted( - index, m_prebuilt->trx, "CHECK TABLE"); + dict_set_corrupted(index, "CHECK TABLE", false); } push_warning_printf(m_user_thd, @@ -14919,9 +14917,9 @@ ha_innobase::check( "dict_set_index_corrupted", if (!index->is_primary()) { m_prebuilt->index_usable = FALSE; - // row_mysql_lock_data_dictionary(m_prebuilt->trx); - dict_set_corrupted(index, m_prebuilt->trx, "dict_set_index_corrupted"); - // row_mysql_unlock_data_dictionary(m_prebuilt->trx); + dict_set_corrupted(index, + "dict_set_index_corrupted", + false); }); if (UNIV_UNLIKELY(!m_prebuilt->index_usable)) { @@ -14983,8 +14981,8 @@ ha_innobase::check( " index %s is corrupted.", index->name()); is_ok = false; - dict_set_corrupted( - index, m_prebuilt->trx, "CHECK TABLE-check index"); + dict_set_corrupted(index, "CHECK TABLE-check index", + false); } @@ -14999,9 +14997,8 @@ ha_innobase::check( " entries, should be " ULINTPF ".", index->name(), n_rows, n_rows_in_table); is_ok = false; - dict_set_corrupted( - index, m_prebuilt->trx, - "CHECK TABLE; Wrong count"); + dict_set_corrupted(index, "CHECK TABLE; Wrong count", + false); } } @@ -17103,7 +17100,7 @@ static int innodb_ft_aux_table_validate(THD *thd, st_mysql_sys_var*, table_name, FALSE, TRUE, DICT_ERR_IGNORE_NONE)) { const table_id_t id = dict_table_has_fts_index(table) ? table->id : 0; - dict_table_close(table, FALSE, FALSE); + dict_table_close(table); if (id) { innodb_ft_aux_table_id = id; if (table_name == buf) { diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index e7b01a4f72be3..a9801cd35ae2e 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -2052,11 +2052,7 @@ ha_innobase::check_if_supported_inplace_alter( DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); } - if (!dict_sys.sys_tables_exist()) { - ha_alter_info->unsupported_reason - = "missing InnoDB system tables"; - DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); - } + ut_ad(dict_sys.sys_tables_exist()); /* Only support online add foreign key constraint when check_foreigns is turned off */ @@ -4824,8 +4820,7 @@ innobase_update_gis_column_type( "BEGIN\n" "UPDATE SYS_COLUMNS SET MTYPE=:mtype\n" "WHERE TABLE_ID=:tableid AND NAME=:name;\n" - "END;\n", - false, trx); + "END;\n", trx); trx->error_state = DB_SUCCESS; trx->op_info = ""; @@ -5144,8 +5139,7 @@ static bool innobase_insert_sys_virtual( "PROCEDURE P () IS\n" "BEGIN\n" "INSERT INTO SYS_VIRTUAL VALUES (:id, :pos, :base_pos);\n" - "END;\n", - FALSE, trx)) { + "END;\n", trx)) { my_error(ER_INTERNAL_ERROR, MYF(0), "InnoDB: ADD COLUMN...VIRTUAL"); return true; @@ -5194,7 +5188,7 @@ static bool innodb_insert_sys_columns( "NAME=:name, MTYPE=:mtype, PRTYPE=:prtype, " "LEN=:len, PREC=:base\n" "WHERE TABLE_ID=:id AND POS=:pos;\n" - "END;\n", FALSE, trx)) { + "END;\n", trx)) { my_error(ER_INTERNAL_ERROR, MYF(0), "InnoDB: Updating SYS_COLUMNS failed"); return true; @@ -5209,7 +5203,7 @@ static bool innodb_insert_sys_columns( "BEGIN\n" "INSERT INTO SYS_COLUMNS VALUES" "(:id,:pos,:name,:mtype,:prtype,:len,:base);\n" - "END;\n", FALSE, trx)) { + "END;\n", trx)) { my_error(ER_INTERNAL_ERROR, MYF(0), "InnoDB: Insert into SYS_COLUMNS failed"); return true; @@ -5267,7 +5261,7 @@ static bool innodb_update_cols(const dict_table_t* table, ulint n, trx_t* trx) "BEGIN\n" "UPDATE SYS_TABLES SET N_COLS = :n" " WHERE ID = :id;\n" - "END;\n", FALSE, trx)) { + "END;\n", trx)) { my_error(ER_INTERNAL_ERROR, MYF(0), "InnoDB: Updating SYS_TABLES.N_COLS failed"); return true; @@ -5322,7 +5316,7 @@ static bool innobase_instant_drop_cols(table_id_t id, ulint pos, trx_t* trx) "DELETE FROM SYS_COLUMNS WHERE\n" "TABLE_ID = :id AND POS >= :pos;\n" "DELETE FROM SYS_VIRTUAL WHERE TABLE_ID = :id;\n" - "END;\n", FALSE, trx); + "END;\n", trx); if (err != DB_SUCCESS) { my_error(ER_INTERNAL_ERROR, MYF(0), "InnoDB: DELETE from SYS_COLUMNS/SYS_VIRTUAL failed"); @@ -5360,8 +5354,7 @@ innobase_update_v_pos_sys_columns( "SET POS = :val\n" "WHERE POS = :pos\n" "AND TABLE_ID = :id;\n" - "END;\n", - FALSE, trx); + "END;\n", trx); return(error); } @@ -5394,8 +5387,7 @@ innobase_update_v_pos_sys_virtual( "SET POS = :val\n" "WHERE POS = :pos\n" "AND TABLE_ID = :id;\n" - "END;\n", - FALSE, trx); + "END;\n", trx); return(error); } @@ -5429,8 +5421,7 @@ innobase_drop_one_virtual_sys_columns( "DELETE FROM SYS_COLUMNS\n" "WHERE TABLE_ID = :id\n" "AND NAME = :name;\n" - "END;\n", - FALSE, trx); + "END;\n", trx); if (error != DB_SUCCESS) { return(error); @@ -5488,8 +5479,7 @@ innobase_drop_one_virtual_sys_virtual( "DELETE FROM SYS_VIRTUAL\n" "WHERE TABLE_ID = :id\n" "AND POS = :pos;\n" - "END;\n", - FALSE, trx); + "END;\n", trx); return(error); } @@ -7367,8 +7357,7 @@ rename_index_try( "WHERE\n" "ID = :index_id AND\n" "TABLE_ID = :table_id;\n" - "END;\n", - FALSE, trx); /* pinfo is freed by que_eval_sql() */ + "END;\n", trx); /* pinfo is freed by que_eval_sql() */ DBUG_EXECUTE_IF( "ib_rename_index_fail1", @@ -8864,7 +8853,7 @@ innobase_drop_foreign_try( pars_info_add_str_literal(info, "id", foreign_id); trx->op_info = "dropping foreign key constraint from dictionary"; - error = que_eval_sql(info, sql, FALSE, trx); + error = que_eval_sql(info, sql, trx); trx->op_info = ""; DBUG_EXECUTE_IF("ib_drop_foreign_error", @@ -8949,8 +8938,7 @@ innobase_rename_column_try( "UPDATE SYS_FIELDS SET COL_NAME=:new\n" "WHERE INDEX_ID=:indexid\n" "AND POS=:nth;\n" - "END;\n", - FALSE, trx); + "END;\n", trx); DBUG_EXECUTE_IF("ib_rename_column_error", error = DB_OUT_OF_FILE_SPACE;); @@ -8980,8 +8968,7 @@ innobase_rename_column_try( "UPDATE SYS_FIELDS SET COL_NAME=:new\n" "WHERE INDEX_ID=:indexid\n" "AND POS=:nth;\n" - "END;\n", - FALSE, trx); + "END;\n", trx); if (error != DB_SUCCESS) { goto err_exit; @@ -9042,8 +9029,7 @@ innobase_rename_column_try( "UPDATE SYS_FOREIGN_COLS\n" "SET FOR_COL_NAME=:new\n" "WHERE ID=:id AND POS=:nth;\n" - "END;\n", - FALSE, trx); + "END;\n", trx); if (error != DB_SUCCESS) { goto err_exit; @@ -9084,8 +9070,7 @@ innobase_rename_column_try( "UPDATE SYS_FOREIGN_COLS\n" "SET REF_COL_NAME=:new\n" "WHERE ID=:id AND POS=:nth;\n" - "END;\n", - FALSE, trx); + "END;\n", trx); if (error != DB_SUCCESS) { goto err_exit; @@ -9761,8 +9746,7 @@ vers_change_field_try( "BEGIN\n" "UPDATE SYS_COLUMNS SET PRTYPE=:prtype\n" "WHERE TABLE_ID=:tableid AND POS=:pos;\n" - "END;\n", - false, trx); + "END;\n", trx); if (error != DB_SUCCESS) { my_error_innodb(error, table_name, 0); @@ -10105,8 +10089,7 @@ innobase_page_compression_try( "BEGIN\n" "UPDATE SYS_TABLES SET TYPE=:type\n" "WHERE ID=:id;\n" - "END;\n", - false, trx); + "END;\n", trx); if (error != DB_SUCCESS) { my_error_innodb(error, table_name, 0); @@ -10262,7 +10245,7 @@ commit_try_norebuild( pars_info_t* info = pars_info_create(); pars_info_add_ull_literal(info, "indexid", index->id); - error = que_eval_sql(info, drop_index, FALSE, trx); + error = que_eval_sql(info, drop_index, trx); if (error == DB_SUCCESS && index->type & DICT_FTS) { DBUG_ASSERT(index->table->fts); @@ -11030,7 +11013,9 @@ ha_innobase::commit_inplace_alter_table( ut_ad(ctx->new_table->get_ref_count() == 1); const bool own = m_prebuilt == ctx->prebuilt; trx_t* const user_trx = m_prebuilt->trx; - row_prebuilt_free(ctx->prebuilt, true); + ctx->prebuilt->table->release(); + ctx->prebuilt->table = nullptr; + row_prebuilt_free(ctx->prebuilt); /* Rebuild the prebuilt object. */ ctx->prebuilt = row_create_prebuilt( ctx->new_table, altered_table->s->reclength); diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 1842650f1f62f..a031d2d0e1e8a 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -152,6 +152,9 @@ dict_table_open_on_id(table_id_t table_id, bool dict_locked, MDL_ticket **mdl= nullptr) MY_ATTRIBUTE((warn_unused_result)); +/** Decrement the count of open handles */ +void dict_table_close(dict_table_t *table); + /** Decrements the count of open handles of a table. @param[in,out] table table @param[in] dict_locked data dictionary locked @@ -1695,16 +1698,13 @@ dict_table_is_corrupted( const dict_table_t* table) /*!< in: table */ MY_ATTRIBUTE((nonnull, warn_unused_result)); -/**********************************************************************//** -Flags an index and table corrupted both in the data dictionary cache -and in the system table SYS_INDEXES. */ -void -dict_set_corrupted( -/*===============*/ - dict_index_t* index, /*!< in/out: index */ - trx_t* trx, /*!< in/out: transaction */ - const char* ctx) /*!< in: context */ - ATTRIBUTE_COLD __attribute__((nonnull)); +/** Flag an index and table corrupted both in the data dictionary cache +and in the system table SYS_INDEXES. +@param index index to be flagged as corrupted +@param ctx context (for error log reporting) +@param dict_locked whether dict_sys.latch is held in exclusive mode */ +void dict_set_corrupted(dict_index_t *index, const char *ctx, bool dict_locked) + ATTRIBUTE_COLD __attribute__((nonnull)); /** Flags an index corrupted in the data dictionary cache only. This is used mostly to mark a corrupted index when index's own dictionary diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h index 4918b3d5747a4..6f9ceca1c0ca8 100644 --- a/storage/innobase/include/fts0fts.h +++ b/storage/innobase/include/fts0fts.h @@ -447,8 +447,7 @@ fts_trx_free( fts_trx_t* fts_trx); /*!< in, own: FTS trx */ /** Creates the common auxiliary tables needed for supporting an FTS index -on the given table. row_mysql_lock_data_dictionary must have been called -before this. +on the given table. The following tables are created. CREATE TABLE $FTS_PREFIX_DELETED (doc_id BIGINT UNSIGNED, UNIQUE CLUSTERED INDEX on doc_id) @@ -471,8 +470,7 @@ fts_create_common_tables( bool skip_doc_id_index) MY_ATTRIBUTE((nonnull, warn_unused_result)); /** Creates the column specific ancillary tables needed for supporting an -FTS index on the given table. row_mysql_lock_data_dictionary must have -been called before this. +FTS index on the given table. All FTS AUX Index tables have the following schema. CREAT TABLE $FTS_PREFIX_INDEX_[1-6]( diff --git a/storage/innobase/include/pars0pars.h b/storage/innobase/include/pars0pars.h index bef446184a177..16823ce1461d0 100644 --- a/storage/innobase/include/pars0pars.h +++ b/storage/innobase/include/pars0pars.h @@ -390,13 +390,6 @@ pars_info_t* pars_info_create(void); /*==================*/ -/****************************************************************//** -Free info struct and everything it contains. */ -void -pars_info_free( -/*===========*/ - pars_info_t* info); /*!< in, own: info struct */ - /****************************************************************//** Add bound literal. */ void @@ -559,11 +552,10 @@ struct pars_info_t { (pars_bound_lit_t*) */ ib_vector_t* bound_ids; /*!< bound ids, or NULL (pars_bound_id_t*) */ - - ibool graph_owns_us; /*!< if TRUE (which is the default), - que_graph_free() will free us */ }; +inline void pars_info_free(pars_info_t *info) { mem_heap_free(info->heap); } + /** User-supplied function and argument. */ struct pars_user_func_t { const char* name; /*!< function name */ diff --git a/storage/innobase/include/que0que.h b/storage/innobase/include/que0que.h index d81c77e3d36bf..f0aed6d22f475 100644 --- a/storage/innobase/include/que0que.h +++ b/storage/innobase/include/que0que.h @@ -207,9 +207,6 @@ que_eval_sql( /*=========*/ pars_info_t* info, /*!< in: info struct, or NULL */ const char* sql, /*!< in: SQL string */ - bool lock_dict, - /*!< in: whether to acquire/release - dict_sys.latch around call to pars_sql(). */ trx_t* trx); /*!< in: trx */ /**********************************************************************//** diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 998de196dd9d6..ba8ac02dfd1cc 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -182,13 +182,8 @@ row_create_prebuilt( dict_table_t* table, /*!< in: Innobase table handle */ ulint mysql_row_len); /*!< in: length in bytes of a row in the MySQL format */ -/********************************************************************//** -Free a prebuilt struct for a MySQL table handle. */ -void -row_prebuilt_free( -/*==============*/ - row_prebuilt_t* prebuilt, /*!< in, own: prebuilt struct */ - ibool dict_locked); /*!< in: TRUE=data dictionary locked */ +/** Free a prebuilt struct for a TABLE handle. */ +void row_prebuilt_free(row_prebuilt_t *prebuilt); /*********************************************************************//** Updates the transaction pointers in query graphs stored in the prebuilt struct. */ @@ -362,18 +357,6 @@ row_create_index_for_mysql( uint32_t key_id) /*!< in: encryption key_id */ MY_ATTRIBUTE((warn_unused_result)); -/*********************************************************************//** -Sets an exclusive lock on a table. -@return error code or DB_SUCCESS */ -dberr_t -row_mysql_lock_table( -/*=================*/ - trx_t* trx, /*!< in/out: transaction */ - dict_table_t* table, /*!< in: table to lock */ - enum lock_mode mode, /*!< in: LOCK_X or LOCK_S */ - const char* op_info) /*!< in: string for trx->op_info */ - MY_ATTRIBUTE((nonnull, warn_unused_result)); - /*********************************************************************//** Discards the tablespace of a table which stored in an .ibd file. Discarding means that this function deletes the .ibd file and assigns a new table id for diff --git a/storage/innobase/pars/pars0pars.cc b/storage/innobase/pars/pars0pars.cc index d49e5668aa13b..1ade99eb1c34a 100644 --- a/storage/innobase/pars/pars0pars.cc +++ b/storage/innobase/pars/pars0pars.cc @@ -2051,27 +2051,13 @@ pars_info_create(void) heap = mem_heap_create(512); - info = static_cast(mem_heap_alloc(heap, sizeof(*info))); + info = static_cast(mem_heap_zalloc(heap, sizeof(*info))); info->heap = heap; - info->funcs = NULL; - info->bound_lits = NULL; - info->bound_ids = NULL; - info->graph_owns_us = TRUE; return(info); } -/****************************************************************//** -Free info struct and everything it contains. */ -void -pars_info_free( -/*===========*/ - pars_info_t* info) /*!< in, own: info struct */ -{ - mem_heap_free(info->heap); -} - /****************************************************************//** Add bound literal. */ void diff --git a/storage/innobase/que/que0que.cc b/storage/innobase/que/que0que.cc index 074f8c54e2413..642a852b47308 100644 --- a/storage/innobase/que/que0que.cc +++ b/storage/innobase/que/que0que.cc @@ -435,7 +435,7 @@ que_graph_free( sym_tab_free_private(graph->sym_tab); } - if (graph->info && graph->info->graph_owns_us) { + if (graph->info) { pars_info_free(graph->info); } @@ -748,9 +748,6 @@ que_eval_sql( /*=========*/ pars_info_t* info, /*!< in: info struct, or NULL */ const char* sql, /*!< in: SQL string */ - bool lock_dict, - /*!< in: whether to acquire/release - dict_sys.latch around call to pars_sql(). */ trx_t* trx) /*!< in: trx */ { que_thr_t* thr; @@ -761,16 +758,8 @@ que_eval_sql( ut_a(trx->error_state == DB_SUCCESS); - if (lock_dict) { - dict_sys.lock(SRW_LOCK_CALL); - } - graph = pars_sql(info, sql); - if (lock_dict) { - dict_sys.unlock(); - } - graph->trx = trx; trx->graph = NULL; @@ -778,15 +767,7 @@ que_eval_sql( que_run_threads(thr); - if (lock_dict) { - dict_sys.lock(SRW_LOCK_CALL); - } - que_graph_free(graph); - if (lock_dict) { - dict_sys.unlock(); - } - DBUG_RETURN(trx->error_state); } diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 0d380405e5d86..ce23587090937 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -2209,10 +2209,6 @@ row_import_cleanup( ib::info() << "Discarding tablespace of table " << table->name << ": " << err; - if (!trx->dict_operation_lock_mode) { - row_mysql_lock_data_dictionary(trx); - } - for (dict_index_t* index = UT_LIST_GET_FIRST(table->indexes); index; index = UT_LIST_GET_NEXT(indexes, index)) { @@ -2220,13 +2216,13 @@ row_import_cleanup( } } - ut_a(trx->dict_operation_lock_mode == RW_X_LATCH); - DBUG_EXECUTE_IF("ib_import_before_commit_crash", DBUG_SUICIDE();); trx_commit_for_mysql(trx); - row_mysql_unlock_data_dictionary(trx); + if (trx->dict_operation_lock_mode) { + row_mysql_unlock_data_dictionary(trx); + } trx->free(); @@ -3343,7 +3339,7 @@ dberr_t row_import_update_discarded_flag(trx_t* trx, table_id_t table_id, pars_info_bind_function( info, "my_func", row_import_set_discarded, &discard); - dberr_t err = que_eval_sql(info, sql, false, trx); + dberr_t err = que_eval_sql(info, sql, trx); ut_a(discard.n_recs == 1); ut_a(discard.flags2 != ULINT32_UNDEFINED); @@ -4179,8 +4175,6 @@ row_import_for_mysql( return(row_import_cleanup(prebuilt, trx, err)); } - row_mysql_lock_data_dictionary(trx); - /* If the table is stored in a remote tablespace, we need to determine that filepath from the link file and system tables. Find the space ID in SYS_TABLES since this is an ALTER TABLE. */ @@ -4202,7 +4196,6 @@ row_import_for_mysql( ); if (filepath == NULL) { - row_mysql_unlock_data_dictionary(trx); return(row_import_cleanup(prebuilt, trx, DB_OUT_OF_MEMORY)); } @@ -4222,22 +4215,16 @@ row_import_for_mysql( err = DB_TABLESPACE_NOT_FOUND; table->space = NULL;); if (!table->space) { - row_mysql_unlock_data_dictionary(trx); - ib_senderrf(trx->mysql_thd, IB_LOG_LEVEL_ERROR, ER_GET_ERRMSG, err, ut_strerr(err), filepath); - - ut_free(filepath); - - return(row_import_cleanup(prebuilt, trx, err)); } - row_mysql_unlock_data_dictionary(trx); - ut_free(filepath); - err = ibuf_check_bitmap_on_import(trx, table->space); + if (err == DB_SUCCESS) { + err = ibuf_check_bitmap_on_import(trx, table->space); + } DBUG_EXECUTE_IF("ib_import_check_bitmap_failure", err = DB_CORRUPTION;); diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index eb5a3cc91b82f..40b51e2e86682 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -1950,8 +1950,8 @@ row_ins_check_foreign_constraints( err = row_ins_check_foreign_constraint( TRUE, foreign, table, ref_tuple, thr); - if (ref_table != NULL) { - dict_table_close(ref_table, FALSE, FALSE); + if (ref_table) { + dict_table_close(ref_table); } } } diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 459f0db39971b..ab294e6554134 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -3685,7 +3685,7 @@ row_merge_drop_index_dict( info = pars_info_create(); pars_info_add_ull_literal(info, "indexid", index_id); trx->op_info = "dropping index from dictionary"; - error = que_eval_sql(info, sql, FALSE, trx); + error = que_eval_sql(info, sql, trx); if (error != DB_SUCCESS) { /* Even though we ensure that DDL transactions are WAIT @@ -3754,7 +3754,7 @@ row_merge_drop_indexes_dict( info = pars_info_create(); pars_info_add_ull_literal(info, "tableid", table_id); trx->op_info = "dropping indexes"; - error = que_eval_sql(info, sql, FALSE, trx); + error = que_eval_sql(info, sql, trx); switch (error) { case DB_SUCCESS: @@ -4036,7 +4036,7 @@ static ibool row_merge_drop_fts(void *node, void *trx) (mach_read_from_8(static_cast(index_id->data)))); auto pinfo= pars_info_create(); pars_info_add_str_literal(pinfo, "name", buf); - que_eval_sql(pinfo, sql, false, static_cast(trx)); + que_eval_sql(pinfo, sql, static_cast(trx)); } return true; @@ -4106,7 +4106,7 @@ void row_merge_drop_temp_indexes() pars_info_t* pinfo = pars_info_create(); pars_info_bind_function(pinfo, "drop_fts", row_merge_drop_fts, trx); - if (dberr_t error = que_eval_sql(pinfo, sql, FALSE, trx)) { + if (dberr_t error = que_eval_sql(pinfo, sql, trx)) { /* Even though we ensure that DDL transactions are WAIT and DEADLOCK free, we could encounter other errors e.g., DB_TOO_MANY_CONCURRENT_TRXS. */ @@ -4254,7 +4254,7 @@ row_merge_rename_index_to_add( pars_info_add_ull_literal(info, "tableid", table_id); pars_info_add_ull_literal(info, "indexid", index_id); - err = que_eval_sql(info, rename_index, FALSE, trx); + err = que_eval_sql(info, rename_index, trx); if (err != DB_SUCCESS) { /* Even though we ensure that DDL transactions are WAIT diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index b38ce54b6cad9..17ac86f2300ba 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -905,13 +905,8 @@ row_create_prebuilt( DBUG_RETURN(prebuilt); } -/********************************************************************//** -Free a prebuilt struct for a MySQL table handle. */ -void -row_prebuilt_free( -/*==============*/ - row_prebuilt_t* prebuilt, /*!< in, own: prebuilt struct */ - ibool dict_locked) /*!< in: TRUE=data dictionary locked */ +/** Free a prebuilt struct for a TABLE handle. */ +void row_prebuilt_free(row_prebuilt_t *prebuilt) { DBUG_ENTER("row_prebuilt_free"); @@ -971,7 +966,7 @@ row_prebuilt_free( rtr_clean_rtr_info(prebuilt->rtr_info, true); } if (prebuilt->table) { - dict_table_close(prebuilt->table, dict_locked, FALSE); + dict_table_close(prebuilt->table); } mem_heap_free(prebuilt->heap); @@ -1273,7 +1268,7 @@ row_insert_for_mysql( /* Mark the table corrupted for the clustered index */ dict_index_t* index = dict_table_get_first_index(table); ut_ad(dict_index_is_clust(index)); - dict_set_corrupted(index, trx, "INSERT TABLE"); }); + dict_set_corrupted(index, "INSERT TABLE", false); }); if (dict_table_is_corrupted(table)) { @@ -2184,6 +2179,7 @@ row_create_table_for_mysql( que_thr_t* thr; dberr_t err; + ut_ad(dict_sys.sys_tables_exist()); ut_ad(dict_sys.locked()); ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); @@ -2194,16 +2190,8 @@ row_create_table_for_mysql( dict_mem_table_free(table); return DB_ERROR; ); - if (!dict_sys.sys_tables_exist()) { - sql_print_error("InnoDB: Some system tables are missing"); - dict_mem_table_free(table); - return DB_ERROR; - } - trx->op_info = "creating table"; - trx_start_if_not_started_xa(trx, true); - heap = mem_heap_create(512); trx->dict_operation = true; @@ -2380,7 +2368,7 @@ row_mysql_table_id_reassign( " WHERE TABLE_ID = :old_id;\n" "UPDATE SYS_VIRTUAL SET TABLE_ID = :new_id\n" " WHERE TABLE_ID = :old_id;\n" - "END;\n", FALSE, trx); + "END;\n", trx); return(err); } @@ -2609,54 +2597,6 @@ dberr_t row_discard_tablespace_for_mysql(dict_table_t *table, trx_t *trx) return err; } -/*********************************************************************//** -Sets an exclusive lock on a table. -@return error code or DB_SUCCESS */ -dberr_t -row_mysql_lock_table( -/*=================*/ - trx_t* trx, /*!< in/out: transaction */ - dict_table_t* table, /*!< in: table to lock */ - enum lock_mode mode, /*!< in: LOCK_X or LOCK_S */ - const char* op_info) /*!< in: string for trx->op_info */ -{ - mem_heap_t* heap; - que_thr_t* thr; - dberr_t err; - sel_node_t* node; - - ut_ad(mode == LOCK_X || mode == LOCK_S); - - heap = mem_heap_create(512); - - trx->op_info = op_info; - - node = sel_node_create(heap); - thr = pars_complete_graph_for_exec(node, trx, heap, NULL); - thr->graph->state = QUE_FORK_ACTIVE; - - /* We use the select query graph as the dummy graph needed - in the lock module call */ - - thr = que_fork_get_first_thr( - static_cast(que_node_get_parent(thr))); - - do { - thr->run_node = thr; - thr->prev_node = thr->common.parent; - - err = lock_table(table, mode, thr); - - trx->error_state = err; - } while (err != DB_SUCCESS - && row_mysql_handle_errors(&err, trx, thr, NULL)); - - que_graph_free(thr->graph); - trx->op_info = ""; - - return(err); -} - /****************************************************************//** Delete a single constraint. @return error code or DB_SUCCESS */ @@ -2676,8 +2616,7 @@ row_delete_constraint_low( "BEGIN\n" "DELETE FROM SYS_FOREIGN_COLS WHERE ID = :id;\n" "DELETE FROM SYS_FOREIGN WHERE ID = :id;\n" - "END;\n" - , FALSE, trx)); + "END;\n", trx)); } /****************************************************************//** @@ -2732,7 +2671,6 @@ row_rename_table_for_mysql( ulint n_constraints_to_drop = 0; ibool old_is_tmp, new_is_tmp; pars_info_t* info = NULL; - char* is_part = NULL; ut_a(old_name != NULL); ut_a(new_name != NULL); @@ -2751,14 +2689,6 @@ row_rename_table_for_mysql( table = dict_table_open_on_name(old_name, true, false, DICT_ERR_IGNORE_FK_NOKEY); - /* We look for pattern #P# to see if the table is partitioned - MySQL table. */ -#ifdef _WIN32 - is_part = strstr((char *)old_name, (char *)"#p#"); -#else - is_part = strstr((char *)old_name, (char *)"#P#"); -#endif /* _WIN32 */ - /* MariaDB partition engine hard codes the file name separator as "#P#" and "#SP#". The text case is fixed even if lower_case_table_names is set to 1 or 2. InnoDB always @@ -2775,7 +2705,8 @@ row_rename_table_for_mysql( sensitive platform in Windows, we might need to check the existence of table name without lowering case them in the system table. */ - if (!table && is_part && lower_case_table_names == 1) { + if (!table && lower_case_table_names == 1 + && strstr(old_name, IF_WIN("#p#", "#P#"))) { char par_case_name[MAX_FULL_NAME_LEN + 1]; #ifndef _WIN32 /* Check for the table using lower @@ -2853,8 +2784,7 @@ row_rename_table_for_mysql( "UPDATE SYS_TABLES" " SET NAME = :new_table_name\n" " WHERE NAME = :old_table_name;\n" - "END;\n" - , FALSE, trx); + "END;\n", trx); if (err != DB_SUCCESS) { // Assume the caller guarantees destination name doesn't exist. @@ -2972,8 +2902,7 @@ row_rename_table_for_mysql( "WHERE REF_NAME = :old_table_name\n" " AND TO_BINARY(REF_NAME)\n" " = TO_BINARY(:old_table_name);\n" - "END;\n" - , FALSE, trx); + "END;\n", trx); } else if (n_constraints_to_drop > 0) { /* Drop some constraints of tmp tables. */ diff --git a/storage/innobase/row/row0quiesce.cc b/storage/innobase/row/row0quiesce.cc index 04de3465dcfd4..0d941feb0a1c1 100644 --- a/storage/innobase/row/row0quiesce.cc +++ b/storage/innobase/row/row0quiesce.cc @@ -667,8 +667,6 @@ row_quiesce_set_state( dict_index_t* clust_index = dict_table_get_first_index(table); - row_mysql_lock_data_dictionary(trx); - for (dict_index_t* index = dict_table_get_next_index(clust_index); index != NULL; index = dict_table_get_next_index(index)) { @@ -698,8 +696,6 @@ row_quiesce_set_state( index->lock.x_unlock(); } - row_mysql_unlock_data_dictionary(trx); - return(DB_SUCCESS); } diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index 7261636a9eeb8..b343141f84bdc 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -255,8 +255,8 @@ row_upd_check_references_constraints( err = row_ins_check_foreign_constraint( FALSE, foreign, table, entry, thr); - if (ref_table != NULL) { - dict_table_close(ref_table, FALSE, FALSE); + if (ref_table) { + dict_table_close(ref_table); } if (err != DB_SUCCESS) { @@ -345,8 +345,8 @@ wsrep_row_upd_check_foreign_constraints( TRUE, foreign, table, entry, thr); if (foreign->referenced_table) { - if (opened == TRUE) { - dict_table_close(foreign->referenced_table, FALSE, FALSE); + if (opened) { + dict_table_close(foreign->referenced_table); opened = FALSE; } } diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 4f01de111832f..246a036379655 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -605,7 +605,7 @@ trx_resurrect_table_locks( p.first, FALSE, DICT_TABLE_OP_LOAD_TABLESPACE)) { if (!table->is_readable()) { dict_sys.lock(SRW_LOCK_CALL); - dict_table_close(table, TRUE, FALSE); + table->release(); dict_sys.remove(table); dict_sys.unlock(); continue; @@ -622,7 +622,7 @@ trx_resurrect_table_locks( "resurrect " << ib::hex(trx->id) << " lock on " << table->name); - dict_table_close(table, FALSE, FALSE); + table->release(); } } } @@ -1199,18 +1199,17 @@ void trx_t::evict_table(table_id_t table_id, bool reset_only) { ut_ad(in_rollback); - dict_table_t* table = dict_table_open_on_id( - table_id, true, DICT_TABLE_OP_OPEN_ONLY_IF_CACHED); + dict_table_t* table = dict_sys.find_table(table_id); if (!table) { return; } table->def_trx_id = 0; - if (!table->release()) { + if (auto ref_count = table->get_ref_count()) { /* This must be a DDL operation that is being rolled back in an active connection. */ - ut_a(table->get_ref_count() == 1); + ut_a(ref_count == 1); ut_ad(!is_recovered); ut_ad(mysql_thd); return; From c5fd9aa562fb15e8d6ededceccbec0c9792a3243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 31 Aug 2021 13:54:44 +0300 Subject: [PATCH 7/9] MDEV-25919: Lock tables before acquiring dict_sys.latch In commit 1bd681c8b3c5213ce1f7976940a7dc38b48a0d39 (MDEV-25506 part 3) we introduced a "fake instant timeout" when a transaction would wait for a table or record lock while holding dict_sys.latch. This prevented a deadlock of the server but could cause bogus errors for operations on the InnoDB persistent statistics tables. A better fix is to ensure that whenever a transaction is being executed in the InnoDB internal SQL parser (which will for now require dict_sys.latch to be held), it will already have acquired all locks that could be required for the execution. So, we will acquire the following locks upfront, before acquiring dict_sys.latch: (1) MDL on the affected user table (acquired by the SQL layer) (2) If applicable (not for RENAME TABLE): InnoDB table lock (3) If persistent statistics are going to be modified: (3.a) MDL_SHARED on mysql.innodb_table_stats, mysql.innodb_index_stats (3.b) exclusive table locks on the statistics tables (4) Exclusive table locks on the InnoDB data dictionary tables (not needed in ANALYZE TABLE and the like) Note: Acquiring exclusive locks on the statistics tables may cause more locking conflicts between concurrent DDL operations. Notably, RENAME TABLE will lock the statistics tables even if no persistent statistics are enabled for the table. DROP DATABASE will only acquire locks on statistics tables if persistent statistics are enabled for the tables on which the SQL layer is invoking ha_innobase::delete_table(). For any "garbage collection" in innodb_drop_database(), a timeout while acquiring locks on the statistics tables will result in any statistics not being deleted for any tables that the SQL layer did not know about. If innodb_defragment=ON, information may be written to the statistics tables even for tables for which InnoDB persistent statistics are disabled. But, DROP TABLE will no longer attempt to delete that information if persistent statistics are not enabled for the table. This change should also fix the hangs related to InnoDB persistent statistics and STATS_AUTO_RECALC (MDEV-15020) as well as a bug that running ALTER TABLE on the statistics tables concurrently with running ALTER TABLE on InnoDB tables could cause trouble. lock_rec_enqueue_waiting(), lock_table_enqueue_waiting(): Do not issue a fake instant timeout error when the transaction is holding dict_sys.latch. Instead, assert that the dict_sys.latch is never being held here. lock_sys_tables(): A new function to acquire exclusive locks on all dictionary tables, in case DROP TABLE or similar operation is being executed. Locking non-hard-coded tables is optional to avoid a crash in row_merge_drop_temp_indexes(). The SYS_VIRTUAL table was introduced in MySQL 5.7 and MariaDB Server 10.2. Normally, we require all these dictionary tables to exist before executing any DDL, but the function row_merge_drop_temp_indexes() is an exception. When upgrading from MariaDB Server 10.1 or MySQL 5.6 or earlier, the table SYS_VIRTUAL would not exist at this point. ha_innobase::commit_inplace_alter_table(): Invoke log_write_up_to() while not holding dict_sys.latch. dict_sys_t::remove(), dict_table_close(): No longer try to drop index stubs that were left behind by aborted online ADD INDEX. Such indexes should be dropped from the InnoDB data dictionary by row_merge_drop_indexes() as part of the failed DDL operation. Stubs for aborted indexes may only be left behind in the data dictionary cache. dict_stats_fetch_from_ps(): Use a normal read-only transaction. ha_innobase::delete_table(), ha_innobase::truncate(), fts_lock_table(): While waiting for purge to stop using the table, do not hold dict_sys.latch. ha_innobase::delete_table(): Implement a work-around for the rollback of ALTER TABLE...ADD PARTITION. MDL_EXCLUSIVE would not be held if ALTER TABLE hits lock_wait_timeout while trying to upgrade the MDL due to a conflicting LOCK TABLES, such as in the first ALTER TABLE in the test case of Bug#53676 in parts.partition_special_innodb. Therefore, we must explicitly stop purge, because it would not be stopped by MDL. dict_stats_func(), btr_defragment_chunk(): Allocate a THD so that we can acquire MDL on the InnoDB persistent statistics tables. mysqltest_embedded: Invoke ha_pre_shutdown() before free_used_memory() in order to avoid ASAN heap-use-after-free related to acquire_thd(). trx_t::dict_operation_lock_mode: Changed the type to bool. row_mysql_lock_data_dictionary(), row_mysql_unlock_data_dictionary(): Implemented as macros. rollback_inplace_alter_table(): Apply an infinite timeout to lock waits. innodb_thd_increment_pending_ops(): Wrapper for thd_increment_pending_ops(). Never attempt async operation for InnoDB background threads, such as the trx_t::commit() in dict_stats_process_entry_from_recalc_pool(). lock_sys_t::cancel(trx_t*): Make dictionary transactions immune to KILL. lock_wait(): Make dictionary transactions immune to KILL, and to lock wait timeout when waiting for locks on dictionary tables. parts.partition_special_innodb: Use lock_wait_timeout=0 to instantly get ER_LOCK_WAIT_TIMEOUT. main.mdl: Filter out MDL on InnoDB persistent statistics tables Reviewed by: Thirunarayanan Balathandayuthapani --- client/mysqltest.cc | 10 + mysql-test/main/mdl.result | 21 +- mysql-test/main/mdl.test | 21 +- .../suite/innodb/r/alter_partitioned.result | 4 + .../suite/innodb/r/innodb_defrag_stats.result | 1 + .../innodb/r/innodb_stats_drop_locked.result | 1 + .../suite/innodb/t/alter_partitioned.test | 4 + .../suite/innodb/t/innodb_defrag_stats.test | 2 + .../innodb/t/innodb_stats_drop_locked.test | 2 + .../parts/r/partition_special_innodb.result | 60 +-- .../t/partition_special_innodb-master.opt | 1 - .../parts/t/partition_special_innodb.test | 67 +--- sql/sql_class.cc | 6 +- sql/sql_class.h | 2 +- storage/innobase/btr/btr0defragment.cc | 15 +- storage/innobase/dict/dict0crea.cc | 16 +- storage/innobase/dict/dict0defrag_bg.cc | 241 ++++++++---- storage/innobase/dict/dict0dict.cc | 214 ++-------- storage/innobase/dict/dict0stats.cc | 103 +++-- storage/innobase/dict/dict0stats_bg.cc | 10 +- storage/innobase/dict/drop.cc | 6 +- storage/innobase/fts/fts0fts.cc | 12 +- storage/innobase/fts/fts0opt.cc | 2 +- storage/innobase/handler/ha_innodb.cc | 368 ++++++++++++++---- storage/innobase/handler/handler0alter.cc | 277 ++++++++----- storage/innobase/handler/i_s.cc | 14 +- storage/innobase/include/dict0defrag_bg.h | 7 +- storage/innobase/include/dict0dict.h | 28 +- storage/innobase/include/dict0mem.h | 2 +- storage/innobase/include/dict0stats.h | 17 +- storage/innobase/include/ha_prototypes.h | 10 +- storage/innobase/include/lock0lock.h | 17 + storage/innobase/include/row0merge.h | 11 - storage/innobase/include/row0mysql.h | 40 +- storage/innobase/include/row0purge.h | 2 +- storage/innobase/include/trx0trx.h | 15 +- storage/innobase/lock/lock0lock.cc | 103 +++-- storage/innobase/pars/pars0pars.cc | 2 +- storage/innobase/row/row0ftsort.cc | 2 +- storage/innobase/row/row0import.cc | 85 ++-- storage/innobase/row/row0ins.cc | 2 +- storage/innobase/row/row0merge.cc | 27 +- storage/innobase/row/row0mysql.cc | 56 +-- storage/innobase/row/row0purge.cc | 4 +- storage/innobase/row/row0uins.cc | 19 +- storage/innobase/row/row0umod.cc | 7 +- storage/innobase/row/row0upd.cc | 4 +- storage/innobase/trx/trx0trx.cc | 24 +- 48 files changed, 1111 insertions(+), 853 deletions(-) delete mode 100644 mysql-test/suite/parts/t/partition_special_innodb-master.opt diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 5008a0481485f..1979214de1726 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -1464,8 +1464,18 @@ void free_used_memory() } +#ifdef EMBEDDED_LIBRARY +void ha_pre_shutdown(); +#endif + + ATTRIBUTE_NORETURN static void cleanup_and_exit(int exit_code) { +#ifdef EMBEDDED_LIBRARY + if (server_initialized) + ha_pre_shutdown(); +#endif + free_used_memory(); /* Only call mysql_server_end if mysql_server_init has been called */ diff --git a/mysql-test/main/mdl.result b/mysql-test/main/mdl.result index fbf80312ac039..343895803b200 100644 --- a/mysql-test/main/mdl.result +++ b/mysql-test/main/mdl.result @@ -8,20 +8,23 @@ CREATE TABLE t1(a INT) ENGINE=InnoDB; CREATE TABLE t3(a INT) ENGINE=myisam; LOCK TABLES t1 WRITE CONCURRENT, t1 AS t2 READ; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; LOCK_MODE LOCK_TYPE TABLE_SCHEMA TABLE_NAME MDL_BACKUP_TRANS_DML Backup lock MDL_SHARED_NO_READ_WRITE Table metadata lock test t1 UNLOCK TABLES; LOCK TABLES t1 AS t2 READ, t1 WRITE CONCURRENT; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; LOCK_MODE LOCK_TYPE TABLE_SCHEMA TABLE_NAME MDL_BACKUP_TRANS_DML Backup lock MDL_SHARED_WRITE Table metadata lock test t1 MDL_SHARED_READ_ONLY Table metadata lock test t1 UNLOCK TABLES; LOCK TABLES t1 WRITE CONCURRENT, t3 WRITE; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; LOCK_MODE LOCK_TYPE TABLE_SCHEMA TABLE_NAME MDL_BACKUP_DDL Backup lock MDL_BACKUP_DML Backup lock @@ -30,7 +33,8 @@ MDL_SHARED_NO_READ_WRITE Table metadata lock test t3 MDL_INTENTION_EXCLUSIVE Schema metadata lock test UNLOCK TABLES; LOCK TABLES t3 WRITE, t1 WRITE CONCURRENT; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; LOCK_MODE LOCK_TYPE TABLE_SCHEMA TABLE_NAME MDL_BACKUP_DDL Backup lock MDL_BACKUP_DML Backup lock @@ -39,7 +43,8 @@ MDL_SHARED_NO_READ_WRITE Table metadata lock test t3 MDL_INTENTION_EXCLUSIVE Schema metadata lock test UNLOCK TABLES; LOCK TABLES t1 WRITE, mysql.user WRITE; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; LOCK_MODE LOCK_TYPE TABLE_SCHEMA TABLE_NAME MDL_BACKUP_DDL Backup lock MDL_SHARED_NO_READ_WRITE Table metadata lock mysql user @@ -67,7 +72,8 @@ connection locker; insert into t1 values (1); connection default; connection default; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; LOCK_MODE LOCK_TYPE TABLE_SCHEMA TABLE_NAME MDL_BACKUP_FTWRL2 Backup lock MDL_SHARED_WRITE Table metadata lock test t1 @@ -80,7 +86,8 @@ connection locker; insert into t3 values (2); connection default; connection default; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; LOCK_MODE LOCK_TYPE TABLE_SCHEMA TABLE_NAME MDL_BACKUP_FTWRL2 Backup lock MDL_SHARED_WRITE Table metadata lock test t3 diff --git a/mysql-test/main/mdl.test b/mysql-test/main/mdl.test index 0c1b7a13a0ce0..f7fac0a062dd3 100644 --- a/mysql-test/main/mdl.test +++ b/mysql-test/main/mdl.test @@ -12,19 +12,24 @@ CREATE TABLE t1(a INT) ENGINE=InnoDB; CREATE TABLE t3(a INT) ENGINE=myisam; LOCK TABLES t1 WRITE CONCURRENT, t1 AS t2 READ; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; UNLOCK TABLES; LOCK TABLES t1 AS t2 READ, t1 WRITE CONCURRENT; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; UNLOCK TABLES; LOCK TABLES t1 WRITE CONCURRENT, t3 WRITE; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; UNLOCK TABLES; LOCK TABLES t3 WRITE, t1 WRITE CONCURRENT; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; UNLOCK TABLES; LOCK TABLES t1 WRITE, mysql.user WRITE; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; UNLOCK TABLES; --error ER_CANT_LOCK_LOG_TABLE LOCK TABLES mysql.general_log WRITE; @@ -55,7 +60,8 @@ let $wait_condition= where state = "Waiting for backup lock"; --source include/wait_condition.inc connection default; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; unlock tables; connection locker; --reap @@ -72,7 +78,8 @@ let $wait_condition= where state = "Waiting for backup lock"; --source include/wait_condition.inc connection default; -SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info; +SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info +WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; unlock tables; connection locker; --reap diff --git a/mysql-test/suite/innodb/r/alter_partitioned.result b/mysql-test/suite/innodb/r/alter_partitioned.result index 6c32142db9a16..e46fa66e43b1a 100644 --- a/mysql-test/suite/innodb/r/alter_partitioned.result +++ b/mysql-test/suite/innodb/r/alter_partitioned.result @@ -11,6 +11,8 @@ SAVEPOINT sp; INSERT INTO t1 (pk) VALUES (1); ROLLBACK TO SAVEPOINT sp; connection default; +SET @save_timeout=@@lock_wait_timeout; +SET @save_innodb_timeout=@@innodb_lock_wait_timeout; SET lock_wait_timeout=0; SET innodb_lock_wait_timeout=0; ALTER TABLE t1 PARTITION BY HASH(pk); @@ -24,6 +26,8 @@ t1 CREATE TABLE `t1` ( connection con1; COMMIT; connection default; +SET lock_wait_timeout=@save_timeout; +SET innodb_lock_wait_timeout=@save_innodb_timeout; ALTER TABLE t2 PARTITION BY HASH(pk); disconnect con1; connection default; diff --git a/mysql-test/suite/innodb/r/innodb_defrag_stats.result b/mysql-test/suite/innodb/r/innodb_defrag_stats.result index c2fd378cb4b65..2dae62ebbda39 100644 --- a/mysql-test/suite/innodb/r/innodb_defrag_stats.result +++ b/mysql-test/suite/innodb/r/innodb_defrag_stats.result @@ -116,6 +116,7 @@ select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't count(stat_value) > 0 1 # Clean up +ALTER TABLE t2 STATS_PERSISTENT=1; DROP TABLE t2; select * from mysql.innodb_index_stats where table_name = 't2'; database_name table_name index_name last_update stat_name stat_value sample_size stat_description diff --git a/mysql-test/suite/innodb/r/innodb_stats_drop_locked.result b/mysql-test/suite/innodb/r/innodb_stats_drop_locked.result index 7a6d5c46aab29..13f21463390c3 100644 --- a/mysql-test/suite/innodb/r/innodb_stats_drop_locked.result +++ b/mysql-test/suite/innodb/r/innodb_stats_drop_locked.result @@ -26,6 +26,7 @@ innodb_stats_drop_locked innodb_stats_drop_locked innodb_stats_drop_locked connect con1,localhost,root,,; +SET innodb_lock_wait_timeout=1; ALTER TABLE innodb_stats_drop_locked DROP INDEX c_key; ERROR HY000: Lock wait timeout exceeded; try restarting transaction SHOW CREATE TABLE innodb_stats_drop_locked; diff --git a/mysql-test/suite/innodb/t/alter_partitioned.test b/mysql-test/suite/innodb/t/alter_partitioned.test index 4990c265b5e92..aaada25dcbe4d 100644 --- a/mysql-test/suite/innodb/t/alter_partitioned.test +++ b/mysql-test/suite/innodb/t/alter_partitioned.test @@ -18,6 +18,8 @@ INSERT INTO t1 (pk) VALUES (1); ROLLBACK TO SAVEPOINT sp; --connection default +SET @save_timeout=@@lock_wait_timeout; +SET @save_innodb_timeout=@@innodb_lock_wait_timeout; SET lock_wait_timeout=0; SET innodb_lock_wait_timeout=0; --error ER_LOCK_WAIT_TIMEOUT @@ -27,6 +29,8 @@ SHOW CREATE TABLE t1; --connection con1 COMMIT; --connection default +SET lock_wait_timeout=@save_timeout; +SET innodb_lock_wait_timeout=@save_innodb_timeout; ALTER TABLE t2 PARTITION BY HASH(pk); # Cleanup --disconnect con1 diff --git a/mysql-test/suite/innodb/t/innodb_defrag_stats.test b/mysql-test/suite/innodb/t/innodb_defrag_stats.test index 248fd24f0c897..2dc5e65309152 100644 --- a/mysql-test/suite/innodb/t/innodb_defrag_stats.test +++ b/mysql-test/suite/innodb/t/innodb_defrag_stats.test @@ -82,6 +82,8 @@ select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_leaf_pages_defrag'); --echo # Clean up +# DROP TABLE will not touch persistent statistics if the table has none! +ALTER TABLE t2 STATS_PERSISTENT=1; DROP TABLE t2; select * from mysql.innodb_index_stats where table_name = 't2'; diff --git a/mysql-test/suite/innodb/t/innodb_stats_drop_locked.test b/mysql-test/suite/innodb/t/innodb_stats_drop_locked.test index ab4cc78b337a1..6532816bb37db 100644 --- a/mysql-test/suite/innodb/t/innodb_stats_drop_locked.test +++ b/mysql-test/suite/innodb/t/innodb_stats_drop_locked.test @@ -23,6 +23,8 @@ WHERE table_name='innodb_stats_drop_locked' FOR UPDATE; -- connect (con1,localhost,root,,) +SET innodb_lock_wait_timeout=1; + --error ER_LOCK_WAIT_TIMEOUT ALTER TABLE innodb_stats_drop_locked DROP INDEX c_key; diff --git a/mysql-test/suite/parts/r/partition_special_innodb.result b/mysql-test/suite/parts/r/partition_special_innodb.result index 37191eae502b9..c36eda2345a2d 100644 --- a/mysql-test/suite/parts/r/partition_special_innodb.result +++ b/mysql-test/suite/parts/r/partition_special_innodb.result @@ -216,14 +216,12 @@ ENGINE = InnoDB PARTITION BY HASH (a) PARTITIONS 2; connect con1, localhost, root,,; -connect con2, localhost, root,,; -connection con1; SET autocommit=OFF; START TRANSACTION; INSERT INTO t1 VALUES (NULL, 'first row t2'); -connection con2; +connect con2, localhost, root,,; SET autocommit=OFF; -SET SESSION lock_wait_timeout= 1; +SET SESSION lock_wait_timeout= 0; ALTER TABLE t1 AUTO_INCREMENT = 10; ERROR HY000: Lock wait timeout exceeded; try restarting transaction disconnect con2; @@ -233,17 +231,12 @@ DROP TABLE t1; # # Bug#53676: Unexpected errors and possible table corruption on # ADD PARTITION and LOCK TABLE -connect con1,localhost,root,,; CREATE TABLE t1 ( i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, f INT ) ENGINE = InnoDB PARTITION BY HASH(i) PARTITIONS 2; INSERT INTO t1 VALUES (2, 2), (3, 3), (4, 4), (5, 5); -connect con2,localhost,root,,; -SET lock_wait_timeout = 2; -connection con1; -#Connection 1 locks the table LOCK TABLE t1 READ; -connection con2; -# Connection 2 tries to add partitions: +connect con2,localhost,root,,; +SET lock_wait_timeout = 0; # First attempt: lock wait timeout (as expected) ALTER TABLE t1 ADD PARTITION PARTITIONS 2; ERROR HY000: Lock wait timeout exceeded; try restarting transaction @@ -263,12 +256,10 @@ i f 3 3 4 4 5 5 -connection con1; -# Connection 1 unlocks the table and locks it again: +connection default; UNLOCK TABLES; LOCK TABLE t1 READ; connection con2; -# Connection 2 tries again to add partitions: # Third attempt: says that the table does not exist ALTER TABLE t1 ADD PARTITION PARTITIONS 2; ERROR HY000: Lock wait timeout exceeded; try restarting transaction @@ -276,22 +267,21 @@ ERROR HY000: Lock wait timeout exceeded; try restarting transaction CHECK TABLE t1; Table Op Msg_type Msg_text test.t1 check status OK -connection con1; +connection default; UNLOCK TABLES; connection con2; DROP TABLE t1; -connection con1; +connection default; CREATE TABLE t2 ( i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, f INT ) ENGINE = InnoDB PARTITION BY HASH(i) PARTITIONS 2; -connection con2; -SET lock_wait_timeout = 2; -connection con1; LOCK TABLE t2 READ; connection con2; +SET lock_wait_timeout = 0; ALTER TABLE t2 ADD PARTITION PARTITIONS 2; ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SET lock_wait_timeout = 2; ALTER TABLE t2 ADD PARTITION PARTITIONS 2; -connection con1; +connection default; UNLOCK TABLES; connection con2; connect con3,localhost,root,,; @@ -301,31 +291,23 @@ test.t2 check status OK SELECT * FROM t2; i f DROP TABLE t2; -connection con1; +connection default; CREATE TABLE t3 ( i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, f INT ) ENGINE = InnoDB PARTITION BY HASH(i) PARTITIONS 2; -connection con2; -SET lock_wait_timeout = 2; -connection con1; -# Connection 1 locks the table LOCK TABLE t3 READ; connection con2; -# Connection 2 tries to add partitions (timeout): +SET lock_wait_timeout = 0; ALTER TABLE t3 ADD PARTITION PARTITIONS 2; ERROR HY000: Lock wait timeout exceeded; try restarting transaction connection con3; -SET lock_wait_timeout = 2; -# Connection 3 tries to add partitions (partition already exists): +SET lock_wait_timeout = 0; ALTER TABLE t3 ADD PARTITION PARTITIONS 2; ERROR HY000: Lock wait timeout exceeded; try restarting transaction connect con4,localhost,root,,; -# Connection 4 tries to rename the table: RENAME TABLE t3 TO t4; -connection con1; -# Connection 1 unlocks the table: +connection default; UNLOCK TABLES; connection con4; -# Connection 4 gets error on rename: connect con5,localhost,root,,; # SHOW TABLES returns the table (not renamed): SHOW TABLES; @@ -339,7 +321,6 @@ disconnect con5; disconnect con4; disconnect con3; disconnect con2; -disconnect con1; connection default; CREATE TABLE t1( f1 INT, f2 VARCHAR(10) CHARSET ascii, @@ -350,17 +331,12 @@ PARTITION p2 VALUES LESS THAN (100)); ALTER TABLE t1 convert to charset ascii collate ascii_bin, ALGORITHM=INSTANT; DROP TABLE t1; # Test WRITE LOCK. -connect con1,localhost,root,,; CREATE TABLE t1 ( i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, f INT ) ENGINE = InnoDB PARTITION BY HASH(i) PARTITIONS 2; INSERT INTO t1 VALUES (3, 3), (4, 4); -connect con2,localhost,root,,; -SET lock_wait_timeout = 2; -connection con1; -#Connection 1 locks the table LOCK TABLE t1 WRITE; -connection con2; -# Check that we still can SELECT, but not insert/update/delete. +connect con2,localhost,root,,; +SET lock_wait_timeout = 0; # Check that we only can select, not insert/update/delete. INSERT INTO t1 VALUES (NULL, 1), (NULL, 2), (10, 10), (11, 11); ERROR HY000: Lock wait timeout exceeded; try restarting transaction @@ -370,9 +346,9 @@ DELETE FROM t1 WHERE i = 10; ERROR HY000: Lock wait timeout exceeded; try restarting transaction SELECT * FROM t1; ERROR HY000: Lock wait timeout exceeded; try restarting transaction -connection con1; +connection default; UNLOCK TABLES; connection con2; DROP TABLE t1; -disconnect con1; +disconnect con2; connection default; diff --git a/mysql-test/suite/parts/t/partition_special_innodb-master.opt b/mysql-test/suite/parts/t/partition_special_innodb-master.opt deleted file mode 100644 index 79851bac7b233..0000000000000 --- a/mysql-test/suite/parts/t/partition_special_innodb-master.opt +++ /dev/null @@ -1 +0,0 @@ ---loose-innodb-lock-wait-timeout=2 --loose-innodb-file-per-table diff --git a/mysql-test/suite/parts/t/partition_special_innodb.test b/mysql-test/suite/parts/t/partition_special_innodb.test index a25feed08ef1d..6273cc5cb2aec 100644 --- a/mysql-test/suite/parts/t/partition_special_innodb.test +++ b/mysql-test/suite/parts/t/partition_special_innodb.test @@ -59,16 +59,13 @@ PARTITION BY HASH (a) PARTITIONS 2; connect (con1, localhost, root,,); -connect (con2, localhost, root,,); - ---connection con1 SET autocommit=OFF; START TRANSACTION; INSERT INTO t1 VALUES (NULL, 'first row t2'); ---connection con2 +connect (con2, localhost, root,,); SET autocommit=OFF; -SET SESSION lock_wait_timeout= 1; +SET SESSION lock_wait_timeout= 0; --error ER_LOCK_WAIT_TIMEOUT ALTER TABLE t1 AUTO_INCREMENT = 10; @@ -80,20 +77,14 @@ DROP TABLE t1; --echo # --echo # Bug#53676: Unexpected errors and possible table corruption on --echo # ADD PARTITION and LOCK TABLE ---connect (con1,localhost,root,,) CREATE TABLE t1 ( i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, f INT ) ENGINE = InnoDB PARTITION BY HASH(i) PARTITIONS 2; INSERT INTO t1 VALUES (2, 2), (3, 3), (4, 4), (5, 5); ---connect (con2,localhost,root,,) -SET lock_wait_timeout = 2; - ---connection con1 ---echo #Connection 1 locks the table LOCK TABLE t1 READ; ---connection con2 ---echo # Connection 2 tries to add partitions: +--connect (con2,localhost,root,,) +SET lock_wait_timeout = 0; --echo # First attempt: lock wait timeout (as expected) --error ER_LOCK_WAIT_TIMEOUT ALTER TABLE t1 ADD PARTITION PARTITIONS 2; @@ -110,21 +101,18 @@ DELETE FROM t1 WHERE i = 10; --sorted_result SELECT * FROM t1; ---connection con1 ---echo # Connection 1 unlocks the table and locks it again: +--connection default UNLOCK TABLES; ---real_sleep 1 LOCK TABLE t1 READ; --connection con2 ---echo # Connection 2 tries again to add partitions: --echo # Third attempt: says that the table does not exist --error ER_LOCK_WAIT_TIMEOUT ALTER TABLE t1 ADD PARTITION PARTITIONS 2; --echo # Check table returns the same (not after fixing bug#56172!) CHECK TABLE t1; ---connection con1 +--connection default UNLOCK TABLES; --connection con2 @@ -134,23 +122,21 @@ DROP TABLE t1; # Test2 ---connection con1 +--connection default CREATE TABLE t2 ( i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, f INT ) ENGINE = InnoDB PARTITION BY HASH(i) PARTITIONS 2; ---connection con2 -SET lock_wait_timeout = 2; - ---connection con1 LOCK TABLE t2 READ; --connection con2 +SET lock_wait_timeout = 0; --error ER_LOCK_WAIT_TIMEOUT ALTER TABLE t2 ADD PARTITION PARTITIONS 2; +SET lock_wait_timeout = 2; send ALTER TABLE t2 ADD PARTITION PARTITIONS 2; ---connection con1 +--connection default UNLOCK TABLES; --connection con2 @@ -164,40 +150,30 @@ DROP TABLE t2; # End of Test2 # Test #3 ---connection con1 +--connection default CREATE TABLE t3 ( i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, f INT ) ENGINE = InnoDB PARTITION BY HASH(i) PARTITIONS 2; ---connection con2 -SET lock_wait_timeout = 2; - ---connection con1 ---echo # Connection 1 locks the table LOCK TABLE t3 READ; --connection con2 ---echo # Connection 2 tries to add partitions (timeout): +SET lock_wait_timeout = 0; --error ER_LOCK_WAIT_TIMEOUT ALTER TABLE t3 ADD PARTITION PARTITIONS 2; --connection con3 -SET lock_wait_timeout = 2; ---echo # Connection 3 tries to add partitions (partition already exists): +SET lock_wait_timeout = 0; --error ER_LOCK_WAIT_TIMEOUT ALTER TABLE t3 ADD PARTITION PARTITIONS 2; --connect (con4,localhost,root,,) ---echo # Connection 4 tries to rename the table: send RENAME TABLE t3 TO t4; ---connection con1 ---real_sleep 1 ---echo # Connection 1 unlocks the table: +--connection default UNLOCK TABLES; --connection con4 ---echo # Connection 4 gets error on rename: --reap --connect (con5,localhost,root,,) @@ -212,7 +188,6 @@ DROP TABLE t4; --disconnect con4 --disconnect con3 --disconnect con2 ---disconnect con1 --connection default # End of Test #3 @@ -227,20 +202,14 @@ ALTER TABLE t1 convert to charset ascii collate ascii_bin, ALGORITHM=INSTANT; DROP TABLE t1; --echo # Test WRITE LOCK. ---connect (con1,localhost,root,,) CREATE TABLE t1 ( i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, f INT ) ENGINE = InnoDB PARTITION BY HASH(i) PARTITIONS 2; INSERT INTO t1 VALUES (3, 3), (4, 4); ---connect (con2,localhost,root,,) -SET lock_wait_timeout = 2; - ---connection con1 ---echo #Connection 1 locks the table LOCK TABLE t1 WRITE; ---connection con2 ---echo # Check that we still can SELECT, but not insert/update/delete. +--connect (con2,localhost,root,,) +SET lock_wait_timeout = 0; --echo # Check that we only can select, not insert/update/delete. --error ER_LOCK_WAIT_TIMEOUT INSERT INTO t1 VALUES (NULL, 1), (NULL, 2), (10, 10), (11, 11); @@ -251,11 +220,11 @@ DELETE FROM t1 WHERE i = 10; --error ER_LOCK_WAIT_TIMEOUT SELECT * FROM t1; ---connection con1 +--connection default UNLOCK TABLES; --connection con2 DROP TABLE t1; ---disconnect con1 +--disconnect con2 --connection default diff --git a/sql/sql_class.cc b/sql/sql_class.cc index c26d8906cbd09..a758196feeaf1 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -5018,13 +5018,9 @@ void reset_thd(MYSQL_THD thd) guarantees, in other words, server can't send OK packet before modified data is durable in redo log. */ -extern "C" MYSQL_THD thd_increment_pending_ops(void) +extern "C" void thd_increment_pending_ops(MYSQL_THD thd) { - THD *thd = current_thd; - if (!thd) - return NULL; thd->async_state.inc_pending_ops(); - return thd; } /** diff --git a/sql/sql_class.h b/sql/sql_class.h index 2fecf60c0861c..b5874d2435a0e 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2531,7 +2531,7 @@ struct thd_async_state } }; -extern "C" MYSQL_THD thd_increment_pending_ops(void); +extern "C" void thd_increment_pending_ops(MYSQL_THD); extern "C" void thd_decrement_pending_ops(MYSQL_THD); diff --git a/storage/innobase/btr/btr0defragment.cc b/storage/innobase/btr/btr0defragment.cc index fa0ad06d7aba0..0e21acb4fda4d 100644 --- a/storage/innobase/btr/btr0defragment.cc +++ b/storage/innobase/btr/btr0defragment.cc @@ -36,6 +36,7 @@ Modified 30/07/2014 Jan Lindström jan.lindstrom@mariadb.com #include "ibuf0ibuf.h" #include "lock0lock.h" #include "srv0start.h" +#include "mysqld.h" #include @@ -614,6 +615,9 @@ The state (current item) is stored in function parameter. */ static void btr_defragment_chunk(void*) { + THD *thd = innobase_create_background_thd("InnoDB defragment"); + set_current_thd(thd); + btr_defragment_item_t* item = nullptr; mtr_t mtr; @@ -622,7 +626,11 @@ static void btr_defragment_chunk(void*) while (srv_shutdown_state == SRV_SHUTDOWN_NONE) { if (!item) { if (btr_defragment_wq.empty()) { +release_and_exit: mysql_mutex_unlock(&btr_defragment_mutex); +func_exit: + set_current_thd(nullptr); + innobase_destroy_background_thd(thd); return; } item = *btr_defragment_wq.begin(); @@ -651,7 +659,7 @@ static void btr_defragment_chunk(void*) int sleep_ms = (int)((srv_defragment_interval - elapsed) / 1000 / 1000); if (sleep_ms) { btr_defragment_timer->set_time(sleep_ms, 0); - return; + goto func_exit; } } log_free_check(); @@ -693,7 +701,8 @@ static void btr_defragment_chunk(void*) << " index " << index->name() << " failed with error " << err; } else { - err = dict_stats_save_defrag_summary(index); + err = dict_stats_save_defrag_summary(index, + thd); if (err != DB_SUCCESS) { ib::error() << "Saving defragmentation summary for table " @@ -711,5 +720,5 @@ static void btr_defragment_chunk(void*) } } - mysql_mutex_unlock(&btr_defragment_mutex); + goto release_and_exit; } diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc index eafc9bf78146a..667a64f907a7d 100644 --- a/storage/innobase/dict/dict0crea.cc +++ b/storage/innobase/dict/dict0crea.cc @@ -33,6 +33,7 @@ Created 1/8/1996 Heikki Tuuri #include "mach0data.h" #include "dict0boot.h" #include "dict0dict.h" +#include "lock0lock.h" #include "que0que.h" #include "row0ins.h" #include "row0mysql.h" @@ -653,7 +654,7 @@ dict_build_index_def_step( index = node->index; table = dict_table_open_on_name( - node->table_name, TRUE, FALSE, DICT_ERR_IGNORE_DROP); + node->table_name, true, DICT_ERR_IGNORE_DROP); if (!table) { return DB_TABLE_NOT_FOUND; @@ -1377,7 +1378,18 @@ dberr_t dict_sys_t::create_or_check_sys_tables() return DB_SUCCESS; trx_t *trx= trx_create(); - trx->dict_operation= true; + trx_start_for_ddl(trx); + + { + LockMutexGuard g{SRW_LOCK_CALL}; + trx->mutex_lock(); + lock_table_create(dict_sys.sys_tables, LOCK_X, trx); + lock_table_create(dict_sys.sys_columns, LOCK_X, trx); + lock_table_create(dict_sys.sys_indexes, LOCK_X, trx); + lock_table_create(dict_sys.sys_fields, LOCK_X, trx); + trx->mutex_unlock(); + } + row_mysql_lock_data_dictionary(trx); /* NOTE: when designing InnoDB's foreign key support in 2001, Heikki Tuuri diff --git a/storage/innobase/dict/dict0defrag_bg.cc b/storage/innobase/dict/dict0defrag_bg.cc index 44cc4289a672c..8dd1a8601aab6 100644 --- a/storage/innobase/dict/dict0defrag_bg.cc +++ b/storage/innobase/dict/dict0defrag_bg.cc @@ -29,6 +29,9 @@ Created 25/08/2016 Jan Lindström #include "dict0defrag_bg.h" #include "btr0btr.h" #include "srv0start.h" +#include "trx0trx.h" +#include "lock0lock.h" +#include "row0mysql.h" static mysql_mutex_t defrag_pool_mutex; @@ -200,44 +203,84 @@ static void dict_stats_process_entry_from_defrag_pool() } } -/*****************************************************************//** +/** Get the first index that has been added for updating persistent defrag stats and eventually save its stats. */ -void -dict_defrag_process_entries_from_defrag_pool() -/*==========================================*/ +void dict_defrag_process_entries_from_defrag_pool() { - while (defrag_pool.size()) { - dict_stats_process_entry_from_defrag_pool(); - } + while (!defrag_pool.empty()) + dict_stats_process_entry_from_defrag_pool(); } /*********************************************************************//** Save defragmentation result. @return DB_SUCCESS or error code */ -dberr_t -dict_stats_save_defrag_summary( -/*============================*/ - dict_index_t* index) /*!< in: index */ +dberr_t dict_stats_save_defrag_summary(dict_index_t *index, THD *thd) { - dberr_t ret=DB_SUCCESS; - - if (dict_index_is_ibuf(index)) { - return DB_SUCCESS; - } - - dict_sys.lock(SRW_LOCK_CALL); + if (index->is_ibuf()) + return DB_SUCCESS; - ret = dict_stats_save_index_stat(index, time(NULL), "n_pages_freed", - index->stat_defrag_n_pages_freed, - NULL, - "Number of pages freed during" - " last defragmentation run.", - NULL); + MDL_ticket *mdl_table= nullptr, *mdl_index= nullptr; + dict_table_t *table_stats= dict_table_open_on_name(TABLE_STATS_NAME, false, + DICT_ERR_IGNORE_NONE); + if (table_stats) + { + dict_sys.freeze(SRW_LOCK_CALL); + table_stats= dict_acquire_mdl_shared(table_stats, thd, &mdl_table); + dict_sys.unfreeze(); + } + if (!table_stats || strcmp(table_stats->name.m_name, TABLE_STATS_NAME)) + { +release_and_exit: + if (table_stats) + dict_table_close(table_stats, false, thd, mdl_table); + return DB_STATS_DO_NOT_EXIST; + } - dict_sys.unlock(); + dict_table_t *index_stats= dict_table_open_on_name(INDEX_STATS_NAME, false, + DICT_ERR_IGNORE_NONE); + if (index_stats) + { + dict_sys.freeze(SRW_LOCK_CALL); + index_stats= dict_acquire_mdl_shared(index_stats, thd, &mdl_index); + dict_sys.unfreeze(); + } + if (!index_stats) + goto release_and_exit; + if (strcmp(index_stats->name.m_name, INDEX_STATS_NAME)) + { + dict_table_close(index_stats, false, thd, mdl_index); + goto release_and_exit; + } - return (ret); + trx_t *trx= trx_create(); + trx->mysql_thd= thd; + trx_start_internal(trx); + dberr_t ret= lock_table_for_trx(table_stats, trx, LOCK_X); + if (ret == DB_SUCCESS) + ret= lock_table_for_trx(index_stats, trx, LOCK_X); + row_mysql_lock_data_dictionary(trx); + if (ret == DB_SUCCESS) + ret= dict_stats_save_index_stat(index, time(nullptr), "n_pages_freed", + index->stat_defrag_n_pages_freed, + nullptr, + "Number of pages freed during" + " last defragmentation run.", + trx); + if (ret == DB_SUCCESS) + trx->commit(); + else + trx->rollback(); + + if (table_stats) + dict_table_close(table_stats, true, thd, mdl_table); + if (index_stats) + dict_table_close(index_stats, true, thd, mdl_index); + + row_mysql_unlock_data_dictionary(trx); + trx->free(); + + return ret; } /**************************************************************//** @@ -293,63 +336,97 @@ dict_stats_save_defrag_stats( /*============================*/ dict_index_t* index) /*!< in: index */ { - dberr_t ret; - - if (dict_index_is_ibuf(index)) { - return DB_SUCCESS; - } - - if (!index->is_readable()) { - return dict_stats_report_error(index->table, true); - } - - const time_t now = time(NULL); - mtr_t mtr; - ulint n_leaf_pages; - ulint n_leaf_reserved; - mtr.start(); - mtr_s_lock_index(index, &mtr); - n_leaf_reserved = btr_get_size_and_reserved(index, BTR_N_LEAF_PAGES, - &n_leaf_pages, &mtr); - mtr.commit(); - - if (n_leaf_reserved == ULINT_UNDEFINED) { - // The index name is different during fast index creation, - // so the stats won't be associated with the right index - // for later use. We just return without saving. - return DB_SUCCESS; - } + if (index->is_ibuf()) + return DB_SUCCESS; + if (!index->is_readable()) + return dict_stats_report_error(index->table, true); + + const time_t now= time(nullptr); + mtr_t mtr; + ulint n_leaf_pages; + mtr.start(); + mtr_s_lock_index(index, &mtr); + ulint n_leaf_reserved= btr_get_size_and_reserved(index, BTR_N_LEAF_PAGES, + &n_leaf_pages, &mtr); + mtr.commit(); + + if (n_leaf_reserved == ULINT_UNDEFINED) + return DB_SUCCESS; + + THD *thd= current_thd; + MDL_ticket *mdl_table= nullptr, *mdl_index= nullptr; + dict_table_t* table_stats= dict_table_open_on_name(TABLE_STATS_NAME, false, + DICT_ERR_IGNORE_NONE); + if (table_stats) + { + dict_sys.freeze(SRW_LOCK_CALL); + table_stats= dict_acquire_mdl_shared(table_stats, thd, &mdl_table); + dict_sys.unfreeze(); + } + if (!table_stats || strcmp(table_stats->name.m_name, TABLE_STATS_NAME)) + { +release_and_exit: + if (table_stats) + dict_table_close(table_stats, false, thd, mdl_table); + return DB_STATS_DO_NOT_EXIST; + } - dict_sys.lock(SRW_LOCK_CALL); - ret = dict_stats_save_index_stat(index, now, "n_page_split", - index->stat_defrag_n_page_split, - NULL, - "Number of new page splits on leaves" - " since last defragmentation.", - NULL); - if (ret != DB_SUCCESS) { - goto end; - } + dict_table_t *index_stats= dict_table_open_on_name(INDEX_STATS_NAME, false, + DICT_ERR_IGNORE_NONE); + if (index_stats) + { + dict_sys.freeze(SRW_LOCK_CALL); + index_stats= dict_acquire_mdl_shared(index_stats, thd, &mdl_index); + dict_sys.unfreeze(); + } + if (!index_stats) + goto release_and_exit; - ret = dict_stats_save_index_stat( - index, now, "n_leaf_pages_defrag", - n_leaf_pages, - NULL, - "Number of leaf pages when this stat is saved to disk", - NULL); - if (ret != DB_SUCCESS) { - goto end; - } + if (strcmp(index_stats->name.m_name, INDEX_STATS_NAME)) + { + dict_table_close(index_stats, false, thd, mdl_index); + goto release_and_exit; + } - ret = dict_stats_save_index_stat( - index, now, "n_leaf_pages_reserved", - n_leaf_reserved, - NULL, - "Number of pages reserved for this index leaves when this stat " - "is saved to disk", - NULL); - -end: - dict_sys.unlock(); - return ret; + trx_t *trx= trx_create(); + trx->mysql_thd= thd; + trx_start_internal(trx); + dberr_t ret= lock_table_for_trx(table_stats, trx, LOCK_X); + if (ret == DB_SUCCESS) + ret= lock_table_for_trx(index_stats, trx, LOCK_X); + + row_mysql_lock_data_dictionary(trx); + + if (ret == DB_SUCCESS) + ret= dict_stats_save_index_stat(index, now, "n_page_split", + index->stat_defrag_n_page_split, nullptr, + "Number of new page splits on leaves" + " since last defragmentation.", trx); + + if (ret == DB_SUCCESS) + ret= dict_stats_save_index_stat(index, now, "n_leaf_pages_defrag", + n_leaf_pages, nullptr, + "Number of leaf pages when" + " this stat is saved to disk", trx); + + if (ret == DB_SUCCESS) + ret= dict_stats_save_index_stat(index, now, "n_leaf_pages_reserved", + n_leaf_reserved, nullptr, + "Number of pages reserved for" + " this index leaves" + " when this stat is saved to disk", trx); + + if (ret == DB_SUCCESS) + trx->commit(); + else + trx->rollback(); + + if (table_stats) + dict_table_close(table_stats, true, thd, mdl_table); + if (index_stats) + dict_table_close(index_stats, true, thd, mdl_index); + row_mysql_unlock_data_dictionary(trx); + trx->free(); + + return ret; } diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 13b71c9a8b68b..447ff7929f006 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -209,110 +209,26 @@ dict_remove_db_name( return(s + 1); } -/** Open a persistent table. -@param[in] table_id persistent table identifier -@param[in] ignore_err errors to ignore -@param[in] cached_only whether to skip loading -@return persistent table -@retval NULL if not found */ -static dict_table_t* dict_table_open_on_id_low( - table_id_t table_id, - dict_err_ignore_t ignore_err, - bool cached_only) -{ - dict_table_t* table = dict_sys.find_table(table_id); - - if (!table && !cached_only) { - table = dict_load_table_on_id(table_id, ignore_err); - } - - return table; -} - -/**********************************************************************//** -Try to drop any indexes after an aborted index creation. -This can also be after a server kill during DROP INDEX. */ -static -void -dict_table_try_drop_aborted( -/*========================*/ - dict_table_t* table, /*!< in: table, or NULL if it - needs to be looked up again */ - table_id_t table_id, /*!< in: table identifier */ - uint32_t ref_count) /*!< in: expected table->n_ref_count */ -{ - trx_t* trx; - - trx = trx_create(); - trx->op_info = "try to drop any indexes after an aborted index creation"; - row_mysql_lock_data_dictionary(trx); - trx->dict_operation = true; - - if (table == NULL) { - table = dict_table_open_on_id_low( - table_id, DICT_ERR_IGNORE_FK_NOKEY, FALSE); - } else { - ut_ad(table->id == table_id); - } - - if (table && table->get_ref_count() == ref_count && table->drop_aborted - && !UT_LIST_GET_FIRST(table->locks)) { - /* Silence a debug assertion in row_merge_drop_indexes(). */ - ut_d(table->acquire()); - row_merge_drop_indexes(trx, table, true); - ut_d(table->release()); - ut_ad(table->get_ref_count() == ref_count); - trx_commit_for_mysql(trx); - } - - row_mysql_unlock_data_dictionary(trx); - trx->free(); -} - -/**********************************************************************//** -When opening a table, -try to drop any indexes after an aborted index creation. -Invoke dict_sys.unlock(). */ -static -void -dict_table_try_drop_aborted_and_unlock( - dict_table_t* table, /*!< in: table (may be NULL) */ - ibool try_drop) /*!< in: FALSE if should try to - drop indexes whose online creation - was aborted */ -{ - if (try_drop - && table != NULL - && table->drop_aborted - && table->get_ref_count() == 1 - && dict_table_get_first_index(table)) { - - /* Attempt to drop the indexes whose online creation - was aborted. */ - table_id_t table_id = table->id; - - dict_sys.unlock(); - - dict_table_try_drop_aborted(table, table_id, 1); - } else { - dict_sys.unlock(); - } -} - /** Decrement the count of open handles */ void dict_table_close(dict_table_t *table) { - if (dict_stats_is_persistent_enabled(table) && + if (table->get_ref_count() == 1 && + dict_stats_is_persistent_enabled(table) && strchr(table->name.m_name, '/')) { - dict_sys.freeze(SRW_LOCK_CALL); + /* It looks like we are closing the last handle. The user could + have executed FLUSH TABLES in order to have the statistics reloaded + from the InnoDB persistent statistics tables. We must acquire + exclusive dict_sys.latch to prevent a race condition with another + thread concurrently acquiring a handle on the table. */ + dict_sys.lock(SRW_LOCK_CALL); if (table->release()) { table->stats_mutex_lock(); dict_stats_deinit(table); table->stats_mutex_unlock(); } - dict_sys.unfreeze(); + dict_sys.unlock(); } else table->release(); @@ -320,9 +236,7 @@ void dict_table_close(dict_table_t *table) /** Decrements the count of open handles of a table. @param[in,out] table table -@param[in] dict_locked data dictionary locked -@param[in] try_drop try to drop any orphan indexes after - an aborted online index creation +@param[in] dict_locked whether dict_sys.latch is being held @param[in] thd thread to release MDL @param[in] mdl metadata lock or NULL if the thread is a foreground one. */ @@ -330,57 +244,32 @@ void dict_table_close( dict_table_t* table, bool dict_locked, - bool try_drop, THD* thd, MDL_ticket* mdl) { - if (!dict_locked) { - dict_sys.lock(SRW_LOCK_CALL); - } - - ut_ad(dict_sys.locked()); - ut_a(table->get_ref_count() > 0); - - const bool last_handle = table->release(); - - /* Force persistent stats re-read upon next open of the table - so that FLUSH TABLE can be used to forcibly fetch stats from disk - if they have been manually modified. We reset table->stat_initialized - only if table reference count is 0 because we do not want too frequent - stats re-reads (e.g. in other cases than FLUSH TABLE). */ - if (last_handle - && dict_stats_is_persistent_enabled(table) - && strchr(table->name.m_name, '/')) { - - table->stats_mutex_lock(); - dict_stats_deinit(table); - table->stats_mutex_unlock(); - } - - ut_ad(dict_lru_validate()); - ut_ad(dict_sys.find(table)); - - if (!dict_locked) { - table_id_t table_id = table->id; - const bool drop_aborted = last_handle && try_drop - && table->drop_aborted - && dict_table_get_first_index(table); - - dict_sys.unlock(); + if (!dict_locked) + dict_table_close(table); + else + { + if (table->release() && dict_stats_is_persistent_enabled(table) && + strchr(table->name.m_name, '/')) + { + /* Force persistent stats re-read upon next open of the table so + that FLUSH TABLE can be used to forcibly fetch stats from disk if + they have been manually modified. */ + table->stats_mutex_lock(); + dict_stats_deinit(table); + table->stats_mutex_unlock(); + } - /* dict_table_try_drop_aborted() can generate undo logs. - So it should be avoided after shutdown of background - threads */ - if (drop_aborted && !srv_undo_sources) { - dict_table_try_drop_aborted(NULL, table_id, 0); - } - } + ut_ad(dict_lru_validate()); + ut_ad(dict_sys.find(table)); + } - if (!thd || !mdl) { - } else if (MDL_context *mdl_context= static_cast( - thd_mdl_context(thd))) { - mdl_context->release_lock(mdl); - } + if (!thd || !mdl); + else if (MDL_context *mdl_context= static_cast + (thd_mdl_context(thd))) + mdl_context->release_lock(mdl); } /** Check if the table has a given (non_virtual) column. @@ -1117,22 +1006,20 @@ ATTRIBUTE_NOINLINE void dict_sys_t::unfreeze() #endif /* UNIV_PFS_RWLOCK */ /**********************************************************************//** -Returns a table object and increment its open handle count. +Returns a table object and increments its open handle count. NOTE! This is a high-level function to be used mainly from outside the -'dict' module. Inside this directory dict_table_get_low +'dict' directory. Inside this directory dict_table_get_low is usually the appropriate function. -@return table, NULL if does not exist */ +@param[in] table_name Table name +@param[in] dict_locked whether dict_sys.latch is being held exclusively +@param[in] ignore_err error to be ignored when loading the table +@return table +@retval nullptr if does not exist */ dict_table_t* dict_table_open_on_name( -/*====================*/ - const char* table_name, /*!< in: table name */ - ibool dict_locked, /*!< in: TRUE=data dictionary locked */ - ibool try_drop, /*!< in: TRUE=try to drop any orphan - indexes after an aborted online - index creation */ - dict_err_ignore_t - ignore_err) /*!< in: error to be ignored when - loading a table definition */ + const char* table_name, + bool dict_locked, + dict_err_ignore_t ignore_err) { dict_table_t *table; DBUG_ENTER("dict_table_open_on_name"); @@ -1183,7 +1070,7 @@ dict_table_open_on_name( ut_ad(dict_lru_validate()); if (!dict_locked) - dict_table_try_drop_aborted_and_unlock(table, try_drop); + dict_sys.unlock(); DBUG_RETURN(table); } @@ -1979,23 +1866,6 @@ void dict_sys_t::remove(dict_table_t* table, bool lru, bool keep) UT_LIST_REMOVE(table_non_LRU, table); } - if (lru && table->drop_aborted) { - /* When evicting the table definition, - drop the orphan indexes from the data dictionary - and free the index pages. */ - trx_t* trx = trx_create(); - - ut_ad(dict_sys.locked()); - /* Mimic row_mysql_lock_data_dictionary(). */ - trx->dict_operation_lock_mode = RW_X_LATCH; - - trx->dict_operation = true; - row_merge_drop_indexes_dict(trx, table->id); - trx_commit_for_mysql(trx); - trx->dict_operation_lock_mode = 0; - trx->free(); - } - /* Free virtual column template if any */ if (table->vc_templ != NULL) { dict_free_vc_templ(table->vc_templ); diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index 9c4d87f3feaac..2eced56c5e29f 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -25,11 +25,10 @@ Created Jan 06, 2010 Vasil Dimov *******************************************************/ #include "dict0stats.h" -#include "ut0ut.h" -#include "ut0rnd.h" #include "dyn0buf.h" #include "row0sel.h" #include "trx0trx.h" +#include "lock0lock.h" #include "pars0pars.h" #include #include "log.h" @@ -142,7 +141,7 @@ typedef ut_allocator > typedef std::map index_map_t; -inline bool dict_table_t::is_stats_table() const +bool dict_table_t::is_stats_table() const { return !strcmp(name.m_name, TABLE_STATS_NAME) || !strcmp(name.m_name, INDEX_STATS_NAME); @@ -517,9 +516,7 @@ This function will free the pinfo object. @param[in,out] pinfo pinfo to pass to que_eval_sql() must already have any literals bound to it @param[in] sql SQL string to execute -@param[in,out] trx in case of NULL the function will allocate and -free the trx object. If it is not NULL then it will be rolled back -only in the case of error, but not freed. +@param[in,out] trx transaction @return DB_SUCCESS or error code */ static dberr_t dict_stats_exec_sql(pars_info_t *pinfo, const char* sql, trx_t *trx) @@ -532,22 +529,7 @@ dberr_t dict_stats_exec_sql(pars_info_t *pinfo, const char* sql, trx_t *trx) return DB_STATS_DO_NOT_EXIST; } - if (trx) - return que_eval_sql(pinfo, sql, trx); - - trx= trx_create(); - trx_start_internal(trx); - - trx->dict_operation_lock_mode= RW_X_LATCH; - dberr_t err= que_eval_sql(pinfo, sql, trx); - - if (err == DB_SUCCESS) - trx->commit(); - else - trx->rollback(); - trx->dict_operation_lock_mode= 0; - trx->free(); - return err; + return que_eval_sql(pinfo, sql, trx); } /*********************************************************************//** @@ -2557,9 +2539,7 @@ storage. @param[in] stat_value value of the stat @param[in] sample_size n pages sampled or NULL @param[in] stat_description description of the stat -@param[in,out] trx in case of NULL the function will -allocate and free the trx object. If it is not NULL then it will be -rolled back only in the case of error, but not freed. +@param[in,out] trx transaction @return DB_SUCCESS or error code */ dberr_t dict_stats_save_index_stat( @@ -2690,8 +2670,6 @@ dict_stats_save( const index_id_t* only_for_index) { pars_info_t* pinfo; - dberr_t ret; - dict_table_t* table; char db_utf8[MAX_DB_UTF8_LEN]; char table_utf8[MAX_TABLE_UTF8_LEN]; @@ -2703,16 +2681,59 @@ dict_stats_save( return (dict_stats_report_error(table_orig)); } - table = dict_stats_snapshot_create(table_orig); + THD* thd = current_thd; + MDL_ticket *mdl_table = nullptr, *mdl_index = nullptr; + dict_table_t* table_stats = dict_table_open_on_name( + TABLE_STATS_NAME, false, DICT_ERR_IGNORE_NONE); + if (table_stats) { + dict_sys.freeze(SRW_LOCK_CALL); + table_stats = dict_acquire_mdl_shared(table_stats, thd, + &mdl_table); + dict_sys.unfreeze(); + } + if (!table_stats + || strcmp(table_stats->name.m_name, TABLE_STATS_NAME)) { +release_and_exit: + if (table_stats) { + dict_table_close(table_stats, false, thd, mdl_table); + } + return DB_STATS_DO_NOT_EXIST; + } + + dict_table_t* index_stats = dict_table_open_on_name( + INDEX_STATS_NAME, false, DICT_ERR_IGNORE_NONE); + if (index_stats) { + dict_sys.freeze(SRW_LOCK_CALL); + index_stats = dict_acquire_mdl_shared(index_stats, thd, + &mdl_index); + dict_sys.unfreeze(); + } + if (!index_stats) { + goto release_and_exit; + } + if (strcmp(index_stats->name.m_name, INDEX_STATS_NAME)) { + dict_table_close(index_stats, false, thd, mdl_index); + goto release_and_exit; + } + + dict_table_t* table = dict_stats_snapshot_create(table_orig); dict_fs2utf8(table->name.m_name, db_utf8, sizeof(db_utf8), table_utf8, sizeof(table_utf8)); - const time_t now = time(NULL); trx_t* trx = trx_create(); + trx->mysql_thd = thd; trx_start_internal(trx); - trx->dict_operation_lock_mode = RW_X_LATCH; - dict_sys.lock(SRW_LOCK_CALL); + dberr_t ret = trx->read_only + ? DB_READ_ONLY + : lock_table_for_trx(table_stats, trx, LOCK_X); + if (ret == DB_SUCCESS) { + ret = lock_table_for_trx(index_stats, trx, LOCK_X); + } + if (ret != DB_SUCCESS) { + trx->commit(); + goto unlocked_free_and_exit; + } pinfo = pars_info_create(); @@ -2725,6 +2746,9 @@ dict_stats_save( pars_info_add_ull_literal(pinfo, "sum_of_other_index_sizes", table->stat_sum_of_other_index_sizes); + dict_sys.lock(SRW_LOCK_CALL); + trx->dict_operation_lock_mode = true; + ret = dict_stats_exec_sql( pinfo, "PROCEDURE TABLE_STATS_SAVE () IS\n" @@ -2753,10 +2777,13 @@ dict_stats_save( rollback_and_exit: trx->rollback(); free_and_exit: - trx->dict_operation_lock_mode = 0; + trx->dict_operation_lock_mode = false; dict_sys.unlock(); +unlocked_free_and_exit: trx->free(); dict_stats_snapshot_free(table); + dict_table_close(table_stats, false, thd, mdl_table); + dict_table_close(index_stats, false, thd, mdl_index); return ret; } @@ -3227,13 +3254,7 @@ dict_stats_fetch_from_ps( trx = trx_create(); - /* Use 'read-uncommitted' so that the SELECTs we execute - do not get blocked in case some user has locked the rows we - are SELECTing */ - - trx->isolation_level = TRX_ISO_READ_UNCOMMITTED; - - trx_start_internal(trx); + trx_start_internal_read_only(trx); dict_fs2utf8(table->name.m_name, db_utf8, sizeof(db_utf8), table_utf8, sizeof(table_utf8)); @@ -3644,7 +3665,7 @@ dberr_t dict_stats_delete_from_table_stats(const char *database_name, /** Execute DELETE FROM mysql.innodb_index_stats @param database_name database name @param table_name table name -@param trx transaction (nullptr=start and commit a new one) +@param trx transaction @return DB_SUCCESS or error code */ dberr_t dict_stats_delete_from_index_stats(const char *database_name, const char *table_name, trx_t *trx) @@ -3672,7 +3693,7 @@ dberr_t dict_stats_delete_from_index_stats(const char *database_name, @param database_name database name @param table_name table name @param index_name name of the index -@param trx transaction (nullptr=start and commit a new one) +@param trx transaction @return DB_SUCCESS or error code */ dberr_t dict_stats_delete_from_index_stats(const char *database_name, const char *table_name, diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc index 23b00bb8e2385..7d50174c306ce 100644 --- a/storage/innobase/dict/dict0stats_bg.cc +++ b/storage/innobase/dict/dict0stats_bg.cc @@ -383,7 +383,7 @@ static bool dict_stats_process_entry_from_recalc_pool() dict_sys.lock(SRW_LOCK_CALL); table->stats_bg_flag = BG_STAT_NONE; - dict_table_close(table, TRUE, FALSE); + dict_table_close(table, true); dict_sys.unlock(); return ret; @@ -409,8 +409,12 @@ static std::mutex dict_stats_mutex; static void dict_stats_func(void*) { - while (dict_stats_process_entry_from_recalc_pool()) {} - dict_defrag_process_entries_from_defrag_pool(); + THD *thd= innobase_create_background_thd("InnoDB statistics"); + set_current_thd(thd); + while (dict_stats_process_entry_from_recalc_pool()) {} + dict_defrag_process_entries_from_defrag_pool(); + set_current_thd(nullptr); + innobase_destroy_background_thd(thd); } diff --git a/storage/innobase/dict/drop.cc b/storage/innobase/dict/drop.cc index f837798ab8f0a..20ee4ff545b08 100644 --- a/storage/innobase/dict/drop.cc +++ b/storage/innobase/dict/drop.cc @@ -81,7 +81,7 @@ dberr_t trx_t::drop_table_foreign(const table_name_t &name) ut_ad(dict_sys.locked()); ut_ad(state == TRX_STATE_ACTIVE); ut_ad(dict_operation); - ut_ad(dict_operation_lock_mode == RW_X_LATCH); + ut_ad(dict_operation_lock_mode); if (!dict_sys.sys_foreign || !dict_sys.sys_foreign_cols) return DB_SUCCESS; @@ -117,7 +117,7 @@ dberr_t trx_t::drop_table_foreign(const table_name_t &name) dberr_t trx_t::drop_table_statistics(const table_name_t &name) { ut_ad(dict_sys.locked()); - ut_ad(dict_operation_lock_mode == RW_X_LATCH); + ut_ad(dict_operation_lock_mode); if (strstr(name.m_name, "/" TEMP_FILE_PREFIX_INNODB) || !strcmp(name.m_name, TABLE_STATS_NAME) || @@ -146,7 +146,7 @@ dberr_t trx_t::drop_table(const dict_table_t &table) ut_ad(dict_sys.locked()); ut_ad(state == TRX_STATE_ACTIVE); ut_ad(dict_operation); - ut_ad(dict_operation_lock_mode == RW_X_LATCH); + ut_ad(dict_operation_lock_mode); ut_ad(!table.is_temporary()); ut_ad(!(table.stats_bg_flag & BG_STAT_IN_PROGRESS)); /* The table must be exclusively locked by this transaction. */ diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 1d0d9b7148900..5d75bcb37bd80 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -1371,7 +1371,7 @@ fts_cache_add_doc( @retval DB_FAIL if the table did not exist */ static dberr_t fts_drop_table(trx_t *trx, const char *table_name, bool rename) { - if (dict_table_t *table= dict_table_open_on_name(table_name, TRUE, FALSE, + if (dict_table_t *table= dict_table_open_on_name(table_name, true, DICT_ERR_IGNORE_DROP)) { table->release(); @@ -1503,24 +1503,20 @@ static dberr_t fts_lock_table(trx_t *trx, const char *table_name) { ut_ad(purge_sys.must_wait_FTS()); - if (dict_table_t *table= dict_table_open_on_name(table_name, false, false, + if (dict_table_t *table= dict_table_open_on_name(table_name, false, DICT_ERR_IGNORE_DROP)) { dberr_t err= lock_table_for_trx(table, trx, LOCK_X); /* Wait for purge threads to stop using the table. */ - dict_sys.freeze(SRW_LOCK_CALL); for (uint n= 15; table->get_ref_count() > 1; ) { - dict_sys.unfreeze(); if (!--n) { err= DB_LOCK_WAIT_TIMEOUT; goto fail; } std::this_thread::sleep_for(std::chrono::milliseconds(50)); - dict_sys.freeze(SRW_LOCK_CALL); } - dict_sys.unfreeze(); fail: table->release(); return err; @@ -4077,7 +4073,7 @@ fts_sync_commit( } /* Avoid assertion in trx_t::free(). */ - trx->dict_operation_lock_mode = 0; + trx->dict_operation_lock_mode = false; trx->free(); return(error); @@ -4127,7 +4123,7 @@ fts_sync_rollback( fts_sql_rollback(trx); /* Avoid assertion in trx_t::free(). */ - trx->dict_operation_lock_mode = 0; + trx->dict_operation_lock_mode = false; trx->free(); } diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc index 7f7c23aee8fff..da24cd54aec42 100644 --- a/storage/innobase/fts/fts0opt.cc +++ b/storage/innobase/fts/fts0opt.cc @@ -2798,7 +2798,7 @@ static void fts_optimize_sync_table(dict_table_t *table, std::this_thread::sleep_for(std::chrono::seconds(6));); if (mdl_ticket) - dict_table_close(sync_table, false, false, fts_opt_thd, mdl_ticket); + dict_table_close(sync_table, false, fts_opt_thd, mdl_ticket); } /**********************************************************************//** diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 96a9012e1cbf4..81a03c1208aa6 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1337,7 +1337,8 @@ static void innodb_drop_database(handlerton*, char *path) innobase_casedn_str(namebuf); #endif /* _WIN32 */ - trx_t *trx= innobase_trx_allocate(current_thd); + THD * const thd= current_thd; + trx_t *trx= innobase_trx_allocate(thd); retry: dict_sys.lock(SRW_LOCK_CALL); @@ -1385,21 +1386,56 @@ static void innodb_drop_database(handlerton*, char *path) } } - trx->dict_operation_lock_mode= RW_X_LATCH; + dict_sys.unlock(); + + dict_table_t *table_stats, *index_stats; + MDL_ticket *mdl_table= nullptr, *mdl_index= nullptr; + table_stats= dict_table_open_on_name(TABLE_STATS_NAME, false, + DICT_ERR_IGNORE_NONE); + if (table_stats) + { + dict_sys.freeze(SRW_LOCK_CALL); + table_stats= dict_acquire_mdl_shared(table_stats, + thd, &mdl_table); + dict_sys.unfreeze(); + } + index_stats= dict_table_open_on_name(INDEX_STATS_NAME, false, + DICT_ERR_IGNORE_NONE); + if (index_stats) + { + dict_sys.freeze(SRW_LOCK_CALL); + index_stats= dict_acquire_mdl_shared(index_stats, + thd, &mdl_index); + dict_sys.unfreeze(); + } + trx_start_for_ddl(trx); + uint errors= 0; char db[NAME_LEN + 1]; strconvert(&my_charset_filename, namebuf, len, system_charset_info, db, sizeof db, &errors); - if (errors); - else if (dict_stats_delete(db, trx)) + if (!errors && table_stats && index_stats && + !strcmp(table_stats->name.m_name, TABLE_STATS_NAME) && + !strcmp(index_stats->name.m_name, INDEX_STATS_NAME) && + lock_table_for_trx(table_stats, trx, LOCK_X) == DB_SUCCESS && + lock_table_for_trx(index_stats, trx, LOCK_X) == DB_SUCCESS) { - /* Ignore this error. Leaving garbage statistics behind is a - lesser evil. Carry on to try to remove any garbage tables. */ - trx->rollback(); - trx_start_for_ddl(trx); + row_mysql_lock_data_dictionary(trx); + if (dict_stats_delete(db, trx)) + { + /* Ignore this error. Leaving garbage statistics behind is a + lesser evil. Carry on to try to remove any garbage tables. */ + trx->rollback(); + trx_start_for_ddl(trx); + } + row_mysql_unlock_data_dictionary(trx); } + if (err == DB_SUCCESS) + err= lock_sys_tables(trx); + row_mysql_lock_data_dictionary(trx); + static const char drop_database[] = "PROCEDURE DROP_DATABASE_PROC () IS\n" "fk CHAR;\n" @@ -1482,8 +1518,12 @@ static void innodb_drop_database(handlerton*, char *path) ib::error() << "DROP DATABASE " << namebuf << ": " << err; } else - trx_commit_for_mysql(trx); + trx->commit(); + if (table_stats) + dict_table_close(table_stats, true, thd, mdl_table); + if (index_stats) + dict_table_close(index_stats, true, thd, mdl_index); row_mysql_unlock_data_dictionary(trx); trx->free(); @@ -1779,6 +1819,15 @@ MYSQL_THD innobase_create_background_thd(const char* name) return thd; } +extern "C" void thd_increment_pending_ops(MYSQL_THD); + +THD *innodb_thd_increment_pending_ops(THD *thd) +{ + if (!thd || THDVAR(thd, background_thread)) + return nullptr; + thd_increment_pending_ops(thd); + return thd; +} /** Destroy a background purge thread THD. @param[in] thd MYSQL_THD to destroy */ @@ -1856,7 +1905,7 @@ thd_has_edited_nontrans_tables( /******************************************************************//** Returns the lock wait timeout for the current connection. @return the lock wait timeout, in seconds */ -uint +uint& thd_lock_wait_timeout( /*==================*/ THD* thd) /*!< in: thread handle, or NULL to query @@ -1936,7 +1985,7 @@ static int innodb_check_version(handlerton *hton, const char *path, char norm_path[FN_REFLEN]; normalize_table_name(norm_path, path); - if (dict_table_t *table= dict_table_open_on_name(norm_path, false, false, + if (dict_table_t *table= dict_table_open_on_name(norm_path, false, DICT_ERR_IGNORE_NONE)) { const trx_id_t trx_id= table->def_trx_id; @@ -2013,8 +2062,8 @@ static void drop_garbage_tables_after_restore() trx_start_for_ddl(trx); std::vector deleted; - row_mysql_lock_data_dictionary(trx); dberr_t err= DB_TABLE_NOT_FOUND; + row_mysql_lock_data_dictionary(trx); if (dict_table_t *table= dict_sys.load_table ({reinterpret_cast(pcur.old_rec), len}, @@ -2022,15 +2071,17 @@ static void drop_garbage_tables_after_restore() { ut_ad(table->stats_bg_flag == BG_STAT_NONE); table->acquire(); + row_mysql_unlock_data_dictionary(trx); err= lock_table_for_trx(table, trx, LOCK_X); if (err == DB_SUCCESS && (table->flags2 & (DICT_TF2_FTS_HAS_DOC_ID | DICT_TF2_FTS))) { - dict_sys.unlock(); fts_optimize_remove_table(table); err= fts_lock_tables(trx, *table); - dict_sys.lock(SRW_LOCK_CALL); } + if (err == DB_SUCCESS) + err= lock_sys_tables(trx); + row_mysql_lock_data_dictionary(trx); table->release(); if (err == DB_SUCCESS) @@ -3035,7 +3086,7 @@ ha_innobase::update_thd( trx_t* trx = check_trx_exists(thd); - ut_ad(trx->dict_operation_lock_mode == 0); + ut_ad(!trx->dict_operation_lock_mode); ut_ad(!trx->dict_operation); if (m_prebuilt->trx != trx) { @@ -3187,7 +3238,7 @@ static bool innobase_query_caching_table_check( const char* norm_name) { dict_table_t* table = dict_table_open_on_name( - norm_name, FALSE, FALSE, DICT_ERR_IGNORE_FK_NOKEY); + norm_name, false, DICT_ERR_IGNORE_FK_NOKEY); if (table == NULL) { return false; @@ -4439,7 +4490,7 @@ innobase_commit( trx_t* trx = check_trx_exists(thd); - ut_ad(trx->dict_operation_lock_mode == 0); + ut_ad(!trx->dict_operation_lock_mode); ut_ad(!trx->dict_operation); /* Transaction is deregistered only in a commit or a rollback. If @@ -4528,7 +4579,7 @@ innobase_rollback( trx_t* trx = check_trx_exists(thd); - ut_ad(trx->dict_operation_lock_mode == 0); + ut_ad(!trx->dict_operation_lock_mode); ut_ad(!trx->dict_operation); /* Reset the number AUTO-INC rows required */ @@ -4893,14 +4944,14 @@ static void innobase_kill_query(handlerton*, THD *thd, enum thd_kill_levels) if (trx_t* trx= thd_to_trx(thd)) { ut_ad(trx->mysql_thd == thd); + if (!trx->lock.wait_lock); #ifdef WITH_WSREP - if (trx->is_wsrep() && wsrep_thd_is_aborting(thd)) + else if (trx->is_wsrep() && wsrep_thd_is_aborting(thd)) /* if victim has been signaled by BF thread and/or aborting is already progressing, following query aborting is not necessary any more. - Also, BF thread should own trx mutex for the victim. */ - DBUG_VOID_RETURN; + Also, BF thread should own trx mutex for the victim. */; #endif /* WITH_WSREP */ - if (trx->lock.wait_lock) + else lock_sys_t::cancel(trx); } @@ -6109,8 +6160,9 @@ ha_innobase::open_dict_table( dict_err_ignore_t ignore_err) { DBUG_ENTER("ha_innobase::open_dict_table"); - dict_table_t* ib_table = dict_table_open_on_name(norm_name, FALSE, - TRUE, ignore_err); + /* FIXME: try_drop_aborted */ + dict_table_t* ib_table = dict_table_open_on_name(norm_name, false, + ignore_err); if (NULL == ib_table && is_partition) { /* MySQL partition engine hard codes the file name @@ -6147,9 +6199,9 @@ ha_innobase::open_dict_table( normalize_table_name_c_low( par_case_name, table_name, false); #endif + /* FIXME: try_drop_aborted */ ib_table = dict_table_open_on_name( - par_case_name, FALSE, TRUE, - ignore_err); + par_case_name, false, ignore_err); } if (ib_table != NULL) { @@ -10603,7 +10655,6 @@ create_table_info_t::create_table_def() table->name.m_name, field->field_name.str); err_col: dict_mem_table_free(table); - ut_ad(trx_state_eq(m_trx, TRX_STATE_NOT_STARTED)); DBUG_RETURN(HA_ERR_GENERIC); } @@ -10771,9 +10822,9 @@ create_table_info_t::create_table_def() table->space = fil_system.temp_space; table->add_to_cache(); } else { - if (err == DB_SUCCESS) { - err = row_create_table_for_mysql(table, m_trx); - } + ut_ad(dict_sys.sys_tables_exist()); + + err = row_create_table_for_mysql(table, m_trx); DBUG_EXECUTE_IF("ib_crash_during_create_for_encryption", DBUG_SUICIDE();); @@ -12990,7 +13041,7 @@ create_table_info_t::create_table_update_dict() DBUG_ENTER("create_table_update_dict"); innobase_table = dict_table_open_on_name( - m_table_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE); + m_table_name, false, DICT_ERR_IGNORE_NONE); DBUG_ASSERT(innobase_table != 0); if (innobase_table->fts != NULL) { @@ -13126,18 +13177,27 @@ ha_innobase::create( } const bool own_trx = !trx; + int error = 0; if (own_trx) { info.allocate_trx(); trx = info.trx(); - /* Latch the InnoDB data dictionary exclusively so that no deadlocks - or lock waits can happen in it during a table create operation. - Drop table etc. do this latching in row0mysql.cc. */ - row_mysql_lock_data_dictionary(trx); DBUG_ASSERT(trx_state_eq(trx, TRX_STATE_NOT_STARTED)); } + if (own_trx && !(info.flags2() & DICT_TF2_TEMPORARY)) { + trx_start_for_ddl(trx); + if (dberr_t err = lock_sys_tables(trx)) { + error = convert_error_code_to_mysql(err, 0, nullptr); + } + } + if (own_trx) { + row_mysql_lock_data_dictionary(trx); + } + + if (!error) { + error = info.create_table(own_trx); + } - int error = info.create_table(own_trx); if (error) { /* Drop the being-created table before rollback, so that rollback can possibly rename back a table @@ -13216,13 +13276,18 @@ ha_innobase::discard_or_import_tablespace( } trx_start_if_not_started(m_prebuilt->trx, true); + m_prebuilt->trx->dict_operation = true; /* Obtain an exclusive lock on the table. */ dberr_t err = lock_table_for_trx(m_prebuilt->table, m_prebuilt->trx, LOCK_X); + if (err == DB_SUCCESS) { + err = lock_sys_tables(m_prebuilt->trx); + } if (err != DB_SUCCESS) { /* unable to lock the table: do nothing */ + m_prebuilt->trx->commit(); } else if (discard) { /* Discarding an already discarded tablespace should be an @@ -13239,7 +13304,6 @@ ha_innobase::discard_or_import_tablespace( err = row_discard_tablespace_for_mysql( m_prebuilt->table, m_prebuilt->trx); - } else if (m_prebuilt->table->is_readable()) { /* Commit the transaction in order to release the table lock. */ @@ -13268,8 +13332,7 @@ ha_innobase::discard_or_import_tablespace( } } - /* Commit the transaction in order to release the table lock. */ - trx_commit_for_mysql(m_prebuilt->trx); + ut_ad(m_prebuilt->trx->state == TRX_STATE_NOT_STARTED); if (discard || err != DB_SUCCESS) { DBUG_RETURN(convert_error_code_to_mysql( @@ -13398,9 +13461,13 @@ int ha_innobase::delete_table(const char *name) trx_start_for_ddl(trx); } + dict_table_t *table_stats= nullptr, *index_stats= nullptr; + MDL_ticket *mdl_table= nullptr, *mdl_index= nullptr; dberr_t err= lock_table_for_trx(table, trx, LOCK_X); + const bool fts= err == DB_SUCCESS && (table->flags2 & (DICT_TF2_FTS_HAS_DOC_ID | DICT_TF2_FTS)); + const enum_sql_command sqlcom= enum_sql_command(thd_sql_command(thd)); if (fts) { @@ -13409,16 +13476,73 @@ int ha_innobase::delete_table(const char *name) err= fts_lock_tables(trx, *table); } +#ifdef WITH_PARTITION_STORAGE_ENGINE + const bool rollback_add_partition= + (sqlcom == SQLCOM_ALTER_TABLE && table->name.part()); + + if (rollback_add_partition) + { + if (!fts) + purge_sys.stop_FTS(); + /* This looks like the rollback of ALTER TABLE...ADD PARTITION + that was caused by MDL timeout. We could have written undo log + for inserting the data into the new partitions. */ + if (table->stat_persistent != DICT_STATS_PERSISTENT_OFF) + { + /* We do not really know if we are holding MDL_EXCLUSIVE. Even + though this code is handling the case that we are not holding + it, we might actually hold it. We want to avoid a deadlock + with dict_stats_process_entry_from_recalc_pool(). */ + dict_stats_recalc_pool_del(table->id, true); + /* If statistics calculation is still using this table, we will + catch it below while waiting for purge to stop using this table. */ + } + } +#endif + + if (err == DB_SUCCESS && dict_stats_is_persistent_enabled(table) && + !table->is_stats_table()) + { + table_stats= dict_table_open_on_name(TABLE_STATS_NAME, false, + DICT_ERR_IGNORE_NONE); + if (table_stats) + { + dict_sys.freeze(SRW_LOCK_CALL); + table_stats= dict_acquire_mdl_shared(table_stats, + thd, &mdl_table); + dict_sys.unfreeze(); + } + + index_stats= dict_table_open_on_name(INDEX_STATS_NAME, false, + DICT_ERR_IGNORE_NONE); + if (index_stats) + { + dict_sys.freeze(SRW_LOCK_CALL); + index_stats= dict_acquire_mdl_shared(index_stats, + thd, &mdl_index); + dict_sys.unfreeze(); + } + + if (table_stats && index_stats && + !strcmp(table_stats->name.m_name, TABLE_STATS_NAME) && + !strcmp(index_stats->name.m_name, INDEX_STATS_NAME) && + !(err= lock_table_for_trx(table_stats, trx, LOCK_X))) + err= lock_table_for_trx(index_stats, trx, LOCK_X); + } + + if (err == DB_SUCCESS) + err= lock_sys_tables(trx); + dict_sys.lock(SRW_LOCK_CALL); - trx->dict_operation_lock_mode= RW_X_LATCH; + if (!table->release() && err == DB_SUCCESS) { /* Wait for purge threads to stop using the table. */ for (uint n= 15;;) { - row_mysql_unlock_data_dictionary(trx); + dict_sys.unlock(); std::this_thread::sleep_for(std::chrono::milliseconds(50)); - row_mysql_lock_data_dictionary(trx); + dict_sys.lock(SRW_LOCK_CALL); if (!--n) { @@ -13430,11 +13554,13 @@ int ha_innobase::delete_table(const char *name) } } + trx->dict_operation_lock_mode= true; + if (err != DB_SUCCESS) { err_exit: + trx->dict_operation_lock_mode= false; trx->rollback(); - trx->dict_operation_lock_mode= 0; switch (err) { case DB_CANNOT_DROP_CONSTRAINT: case DB_LOCK_WAIT_TIMEOUT: @@ -13448,6 +13574,14 @@ int ha_innobase::delete_table(const char *name) fts_optimize_add_table(table); purge_sys.resume_FTS(); } +#ifdef WITH_PARTITION_STORAGE_ENGINE + else if (rollback_add_partition) + purge_sys.resume_FTS(); +#endif + if (table_stats) + dict_table_close(table_stats, true, thd, mdl_table); + if (index_stats) + dict_table_close(index_stats, true, thd, mdl_index); dict_sys.unlock(); if (trx != parent_trx) trx->free(); @@ -13456,7 +13590,7 @@ int ha_innobase::delete_table(const char *name) if (!table->no_rollback() && trx->check_foreigns) { - const bool drop_db= thd_sql_command(thd) == SQLCOM_DROP_DB; + const bool drop_db= sqlcom == SQLCOM_DROP_DB; for (auto foreign : table->referenced_set) { /* We should allow dropping a referenced table if creating @@ -13485,7 +13619,7 @@ int ha_innobase::delete_table(const char *name) if (!table->no_rollback()) { err= trx->drop_table_foreign(table->name); - if (err == DB_SUCCESS) + if (err == DB_SUCCESS && table_stats && index_stats) err= trx->drop_table_statistics(table->name); if (err != DB_SUCCESS) goto err_exit; @@ -13497,14 +13631,22 @@ int ha_innobase::delete_table(const char *name) std::vector deleted; trx->commit(deleted); + if (table_stats) + dict_table_close(table_stats, true, thd, mdl_table); + if (index_stats) + dict_table_close(index_stats, true, thd, mdl_index); row_mysql_unlock_data_dictionary(trx); for (pfs_os_file_t d : deleted) os_file_close(d); log_write_up_to(trx->commit_lsn, true); if (trx != parent_trx) trx->free(); - if (fts) - purge_sys.resume_FTS(); + if (!fts) +#ifdef WITH_PARTITION_STORAGE_ENGINE + if (!rollback_add_partition) +#endif + DBUG_RETURN(0); + purge_sys.resume_FTS(); DBUG_RETURN(0); } @@ -13514,7 +13656,7 @@ int ha_innobase::delete_table(const char *name) @param[in] to new table name @param[in] use_fk whether to enforce FOREIGN KEY @return DB_SUCCESS or error code */ -inline dberr_t innobase_rename_table(trx_t *trx, const char *from, +static dberr_t innobase_rename_table(trx_t *trx, const char *from, const char *to, bool use_fk) { dberr_t error; @@ -13665,6 +13807,9 @@ int ha_innobase::truncate() heap, ib_table->name.m_name, ib_table->id); const char* name = mem_heap_strdup(heap, ib_table->name.m_name); + dict_table_t *table_stats = nullptr, *index_stats = nullptr; + MDL_ticket *mdl_table = nullptr, *mdl_index = nullptr; + dberr_t error = lock_table_for_trx(ib_table, trx, LOCK_X); const bool fts = error == DB_SUCCESS && ib_table->flags2 & (DICT_TF2_FTS_HAS_DOC_ID | DICT_TF2_FTS); @@ -13675,8 +13820,6 @@ int ha_innobase::truncate() error = fts_lock_tables(trx, *ib_table); } - row_mysql_lock_data_dictionary(trx); - dict_stats_wait_bg_to_stop_using_table(ib_table); /* Wait for purge threads to stop using the table. */ for (uint n = 15; ib_table->get_ref_count() > 1; ) { if (!--n) { @@ -13684,11 +13827,43 @@ int ha_innobase::truncate() break; } - row_mysql_unlock_data_dictionary(trx); std::this_thread::sleep_for(std::chrono::milliseconds(50)); - row_mysql_lock_data_dictionary(trx); + } + + if (error == DB_SUCCESS && dict_stats_is_persistent_enabled(ib_table) + && !ib_table->is_stats_table()) { + table_stats= dict_table_open_on_name(TABLE_STATS_NAME, false, + DICT_ERR_IGNORE_NONE); + if (table_stats) { + dict_sys.freeze(SRW_LOCK_CALL); + table_stats = dict_acquire_mdl_shared( + table_stats, m_user_thd, &mdl_table); + dict_sys.unfreeze(); + } + index_stats = dict_table_open_on_name(INDEX_STATS_NAME, false, + DICT_ERR_IGNORE_NONE); + if (index_stats) { + dict_sys.freeze(SRW_LOCK_CALL); + index_stats = dict_acquire_mdl_shared( + index_stats, m_user_thd, &mdl_index); + dict_sys.unfreeze(); + } + + if (table_stats && index_stats + && !strcmp(table_stats->name.m_name, TABLE_STATS_NAME) + && !strcmp(index_stats->name.m_name, INDEX_STATS_NAME) && + !(error = lock_table_for_trx(table_stats, trx, LOCK_X))) { + error = lock_table_for_trx(index_stats, trx, LOCK_X); + } } + if (error == DB_SUCCESS) { + error = lock_sys_tables(trx); + } + + row_mysql_lock_data_dictionary(trx); + dict_stats_wait_bg_to_stop_using_table(ib_table); + if (error == DB_SUCCESS) { error = innobase_rename_table(trx, ib_table->name.m_name, temp_name, false); @@ -13724,7 +13899,7 @@ int ha_innobase::truncate() if (err) { reload: m_prebuilt->table = dict_table_open_on_name( - name, false, false, DICT_ERR_IGNORE_NONE); + name, false, DICT_ERR_IGNORE_NONE); m_prebuilt->table->def_trx_id = def_trx_id; } else { row_prebuilt_t* prebuilt = m_prebuilt; @@ -13756,6 +13931,14 @@ int ha_innobase::truncate() trx->free(); mem_heap_free(heap); + + if (table_stats) { + dict_table_close(table_stats, false, m_user_thd, mdl_table); + } + if (index_stats) { + dict_table_close(index_stats, false, m_user_thd, mdl_index); + } + DBUG_RETURN(err); } @@ -13779,23 +13962,69 @@ ha_innobase::rename_table( } trx_t* trx = innobase_trx_allocate(thd); + trx_start_for_ddl(trx); - /* We are doing a DDL operation. */ - trx->will_lock = true; - trx->dict_operation = true; - row_mysql_lock_data_dictionary(trx); + dict_table_t *table_stats = nullptr, *index_stats = nullptr; + MDL_ticket *mdl_table = nullptr, *mdl_index = nullptr; + char norm_from[MAX_FULL_NAME_LEN]; + char norm_to[MAX_FULL_NAME_LEN]; - dberr_t error = innobase_rename_table(trx, from, to, true); + normalize_table_name(norm_from, from); + normalize_table_name(norm_to, to); - DEBUG_SYNC(thd, "after_innobase_rename_table"); + dberr_t error = DB_SUCCESS; + + if (strcmp(norm_from, TABLE_STATS_NAME) + && strcmp(norm_from, INDEX_STATS_NAME) + && strcmp(norm_to, TABLE_STATS_NAME) + && strcmp(norm_to, INDEX_STATS_NAME)) { + table_stats = dict_table_open_on_name(TABLE_STATS_NAME, false, + DICT_ERR_IGNORE_NONE); + if (table_stats) { + dict_sys.freeze(SRW_LOCK_CALL); + table_stats = dict_acquire_mdl_shared( + table_stats, thd, &mdl_table); + dict_sys.unfreeze(); + } + index_stats = dict_table_open_on_name(INDEX_STATS_NAME, false, + DICT_ERR_IGNORE_NONE); + if (index_stats) { + dict_sys.freeze(SRW_LOCK_CALL); + index_stats = dict_acquire_mdl_shared( + index_stats, thd, &mdl_index); + dict_sys.unfreeze(); + } + + if (table_stats && index_stats + && !strcmp(table_stats->name.m_name, TABLE_STATS_NAME) + && !strcmp(index_stats->name.m_name, INDEX_STATS_NAME) && + !(error = lock_table_for_trx(table_stats, trx, LOCK_X))) { + error = lock_table_for_trx(index_stats, trx, LOCK_X); + } + } + + if (error == DB_SUCCESS) { + error = lock_table_for_trx(dict_sys.sys_tables, trx, LOCK_X); + if (error == DB_SUCCESS) { + error = lock_table_for_trx(dict_sys.sys_foreign, trx, + LOCK_X); + if (error == DB_SUCCESS) { + error = lock_table_for_trx( + dict_sys.sys_foreign_cols, + trx, LOCK_X); + } + } + } + + row_mysql_lock_data_dictionary(trx); if (error == DB_SUCCESS) { - char norm_from[MAX_FULL_NAME_LEN]; - char norm_to[MAX_FULL_NAME_LEN]; + error = innobase_rename_table(trx, from, to, true); + } - normalize_table_name(norm_from, from); - normalize_table_name(norm_to, to); + DEBUG_SYNC(thd, "after_innobase_rename_table"); + if (error == DB_SUCCESS && table_stats && index_stats) { error = dict_stats_rename_table(norm_from, norm_to, trx); if (error == DB_DUPLICATE_KEY) { /* The duplicate may also occur in @@ -13812,6 +14041,12 @@ ha_innobase::rename_table( trx->rollback(); } + if (table_stats) { + dict_table_close(table_stats, true, thd, mdl_table); + } + if (index_stats) { + dict_table_close(index_stats, true, thd, mdl_index); + } row_mysql_unlock_data_dictionary(trx); if (error == DB_SUCCESS) { log_write_up_to(trx->commit_lsn, true); @@ -15161,7 +15396,7 @@ get_foreign_key_info( dict_table_t* ref_table = dict_table_open_on_name( foreign->referenced_table_name_lookup, - TRUE, FALSE, DICT_ERR_IGNORE_NONE); + true, DICT_ERR_IGNORE_NONE); if (ref_table == NULL) { @@ -15174,8 +15409,7 @@ get_foreign_key_info( << foreign->foreign_table_name; } } else { - - dict_table_close(ref_table, TRUE, FALSE); + dict_table_close(ref_table, true); } } @@ -17097,7 +17331,7 @@ static int innodb_ft_aux_table_validate(THD *thd, st_mysql_sys_var*, if (const char* table_name = value->val_str(value, buf, &len)) { if (dict_table_t* table = dict_table_open_on_name( - table_name, FALSE, TRUE, DICT_ERR_IGNORE_NONE)) { + table_name, false, DICT_ERR_IGNORE_NONE)) { const table_id_t id = dict_table_has_fts_index(table) ? table->id : 0; dict_table_close(table); diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index a9801cd35ae2e..06eaa934834a9 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -4067,7 +4067,7 @@ online_retry_drop_indexes_low( trx_t* trx) /*!< in/out: transaction */ { ut_ad(dict_sys.locked()); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); + ut_ad(trx->dict_operation_lock_mode); ut_ad(trx->dict_operation); /* We can have table->n_ref_count > 1, because other threads @@ -4101,65 +4101,34 @@ static void commit_unlock_and_unlink(trx_t *trx) unlock_and_close_files(deleted, trx); } -/********************************************************************//** +/** Drop any indexes that we were not able to free previously due to -open table handles. */ -static MY_ATTRIBUTE((nonnull)) -void -online_retry_drop_indexes( -/*======================*/ - dict_table_t* table, /*!< in/out: table */ - THD* user_thd) /*!< in/out: MySQL connection */ -{ - if (table->drop_aborted) { - trx_t* trx = innobase_trx_allocate(user_thd); - - trx_start_for_ddl(trx); - - row_mysql_lock_data_dictionary(trx); - online_retry_drop_indexes_low(table, trx); - commit_unlock_and_unlink(trx); - trx->free(); - } - - ut_d(dict_sys.freeze(SRW_LOCK_CALL)); - ut_d(dict_table_check_for_dup_indexes(table, CHECK_ALL_COMPLETE)); - ut_d(dict_sys.unfreeze()); - ut_ad(!table->drop_aborted); -} - -/********************************************************************//** -Commit a dictionary transaction and drop any indexes that we were not -able to free previously due to open table handles. */ -static MY_ATTRIBUTE((nonnull)) -void -online_retry_drop_indexes_with_trx( -/*===============================*/ - dict_table_t* table, /*!< in/out: table */ - trx_t* trx) /*!< in/out: transaction */ +open table handles. +@param table InnoDB table +@param thd connection handle +*/ +static void online_retry_drop_indexes(dict_table_t *table, THD *thd) { - ut_ad(trx_state_eq(trx, TRX_STATE_NOT_STARTED)); - - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); + if (table->drop_aborted) + { + trx_t *trx= innobase_trx_allocate(thd); - /* Now that the dictionary is being locked, check if we can - drop any incompletely created indexes that may have been left - behind in rollback_inplace_alter_table() earlier. */ - if (table->drop_aborted) { - trx_start_for_ddl(trx); + trx_start_for_ddl(trx); + if (lock_sys_tables(trx) == DB_SUCCESS) + { + row_mysql_lock_data_dictionary(trx); + online_retry_drop_indexes_low(table, trx); + commit_unlock_and_unlink(trx); + } + else + trx->commit(); + trx->free(); + } - online_retry_drop_indexes_low(table, trx); - std::vector deleted; - trx->commit(deleted); - /* FIXME: We are holding the data dictionary latch here - while waiting for the files to be actually deleted. - However, we should never have any deleted files here, - because they would be related to ADD FULLTEXT INDEX, - and that operation is never supported online. */ - for (pfs_os_file_t d : deleted) { - os_file_close(d); - } - } + ut_d(dict_sys.freeze(SRW_LOCK_CALL)); + ut_d(dict_table_check_for_dup_indexes(table, CHECK_ALL_COMPLETE)); + ut_d(dict_sys.unfreeze()); + ut_ad(!table->drop_aborted); } /** Determines if InnoDB is dropping a foreign key constraint. @@ -4803,7 +4772,7 @@ innobase_update_gis_column_type( DBUG_ENTER("innobase_update_gis_column_type"); DBUG_ASSERT(trx->dict_operation); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); + ut_ad(trx->dict_operation_lock_mode); ut_ad(dict_sys.locked()); info = pars_info_create(); @@ -6297,6 +6266,10 @@ prepare_inplace_alter_table_dict( } } + if (error == DB_SUCCESS) { + error = lock_sys_tables(ctx->trx); + } + if (error != DB_SUCCESS) { table_lock_failed = true; goto error_handling; @@ -6339,8 +6312,20 @@ prepare_inplace_alter_table_dict( ut_ad(user_table->get_ref_count() == 1); - online_retry_drop_indexes_with_trx( - user_table, ctx->trx); + if (user_table->drop_aborted) { + row_mysql_unlock_data_dictionary(ctx->trx); + trx_start_for_ddl(ctx->trx); + if (lock_sys_tables(ctx->trx) == DB_SUCCESS) { + row_mysql_lock_data_dictionary( + ctx->trx); + online_retry_drop_indexes_low( + user_table, ctx->trx); + commit_unlock_and_unlink(ctx->trx); + } else { + ctx->trx->commit(); + } + row_mysql_lock_data_dictionary(ctx->trx); + } if (ctx->need_rebuild()) { if (ctx->new_table) { @@ -6613,8 +6598,8 @@ prepare_inplace_alter_table_dict( ha_alter_info, ctx->new_table, ctx->trx); if (error != DB_SUCCESS) { ut_ad(error == DB_ERROR); - error = DB_UNSUPPORTED; - goto error_handling; + my_error(ER_TABLE_CANT_HANDLE_SPKEYS, MYF(0), "SYS_COLUMNS"); + goto error_handled; } } @@ -7042,7 +7027,7 @@ prepare_inplace_alter_table_dict( if (fts_index) { ut_ad(ctx->trx->dict_operation); - ut_ad(ctx->trx->dict_operation_lock_mode == RW_X_LATCH); + ut_ad(ctx->trx->dict_operation_lock_mode); ut_ad(dict_sys.locked()); DICT_TF2_FLAG_SET(ctx->new_table, DICT_TF2_FTS); @@ -7135,27 +7120,12 @@ prepare_inplace_alter_table_dict( case DB_DUPLICATE_KEY: my_error(ER_DUP_KEY, MYF(0), "SYS_INDEXES"); break; - case DB_UNSUPPORTED: - my_error(ER_TABLE_CANT_HANDLE_SPKEYS, MYF(0), "SYS_COLUMNS"); - break; default: my_error_innodb(error, table_name, user_table->flags); } ctx->trx->rollback(); -error_handled: - - ctx->prebuilt->trx->error_info = NULL; - ctx->trx->error_state = DB_SUCCESS; - - if (!dict_locked) { - row_mysql_lock_data_dictionary(ctx->trx); - if (table_lock_failed) { - goto err_exit; - } - } - if (ctx->need_rebuild()) { /* Free the log for online table rebuild, if one was allocated. */ @@ -7175,17 +7145,48 @@ prepare_inplace_alter_table_dict( clust_index->lock.x_unlock(); } + ctx->prebuilt->trx->error_info = NULL; + ctx->trx->error_state = DB_SUCCESS; + + if (false) { +error_handled: + ut_ad(!table_lock_failed); + ut_ad(ctx->trx->state == TRX_STATE_ACTIVE); + ut_ad(!ctx->trx->undo_no); + ut_ad(dict_locked); + } else if (table_lock_failed) { + if (!dict_locked) { + row_mysql_lock_data_dictionary(ctx->trx); + } + goto err_exit; + } else { + ut_ad(ctx->trx->state == TRX_STATE_NOT_STARTED); + if (new_clustered && !user_table->drop_aborted) { + goto err_exit; + } + if (dict_locked) { + row_mysql_unlock_data_dictionary(ctx->trx); + } + trx_start_for_ddl(ctx->trx); + dberr_t err= lock_sys_tables(ctx->trx); + row_mysql_lock_data_dictionary(ctx->trx); + if (err != DB_SUCCESS) { + goto err_exit; + } + } + /* n_ref_count must be 1, because purge cannot be executing on this very table as we are - holding dict_sys.latch X-latch. */ + holding MDL_EXCLUSIVE. */ ut_ad(!stats_wait || ctx->online || user_table->get_ref_count() == 1); if (new_clustered) { - online_retry_drop_indexes_with_trx(user_table, ctx->trx); + online_retry_drop_indexes_low(user_table, ctx->trx); + commit_unlock_and_unlink(ctx->trx); + row_mysql_lock_data_dictionary(ctx->trx); } else { - trx_start_for_ddl(ctx->trx); row_merge_drop_indexes(ctx->trx, user_table, true); - trx_commit_for_mysql(ctx->trx); + ctx->trx->commit(); } ut_d(dict_table_check_for_dup_indexes(user_table, CHECK_ALL_COMPLETE)); @@ -7330,7 +7331,7 @@ rename_index_try( { DBUG_ENTER("rename_index_try"); ut_ad(dict_sys.locked()); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); + ut_ad(trx->dict_operation_lock_mode); pars_info_t* pinfo; dberr_t err; @@ -7552,7 +7553,7 @@ ha_innobase::prepare_inplace_alter_table( if (!(ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE)) { /* Nothing to do */ - DBUG_ASSERT(m_prebuilt->trx->dict_operation_lock_mode == 0); + DBUG_ASSERT(!m_prebuilt->trx->dict_operation_lock_mode); DBUG_RETURN(false); } @@ -7632,7 +7633,7 @@ ha_innobase::prepare_inplace_alter_table( ha_alter_info->key_info_buffer, ha_alter_info->key_count)) { err_exit_no_heap: - DBUG_ASSERT(m_prebuilt->trx->dict_operation_lock_mode == 0); + DBUG_ASSERT(!m_prebuilt->trx->dict_operation_lock_mode); online_retry_drop_indexes(m_prebuilt->table, m_user_thd); DBUG_RETURN(true); } @@ -8091,7 +8092,7 @@ ha_innobase::prepare_inplace_alter_table( == ALTER_OPTIONS && !alter_options_need_rebuild(ha_alter_info, table))) { - DBUG_ASSERT(m_prebuilt->trx->dict_operation_lock_mode == 0); + DBUG_ASSERT(!m_prebuilt->trx->dict_operation_lock_mode); online_retry_drop_indexes(m_prebuilt->table, m_user_thd); if (heap) { @@ -8709,6 +8710,9 @@ inline bool rollback_inplace_alter_table(Alter_inplace_info *ha_alter_info, if (index->type & DICT_FTS) err= fts_lock_index_tables(ctx->trx, *index); } + if (err == DB_SUCCESS) + err= lock_sys_tables(ctx->trx); + row_mysql_lock_data_dictionary(ctx->trx); /* Detach ctx->new_table from dict_index_t::online_log. */ innobase_online_rebuild_log_free(ctx->old_table); @@ -8735,18 +8739,28 @@ inline bool rollback_inplace_alter_table(Alter_inplace_info *ha_alter_info, { DBUG_ASSERT(!(ha_alter_info->handler_flags & ALTER_ADD_PK_INDEX)); DBUG_ASSERT(ctx->old_table == prebuilt->table); + uint &innodb_lock_wait_timeout= + thd_lock_wait_timeout(ctx->trx->mysql_thd); + const uint save_timeout= innodb_lock_wait_timeout; + innodb_lock_wait_timeout= ~0U; /* infinite */ + if (fts_exist) { for (ulint a= 0; a < ctx->num_to_add_index; a++) { const dict_index_t *index = ctx->add_index[a]; - // FIXME: skip fts_drop_index_tables() if we failed to acquire locks if (index->type & DICT_FTS) - fts_lock_index_tables(ctx->trx, *index); + ut_a(!fts_lock_index_tables(ctx->trx, *index)); } - // FIXME: skip fts_drop_tables() if we failed to acquire locks - fts_lock_common_tables(ctx->trx, *ctx->new_table); + ut_a(!fts_lock_common_tables(ctx->trx, *ctx->new_table)); + ut_a(!lock_sys_tables(ctx->trx)); + } + else + { + ut_a(!lock_table_for_trx(dict_sys.sys_indexes, ctx->trx, LOCK_X)); + ut_a(!lock_table_for_trx(dict_sys.sys_fields, ctx->trx, LOCK_X)); } + innodb_lock_wait_timeout= save_timeout; row_mysql_lock_data_dictionary(ctx->trx); ctx->rollback_instant(); innobase_rollback_sec_index(ctx->old_table, table, @@ -8835,7 +8849,7 @@ innobase_drop_foreign_try( DBUG_ENTER("innobase_drop_foreign_try"); DBUG_ASSERT(trx->dict_operation); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); + ut_ad(trx->dict_operation_lock_mode); ut_ad(dict_sys.locked()); /* Drop the constraint from the data dictionary. */ @@ -8891,7 +8905,7 @@ innobase_rename_column_try( DBUG_ENTER("innobase_rename_column_try"); DBUG_ASSERT(trx->dict_operation); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); + ut_ad(trx->dict_operation_lock_mode); ut_ad(dict_sys.locked()); if (ctx.need_rebuild()) { @@ -9205,7 +9219,7 @@ innobase_rename_or_enlarge_column_try( DBUG_ASSERT(!ctx->need_rebuild()); DBUG_ASSERT(trx->dict_operation); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); + ut_ad(trx->dict_operation_lock_mode); ut_ad(dict_sys.locked()); ulint n_base; @@ -9883,7 +9897,7 @@ commit_try_rebuild( DBUG_ENTER("commit_try_rebuild"); DBUG_ASSERT(ctx->need_rebuild()); - DBUG_ASSERT(trx->dict_operation_lock_mode == RW_X_LATCH); + DBUG_ASSERT(trx->dict_operation_lock_mode); DBUG_ASSERT(!(ha_alter_info->handler_flags & ALTER_DROP_FOREIGN_KEY) || ctx->num_to_drop_fk > 0); @@ -10150,7 +10164,7 @@ commit_try_norebuild( { DBUG_ENTER("commit_try_norebuild"); DBUG_ASSERT(!ctx->need_rebuild()); - DBUG_ASSERT(trx->dict_operation_lock_mode == RW_X_LATCH); + DBUG_ASSERT(trx->dict_operation_lock_mode); DBUG_ASSERT(!(ha_alter_info->handler_flags & ALTER_DROP_FOREIGN_KEY) || ctx->num_to_drop_fk > 0); @@ -10908,8 +10922,55 @@ ha_innobase::commit_inplace_alter_table( } } - /* Latch the InnoDB data dictionary exclusively so that no deadlocks - or lock waits can happen in it during the data dictionary operation. */ + dict_table_t *table_stats = nullptr, *index_stats = nullptr; + MDL_ticket *mdl_table = nullptr, *mdl_index = nullptr; + dberr_t error = DB_SUCCESS; + if (!ctx0->old_table->is_stats_table() && + !ctx0->new_table->is_stats_table()) { + table_stats = dict_table_open_on_name( + TABLE_STATS_NAME, false, DICT_ERR_IGNORE_NONE); + if (table_stats) { + dict_sys.freeze(SRW_LOCK_CALL); + table_stats = dict_acquire_mdl_shared( + table_stats, m_user_thd, &mdl_table); + dict_sys.unfreeze(); + } + index_stats = dict_table_open_on_name( + INDEX_STATS_NAME, false, DICT_ERR_IGNORE_NONE); + if (index_stats) { + dict_sys.freeze(SRW_LOCK_CALL); + index_stats = dict_acquire_mdl_shared( + index_stats, m_user_thd, &mdl_index); + dict_sys.unfreeze(); + } + + if (table_stats && index_stats + && !strcmp(table_stats->name.m_name, TABLE_STATS_NAME) + && !strcmp(index_stats->name.m_name, INDEX_STATS_NAME) + && !(error = lock_table_for_trx(table_stats, + trx, LOCK_X))) { + error = lock_table_for_trx(index_stats, trx, LOCK_X); + } + } + if (error == DB_SUCCESS) { + error = lock_sys_tables(trx); + } + if (error != DB_SUCCESS) { + if (table_stats) { + dict_table_close(table_stats, false, m_user_thd, + mdl_table); + } + if (index_stats) { + dict_table_close(index_stats, false, m_user_thd, + mdl_index); + } + my_error_innodb(error, table_share->table_name.str, 0); + if (fts_exist) { + purge_sys.resume_FTS(); + } + DBUG_RETURN(true); + } + row_mysql_lock_data_dictionary(trx); /* Prevent the background statistics collection from accessing @@ -10953,6 +11014,14 @@ ha_innobase::commit_inplace_alter_table( fail: trx->rollback(); ut_ad(!trx->fts_trx); + if (table_stats) { + dict_table_close(table_stats, true, m_user_thd, + mdl_table); + } + if (index_stats) { + dict_table_close(index_stats, true, m_user_thd, + mdl_index); + } row_mysql_unlock_data_dictionary(trx); if (fts_exist) { purge_sys.resume_FTS(); @@ -11000,6 +11069,13 @@ ha_innobase::commit_inplace_alter_table( #endif } + if (table_stats) { + dict_table_close(table_stats, true, m_user_thd, mdl_table); + } + if (index_stats) { + dict_table_close(index_stats, true, m_user_thd, mdl_index); + } + /* Commit or roll back the changes to the data dictionary. */ DEBUG_SYNC(m_user_thd, "innodb_alter_inplace_before_commit"); @@ -11051,9 +11127,6 @@ ha_innobase::commit_inplace_alter_table( ha_alter_info->inplace_alter_table_committed = purge_sys.resume_SYS; purge_sys.stop_SYS(); trx->commit(deleted); - log_write_up_to(trx->commit_lsn, true); - DBUG_EXECUTE_IF("innodb_alter_commit_crash_after_commit", - DBUG_SUICIDE();); /* At this point, the changes to the persistent storage have been committed or rolled back. What remains to be done is to @@ -11147,6 +11220,9 @@ ha_innobase::commit_inplace_alter_table( } unlock_and_close_files(deleted, trx); + log_write_up_to(trx->commit_lsn, true); + DBUG_EXECUTE_IF("innodb_alter_commit_crash_after_commit", + DBUG_SUICIDE();); trx->free(); if (fts_exist) { purge_sys.resume_FTS(); @@ -11199,6 +11275,9 @@ ha_innobase::commit_inplace_alter_table( } unlock_and_close_files(deleted, trx); + log_write_up_to(trx->commit_lsn, true); + DBUG_EXECUTE_IF("innodb_alter_commit_crash_after_commit", + DBUG_SUICIDE();); trx->free(); if (fts_exist) { purge_sys.resume_FTS(); diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 9e84e9443811c..e4d53b32c7f99 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -2410,7 +2410,7 @@ i_s_fts_deleted_generic_fill( DBUG_RETURN(0); } else if (!dict_table_has_fts_index(user_table) || !user_table->is_readable()) { - dict_table_close(user_table, false, false, thd, mdl_ticket); + dict_table_close(user_table, false, thd, mdl_ticket); DBUG_RETURN(0); } @@ -2425,7 +2425,7 @@ i_s_fts_deleted_generic_fill( fts_table_fetch_doc_ids(trx, &fts_table, deleted); - dict_table_close(user_table, false, false, thd, mdl_ticket); + dict_table_close(user_table, false, thd, mdl_ticket); trx->free(); @@ -2782,7 +2782,7 @@ i_s_fts_index_cache_fill( } if (!user_table->fts || !user_table->fts->cache) { - dict_table_close(user_table, false, false, thd, mdl_ticket); + dict_table_close(user_table, false, thd, mdl_ticket); DBUG_RETURN(0); } @@ -2807,7 +2807,7 @@ i_s_fts_index_cache_fill( } mysql_mutex_unlock(&cache->lock); - dict_table_close(user_table, false, false, thd, mdl_ticket); + dict_table_close(user_table, false, thd, mdl_ticket); DBUG_RETURN(ret); } @@ -3238,7 +3238,7 @@ i_s_fts_index_table_fill( } } - dict_table_close(user_table, false, false, thd, mdl_ticket); + dict_table_close(user_table, false, thd, mdl_ticket); ut_free(conv_str.f_str); @@ -3374,7 +3374,7 @@ i_s_fts_config_fill( } if (!dict_table_has_fts_index(user_table)) { - dict_table_close(user_table, false, false, thd, mdl_ticket); + dict_table_close(user_table, false, thd, mdl_ticket); DBUG_RETURN(0); } @@ -3431,7 +3431,7 @@ i_s_fts_config_fill( fts_sql_commit(trx); - dict_table_close(user_table, false, false, thd, mdl_ticket); + dict_table_close(user_table, false, thd, mdl_ticket); trx->free(); diff --git a/storage/innobase/include/dict0defrag_bg.h b/storage/innobase/include/dict0defrag_bg.h index 3aea41b0bb878..0edc630478873 100644 --- a/storage/innobase/include/dict0defrag_bg.h +++ b/storage/innobase/include/dict0defrag_bg.h @@ -90,11 +90,8 @@ dict_defrag_process_entries_from_defrag_pool(); /*********************************************************************//** Save defragmentation result. @return DB_SUCCESS or error code */ -dberr_t -dict_stats_save_defrag_summary( -/*============================*/ - dict_index_t* index) /*!< in: index */ - MY_ATTRIBUTE((warn_unused_result)); +dberr_t dict_stats_save_defrag_summary(dict_index_t *index, THD *thd) + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Save defragmentation stats for a given index. diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index a031d2d0e1e8a..e91ee7349d2e1 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -157,9 +157,7 @@ void dict_table_close(dict_table_t *table); /** Decrements the count of open handles of a table. @param[in,out] table table -@param[in] dict_locked data dictionary locked -@param[in] try_drop try to drop any orphan indexes after - an aborted online index creation +@param[in] dict_locked whether dict_sys.latch is being held @param[in] thd thread to release MDL @param[in] mdl metadata lock or NULL if the thread is a foreground one. */ @@ -167,7 +165,6 @@ void dict_table_close( dict_table_t* table, bool dict_locked, - bool try_drop, THD* thd = NULL, MDL_ticket* mdl = NULL); @@ -470,16 +467,14 @@ NOTE! This is a high-level function to be used mainly from outside the 'dict' directory. Inside this directory dict_table_get_low is usually the appropriate function. @param[in] table_name Table name -@param[in] dict_locked TRUE=data dictionary locked -@param[in] try_drop TRUE=try to drop any orphan indexes after - an aborted online index creation +@param[in] dict_locked whether dict_sys.latch is being held exclusively @param[in] ignore_err error to be ignored when loading the table -@return table, NULL if does not exist */ +@return table +@retval nullptr if does not exist */ dict_table_t* dict_table_open_on_name( const char* table_name, - ibool dict_locked, - ibool try_drop, + bool dict_locked, dict_err_ignore_t ignore_err) MY_ATTRIBUTE((warn_unused_result)); @@ -1357,14 +1352,7 @@ class dict_sys_t /** The my_hrtime_coarse().val of the oldest lock_wait() start, or 0 */ std::atomic latch_ex_wait_start; - /** @brief the data dictionary rw-latch protecting dict_sys - - Table create, drop, etc. reserve this in X-mode; implicit or - backround operations that are not fully covered by MDL - (rollback, foreign key checks) reserve this in S-mode. - - This latch also prevents lock waits when accessing the InnoDB - data dictionary tables. @see trx_t::dict_operation_lock_mode */ + /** the rw-latch protecting the data dictionary cache */ MY_ALIGNED(CACHE_LINE_SIZE) srw_lock latch; #ifdef UNIV_DEBUG /** whether latch is being held in exclusive mode (by any thread) */ @@ -1618,9 +1606,9 @@ class dict_sys_t /** Estimate the used memory occupied by the data dictionary table and index objects. @return number of bytes occupied */ - ulint rough_size() const + TPOOL_SUPPRESS_TSAN ulint rough_size() const { - /* No mutex; this is a very crude approximation anyway */ + /* No latch; this is a very crude approximation anyway */ ulint size = UT_LIST_GET_LEN(table_LRU) + UT_LIST_GET_LEN(table_non_LRU); size *= sizeof(dict_table_t) + sizeof(dict_index_t) * 2 diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 45747c255654c..8d636e056ee2d 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -2375,7 +2375,7 @@ struct dict_table_t { /** @return whether the name is mysql.innodb_index_stats or mysql.innodb_table_stats */ - inline bool is_stats_table() const; + bool is_stats_table() const; /** Create metadata. @param name table name diff --git a/storage/innobase/include/dict0stats.h b/storage/innobase/include/dict0stats.h index 7112238c9b6bc..cdc5ec1bffb1e 100644 --- a/storage/innobase/include/dict0stats.h +++ b/storage/innobase/include/dict0stats.h @@ -140,19 +140,21 @@ dict_stats_update( /** Execute DELETE FROM mysql.innodb_table_stats @param database_name database name @param table_name table name -@param trx transaction (nullptr=start and commit a new one) +@param trx transaction @return DB_SUCCESS or error code */ dberr_t dict_stats_delete_from_table_stats(const char *database_name, const char *table_name, - trx_t *trx= nullptr); + trx_t *trx) + MY_ATTRIBUTE((nonnull)); /** Execute DELETE FROM mysql.innodb_index_stats @param database_name database name @param table_name table name -@param trx transaction (nullptr=start and commit a new one) +@param trx transaction @return DB_SUCCESS or error code */ dberr_t dict_stats_delete_from_index_stats(const char *database_name, const char *table_name, - trx_t *trx= nullptr); + trx_t *trx) + MY_ATTRIBUTE((nonnull)); /** Execute DELETE FROM mysql.innodb_index_stats @param database_name database name @param table_name table name @@ -203,9 +205,7 @@ storage. @param[in] stat_value value of the stat @param[in] sample_size n pages sampled or NULL @param[in] stat_description description of the stat -@param[in,out] trx in case of NULL the function will -allocate and free the trx object. If it is not NULL then it will be -rolled back only in the case of error, but not freed. +@param[in,out] trx transaction @return DB_SUCCESS or error code */ dberr_t dict_stats_save_index_stat( @@ -215,7 +215,8 @@ dict_stats_save_index_stat( ib_uint64_t stat_value, ib_uint64_t* sample_size, const char* stat_description, - trx_t* trx); + trx_t* trx) + MY_ATTRIBUTE((nonnull(1, 3, 6, 7))); /** Report an error if updating table statistics failed because .ibd file is missing, table decryption failed or table is corrupted. diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h index 9a2786f9e6965..2dd7c5713866e 100644 --- a/storage/innobase/include/ha_prototypes.h +++ b/storage/innobase/include/ha_prototypes.h @@ -207,6 +207,14 @@ but can be used for comparison. */ extern "C" unsigned long long thd_start_utime(const MYSQL_THD thd); + +/** + Indicate the start of an async operation in a foreground thread. +@param thd current_thd +@return thd +@retval nullptr if this is not a foreground thread */ +THD *innodb_thd_increment_pending_ops(THD *thd); + /** Determines the current SQL statement. Thread unsafe, can only be called from the thread owning the THD. @param[in] thd MySQL thread handle @@ -242,7 +250,7 @@ const char *thd_innodb_tmpdir(THD *thd); /******************************************************************//** Returns the lock wait timeout for the current connection. @return the lock wait timeout, in seconds */ -uint +uint& thd_lock_wait_timeout( /*==================*/ THD* thd); /*!< in: thread handle, or NULL to query diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index 9b83cf6ee1adb..42e8bf4ad2225 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -221,6 +221,17 @@ state was stored on the infimum of a page. whose infimum stored the lock state; lock bits are reset on the infimum */ void lock_rec_restore_from_page_infimum(const buf_block_t &block, const rec_t *rec, page_id_t donator); + +/** +Create a table lock, without checking for deadlocks or lock compatibility. +@param table table on which the lock is created +@param type_mode lock type and mode +@param trx transaction +@param c_lock conflicting lock +@return the created lock object */ +lock_t *lock_table_create(dict_table_t *table, unsigned type_mode, trx_t *trx, + lock_t *c_lock= nullptr); + /*********************************************************************//** Checks if locks of other transactions prevent an immediate insert of a record. If they do, first tests if the query thread should anyway @@ -393,6 +404,12 @@ lock_table_for_trx( enum lock_mode mode) MY_ATTRIBUTE((nonnull, warn_unused_result)); +/** Exclusively lock the data dictionary tables. +@param trx dictionary transaction +@return error code +@retval DB_SUCCESS on success */ +dberr_t lock_sys_tables(trx_t *trx); + /*************************************************************//** Removes a granted record lock of a transaction from the queue and grants locks to other transactions waiting in the queue if they now are entitled diff --git a/storage/innobase/include/row0merge.h b/storage/innobase/include/row0merge.h index c2a474abe4d6f..e9e250435f0b9 100644 --- a/storage/innobase/include/row0merge.h +++ b/storage/innobase/include/row0merge.h @@ -145,17 +145,6 @@ row_merge_dup_report( const dfield_t* entry) /*!< in: duplicate index entry */ MY_ATTRIBUTE((nonnull)); -/*********************************************************************//** -Drop indexes that were created before an error occurred. -The data dictionary must have been locked exclusively by the caller, -because the transaction will not be committed. */ -void -row_merge_drop_indexes_dict( -/*========================*/ - trx_t* trx, /*!< in/out: dictionary transaction */ - table_id_t table_id)/*!< in: table identifier */ - MY_ATTRIBUTE((nonnull)); - /** Drop indexes that were created before an error occurred. The data dictionary must have been locked exclusively by the caller, because the transaction will not be committed. diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index ba8ac02dfd1cc..ed51a3a3d909a 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -300,30 +300,24 @@ row_update_cascade_for_mysql( or set null operation */ dict_table_t* table) /*!< in: table where we do the operation */ MY_ATTRIBUTE((nonnull, warn_unused_result)); -/*********************************************************************//** -Locks the data dictionary exclusively for performing a table create or other -data dictionary modification operation. */ -void -row_mysql_lock_data_dictionary_func( -/*================================*/ -#ifdef UNIV_PFS_RWLOCK - const char* file, /*!< in: file name */ - unsigned line, /*!< in: line number */ -#endif - trx_t* trx); /*!< in/out: transaction */ -#ifdef UNIV_PFS_RWLOCK -#define row_mysql_lock_data_dictionary(trx) \ - row_mysql_lock_data_dictionary_func(__FILE__, __LINE__, trx) -#else -#define row_mysql_lock_data_dictionary row_mysql_lock_data_dictionary_func -#endif -/*********************************************************************//** -Unlocks the data dictionary exclusive lock. */ -void -row_mysql_unlock_data_dictionary( -/*=============================*/ - trx_t* trx); /*!< in/out: transaction */ +/** Lock the data dictionary cache exclusively. */ +#define row_mysql_lock_data_dictionary(trx) \ + do { \ + ut_ad(!trx->dict_operation_lock_mode); \ + dict_sys.lock(SRW_LOCK_CALL); \ + trx->dict_operation_lock_mode = true; \ + } while (0) + +/** Unlock the data dictionary. */ +#define row_mysql_unlock_data_dictionary(trx) \ + do { \ + ut_ad(!lock_trx_has_sys_table_locks(trx)); \ + ut_ad(trx->dict_operation_lock_mode); \ + trx->dict_operation_lock_mode = false; \ + dict_sys.unlock(); \ + } while (0) + /*********************************************************************//** Creates a table for MySQL. On failure the transaction will be rolled back and the 'table' object will be freed. diff --git a/storage/innobase/include/row0purge.h b/storage/innobase/include/row0purge.h index 091d80adec587..34af658cb12b7 100644 --- a/storage/innobase/include/row0purge.h +++ b/storage/innobase/include/row0purge.h @@ -226,7 +226,7 @@ struct purge_node_t{ } innobase_reset_background_thd(purge_thd); - dict_table_close(table, false, false, purge_thd, mdl_ticket); + dict_table_close(table, false, purge_thd, mdl_ticket); table= nullptr; mdl_ticket= nullptr; } diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 96289f2aa3912..d64fd019b85c6 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -122,11 +122,18 @@ void trx_start_internal_low(trx_t *trx, bool read_write); (t)->start_file = __FILE__; \ trx_start_internal_low(t, true); \ } while (false) +#define trx_start_internal_read_only(t) \ + do { \ + (t)->start_line = __LINE__; \ + (t)->start_file = __FILE__; \ + trx_start_internal_low(t, false); \ + } while (false) #else #define trx_start_if_not_started(t, rw) \ trx_start_if_not_started_low((t), rw) #define trx_start_internal(t) trx_start_internal_low(t, true) +#define trx_start_internal_read_only(t) trx_start_internal_low(t, false) #define trx_start_if_not_started_xa(t, rw) \ trx_start_if_not_started_xa_low((t), (rw)) @@ -725,11 +732,9 @@ struct trx_t : ilist_node<> ulint duplicates; /*!< TRX_DUP_IGNORE | TRX_DUP_REPLACE */ bool dict_operation; /**< whether this modifies InnoDB data dictionary */ - ib_uint32_t dict_operation_lock_mode; - /*!< 0, RW_S_LATCH, or RW_X_LATCH: - the latch mode trx currently holds - on dict_sys.latch. Protected - by dict_sys.latch. */ + /** whether dict_sys.latch is held exclusively; protected by + dict_sys.latch */ + bool dict_operation_lock_mode; /** wall-clock time of the latest transition to TRX_STATE_ACTIVE; used for diagnostic purposes only */ diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index f3f5ce4237268..41da85dcc985c 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -1264,19 +1264,13 @@ lock_rec_enqueue_waiting( trx_t* trx = thr_get_trx(thr); ut_ad(trx->mutex_is_owner()); + ut_ad(!trx->dict_operation_lock_mode); - if (UNIV_UNLIKELY(trx->dict_operation_lock_mode == RW_X_LATCH)) { - ut_ad(!strcmp(index->table->name.m_name, TABLE_STATS_NAME) - || !strcmp(index->table->name.m_name, INDEX_STATS_NAME)); -instant_timeout: + if (trx->mysql_thd && thd_lock_wait_timeout(trx->mysql_thd) == 0) { trx->error_state = DB_LOCK_WAIT_TIMEOUT; return DB_LOCK_WAIT_TIMEOUT; } - if (trx->mysql_thd && thd_lock_wait_timeout(trx->mysql_thd) == 0) { - goto instant_timeout; - } - /* Enqueue the lock request that will wait to be granted, note that we already own the trx mutex. */ lock_t* lock = lock_rec_create_low( @@ -1491,6 +1485,12 @@ lock_rec_lock( static_cast(LOCK_MODE_MASK & mode))) return DB_SUCCESS; + /* During CREATE TABLE, we will write to newly created FTS_*_CONFIG + on which no lock has been created yet. */ + ut_ad(!trx->dict_operation_lock_mode || + (strstr(index->table->name.m_name, "/FTS_") && + strstr(index->table->name.m_name, "_CONFIG") + sizeof("_CONFIG") == + index->table->name.m_name + strlen(index->table->name.m_name) + 1)); MONITOR_ATOMIC_INC(MONITOR_NUM_RECLOCK_REQ); const page_id_t id{block->page.id()}; LockGuard g{lock_sys.rec_hash, id}; @@ -1701,7 +1701,6 @@ dberr_t lock_wait(que_thr_t *thr) /* InnoDB system transactions may use the global value of innodb_lock_wait_timeout, because trx->mysql_thd == NULL. */ const ulong innodb_lock_wait_timeout= trx_lock_wait_timeout_get(trx); - const bool no_timeout= innodb_lock_wait_timeout >= 100000000; const my_hrtime_t suspend_time= my_hrtime_coarse(); ut_ad(!trx->dict_operation_lock_mode); @@ -1757,6 +1756,14 @@ dberr_t lock_wait(que_thr_t *thr) timespec abstime; set_timespec_time_nsec(abstime, suspend_time.val * 1000); abstime.MY_tv_sec+= innodb_lock_wait_timeout; + /* Dictionary transactions must wait be immune to lock wait timeouts + for locks on data dictionary tables. Here we check only for + SYS_TABLES, SYS_COLUMNS, SYS_INDEXES, SYS_FIELDS. Locks on further + tables SYS_FOREIGN, SYS_FOREIGN_COLS, SYS_VIRTUAL will only be + acquired while holding an exclusive lock on one of the 4 tables. */ + const bool no_timeout= innodb_lock_wait_timeout >= 100000000 || + ((type_mode & LOCK_TABLE) && + wait_lock->un_member.tab_lock.table->id <= DICT_FIELDS_ID); thd_wait_begin(trx->mysql_thd, (type_mode & LOCK_TABLE) ? THD_WAIT_TABLE_LOCK : THD_WAIT_ROW_LOCK); dberr_t error_state= DB_SUCCESS; @@ -1803,7 +1810,10 @@ dberr_t lock_wait(que_thr_t *thr) break; default: ut_ad(error_state != DB_LOCK_WAIT_TIMEOUT); - if (trx_is_interrupted(trx)) + /* Dictionary transactions must ignore KILL, because they could + be executed as part of a multi-transaction DDL operation, + such as rollback_inplace_alter_table() or ha_innobase::delete_table(). */ + if (!trx->dict_operation && trx_is_interrupted(trx)) /* innobase_kill_query() can only set trx->error_state=DB_INTERRUPTED for any transaction that is attached to a connection. */ error_state= DB_INTERRUPTED; @@ -3072,20 +3082,15 @@ void lock_rec_restore_from_page_infimum(const buf_block_t &block, /*========================= TABLE LOCKS ==============================*/ -/*********************************************************************//** -Creates a table lock object and adds it as the last in the lock queue -of the table. Does NOT check for deadlocks or lock compatibility. -@return own: new lock object */ -UNIV_INLINE -lock_t* -lock_table_create( -/*==============*/ - dict_table_t* table, /*!< in/out: database table - in dictionary cache */ - unsigned type_mode,/*!< in: lock mode possibly ORed with - LOCK_WAIT */ - trx_t* trx, /*!< in: trx */ - lock_t* c_lock) /*!< in: conflicting lock */ +/** +Create a table lock, without checking for deadlocks or lock compatibility. +@param table table on which the lock is created +@param type_mode lock type and mode +@param trx transaction +@param c_lock conflicting lock +@return the created lock object */ +lock_t *lock_table_create(dict_table_t *table, unsigned type_mode, trx_t *trx, + lock_t *c_lock) { lock_t* lock; @@ -3094,6 +3099,12 @@ lock_table_create( ut_ad(!trx->is_wsrep() || lock_sys.is_writer()); ut_ad(trx->state == TRX_STATE_ACTIVE || trx->is_recovered); ut_ad(!trx->is_autocommit_non_locking()); + /* During CREATE TABLE, we will write to newly created FTS_*_CONFIG + on which no lock has been created yet. */ + ut_ad(!trx->dict_operation_lock_mode + || (strstr(table->name.m_name, "/FTS_") + && strstr(table->name.m_name, "_CONFIG") + sizeof("_CONFIG") + == table->name.m_name + strlen(table->name.m_name) + 1)); switch (LOCK_MODE_MASK & type_mode) { case LOCK_AUTO_INC: @@ -3310,13 +3321,7 @@ lock_table_enqueue_waiting( trx_t* trx = thr_get_trx(thr); ut_ad(trx->mutex_is_owner()); - - if (UNIV_UNLIKELY(trx->dict_operation_lock_mode == RW_X_LATCH)) { - ut_ad(!strcmp(table->name.m_name, TABLE_STATS_NAME) - || !strcmp(table->name.m_name, INDEX_STATS_NAME)); - trx->error_state = DB_LOCK_WAIT_TIMEOUT; - return DB_LOCK_WAIT_TIMEOUT; - } + ut_ad(!trx->dict_operation_lock_mode); #ifdef WITH_WSREP if (trx->is_wsrep() && trx->lock.was_chosen_as_deadlock_victim) { @@ -3478,7 +3483,7 @@ void lock_table_resurrect(dict_table_t *table, trx_t *trx, lock_mode mode) ut_ad(!lock_table_other_has_incompatible(trx, LOCK_WAIT, table, mode)); trx->mutex_lock(); - lock_table_create(table, mode, trx, nullptr); + lock_table_create(table, mode, trx); } trx->mutex_unlock(); } @@ -3619,6 +3624,28 @@ lock_table_for_trx( return(err); } +/** Exclusively lock the data dictionary tables. +@param trx dictionary transaction +@return error code +@retval DB_SUCCESS on success */ +dberr_t lock_sys_tables(trx_t *trx) +{ + dberr_t err; + if (!(err= lock_table_for_trx(dict_sys.sys_tables, trx, LOCK_X)) && + !(err= lock_table_for_trx(dict_sys.sys_columns, trx, LOCK_X)) && + !(err= lock_table_for_trx(dict_sys.sys_indexes, trx, LOCK_X)) && + !(err= lock_table_for_trx(dict_sys.sys_fields, trx, LOCK_X))) + { + if (dict_sys.sys_foreign) + err= lock_table_for_trx(dict_sys.sys_foreign, trx, LOCK_X); + if (!err && dict_sys.sys_foreign_cols) + err= lock_table_for_trx(dict_sys.sys_foreign_cols, trx, LOCK_X); + if (!err && dict_sys.sys_virtual) + err= lock_table_for_trx(dict_sys.sys_virtual, trx, LOCK_X); + } + return err; +} + /*=========================== LOCK RELEASE ==============================*/ /*************************************************************//** @@ -3785,7 +3812,7 @@ void lock_release(trx_t *trx) #if defined SAFE_MUTEX && defined UNIV_DEBUG std::set to_evict; if (innodb_evict_tables_on_commit_debug && !trx->is_recovered) - if (!trx->dict_operation_lock_mode && !trx->dict_operation) + if (!!trx->dict_operation) for (const auto& p: trx->mod_tables) if (!p.first->is_temporary()) to_evict.emplace(p.first->id); @@ -5531,8 +5558,14 @@ void lock_sys_t::cancel(trx_t *trx) mysql_mutex_lock(&lock_sys.wait_mutex); if (lock_t *lock= trx->lock.wait_lock) { - trx->error_state= DB_INTERRUPTED; - cancel(trx, lock, false); + /* Dictionary transactions must be immune to KILL, because they + may be executed as part of a multi-transaction DDL operation, such + as rollback_inplace_alter_table() or ha_innobase::delete_table(). */ + if (!trx->dict_operation) + { + trx->error_state= DB_INTERRUPTED; + cancel(trx, lock, false); + } } lock_sys.deadlock_check(); mysql_mutex_unlock(&lock_sys.wait_mutex); diff --git a/storage/innobase/pars/pars0pars.cc b/storage/innobase/pars/pars0pars.cc index 1ade99eb1c34a..61614007bd436 100644 --- a/storage/innobase/pars/pars0pars.cc +++ b/storage/innobase/pars/pars0pars.cc @@ -766,7 +766,7 @@ pars_retrieve_table_def( sym_node->token_type = SYM_TABLE_REF_COUNTED; sym_node->table = dict_table_open_on_name( - sym_node->name, TRUE, FALSE, DICT_ERR_IGNORE_NONE); + sym_node->name, true, DICT_ERR_IGNORE_NONE); ut_a(sym_node->table != NULL); } diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc index e22b08346ccf0..792a9b46e8a16 100644 --- a/storage/innobase/row/row0ftsort.cc +++ b/storage/innobase/row/row0ftsort.cc @@ -1634,7 +1634,7 @@ row_fts_merge_insert( /* Get aux index */ fts_get_table_name(&fts_table, aux_table_name); - aux_table = dict_table_open_on_name(aux_table_name, FALSE, FALSE, + aux_table = dict_table_open_on_name(aux_table_name, false, DICT_ERR_IGNORE_NONE); ut_ad(aux_table != NULL); aux_table->release(); diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index ce23587090937..b9245eb432594 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -40,6 +40,7 @@ Created 2012-02-08 by Sunny Bains. #include "row0quiesce.h" #include "fil0pagecompress.h" #include "trx0undo.h" +#include "lock0lock.h" #ifdef HAVE_LZO #include "lzo/lzo1x.h" #endif @@ -2191,11 +2192,8 @@ dberr_t row_import_cleanup( /*===============*/ row_prebuilt_t* prebuilt, /*!< in/out: prebuilt from handler */ - trx_t* trx, /*!< in/out: transaction for import */ dberr_t err) /*!< in: error code */ { - ut_a(prebuilt->trx != trx); - if (err != DB_SUCCESS) { dict_table_t* table = prebuilt->table; table->file_unreadable = true; @@ -2218,14 +2216,12 @@ row_import_cleanup( DBUG_EXECUTE_IF("ib_import_before_commit_crash", DBUG_SUICIDE();); - trx_commit_for_mysql(trx); + prebuilt->trx->commit(); - if (trx->dict_operation_lock_mode) { - row_mysql_unlock_data_dictionary(trx); + if (prebuilt->trx->dict_operation_lock_mode) { + row_mysql_unlock_data_dictionary(prebuilt->trx); } - trx->free(); - prebuilt->trx->op_info = ""; DBUG_EXECUTE_IF("ib_import_before_checkpoint_crash", DBUG_SUICIDE();); @@ -2242,10 +2238,9 @@ dberr_t row_import_error( /*=============*/ row_prebuilt_t* prebuilt, /*!< in/out: prebuilt from handler */ - trx_t* trx, /*!< in/out: transaction for import */ dberr_t err) /*!< in: error code */ { - if (!trx_is_interrupted(trx)) { + if (!trx_is_interrupted(prebuilt->trx)) { char table_name[MAX_FULL_NAME_LEN + 1]; innobase_format_name( @@ -2253,12 +2248,12 @@ row_import_error( prebuilt->table->name.m_name); ib_senderrf( - trx->mysql_thd, IB_LOG_LEVEL_WARN, + prebuilt->trx->mysql_thd, IB_LOG_LEVEL_WARN, ER_INNODB_IMPORT_ERROR, table_name, (ulong) err, ut_strerr(err)); } - return(row_import_cleanup(prebuilt, trx, err)); + return row_import_cleanup(prebuilt, err); } /*****************************************************************//** @@ -4002,9 +3997,9 @@ row_import_for_mysql( row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL */ { dberr_t err; - trx_t* trx; ib_uint64_t autoinc = 0; char* filepath = NULL; + trx_t* trx = prebuilt->trx; /* The caller assured that this is not read_only_mode and that no temorary tablespace is being imported. */ @@ -4013,22 +4008,12 @@ row_import_for_mysql( ut_ad(table->space_id); ut_ad(table->space_id < SRV_SPACE_ID_UPPER_BOUND); - ut_ad(prebuilt->trx); + ut_ad(trx); + ut_ad(trx->state == TRX_STATE_ACTIVE); ut_ad(!table->is_readable()); ibuf_delete_for_discarded_space(table->space_id); - trx_start_if_not_started(prebuilt->trx, true); - - trx = trx_create(); - - trx->dict_operation = true; - - trx_start_if_not_started(trx, true); - - /* So that we can send error messages to the user. */ - trx->mysql_thd = prebuilt->trx->mysql_thd; - /* Assign an undo segment for the transaction, so that the transaction will be recovered after a crash. */ @@ -4043,21 +4028,19 @@ row_import_for_mysql( DBUG_EXECUTE_IF("ib_import_undo_assign_failure", err = DB_TOO_MANY_CONCURRENT_TRXS;); - if (err != DB_SUCCESS) { - - return(row_import_cleanup(prebuilt, trx, err)); - - } else if (trx->rsegs.m_redo.undo == 0) { - + if (err == DB_SUCCESS && !trx->has_logged_persistent()) { err = DB_TOO_MANY_CONCURRENT_TRXS; - return(row_import_cleanup(prebuilt, trx, err)); + } + if (err != DB_SUCCESS) { + return row_import_cleanup(prebuilt, err); } - prebuilt->trx->op_info = "read meta-data file"; + trx->op_info = "read meta-data file"; row_import cfg; + THD* thd = trx->mysql_thd; - err = row_import_read_cfg(table, trx->mysql_thd, cfg); + err = row_import_read_cfg(table, thd, cfg); /* Check if the table column definitions match the contents of the config file. */ @@ -4067,7 +4050,7 @@ row_import_for_mysql( /* We have a schema file, try and match it with our data dictionary. */ - err = cfg.match_schema(trx->mysql_thd); + err = cfg.match_schema(thd); /* Update index->page and SYS_INDEXES.PAGE_NO to match the B-tree root page numbers in the tablespace. Use the index @@ -4091,13 +4074,13 @@ row_import_for_mysql( cfg.m_zip_size = 0; if (UT_LIST_GET_LEN(table->indexes) > 1) { - ib_errf(trx->mysql_thd, IB_LOG_LEVEL_ERROR, + ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_INTERNAL_ERROR, "Drop all secondary indexes before importing " "table %s when .cfg file is missing.", table->name.m_name); err = DB_ERROR; - return row_import_error(prebuilt, trx, err); + return row_import_error(prebuilt, err); } FetchIndexRootPages fetchIndexRootPages(table, trx); @@ -4121,10 +4104,10 @@ row_import_for_mysql( } if (err != DB_SUCCESS) { - return(row_import_error(prebuilt, trx, err)); + return row_import_error(prebuilt, err); } - prebuilt->trx->op_info = "importing tablespace"; + trx->op_info = "importing tablespace"; ib::info() << "Phase I - Update all pages"; @@ -4166,13 +4149,13 @@ row_import_for_mysql( if (err != DB_DECRYPTION_FAILED) { - ib_errf(trx->mysql_thd, IB_LOG_LEVEL_ERROR, + ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_INTERNAL_ERROR, "Cannot reset LSNs in table %s : %s", table_name, ut_strerr(err)); } - return(row_import_cleanup(prebuilt, trx, err)); + return row_import_cleanup(prebuilt, err); } /* If the table is stored in a remote tablespace, we need to @@ -4196,7 +4179,7 @@ row_import_for_mysql( ); if (filepath == NULL) { - return(row_import_cleanup(prebuilt, trx, DB_OUT_OF_MEMORY)); + return row_import_cleanup(prebuilt, DB_OUT_OF_MEMORY); } /* Open the tablespace so that we can access via the buffer pool. @@ -4215,7 +4198,7 @@ row_import_for_mysql( err = DB_TABLESPACE_NOT_FOUND; table->space = NULL;); if (!table->space) { - ib_senderrf(trx->mysql_thd, IB_LOG_LEVEL_ERROR, + ib_senderrf(thd, IB_LOG_LEVEL_ERROR, ER_GET_ERRMSG, err, ut_strerr(err), filepath); } @@ -4229,7 +4212,7 @@ row_import_for_mysql( DBUG_EXECUTE_IF("ib_import_check_bitmap_failure", err = DB_CORRUPTION;); if (err != DB_SUCCESS) { - return(row_import_cleanup(prebuilt, trx, err)); + return row_import_cleanup(prebuilt, err); } /* The first index must always be the clustered index. */ @@ -4237,7 +4220,7 @@ row_import_for_mysql( dict_index_t* index = dict_table_get_first_index(table); if (!dict_index_is_clust(index)) { - return(row_import_error(prebuilt, trx, DB_CORRUPTION)); + return row_import_error(prebuilt, DB_CORRUPTION); } /* Update the Btree segment headers for index node and @@ -4249,7 +4232,7 @@ row_import_for_mysql( err = DB_CORRUPTION;); if (err != DB_SUCCESS) { - return(row_import_error(prebuilt, trx, err)); + return row_import_error(prebuilt, err); } else if (cfg.requires_purge(index->name)) { /* Purge any delete-marked records that couldn't be @@ -4268,7 +4251,7 @@ row_import_for_mysql( DBUG_EXECUTE_IF("ib_import_cluster_failure", err = DB_CORRUPTION;); if (err != DB_SUCCESS) { - return(row_import_error(prebuilt, trx, err)); + return row_import_error(prebuilt, err); } /* For secondary indexes, purge any records that couldn't be purged @@ -4281,7 +4264,7 @@ row_import_for_mysql( err = DB_CORRUPTION;); if (err != DB_SUCCESS) { - return(row_import_error(prebuilt, trx, err)); + return row_import_error(prebuilt, err); } /* Ensure that the next available DB_ROW_ID is not smaller than @@ -4320,13 +4303,13 @@ row_import_for_mysql( err = row_import_update_index_root(trx, table, false); if (err != DB_SUCCESS) { - return(row_import_error(prebuilt, trx, err)); + return row_import_error(prebuilt, err); } err = row_import_update_discarded_flag(trx, table->id, false); if (err != DB_SUCCESS) { - return(row_import_error(prebuilt, trx, err)); + return row_import_error(prebuilt, err); } table->file_unreadable = false; @@ -4342,5 +4325,5 @@ row_import_for_mysql( btr_write_autoinc(dict_table_get_first_index(table), autoinc); } - return(row_import_cleanup(prebuilt, trx, err)); + return row_import_cleanup(prebuilt, err); } diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 40b51e2e86682..6f228142cbad6 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -1944,7 +1944,7 @@ row_ins_check_foreign_constraints( ref_table = dict_table_open_on_name( foreign->referenced_table_name_lookup, - FALSE, FALSE, DICT_ERR_IGNORE_NONE); + false, DICT_ERR_IGNORE_NONE); } err = row_ins_check_foreign_constraint( diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index ab294e6554134..53e3016180aed 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -3678,7 +3678,7 @@ row_merge_drop_index_dict( pars_info_t* info; ut_ad(!srv_read_only_mode); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); + ut_ad(trx->dict_operation_lock_mode); ut_ad(trx->dict_operation); ut_ad(dict_sys.locked()); @@ -3704,6 +3704,7 @@ row_merge_drop_index_dict( Drop indexes that were created before an error occurred. The data dictionary must have been locked exclusively by the caller, because the transaction will not be committed. */ +static void row_merge_drop_indexes_dict( /*========================*/ @@ -3740,7 +3741,7 @@ row_merge_drop_indexes_dict( pars_info_t* info; ut_ad(!srv_read_only_mode); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); + ut_ad(trx->dict_operation_lock_mode); ut_ad(trx->dict_operation); ut_ad(dict_sys.locked()); @@ -3813,7 +3814,7 @@ row_merge_drop_indexes( dict_index_t* next_index; ut_ad(!srv_read_only_mode); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); + ut_ad(trx->dict_operation_lock_mode); ut_ad(trx->dict_operation); ut_ad(dict_sys.locked()); @@ -3829,18 +3830,10 @@ row_merge_drop_indexes( handle to the table be waiting for the next statement to execute, or waiting for a meta-data lock. - A concurrent purge will be prevented by dict_sys.latch. */ + A concurrent purge will be prevented by MDL. */ if (!locked && (table->get_ref_count() > 1 || table->has_lock_other_than(alter_trx))) { - /* We will have to drop the indexes later, when the - table is guaranteed to be no longer in use. Mark the - indexes as incomplete and corrupted, so that other - threads will stop using them. Let dict_table_close() - or crash recovery or the next invocation of - prepare_inplace_alter_table() take care of dropping - the indexes. */ - while ((index = dict_table_get_next_index(index)) != NULL) { ut_ad(!dict_index_is_clust(index)); @@ -4094,7 +4087,10 @@ void row_merge_drop_temp_indexes() indexes, so that the data dictionary information can be checked when accessing the tablename.ibd files. */ trx_t* trx = trx_create(); + trx_start_for_ddl(trx); trx->op_info = "dropping partially created indexes"; + dberr_t error = lock_sys_tables(trx); + row_mysql_lock_data_dictionary(trx); /* Ensure that this transaction will be rolled back and locks will be released, if the server gets killed before the commit @@ -4105,8 +4101,11 @@ void row_merge_drop_temp_indexes() pars_info_t* pinfo = pars_info_create(); pars_info_bind_function(pinfo, "drop_fts", row_merge_drop_fts, trx); + if (error == DB_SUCCESS) { + error = que_eval_sql(pinfo, sql, trx); + } - if (dberr_t error = que_eval_sql(pinfo, sql, trx)) { + if (error) { /* Even though we ensure that DDL transactions are WAIT and DEADLOCK free, we could encounter other errors e.g., DB_TOO_MANY_CONCURRENT_TRXS. */ @@ -4246,7 +4245,7 @@ row_merge_rename_index_to_add( "WHERE TABLE_ID = :tableid AND ID = :indexid;\n" "END;\n"; - ut_a(trx->dict_operation_lock_mode == RW_X_LATCH); + ut_ad(trx->dict_operation_lock_mode); ut_ad(trx->dict_operation); trx->op_info = "renaming index to add"; diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 17ac86f2300ba..a0ef110f60628 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -2132,36 +2132,6 @@ row_update_cascade_for_mysql( } } -/*********************************************************************//** -Locks the data dictionary exclusively for performing a table create or other -data dictionary modification operation. */ -void -row_mysql_lock_data_dictionary_func( -/*================================*/ -#ifdef UNIV_PFS_RWLOCK - const char* file, /*!< in: file name */ - unsigned line, /*!< in: line number */ -#endif - trx_t* trx) /*!< in/out: transaction */ -{ - ut_ad(trx->dict_operation_lock_mode == 0); - dict_sys.lock(SRW_LOCK_ARGS(file, line)); - trx->dict_operation_lock_mode = RW_X_LATCH; -} - -/*********************************************************************//** -Unlocks the data dictionary exclusive lock. */ -void -row_mysql_unlock_data_dictionary( -/*=============================*/ - trx_t* trx) /*!< in/out: transaction */ -{ - ut_ad(lock_trx_has_sys_table_locks(trx) == NULL); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); - trx->dict_operation_lock_mode = 0; - dict_sys.unlock(); -} - /*********************************************************************//** Creates a table for MySQL. On failure the transaction will be rolled back and the 'table' object will be freed. @@ -2177,11 +2147,11 @@ row_create_table_for_mysql( tab_node_t* node; mem_heap_t* heap; que_thr_t* thr; - dberr_t err; + ut_ad(trx->state == TRX_STATE_ACTIVE); ut_ad(dict_sys.sys_tables_exist()); ut_ad(dict_sys.locked()); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); + ut_ad(trx->dict_operation_lock_mode); DEBUG_SYNC_C("create_table"); @@ -2205,7 +2175,7 @@ row_create_table_for_mysql( que_run_threads(thr); - err = trx->error_state; + dberr_t err = trx->error_state; if (err != DB_SUCCESS) { trx->error_state = DB_SUCCESS; @@ -2271,14 +2241,14 @@ row_create_index_for_mysql( } } - trx->op_info = "creating index"; - /* For temp-table we avoid insertion into SYSTEM TABLES to maintain performance and so we have separate path that directly just updates dictonary cache. */ if (!table->is_temporary()) { - trx_start_if_not_started_xa(trx, true); - trx->dict_operation = true; + ut_ad(trx->state == TRX_STATE_ACTIVE); + ut_ad(trx->dict_operation); + trx->op_info = "creating index"; + /* Note that the space id where we store the index is inherited from the table in dict_build_index_def_step() in dict0crea.cc. */ @@ -2306,6 +2276,8 @@ row_create_index_for_mysql( if (index && (index->type & DICT_FTS)) { err = fts_create_index_tables(trx, index, table->id); } + + trx->op_info = ""; } else { dict_build_index_def(table, index, trx); @@ -2327,8 +2299,6 @@ row_create_index_for_mysql( } } - trx->op_info = ""; - return(err); } @@ -2675,7 +2645,7 @@ row_rename_table_for_mysql( ut_a(old_name != NULL); ut_a(new_name != NULL); ut_ad(trx->state == TRX_STATE_ACTIVE); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); + ut_ad(trx->dict_operation_lock_mode); if (high_level_read_only) { return(DB_READ_ONLY); @@ -2686,7 +2656,7 @@ row_rename_table_for_mysql( old_is_tmp = dict_table_t::is_temporary_name(old_name); new_is_tmp = dict_table_t::is_temporary_name(new_name); - table = dict_table_open_on_name(old_name, true, false, + table = dict_table_open_on_name(old_name, true, DICT_ERR_IGNORE_FK_NOKEY); /* MariaDB partition engine hard codes the file name @@ -2706,7 +2676,7 @@ row_rename_table_for_mysql( check the existence of table name without lowering case them in the system table. */ if (!table && lower_case_table_names == 1 - && strstr(old_name, IF_WIN("#p#", "#P#"))) { + && strstr(old_name, table_name_t::part_suffix)) { char par_case_name[MAX_FULL_NAME_LEN + 1]; #ifndef _WIN32 /* Check for the table using lower @@ -2724,7 +2694,7 @@ row_rename_table_for_mysql( normalize_table_name_c_low( par_case_name, old_name, FALSE); #endif - table = dict_table_open_on_name(par_case_name, true, false, + table = dict_table_open_on_name(par_case_name, true, DICT_ERR_IGNORE_FK_NOKEY); } diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc index 7e10dcdfe9c8a..4588c1d2b0a75 100644 --- a/storage/innobase/row/row0purge.cc +++ b/storage/innobase/row/row0purge.cc @@ -141,7 +141,7 @@ row_purge_remove_clust_if_poss_low( mtr.commit(); close_and_exit: if (table) { - dict_table_close(table, true, false); + dict_table_close(table, true); dict_sys.unlock(); } return success; @@ -181,7 +181,7 @@ row_purge_remove_clust_if_poss_low( mtr.commit(); if (table) { - dict_table_close(table, true, false); + dict_table_close(table, true); dict_sys.unlock(); table = nullptr; } diff --git a/storage/innobase/row/row0uins.cc b/storage/innobase/row/row0uins.cc index 2c7408c950a71..c826d632969d6 100644 --- a/storage/innobase/row/row0uins.cc +++ b/storage/innobase/row/row0uins.cc @@ -73,12 +73,11 @@ row_undo_ins_remove_clust_rec( dict_index_t* index = node->pcur.btr_cur.index; bool online; table_id_t table_id = 0; - const bool dict_locked = node->trx->dict_operation_lock_mode - == RW_X_LATCH; + const bool dict_locked = node->trx->dict_operation_lock_mode; restart: MDL_ticket* mdl_ticket = nullptr; ut_ad(!table_id || dict_locked - || node->trx->dict_operation_lock_mode == 0); + || !node->trx->dict_operation_lock_mode); dict_table_t *table = table_id ? dict_table_open_on_id(table_id, dict_locked, DICT_TABLE_OP_OPEN_ONLY_IF_CACHED, @@ -147,8 +146,7 @@ row_undo_ins_remove_clust_rec( completed. At this point, any corresponding operation to the metadata record will have been rolled back. */ ut_ad(!online); - ut_ad(node->trx->dict_operation_lock_mode - == RW_X_LATCH); + ut_ad(node->trx->dict_operation_lock_mode); ut_ad(node->rec_type == TRX_UNDO_INSERT_REC); if (rec_get_n_fields_old(rec) != DICT_NUM_FIELDS__SYS_COLUMNS @@ -162,8 +160,7 @@ row_undo_ins_remove_clust_rec( break; case DICT_INDEXES_ID: ut_ad(!online); - ut_ad(node->trx->dict_operation_lock_mode - == RW_X_LATCH); + ut_ad(node->trx->dict_operation_lock_mode); ut_ad(node->rec_type == TRX_UNDO_INSERT_REC); if (!table_id) { table_id = mach_read_from_8(rec); @@ -272,7 +269,7 @@ row_undo_ins_remove_clust_rec( btr_pcur_commit_specify_mtr(&node->pcur, &mtr); if (UNIV_LIKELY_NULL(table)) { - dict_table_close(table, dict_locked, false, + dict_table_close(table, dict_locked, node->trx->mysql_thd, mdl_ticket); } @@ -486,7 +483,7 @@ static bool row_undo_ins_parse_undo_rec(undo_node_t* node, bool dict_locked) would probably be better to just drop all temporary tables (and temporary undo log records) of the current connection, instead of doing this rollback. */ - dict_table_close(node->table, dict_locked, FALSE); + dict_table_close(node->table, dict_locked); node->table = NULL; return false; } else { @@ -610,7 +607,7 @@ row_undo_ins( que_thr_t* thr) /*!< in: query thread */ { dberr_t err; - bool dict_locked = node->trx->dict_operation_lock_mode == RW_X_LATCH; + const bool dict_locked = node->trx->dict_operation_lock_mode; if (!row_undo_ins_parse_undo_rec(node, dict_locked)) { return DB_SUCCESS; @@ -683,7 +680,7 @@ row_undo_ins( break; } - dict_table_close(node->table, dict_locked, FALSE); + dict_table_close(node->table, dict_locked); node->table = NULL; diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc index 5039df2e1a61a..751c4e7340152 100644 --- a/storage/innobase/row/row0umod.cc +++ b/storage/innobase/row/row0umod.cc @@ -1239,7 +1239,7 @@ static bool row_undo_mod_parse_undo_rec(undo_node_t* node, bool dict_locked) would probably be better to just drop all temporary tables (and temporary undo log records) of the current connection, instead of doing this rollback. */ - dict_table_close(node->table, dict_locked, FALSE); + dict_table_close(node->table, dict_locked); node->table = NULL; return false; } @@ -1327,8 +1327,7 @@ row_undo_mod( { dberr_t err; ut_ad(thr_get_trx(thr) == node->trx); - const bool dict_locked = node->trx->dict_operation_lock_mode - == RW_X_LATCH; + const bool dict_locked = node->trx->dict_operation_lock_mode; if (!row_undo_mod_parse_undo_rec(node, dict_locked)) { return DB_SUCCESS; @@ -1402,7 +1401,7 @@ row_undo_mod( } } - dict_table_close(node->table, dict_locked, FALSE); + dict_table_close(node->table, dict_locked); node->table = NULL; diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index b343141f84bdc..9d8a19a8dff15 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -249,7 +249,7 @@ row_upd_check_references_constraints( ref_table = dict_table_open_on_name( foreign->foreign_table_name_lookup, - FALSE, FALSE, DICT_ERR_IGNORE_NONE); + false, DICT_ERR_IGNORE_NONE); } err = row_ins_check_foreign_constraint( @@ -332,7 +332,7 @@ wsrep_row_upd_check_foreign_constraints( foreign->referenced_table = dict_table_open_on_name( foreign->referenced_table_name_lookup, - FALSE, FALSE, DICT_ERR_IGNORE_NONE); + false, DICT_ERR_IGNORE_NONE); opened = (foreign->referenced_table) ? TRUE : FALSE; } diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 246a036379655..bb0b988241975 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -174,7 +174,7 @@ struct TrxFactory { trx->rw_trx_hash_pins = 0; trx_init(trx); - trx->dict_operation_lock_mode = 0; + trx->dict_operation_lock_mode = false; trx->detailed_error = reinterpret_cast( ut_zalloc_nokey(MAX_DETAILED_ERROR_LEN)); @@ -215,7 +215,7 @@ struct TrxFactory { ut_a(trx->lock.wait_lock == NULL); ut_a(trx->lock.wait_thr == NULL); - ut_a(trx->dict_operation_lock_mode == 0); + ut_a(!trx->dict_operation_lock_mode); if (trx->lock.lock_heap != NULL) { mem_heap_free(trx->lock.lock_heap); @@ -1114,7 +1114,7 @@ trx_finalize_for_fts( trx->fts_trx = NULL; } -extern "C" MYSQL_THD thd_increment_pending_ops(); + extern "C" void thd_decrement_pending_ops(MYSQL_THD); @@ -1123,11 +1123,11 @@ extern "C" void thd_decrement_pending_ops(MYSQL_THD); /* If required, initiates write and optionally flush of the log to disk - @param[in] lsn - lsn up to which logs are to be flushed. - @param[in] trx_state - if trx_state is PREPARED, the function will + @param lsn LSN up to which logs are to be flushed. + @param trx transaction; if trx->state is PREPARED, the function will also wait for the flush to complete. */ -static void trx_flush_log_if_needed_low(lsn_t lsn, trx_state_t trx_state) +static void trx_flush_log_if_needed_low(lsn_t lsn, const trx_t *trx) { if (!srv_flush_log_at_trx_commit) return; @@ -1138,25 +1138,23 @@ static void trx_flush_log_if_needed_low(lsn_t lsn, trx_state_t trx_state) const bool flush= srv_file_flush_method != SRV_NOSYNC && (srv_flush_log_at_trx_commit & 1); - if (trx_state == TRX_STATE_PREPARED) + if (trx->state == TRX_STATE_PREPARED) { /* XA, which is used with binlog as well. Be conservative, use synchronous wait.*/ +sync: log_write_up_to(lsn, flush); return; } completion_callback cb; - if ((cb.m_param = thd_increment_pending_ops())) + if ((cb.m_param = innodb_thd_increment_pending_ops(trx->mysql_thd))) { cb.m_callback = (void (*)(void *)) thd_decrement_pending_ops; log_write_up_to(lsn, flush, false, &cb); } else - { - /* No THD, synchronous write */ - log_write_up_to(lsn, flush); - } + goto sync; } /**********************************************************************//** @@ -1171,7 +1169,7 @@ trx_flush_log_if_needed( trx_t* trx) /*!< in/out: transaction */ { trx->op_info = "flushing log"; - trx_flush_log_if_needed_low(lsn,trx->state); + trx_flush_log_if_needed_low(lsn, trx); trx->op_info = ""; } From 45a05fda27dc7058ce8a89f14b1daa56352adf6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 31 Aug 2021 13:54:55 +0300 Subject: [PATCH 8/9] MDEV-25919: Replace dict_table_t::stats_bg_flag with MDL The purpose of dict_table_t::stats_bg_flag was to prevent race conditions between DDL operations and a background thread that updates persistent statistics for InnoDB tables. Now that with the parent commit, we started to acquire a shared meta-data lock (MDL) on the InnoDB persistent statistics tables in background tasks that access them, we may easily acquire MDL on the table for which the statistics are being updated. This will by design prevent race conditions with any DDL operations on that table, and the stats_bg_flag may be removed. dict_stats_process_entry_from_recalc_pool(): Complete rewrite. During the processing, retain the entry in recalc_pool, so that dict_stats_recalc_pool_del() will be able to request deletion of the entry, or delete the entry if its caller is holding MDL_EXCLUSIVE while we are waiting for MDL. recalc_pool: In addition to the table ID, store a state for inter-thread communication, so that dict_stats_recalc_pool_del() can wait until all processing is finished. Reviewed by: Thirunarayanan Balathandayuthapani --- storage/innobase/dict/dict0stats.cc | 31 +-- storage/innobase/dict/dict0stats_bg.cc | 306 ++++++++++------------ storage/innobase/dict/drop.cc | 4 +- storage/innobase/handler/ha_innodb.cc | 48 +--- storage/innobase/handler/handler0alter.cc | 44 +--- storage/innobase/include/dict0mem.h | 18 -- storage/innobase/include/dict0stats_bg.h | 51 +--- storage/innobase/row/row0mysql.cc | 3 - 8 files changed, 167 insertions(+), 338 deletions(-) diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index 2eced56c5e29f..d7466ae5f8aa4 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -839,9 +839,6 @@ dict_stats_assert_initialized( MEM_CHECK_DEFINED(&table->stat_modified_counter, sizeof table->stat_modified_counter); - MEM_CHECK_DEFINED(&table->stats_bg_flag, - sizeof table->stats_bg_flag); - for (dict_index_t* index = dict_table_get_first_index(table); index != NULL; index = dict_table_get_next_index(index)) { @@ -1009,7 +1006,6 @@ dict_stats_snapshot_create( t->stat_persistent = table->stat_persistent; t->stats_auto_recalc = table->stats_auto_recalc; t->stats_sample_pages = table->stats_sample_pages; - t->stats_bg_flag = table->stats_bg_flag; dict_sys.unlock(); @@ -2496,21 +2492,20 @@ dict_stats_update_persistent( continue; } - if (!(table->stats_bg_flag & BG_STAT_SHOULD_QUIT)) { - table->stats_mutex_unlock(); - stats = dict_stats_analyze_index(index); - table->stats_mutex_lock(); + table->stats_mutex_unlock(); + stats = dict_stats_analyze_index(index); + table->stats_mutex_lock(); - index->stat_index_size = stats.index_size; - index->stat_n_leaf_pages = stats.n_leaf_pages; - for (size_t i = 0; i < stats.stats.size(); ++i) { - index->stat_n_diff_key_vals[i] - = stats.stats[i].n_diff_key_vals; - index->stat_n_sample_sizes[i] - = stats.stats[i].n_sample_sizes; - index->stat_n_non_null_key_vals[i] - = stats.stats[i].n_non_null_key_vals; - } + index->stat_index_size = stats.index_size; + index->stat_n_leaf_pages = stats.n_leaf_pages; + + for (size_t i = 0; i < stats.stats.size(); ++i) { + index->stat_n_diff_key_vals[i] + = stats.stats[i].n_diff_key_vals; + index->stat_n_sample_sizes[i] + = stats.stats[i].n_sample_sizes; + index->stat_n_non_null_key_vals[i] + = stats.stats[i].n_non_null_key_vals; } table->stat_sum_of_other_index_sizes diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc index 7d50174c306ce..1a5f8b0bda5fc 100644 --- a/storage/innobase/dict/dict0stats_bg.cc +++ b/storage/innobase/dict/dict0stats_bg.cc @@ -50,22 +50,23 @@ static void dict_stats_schedule(int ms); my_bool innodb_dict_stats_disabled_debug; #endif /* UNIV_DEBUG */ -/** This mutex protects the "recalc_pool" variable. */ +/** Protects recalc_pool */ static mysql_mutex_t recalc_pool_mutex; -/** Allocator type, used by std::vector */ -typedef ut_allocator - recalc_pool_allocator_t; +/** for signaling recalc::state */ +static pthread_cond_t recalc_pool_cond; -/** The multitude of tables whose stats are to be automatically -recalculated - an STL vector */ -typedef std::vector - recalc_pool_t; +/** Work item of the recalc_pool; protected by recalc_pool_mutex */ +struct recalc +{ + /** identifies a table with persistent statistics */ + table_id_t id; + /** state of the entry */ + enum { IDLE, IN_PROGRESS, IN_PROGRESS_DELETING, DELETING} state; +}; -/** Iterator type for iterating over the elements of objects of type -recalc_pool_t. */ -typedef recalc_pool_t::iterator - recalc_pool_iterator_t; +/** The multitude of tables whose stats are to be automatically recalculated */ +typedef std::vector> recalc_pool_t; /** Pool where we store information on which tables are to be processed by background statistics gathering. */ @@ -102,35 +103,22 @@ background stats gathering thread. Only the table id is added to the list, so the table can be closed after being enqueued and it will be opened when needed. If the table does not exist later (has been DROPped), then it will be removed from the pool and skipped. */ -static -void -dict_stats_recalc_pool_add( -/*=======================*/ - const dict_table_t* table, /*!< in: table to add */ - bool schedule_dict_stats_task = true /*!< in: schedule dict stats task */ -) +static void dict_stats_recalc_pool_add(table_id_t id) { - ut_ad(!srv_read_only_mode); - - mysql_mutex_lock(&recalc_pool_mutex); - - /* quit if already in the list */ - for (recalc_pool_iterator_t iter = recalc_pool.begin(); - iter != recalc_pool.end(); - ++iter) { + ut_ad(!srv_read_only_mode); + ut_ad(id); + mysql_mutex_lock(&recalc_pool_mutex); - if (*iter == table->id) { - mysql_mutex_unlock(&recalc_pool_mutex); - return; - } - } + const auto begin= recalc_pool.begin(), end= recalc_pool.end(); + if (end == std::find_if(begin, end, [&](const recalc &r){return r.id == id;})) + { + recalc_pool.emplace_back(recalc{id, recalc::IDLE}); + } - recalc_pool.push_back(table->id); - if (recalc_pool.size() == 1 && schedule_dict_stats_task) { - dict_stats_schedule_now(); - } - mysql_mutex_unlock(&recalc_pool_mutex); + mysql_mutex_unlock(&recalc_pool_mutex); + if (begin == end) + dict_stats_schedule_now(); } #ifdef WITH_WSREP @@ -196,7 +184,7 @@ void dict_stats_update_if_needed_func(dict_table_t *table) } #endif /* WITH_WSREP */ - dict_stats_recalc_pool_add(table); + dict_stats_recalc_pool_add(table->id); table->stat_modified_counter = 0; } return; @@ -218,73 +206,41 @@ void dict_stats_update_if_needed_func(dict_table_t *table) } } -/*****************************************************************//** -Get a table from the auto recalc pool. The returned table id is removed -from the pool. -@return true if the pool was non-empty and "id" was set, false otherwise */ -static -bool -dict_stats_recalc_pool_get( -/*=======================*/ - table_id_t* id) /*!< out: table id, or unmodified if list is - empty */ -{ - ut_ad(!srv_read_only_mode); - - mysql_mutex_lock(&recalc_pool_mutex); - - if (recalc_pool.empty()) { - mysql_mutex_unlock(&recalc_pool_mutex); - return(false); - } - - *id = recalc_pool.at(0); - - recalc_pool.erase(recalc_pool.begin()); - - mysql_mutex_unlock(&recalc_pool_mutex); - - return(true); -} - -/*****************************************************************//** -Delete a given table from the auto recalc pool. -dict_stats_recalc_pool_del() */ -void -dict_stats_recalc_pool_del( -/*=======================*/ - const dict_table_t* table) /*!< in: table to remove */ +/** Delete a table from the auto recalc pool, and ensure that +no statistics are being updated on it. */ +void dict_stats_recalc_pool_del(table_id_t id, bool have_mdl_exclusive) { - ut_ad(!srv_read_only_mode); - ut_ad(dict_sys.frozen()); - - mysql_mutex_lock(&recalc_pool_mutex); - - ut_ad(table->id > 0); - - for (recalc_pool_iterator_t iter = recalc_pool.begin(); - iter != recalc_pool.end(); - ++iter) { + ut_ad(!srv_read_only_mode); + ut_ad(id); - if (*iter == table->id) { - /* erase() invalidates the iterator */ - recalc_pool.erase(iter); - break; - } - } + mysql_mutex_lock(&recalc_pool_mutex); - mysql_mutex_unlock(&recalc_pool_mutex); -} + const auto end= recalc_pool.end(); + auto i= std::find_if(recalc_pool.begin(), end, + [&](const recalc &r){return r.id == id;}); + if (i != end) + { + switch (i->state) { + case recalc::IN_PROGRESS: + if (!have_mdl_exclusive) + { + i->state= recalc::IN_PROGRESS_DELETING; + do + my_cond_wait(&recalc_pool_cond, &recalc_pool_mutex.m_mutex); + while (i->state == recalc::IN_PROGRESS_DELETING); + } + /* fall through */ + case recalc::IDLE: + recalc_pool.erase(i); + break; + case recalc::IN_PROGRESS_DELETING: + case recalc::DELETING: + /* another thread will delete the entry in dict_stats_recalc_pool_del() */ + break; + } + } -/*****************************************************************//** -Wait until background stats thread has stopped using the specified table. -The background stats thread is guaranteed not to start using the specified -table after this function returns and before the caller releases -dict_sys.latch. */ -void dict_stats_wait_bg_to_stop_using_table(dict_table_t *table) -{ - while (!dict_stats_stop_bg(table)) - DICT_BG_YIELD; + mysql_mutex_unlock(&recalc_pool_mutex); } /*****************************************************************//** @@ -294,6 +250,7 @@ void dict_stats_init() { ut_ad(!srv_read_only_mode); mysql_mutex_init(recalc_pool_mutex_key, &recalc_pool_mutex, nullptr); + pthread_cond_init(&recalc_pool_cond, nullptr); dict_defrag_pool_init(); stats_initialised= true; } @@ -314,79 +271,100 @@ void dict_stats_deinit() dict_defrag_pool_deinit(); mysql_mutex_destroy(&recalc_pool_mutex); + pthread_cond_destroy(&recalc_pool_cond); } /** Get the first table that has been added for auto recalc and eventually update its stats. @return whether the first entry can be processed immediately */ -static bool dict_stats_process_entry_from_recalc_pool() +static bool dict_stats_process_entry_from_recalc_pool(THD *thd) { - table_id_t table_id; - - ut_ad(!srv_read_only_mode); - -next_table_id: - /* pop the first table from the auto recalc pool */ - if (!dict_stats_recalc_pool_get(&table_id)) { - /* no tables for auto recalc */ - return false; - } - - dict_table_t* table; - - dict_sys.lock(SRW_LOCK_CALL); - - table = dict_table_open_on_id(table_id, TRUE, DICT_TABLE_OP_NORMAL); - - if (table == NULL) { - /* table does not exist, must have been DROPped - after its id was enqueued */ - goto no_table; - } - - ut_ad(!table->is_temporary()); - - if (!table->is_accessible()) { - table->release(); -no_table: - dict_sys.unlock(); - goto next_table_id; - } - - table->stats_bg_flag |= BG_STAT_IN_PROGRESS; - - dict_sys.unlock(); - - /* 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. */ - int ret; - if (difftime(time(NULL), table->stats_last_recalc) - < MIN_RECALC_INTERVAL) { - - /* Stats were (re)calculated not long ago. To avoid - too frequent stats updates we put back the table on - the auto recalc list and do nothing. */ + ut_ad(!srv_read_only_mode); + table_id_t table_id; + mysql_mutex_lock(&recalc_pool_mutex); +next_table_id_with_mutex: + for (auto &r : recalc_pool) + { + if ((table_id= r.id) && r.state == recalc::IDLE) + { + r.state= recalc::IN_PROGRESS; + mysql_mutex_unlock(&recalc_pool_mutex); + goto process; + } + } + mysql_mutex_unlock(&recalc_pool_mutex); + return false; + +process: + MDL_ticket *mdl= nullptr; + dict_table_t *table= dict_table_open_on_id(table_id, false, + DICT_TABLE_OP_NORMAL, thd, &mdl); + if (!table) + { +invalid_table_id: + mysql_mutex_lock(&recalc_pool_mutex); + auto i= std::find_if(recalc_pool.begin(), recalc_pool.end(), + [&](const recalc &r){return r.id == table_id;}); + if (i == recalc_pool.end()); + else if (UNIV_LIKELY(i->state == recalc::IN_PROGRESS)) + recalc_pool.erase(i); + else + { + ut_ad(i->state == recalc::IN_PROGRESS_DELETING); + i->state= recalc::DELETING; + pthread_cond_broadcast(&recalc_pool_cond); + } + goto next_table_id_with_mutex; + } - dict_stats_recalc_pool_add(table, false); - dict_stats_schedule(MIN_RECALC_INTERVAL*1000); - ret = false; - } else { + ut_ad(!table->is_temporary()); - dict_stats_update(table, DICT_STATS_RECALC_PERSISTENT); - ret = true; - } + if (!mdl || !table->is_accessible()) + { + dict_table_close(table, false, thd, mdl); + goto invalid_table_id; + } - dict_sys.lock(SRW_LOCK_CALL); - table->stats_bg_flag = BG_STAT_NONE; - dict_table_close(table, true); - dict_sys.unlock(); + /* 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. */ + const bool update_now= + difftime(time(nullptr), table->stats_last_recalc) >= MIN_RECALC_INTERVAL; + + if (update_now) + dict_stats_update(table, DICT_STATS_RECALC_PERSISTENT); + + dict_table_close(table, false, thd, mdl); + + mysql_mutex_lock(&recalc_pool_mutex); + auto i= std::find_if(recalc_pool.begin(), recalc_pool.end(), + [&](const recalc &r){return r.id == table_id;}); + if (i == recalc_pool.end()) + goto done; + else if (i->state == recalc::IN_PROGRESS_DELETING) + { + i->state= recalc::DELETING; + pthread_cond_broadcast(&recalc_pool_cond); +done: + mysql_mutex_unlock(&recalc_pool_mutex); + } + else + { + ut_ad(i->state == recalc::IN_PROGRESS); + recalc_pool.erase(i); + const bool reschedule= !update_now && recalc_pool.empty(); + if (!update_now) + recalc_pool.emplace_back(recalc{table_id, recalc::IDLE}); + mysql_mutex_unlock(&recalc_pool_mutex); + if (reschedule) + dict_stats_schedule(MIN_RECALC_INTERVAL * 1000); + } - return ret; + return update_now; } #ifdef UNIV_DEBUG @@ -411,7 +389,7 @@ static void dict_stats_func(void*) { THD *thd= innobase_create_background_thd("InnoDB statistics"); set_current_thd(thd); - while (dict_stats_process_entry_from_recalc_pool()) {} + while (dict_stats_process_entry_from_recalc_pool(thd)) {} dict_defrag_process_entries_from_defrag_pool(); set_current_thd(nullptr); innobase_destroy_background_thd(thd); diff --git a/storage/innobase/dict/drop.cc b/storage/innobase/dict/drop.cc index 20ee4ff545b08..0093601f32fd8 100644 --- a/storage/innobase/dict/drop.cc +++ b/storage/innobase/dict/drop.cc @@ -59,7 +59,6 @@ that would cause the InnoDB to hang or to intentionally crash. (d) The only changes to the data dictionary cache that are performed before transaction commit and must be rolled back explicitly are as follows: (d1) fts_optimize_add_table() to undo fts_optimize_remove_table() -(d2) stats_bg_flag= BG_STAT_NONE to undo dict_stats_stop_bg() */ #include "trx0purge.h" @@ -148,7 +147,6 @@ dberr_t trx_t::drop_table(const dict_table_t &table) ut_ad(dict_operation); ut_ad(dict_operation_lock_mode); ut_ad(!table.is_temporary()); - ut_ad(!(table.stats_bg_flag & BG_STAT_IN_PROGRESS)); /* The table must be exclusively locked by this transaction. */ ut_ad(table.get_ref_count() <= 1); ut_ad(table.n_lock_x_or_s == 1); @@ -241,7 +239,7 @@ void trx_t::commit(std::vector &deleted) if (p.second.is_dropped()) { dict_table_t *table= p.first; - dict_stats_recalc_pool_del(table); + dict_stats_recalc_pool_del(table->id, true); dict_stats_defrag_pool_del(table, nullptr); if (btr_defragment_active) btr_defragment_remove_table(table); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 81a03c1208aa6..0ce3255423208 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1339,27 +1339,10 @@ static void innodb_drop_database(handlerton*, char *path) THD * const thd= current_thd; trx_t *trx= innobase_trx_allocate(thd); -retry: - dict_sys.lock(SRW_LOCK_CALL); - - for (auto i= dict_sys.table_id_hash.n_cells; i--; ) - { - for (dict_table_t *table= static_cast - (dict_sys.table_id_hash.array[i].node); table; table= table->id_hash) - { - ut_ad(table->cached); - if (!strncmp(table->name.m_name, namebuf, len) && - !dict_stats_stop_bg(table)) - { - dict_sys.unlock(); - std::this_thread::sleep_for(std::chrono::milliseconds(250)); - goto retry; - } - } - } - dberr_t err= DB_SUCCESS; + dict_sys.lock(SRW_LOCK_CALL); + for (auto i= dict_sys.table_id_hash.n_cells; i--; ) { for (dict_table_t *next, *table= static_cast @@ -2069,7 +2052,6 @@ static void drop_garbage_tables_after_restore() ({reinterpret_cast(pcur.old_rec), len}, DICT_ERR_IGNORE_DROP)) { - ut_ad(table->stats_bg_flag == BG_STAT_NONE); table->acquire(); row_mysql_unlock_data_dictionary(trx); err= lock_table_for_trx(table, trx, LOCK_X); @@ -13399,7 +13381,6 @@ int ha_innobase::delete_table(const char *name) trx_t *parent_trx= check_trx_exists(thd); dict_table_t *table; - for (;;) { char norm_name[FN_REFLEN]; normalize_table_name(norm_name, name); @@ -13420,10 +13401,6 @@ int ha_innobase::delete_table(const char *name) dict_sys.unlock(); DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); } - - if (dict_stats_stop_bg(table)) - break; - dict_sys.unlock(); } if (table->is_temporary()) @@ -13568,7 +13545,6 @@ int ha_innobase::delete_table(const char *name) default: ib::error() << "DROP TABLE " << table->name << ": " << err; } - table->stats_bg_flag= BG_STAT_NONE; if (fts) { fts_optimize_add_table(table); @@ -13862,7 +13838,6 @@ int ha_innobase::truncate() } row_mysql_lock_data_dictionary(trx); - dict_stats_wait_bg_to_stop_using_table(ib_table); if (error == DB_SUCCESS) { error = innobase_rename_table(trx, ib_table->name.m_name, @@ -14569,13 +14544,11 @@ ha_innobase::info_low( m_prebuilt->trx->op_info = "updating table statistics"; if (dict_stats_is_persistent_enabled(ib_table)) { - if (is_analyze) { - dict_sys.lock(SRW_LOCK_CALL); - dict_stats_recalc_pool_del(ib_table); - dict_stats_wait_bg_to_stop_using_table( - ib_table); - dict_sys.unlock(); + if (!srv_read_only_mode) { + dict_stats_recalc_pool_del( + ib_table->id, false); + } opt = DICT_STATS_RECALC_PERSISTENT; } else { /* This is e.g. 'SHOW INDEXES', fetch @@ -14588,15 +14561,6 @@ ha_innobase::info_low( ret = dict_stats_update(ib_table, opt); - if (opt == DICT_STATS_RECALC_PERSISTENT) { - dict_sys.freeze(SRW_LOCK_CALL); - ib_table->stats_mutex_lock(); - ib_table->stats_bg_flag - &= byte(~BG_STAT_SHOULD_QUIT); - ib_table->stats_mutex_unlock(); - dict_sys.unfreeze(); - } - if (ret != DB_SUCCESS) { m_prebuilt->trx->op_info = ""; DBUG_RETURN(HA_ERR_GENERIC); diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 06eaa934834a9..3bf56cd2bc69b 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -6212,7 +6212,6 @@ prepare_inplace_alter_table_dict( create_table_info_t info(ctx->prebuilt->trx->mysql_thd, altered_table, ha_alter_info->create_info, NULL, NULL, srv_file_per_table); - ut_d(bool stats_wait = false); /* The primary index would be rebuilt if a FTS Doc ID column is to be added, and the primary index definition @@ -6280,16 +6279,6 @@ prepare_inplace_alter_table_dict( row_mysql_lock_data_dictionary(ctx->trx); dict_locked = true; - - /* Wait for background stats processing to stop using the table that - we are going to alter. We know bg stats will not start using it again - until we are holding the data dict locked and we are holding it here - at least until checking ut_ad(user_table->n_ref_count == 1) below. - XXX what may happen if bg stats opens the table after we - have unlocked data dictionary below? */ - dict_stats_wait_bg_to_stop_using_table(user_table); - ut_d(stats_wait = true); - online_retry_drop_indexes_low(ctx->new_table, ctx->trx); ut_d(dict_table_check_for_dup_indexes( @@ -7175,10 +7164,10 @@ prepare_inplace_alter_table_dict( } } - /* n_ref_count must be 1, because purge cannot + /* n_ref_count must be 1, because background threads cannot be executing on this very table as we are holding MDL_EXCLUSIVE. */ - ut_ad(!stats_wait || ctx->online || user_table->get_ref_count() == 1); + ut_ad(ctx->online || user_table->get_ref_count() == 1); if (new_clustered) { online_retry_drop_indexes_low(user_table, ctx->trx); @@ -10973,35 +10962,6 @@ ha_innobase::commit_inplace_alter_table( row_mysql_lock_data_dictionary(trx); - /* Prevent the background statistics collection from accessing - the tables. */ - for (;;) { - bool retry = false; - - for (inplace_alter_handler_ctx** pctx = ctx_array; - *pctx; pctx++) { - ha_innobase_inplace_ctx* ctx - = static_cast(*pctx); - - DBUG_ASSERT(new_clustered == ctx->need_rebuild()); - - if (new_clustered - && !dict_stats_stop_bg(ctx->old_table)) { - retry = true; - } - - if (!dict_stats_stop_bg(ctx->new_table)) { - retry = true; - } - } - - if (!retry) { - break; - } - - DICT_BG_YIELD; - } - /* Apply the changes to the data dictionary tables, for all partitions. */ for (inplace_alter_handler_ctx** pctx = ctx_array; *pctx; pctx++) { diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 8d636e056ee2d..417a65f1b0990 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -2244,24 +2244,6 @@ struct dict_table_t { any latch, because this is only used for heuristics. */ ib_uint64_t stat_modified_counter; - /** Background stats thread is not working on this table. */ - #define BG_STAT_NONE 0 - - /** Set in 'stats_bg_flag' when the background stats code is working - on this table. The DROP TABLE code waits for this to be cleared before - proceeding. */ - #define BG_STAT_IN_PROGRESS (1 << 0) - - /** Set in 'stats_bg_flag' when DROP TABLE starts waiting on - BG_STAT_IN_PROGRESS to be cleared. The background stats thread will - detect this and will eventually quit sooner. */ - #define BG_STAT_SHOULD_QUIT (1 << 1) - - /** The state of the background stats thread wrt this table. - See BG_STAT_NONE, BG_STAT_IN_PROGRESS and BG_STAT_SHOULD_QUIT. - Writes are covered by dict_sys.latch and stats_mutex_lock(). */ - byte stats_bg_flag; - bool stats_error_printed; /*!< Has persistent stats error beein already printed for this table ? */ diff --git a/storage/innobase/include/dict0stats_bg.h b/storage/innobase/include/dict0stats_bg.h index 0d5982b231af0..f047d40469328 100644 --- a/storage/innobase/include/dict0stats_bg.h +++ b/storage/innobase/include/dict0stats_bg.h @@ -39,54 +39,9 @@ extern mysql_pfs_key_t recalc_pool_mutex_key; extern my_bool innodb_dict_stats_disabled_debug; #endif /* UNIV_DEBUG */ -/*****************************************************************//** -Delete a given table from the auto recalc pool. -dict_stats_recalc_pool_del() */ -void -dict_stats_recalc_pool_del( -/*=======================*/ - const dict_table_t* table); /*!< in: table to remove */ - -/** 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_BG_YIELD do { \ - dict_sys.unlock(); \ - std::this_thread::sleep_for(std::chrono::milliseconds(250)); \ - dict_sys.lock(SRW_LOCK_CALL); \ -} while (0) - -/*****************************************************************//** -Request the background collection of statistics to stop for a table. -@retval true when no background process is active -@retval false when it is not safe to modify the table definition */ -UNIV_INLINE -bool -dict_stats_stop_bg( -/*===============*/ - dict_table_t* table) /*!< in/out: table */ -{ - ut_ad(!srv_read_only_mode); - ut_ad(dict_sys.locked()); - - if (!(table->stats_bg_flag & BG_STAT_IN_PROGRESS)) { - return(true); - } - - /* In dict_stats_update_persistent() this flag is being read - while holding the mutex, not dict_sys.latch. */ - table->stats_mutex_lock(); - table->stats_bg_flag |= BG_STAT_SHOULD_QUIT; - table->stats_mutex_unlock(); - return(false); -} - -/*****************************************************************//** -Wait until background stats thread has stopped using the specified table. -The background stats thread is guaranteed not to start using the specified -table after this function returns and before the caller releases -dict_sys.latch. */ -void dict_stats_wait_bg_to_stop_using_table(dict_table_t *table); +/** Delete a table from the auto recalc pool, and ensure that +no statistics are being updated on it. */ +void dict_stats_recalc_pool_del(table_id_t id, bool have_mdl_exclusive); /*****************************************************************//** Initialize global variables needed for the operation of dict_stats_thread(). diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index a0ef110f60628..45ec06e452dce 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -2517,8 +2517,6 @@ dberr_t row_discard_tablespace_for_mysql(dict_table_t *table, trx_t *trx) } row_mysql_lock_data_dictionary(trx); - dict_stats_wait_bg_to_stop_using_table(table); - trx->op_info = "discarding tablespace"; trx->dict_operation= true; @@ -2528,7 +2526,6 @@ dberr_t row_discard_tablespace_for_mysql(dict_table_t *table, trx_t *trx) err= row_discard_tablespace_foreign_key_checks(trx, table); if (err != DB_SUCCESS) { - table->stats_bg_flag= BG_STAT_NONE; row_mysql_unlock_data_dictionary(trx); goto rollback; } From 9608773f75e2ca21491ef6825c3616cdc96d1ca5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 31 Aug 2021 13:55:02 +0300 Subject: [PATCH 9/9] MDEV-4750 follow-up: Reduce disabling innodb_stats_persistent This essentially reverts commit 4e89ec6692786bc1cbdce64d43d8e85a5d247dab and only disables InnoDB persistent statistics for tests where it is desirable. By design, InnoDB persistent statistics will not be updated except by ANALYZE TABLE or by STATS_AUTO_RECALC. The internal transactions that update persistent InnoDB statistics in background tasks (with innodb_stats_auto_recalc=ON) may cause nondeterministic query plans or interfere with some tests that deal with other InnoDB internals, such as the purge of transaction history. --- mysql-test/include/default_mysqld.cnf | 3 +- mysql-test/main/bug39022.result | 2 +- mysql-test/main/bug39022.test | 2 +- mysql-test/main/column_compression_rpl.opt | 1 + mysql-test/main/create_or_replace.result | 37 +- mysql-test/main/create_or_replace.test | 40 +- .../main/ctype_utf8mb4_innodb-master.opt | 1 + mysql-test/main/derived_split_innodb.result | 3 + mysql-test/main/derived_split_innodb.test | 5 + mysql-test/main/endspace.result | 3 +- mysql-test/main/endspace.test | 3 +- .../fast_prefix_index_fetch_innodb.result | 3 + .../main/fast_prefix_index_fetch_innodb.test | 4 + mysql-test/main/index_merge_innodb.result | 3 + mysql-test/main/index_merge_innodb.test | 4 + mysql-test/main/innodb_ext_key.result | 11 + mysql-test/main/innodb_ext_key.test | 1 + mysql-test/main/join_outer_innodb.result | 3 + mysql-test/main/join_outer_innodb.test | 3 + mysql-test/main/mysql_upgrade.result | 2 +- mysql-test/main/mysql_upgrade.test | 2 +- .../main/order_by_optimizer_innodb.result | 4 +- .../main/order_by_optimizer_innodb.test | 6 +- mysql-test/main/range_vs_index_merge.result | 2 - mysql-test/main/range_vs_index_merge.test | 7 +- .../main/range_vs_index_merge_innodb.result | 2 - mysql-test/main/rowid_filter_innodb.result | 7 +- mysql-test/main/rowid_filter_innodb.test | 10 +- mysql-test/main/rowid_order_innodb.result | 3 + mysql-test/main/rowid_order_innodb.test | 4 + mysql-test/main/selectivity_innodb.result | 3 + mysql-test/main/selectivity_innodb.test | 3 + mysql-test/main/subselect-crash_15755.result | 7 +- mysql-test/main/subselect-crash_15755.test | 6 +- mysql-test/main/subselect_innodb.result | 4 +- mysql-test/main/subselect_innodb.test | 7 +- mysql-test/main/type_bit_innodb.result | 4 +- mysql-test/main/type_bit_innodb.test | 9 +- mysql-test/main/update_use_source.result | 2 +- mysql-test/main/update_use_source.test | 2 +- .../r/binlog_mysqlbinlog_row_innodb.result | 3 + .../t/binlog_mysqlbinlog_row_innodb.test | 4 + .../engines/funcs/r/se_join_default.result | 3100 ++++++++--------- .../engines/funcs/t/se_join_default.test | 210 ++ mysql-test/suite/gcol/inc/gcol_keys.inc | 2 +- mysql-test/suite/gcol/inc/gcol_select.inc | 12 +- mysql-test/suite/gcol/inc/gcol_view.inc | 14 +- .../suite/gcol/r/gcol_keys_innodb.result | 2 +- .../suite/gcol/r/gcol_keys_myisam.result | 2 +- .../suite/gcol/r/gcol_select_myisam.result | 32 +- .../suite/gcol/r/gcol_view_innodb.result | 24 +- .../suite/gcol/r/gcol_view_myisam.result | 24 +- .../gcol/r/innodb_virtual_debug_purge.result | 3 + .../gcol/t/innodb_virtual_debug_purge.test | 3 + mysql-test/suite/innodb/r/doublewrite.result | 2 +- mysql-test/suite/innodb/r/innodb-16k.result | 13 +- mysql-test/suite/innodb/r/innodb-32k.result | 2 + .../innodb/r/innodb-alter-tempfile.result | 2 +- mysql-test/suite/innodb/r/innodb-dict.result | 4 + .../suite/innodb/r/innodb-index-online.result | 3 + .../suite/innodb/r/innodb-isolation.result | 32 +- .../suite/innodb/r/innodb-wl5522-debug.result | 1 + .../suite/innodb/r/innodb-wl5522.result | 1 + mysql-test/suite/innodb/r/innodb.result | 2 +- .../suite/innodb/r/innodb_bug84958.result | 2 +- .../suite/innodb/r/innodb_defrag_stats.result | 3 +- mysql-test/suite/innodb/r/monitor.result | 2 +- mysql-test/suite/innodb/r/update_time.result | 2 +- mysql-test/suite/innodb/t/doublewrite.test | 2 +- mysql-test/suite/innodb/t/innodb-16k.test | 21 +- mysql-test/suite/innodb/t/innodb-32k.test | 9 +- .../suite/innodb/t/innodb-alter-tempfile.test | 1 + mysql-test/suite/innodb/t/innodb-dict.test | 1 + mysql-test/suite/innodb/t/innodb-index.opt | 1 + .../suite/innodb/t/innodb-index_ucs2.opt | 1 + .../suite/innodb/t/innodb-isolation.test | 26 +- .../t/innodb-stats-modified-counter.opt | 2 +- .../suite/innodb/t/innodb-wl5522-debug.test | 1 + mysql-test/suite/innodb/t/innodb-wl5522.test | 2 + mysql-test/suite/innodb/t/innodb.test | 2 +- .../suite/innodb/t/innodb_bug57252.test | 2 +- .../suite/innodb/t/innodb_bug84958.test | 2 +- .../suite/innodb/t/innodb_defrag_stats.test | 2 - mysql-test/suite/innodb/t/instant_alter.opt | 2 +- .../innodb/t/instant_alter_debug.combinations | 2 + mysql-test/suite/innodb/t/monitor.test | 2 +- mysql-test/suite/innodb/t/purge_secondary.opt | 1 + mysql-test/suite/innodb/t/update_time.test | 2 +- .../suite/innodb_fts/r/misc_debug.result | 1 + mysql-test/suite/innodb_fts/t/misc_debug.test | 1 + mysql-test/suite/innodb_gis/r/1.result | 16 +- mysql-test/suite/innodb_gis/r/geometry.result | 51 +- mysql-test/suite/innodb_gis/r/gis.result | 20 +- .../suite/innodb_gis/r/point_basic.result | 12 +- .../suite/innodb_gis/r/point_big.result | 2 +- .../suite/innodb_gis/r/rt_precise.result | 2 +- mysql-test/suite/innodb_gis/r/types.result | 2 +- mysql-test/suite/innodb_gis/t/1.test | 14 +- mysql-test/suite/innodb_gis/t/geometry.test | 62 +- mysql-test/suite/innodb_gis/t/gis.test | 22 +- .../suite/innodb_gis/t/point_basic.test | 12 +- mysql-test/suite/innodb_gis/t/point_big.test | 2 +- mysql-test/suite/innodb_gis/t/rt_precise.test | 2 +- mysql-test/suite/innodb_gis/t/types.test | 2 +- .../innodb_zip/r/wl5522_debug_zip.result | 1 + .../suite/innodb_zip/r/wl5522_zip.result | 1 + .../innodb_zip/r/wl6344_compress_level.result | 4 +- .../suite/innodb_zip/t/wl5522_debug_zip.test | 1 + mysql-test/suite/innodb_zip/t/wl5522_zip.test | 1 + .../innodb_zip/t/wl6344_compress_level.test | 5 +- mysql-test/suite/parts/r/longname.result | 4 + .../parts/r/partition_alter1_2_innodb.result | 3 + .../parts/r/partition_alter3_innodb.result | 3 + .../r/partition_debug_sync_innodb.result | 6 +- .../parts/t/partition_alter1_2_innodb.test | 5 + .../parts/t/partition_alter3_innodb.test | 5 + .../parts/t/partition_debug_sync_innodb.test | 2 +- .../r/innodb_stats_persistent_basic.result | 5 +- .../t/innodb_stats_persistent_basic.test | 3 +- .../suite/vcol/r/vcol_select_innodb.result | 3 + .../suite/vcol/r/vcol_view_innodb.result | 3 + .../suite/vcol/t/vcol_select_innodb.test | 4 + mysql-test/suite/vcol/t/vcol_view_innodb.test | 4 + mysql-test/suite/versioning/r/cte.result | 3 + .../suite/versioning/r/partition.result | 4 + mysql-test/suite/versioning/r/select.result | 3 + mysql-test/suite/versioning/t/cte.test | 5 + mysql-test/suite/versioning/t/partition.test | 7 + mysql-test/suite/versioning/t/select.test | 5 + .../wrapper/r/alter_table_spatial.result | 3 +- .../wrapper/t/alter_table_spatial.test | 3 +- 131 files changed, 2275 insertions(+), 1862 deletions(-) create mode 100644 mysql-test/main/column_compression_rpl.opt create mode 100644 mysql-test/suite/innodb/t/innodb-index.opt create mode 100644 mysql-test/suite/innodb/t/innodb-index_ucs2.opt diff --git a/mysql-test/include/default_mysqld.cnf b/mysql-test/include/default_mysqld.cnf index cccf72591ccdb..4788fbb7ff633 100644 --- a/mysql-test/include/default_mysqld.cnf +++ b/mysql-test/include/default_mysqld.cnf @@ -1,5 +1,5 @@ # Copyright (c) 2007, 2013, Oracle and/or its affiliates -# Copyright (c) 2010, 2019, MariaDB Corporation +# Copyright (c) 2010, 2021, 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 @@ -54,7 +54,6 @@ loose-innodb_write_io_threads= 2 loose-innodb_read_io_threads= 2 loose-innodb_log_buffer_size= 1M loose-innodb_log_file_size= 10M -loose-innodb-stats-persistent= OFF slave-net-timeout=120 diff --git a/mysql-test/main/bug39022.result b/mysql-test/main/bug39022.result index 599808ca7d7d9..5667c36ae9480 100644 --- a/mysql-test/main/bug39022.result +++ b/mysql-test/main/bug39022.result @@ -28,7 +28,7 @@ SELECT d FROM t2,t1 WHERE d=(SELECT MAX(a) FROM t1 WHERE t1.a > t2.d) LOCK IN SH connection thread1; # should not crash SELECT d FROM t2,t1 WHERE d=(SELECT MAX(a) FROM t1 WHERE t1.a > t2.d) LOCK IN SHARE MODE; -ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +Got one of the listed errors connection thread2; d disconnect thread2; diff --git a/mysql-test/main/bug39022.test b/mysql-test/main/bug39022.test index d293788e58e70..e07d087a3203f 100644 --- a/mysql-test/main/bug39022.test +++ b/mysql-test/main/bug39022.test @@ -40,7 +40,7 @@ SELECT d FROM t2,t1 WHERE d=(SELECT MAX(a) FROM t1 WHERE t1.a > t2.d) LOCK IN SH connection thread1; --echo # should not crash ---error ER_LOCK_DEADLOCK +--error ER_LOCK_DEADLOCK,ER_LOCK_WAIT_TIMEOUT SELECT d FROM t2,t1 WHERE d=(SELECT MAX(a) FROM t1 WHERE t1.a > t2.d) LOCK IN SHARE MODE; #crashes connection thread2; diff --git a/mysql-test/main/column_compression_rpl.opt b/mysql-test/main/column_compression_rpl.opt new file mode 100644 index 0000000000000..1a01b4018c6e2 --- /dev/null +++ b/mysql-test/main/column_compression_rpl.opt @@ -0,0 +1 @@ +--skip-innodb-stats-persistent diff --git a/mysql-test/main/create_or_replace.result b/mysql-test/main/create_or_replace.result index 1eaf87d190d22..19d9f3e65a1eb 100644 --- a/mysql-test/main/create_or_replace.result +++ b/mysql-test/main/create_or_replace.result @@ -1,4 +1,3 @@ -drop table if exists t1,t2,t3; CREATE TABLE t2 (a int); INSERT INTO t2 VALUES(1),(2),(3); # @@ -259,7 +258,8 @@ Note 1051 Unknown table 'test.t1,mysqltest2.t2' create table test.t1 (i int) engine=myisam; create table mysqltest2.t2 like test.t1; lock table test.t1 write, mysqltest2.t2 write; -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_BACKUP_DDL NULL Backup lock # MDL_BACKUP_DML NULL Backup lock @@ -272,7 +272,8 @@ ERROR 42000: A table must have at least 1 column show tables; Tables_in_test t2 -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_BACKUP_DDL NULL Backup lock # MDL_BACKUP_DML NULL Backup lock @@ -281,14 +282,16 @@ THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_SHARED_NO_READ_WRITE NULL Table metadata lock mysqltest2 t2 create or replace table mysqltest2.t2; ERROR 42000: A table must have at least 1 column -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME create table t1 (i int); drop table t1; create table test.t1 (i int); create table mysqltest2.t2 like test.t1; lock table test.t1 write, mysqltest2.t2 write; -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_BACKUP_DDL NULL Backup lock # MDL_BACKUP_DML NULL Backup lock @@ -301,7 +304,8 @@ ERROR 42S21: Duplicate column name 'a' show tables; Tables_in_test t2 -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_BACKUP_DDL NULL Backup lock # MDL_BACKUP_DML NULL Backup lock @@ -310,14 +314,16 @@ THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_SHARED_NO_READ_WRITE NULL Table metadata lock mysqltest2 t2 create or replace table mysqltest2.t2 (a int) select 1 as 'a', 2 as 'a'; ERROR 42S21: Duplicate column name 'a' -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME create table t1 (i int); drop table t1; create table test.t1 (i int) engine=innodb; create table mysqltest2.t2 like test.t1; lock table test.t1 write, mysqltest2.t2 write; -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_BACKUP_DDL NULL Backup lock # MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock mysqltest2 @@ -329,7 +335,8 @@ drop table test.t1,mysqltest2.t2; create table test.t1 (i int) engine=aria transactional=1 checksum=1; create table mysqltest2.t2 like test.t1; lock table test.t1 write, mysqltest2.t2 write; -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_BACKUP_DDL NULL Backup lock # MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock mysqltest2 @@ -424,7 +431,8 @@ drop view t1; # create table t1 (a int); lock table t1 write, t2 read; -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_BACKUP_DDL NULL Backup lock # MDL_BACKUP_DML NULL Backup lock @@ -432,7 +440,8 @@ THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_SHARED_NO_READ_WRITE NULL Table metadata lock test t1 # MDL_SHARED_READ NULL Table metadata lock test t2 create or replace table t1 (i int); -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_BACKUP_DDL NULL Backup lock # MDL_BACKUP_DML NULL Backup lock @@ -440,7 +449,8 @@ THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_SHARED_NO_READ_WRITE NULL Table metadata lock test t1 # MDL_SHARED_READ NULL Table metadata lock test t2 create or replace table t1 like t2; -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_BACKUP_DDL NULL Backup lock # MDL_BACKUP_DML NULL Backup lock @@ -448,7 +458,8 @@ THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_SHARED_NO_READ_WRITE NULL Table metadata lock test t1 # MDL_SHARED_READ NULL Table metadata lock test t2 create or replace table t1 select 1 as f1; -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_BACKUP_DDL NULL Backup lock # MDL_BACKUP_DML NULL Backup lock diff --git a/mysql-test/main/create_or_replace.test b/mysql-test/main/create_or_replace.test index 1b4994e811fe6..a39b3bbe1cd8d 100644 --- a/mysql-test/main/create_or_replace.test +++ b/mysql-test/main/create_or_replace.test @@ -4,9 +4,6 @@ --source include/have_innodb.inc --source include/have_metadata_lock_info.inc ---disable_warnings -drop table if exists t1,t2,t3; ---enable_warnings # # Create help table @@ -215,18 +212,21 @@ create table mysqltest2.t2 like test.t1; lock table test.t1 write, mysqltest2.t2 write; --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; --error ER_TABLE_MUST_HAVE_COLUMNS create or replace table test.t1; show tables; --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; --error ER_TABLE_MUST_HAVE_COLUMNS create or replace table mysqltest2.t2; --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; create table t1 (i int); drop table t1; @@ -235,18 +235,21 @@ create table mysqltest2.t2 like test.t1; lock table test.t1 write, mysqltest2.t2 write; --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; --error ER_DUP_FIELDNAME create or replace table test.t1 (a int) select 1 as 'a', 2 as 'a'; show tables; --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; --error ER_DUP_FIELDNAME create or replace table mysqltest2.t2 (a int) select 1 as 'a', 2 as 'a'; --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; create table t1 (i int); drop table t1; @@ -255,7 +258,8 @@ create table mysqltest2.t2 like test.t1; lock table test.t1 write, mysqltest2.t2 write; --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; unlock tables; drop table test.t1,mysqltest2.t2; @@ -264,7 +268,8 @@ create table mysqltest2.t2 like test.t1; lock table test.t1 write, mysqltest2.t2 write; --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; unlock tables; drop table t1; @@ -344,19 +349,24 @@ create table t1 (a int); lock table t1 write, t2 read; --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; + create or replace table t1 (i int); --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; create or replace table t1 like t2; --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; create or replace table t1 select 1 as f1; --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_name not like 'innodb_%_stats'; drop table t1; unlock tables; diff --git a/mysql-test/main/ctype_utf8mb4_innodb-master.opt b/mysql-test/main/ctype_utf8mb4_innodb-master.opt index 96f0ce3f36c0b..d1dc9a3e00f56 100644 --- a/mysql-test/main/ctype_utf8mb4_innodb-master.opt +++ b/mysql-test/main/ctype_utf8mb4_innodb-master.opt @@ -1 +1,2 @@ --default-storage-engine=MyISAM +--innodb-stats-persistent=OFF diff --git a/mysql-test/main/derived_split_innodb.result b/mysql-test/main/derived_split_innodb.result index 9edf9a1f2ae70..21921d86dab53 100644 --- a/mysql-test/main/derived_split_innodb.result +++ b/mysql-test/main/derived_split_innodb.result @@ -1,3 +1,5 @@ +SET @save_innodb_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; # # MDEV-16917: do not use splitting for derived with join cache # @@ -241,3 +243,4 @@ set optimizer_switch='split_materialized=default'; set use_stat_tables=default; set optimizer_use_condition_selectivity=default; # End of 10.3 tests +SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent; diff --git a/mysql-test/main/derived_split_innodb.test b/mysql-test/main/derived_split_innodb.test index bee9ef497b6cd..de25fd8e3d3d5 100644 --- a/mysql-test/main/derived_split_innodb.test +++ b/mysql-test/main/derived_split_innodb.test @@ -2,6 +2,9 @@ --source include/default_optimizer_switch.inc --source include/have_sequence.inc +SET @save_innodb_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; + --echo # --echo # MDEV-16917: do not use splitting for derived with join cache --echo # @@ -193,3 +196,5 @@ set use_stat_tables=default; set optimizer_use_condition_selectivity=default; --echo # End of 10.3 tests + +SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent; diff --git a/mysql-test/main/endspace.result b/mysql-test/main/endspace.result index f9619db7e6407..e7160f2829bb6 100644 --- a/mysql-test/main/endspace.result +++ b/mysql-test/main/endspace.result @@ -162,7 +162,8 @@ nothing teststring teststring drop table t1; -create table t1 (text1 varchar(32) not NULL, KEY key1 (text1)) engine=innodb; +create table t1 (text1 varchar(32) not NULL, KEY key1 (text1)) engine=innodb +stats_persistent=0; insert into t1 values ('teststring'), ('nothing'), ('teststring\t'); check table t1; Table Op Msg_type Msg_text diff --git a/mysql-test/main/endspace.test b/mysql-test/main/endspace.test index 69b8133c5f738..be120667b5679 100644 --- a/mysql-test/main/endspace.test +++ b/mysql-test/main/endspace.test @@ -74,7 +74,8 @@ drop table t1; # Test InnoDB tables # -create table t1 (text1 varchar(32) not NULL, KEY key1 (text1)) engine=innodb; +create table t1 (text1 varchar(32) not NULL, KEY key1 (text1)) engine=innodb +stats_persistent=0; insert into t1 values ('teststring'), ('nothing'), ('teststring\t'); check table t1; select * from t1 where text1='teststring' or text1 like 'teststring_%'; diff --git a/mysql-test/main/fast_prefix_index_fetch_innodb.result b/mysql-test/main/fast_prefix_index_fetch_innodb.result index ef297e5c6b55d..aa888fb070483 100644 --- a/mysql-test/main/fast_prefix_index_fetch_innodb.result +++ b/mysql-test/main/fast_prefix_index_fetch_innodb.result @@ -3,6 +3,8 @@ set global innodb_prefix_index_cluster_optimization = ON; show variables like 'innodb_prefix_index_cluster_optimization'; Variable_name Value innodb_prefix_index_cluster_optimization ON +SET @save_innodb_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; # Create a table with a large varchar field that we index the prefix # of and ensure we only trigger cluster lookups when we expect it. create table prefixinno ( @@ -455,3 +457,4 @@ blog_id 1 DROP TABLE wp_blogs; SET GLOBAL innodb_prefix_index_cluster_optimization = @save_opt; +SET GLOBAL innodb_stats_persistent = @save_innodb_stats_persistent; diff --git a/mysql-test/main/fast_prefix_index_fetch_innodb.test b/mysql-test/main/fast_prefix_index_fetch_innodb.test index 1987416ff871f..cb7ec642fe340 100644 --- a/mysql-test/main/fast_prefix_index_fetch_innodb.test +++ b/mysql-test/main/fast_prefix_index_fetch_innodb.test @@ -4,6 +4,9 @@ SET @save_opt= @@GLOBAL.innodb_prefix_index_cluster_optimization; set global innodb_prefix_index_cluster_optimization = ON; show variables like 'innodb_prefix_index_cluster_optimization'; +SET @save_innodb_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; + --echo # Create a table with a large varchar field that we index the prefix --echo # of and ensure we only trigger cluster lookups when we expect it. create table prefixinno ( @@ -717,3 +720,4 @@ AND path IN ( '/fondsinvesteringer/', '/' ); DROP TABLE wp_blogs; SET GLOBAL innodb_prefix_index_cluster_optimization = @save_opt; +SET GLOBAL innodb_stats_persistent = @save_innodb_stats_persistent; diff --git a/mysql-test/main/index_merge_innodb.result b/mysql-test/main/index_merge_innodb.result index f1418d6a365ad..ada2abdc0d6a3 100644 --- a/mysql-test/main/index_merge_innodb.result +++ b/mysql-test/main/index_merge_innodb.result @@ -6,6 +6,8 @@ SET DEFAULT_STORAGE_ENGINE = InnoDB; set @optimizer_switch_save= @@optimizer_switch; set optimizer_switch='index_merge_sort_intersection=off'; set optimizer_switch='rowid_filter=off'; +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; #---------------- Index merge test 2 ------------------------------------------- create table t1 ( @@ -835,3 +837,4 @@ a b c DROP TABLE t1; SET sort_buffer_size= @save_sort_buffer_size; disconnect disable_purge; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/main/index_merge_innodb.test b/mysql-test/main/index_merge_innodb.test index 5c4021036e79e..e8ebb6b2a6439 100644 --- a/mysql-test/main/index_merge_innodb.test +++ b/mysql-test/main/index_merge_innodb.test @@ -27,6 +27,9 @@ set @optimizer_switch_save= @@optimizer_switch; set optimizer_switch='index_merge_sort_intersection=off'; set optimizer_switch='rowid_filter=off'; +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; + # The first two tests are disabled because of non deterministic explain output. # If include/index_merge1.inc can be enabled for InnoDB and all other # storage engines, please remove the subtest for Bug#21277 from @@ -222,3 +225,4 @@ DROP TABLE t1; SET sort_buffer_size= @save_sort_buffer_size; disconnect disable_purge; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/main/innodb_ext_key.result b/mysql-test/main/innodb_ext_key.result index 0d3e27e5bf01c..5b99fa4e30b5c 100644 --- a/mysql-test/main/innodb_ext_key.result +++ b/mysql-test/main/innodb_ext_key.result @@ -602,6 +602,17 @@ INSERT INTO t3 VALUES (89,'text-8008',''),(90,'text-9008',''),(91,'text-9',''),(92,'text-1009',''), (93,'text-2009',''),(94,'text-3009',''),(95,'text-4009',''),(96,'text-5009',''), (97,'text-6009',''),(98,'text-7009',''),(99,'text-8009',''),(100,'text-9009',''); +ANALYZE TABLE t1,t2,t3; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze Warning Engine-independent statistics are not collected for column 'page_restrictions' +test.t1 analyze status OK +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK +test.t3 analyze status Engine-independent statistics collected +test.t3 analyze Warning Engine-independent statistics are not collected for column 'old_text' +test.t3 analyze Warning Engine-independent statistics are not collected for column 'old_flags' +test.t3 analyze status OK EXPLAIN SELECT * FROM t1, t2 IGNORE INDEX (PRIMARY), t3 WHERE page_id=rev_page AND rev_text_id=old_id AND page_namespace=4 AND page_title='Sandbox' diff --git a/mysql-test/main/innodb_ext_key.test b/mysql-test/main/innodb_ext_key.test index 77eda0df6f6ee..f1cf6658f0b09 100644 --- a/mysql-test/main/innodb_ext_key.test +++ b/mysql-test/main/innodb_ext_key.test @@ -456,6 +456,7 @@ INSERT INTO t3 VALUES (89,'text-8008',''),(90,'text-9008',''),(91,'text-9',''),(92,'text-1009',''), (93,'text-2009',''),(94,'text-3009',''),(95,'text-4009',''),(96,'text-5009',''), (97,'text-6009',''),(98,'text-7009',''),(99,'text-8009',''),(100,'text-9009',''); +ANALYZE TABLE t1,t2,t3; EXPLAIN diff --git a/mysql-test/main/join_outer_innodb.result b/mysql-test/main/join_outer_innodb.result index 09a37a297029c..6f87048cdc114 100644 --- a/mysql-test/main/join_outer_innodb.result +++ b/mysql-test/main/join_outer_innodb.result @@ -1,3 +1,5 @@ +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; CREATE TABLE t1 (id int(11) NOT NULL PRIMARY KEY, name varchar(20), INDEX (name)) ENGINE=InnoDB; CREATE TABLE t2 (id int(11) NOT NULL PRIMARY KEY, fkey int(11), @@ -515,3 +517,4 @@ UPDATE t1 LEFT JOIN t2 ON t1.c1 = t2.c2 AND t2.c1 = 3 SET t1.c3 = RAND()*10; COMMIT; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; DROP TABLE t1,t2; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/main/join_outer_innodb.test b/mysql-test/main/join_outer_innodb.test index 6b332f3d155f6..d1a8b0c4ab437 100644 --- a/mysql-test/main/join_outer_innodb.test +++ b/mysql-test/main/join_outer_innodb.test @@ -4,6 +4,8 @@ --source include/have_innodb.inc --source include/default_optimizer_switch.inc +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; # # Test for bug #17164: ORed FALSE blocked conversion of outer join into join @@ -391,3 +393,4 @@ COMMIT; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; DROP TABLE t1,t2; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/main/mysql_upgrade.result b/mysql-test/main/mysql_upgrade.result index 347d942be5eff..1c50a499953aa 100644 --- a/mysql-test/main/mysql_upgrade.result +++ b/mysql-test/main/mysql_upgrade.result @@ -1969,7 +1969,7 @@ rename table mysql.global_priv_bak to mysql.global_priv; # Check that mysql_upgrade can be run on mysqldump # of mysql schema from previous versions # -call mtr.add_suppression("innodb_table_stats has length mismatch in the column name table_name"); +call mtr.add_suppression("innodb_(table|index)_stats has length mismatch in the column name table_name"); call mtr.add_suppression("Column count of mysql.proc is wrong. Expected 21, found 20."); # # Upgrade from version 5.5 diff --git a/mysql-test/main/mysql_upgrade.test b/mysql-test/main/mysql_upgrade.test index ae1b328e69934..10dddbe7943d6 100644 --- a/mysql-test/main/mysql_upgrade.test +++ b/mysql-test/main/mysql_upgrade.test @@ -367,7 +367,7 @@ rename table mysql.global_priv_bak to mysql.global_priv; --echo # # The warning appears during mysql_upgrade, before the schema becomes consistent -call mtr.add_suppression("innodb_table_stats has length mismatch in the column name table_name"); +call mtr.add_suppression("innodb_(table|index)_stats has length mismatch in the column name table_name"); # This comes from opening 10.6 sys.host_summary view that uses sys.format_time function, # on still inconsistent mysql.proc, in older versions call mtr.add_suppression("Column count of mysql.proc is wrong. Expected 21, found 20."); diff --git a/mysql-test/main/order_by_optimizer_innodb.result b/mysql-test/main/order_by_optimizer_innodb.result index 0b62ba997d8de..cbb5551b7cfec 100644 --- a/mysql-test/main/order_by_optimizer_innodb.result +++ b/mysql-test/main/order_by_optimizer_innodb.result @@ -1,4 +1,5 @@ -drop table if exists t0,t1,t2,t3; +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=OFF; # # MDEV-6402: Optimizer doesn't choose best execution plan when composite key is used # @@ -96,3 +97,4 @@ ORDER BY pk2 DESC LIMIT 21; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ref key1 key1 55 const,const 1 Using where; Using index drop table t1, t2; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/main/order_by_optimizer_innodb.test b/mysql-test/main/order_by_optimizer_innodb.test index 90430d1154963..33f67e522adaa 100644 --- a/mysql-test/main/order_by_optimizer_innodb.test +++ b/mysql-test/main/order_by_optimizer_innodb.test @@ -1,8 +1,7 @@ --source include/have_innodb.inc ---disable_warnings -drop table if exists t0,t1,t2,t3; ---enable_warnings +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=OFF; --echo # --echo # MDEV-6402: Optimizer doesn't choose best execution plan when composite key is used @@ -96,3 +95,4 @@ ORDER BY pk2 DESC LIMIT 21; drop table t1, t2; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/main/range_vs_index_merge.result b/mysql-test/main/range_vs_index_merge.result index 207e012b825ef..7108fd89a7dd7 100644 --- a/mysql-test/main/range_vs_index_merge.result +++ b/mysql-test/main/range_vs_index_merge.result @@ -1,5 +1,3 @@ -DROP TABLE IF EXISTS t1,t2,t3,t4; -DROP DATABASE IF EXISTS world; set names utf8; CREATE DATABASE world; use world; diff --git a/mysql-test/main/range_vs_index_merge.test b/mysql-test/main/range_vs_index_merge.test index 94210ce5dd373..670762bcb2f81 100644 --- a/mysql-test/main/range_vs_index_merge.test +++ b/mysql-test/main/range_vs_index_merge.test @@ -2,11 +2,6 @@ --source include/default_charset.inc --source include/have_sequence.inc ---disable_warnings -DROP TABLE IF EXISTS t1,t2,t3,t4; -DROP DATABASE IF EXISTS world; ---enable_warnings - set names utf8; CREATE DATABASE world; @@ -1049,6 +1044,8 @@ INSERT INTO t1 VALUES (0,99083,'all','jhjerdvdxboydmpefbiesqbyyvdftsidjtvulamazljx'), (32767,99084,'s','flj'),(-4947,99085,'something','Vermont'), (0,99086,'cjfljhjerd','Washington'); + +ANALYZE TABLE t1; --enable_query_log --enable_result_log diff --git a/mysql-test/main/range_vs_index_merge_innodb.result b/mysql-test/main/range_vs_index_merge_innodb.result index 4ac62e2494087..79a670aedb2c6 100644 --- a/mysql-test/main/range_vs_index_merge_innodb.result +++ b/mysql-test/main/range_vs_index_merge_innodb.result @@ -4,8 +4,6 @@ set @innodb_stats_persistent_sample_pages_save= @@innodb_stats_persistent_sample_pages; set global innodb_stats_persistent= 1; set global innodb_stats_persistent_sample_pages=100; -DROP TABLE IF EXISTS t1,t2,t3,t4; -DROP DATABASE IF EXISTS world; set names utf8; CREATE DATABASE world; use world; diff --git a/mysql-test/main/rowid_filter_innodb.result b/mysql-test/main/rowid_filter_innodb.result index ae52f9416b983..44dd89fa7229c 100644 --- a/mysql-test/main/rowid_filter_innodb.result +++ b/mysql-test/main/rowid_filter_innodb.result @@ -1,4 +1,6 @@ SET SESSION DEFAULT_STORAGE_ENGINE='InnoDB'; +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; DROP DATABASE IF EXISTS dbt3_s001; CREATE DATABASE dbt3_s001; use dbt3_s001; @@ -2144,13 +2146,14 @@ a b drop table t1; SET @@optimizer_switch=@save_optimizer_switch; set @@use_stat_tables=@save_use_stat_tables; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; # # MDEV-18755: possible RORI-plan and possible plan with range filter # create table t1 ( pk int not null primary key, f1 varchar(10), f2 varchar(30), a int(10), key (f1), key (f2) -) engine=innodb; +) engine=innodb stats_persistent=0; insert into t1 values (2,'a','a',2),(3,'a','a',null),(4,'a','a',55),(5,'a','a',4),(6,'a','a',0), (7,'a','a',1),(8,'a','a',4),(9,'a','a',null),(10,'a','a',0),(11,'a','a',0), @@ -2513,7 +2516,7 @@ timestamp timestamp NOT NULL DEFAULT current_timestamp(), PRIMARY KEY (id), KEY ixEventWhoisDomainDomain (domain), KEY ixEventWhoisDomainTimestamp (timestamp) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB STATS_PERSISTENT=0 DEFAULT CHARSET=utf8; INSERT INTO t1 ( id, domain, registrant_name, registrant_organization, registrant_street1, registrant_street2, registrant_street3, registrant_street4, registrant_street5, diff --git a/mysql-test/main/rowid_filter_innodb.test b/mysql-test/main/rowid_filter_innodb.test index ab65a40e89e7e..bc5518eba8d37 100644 --- a/mysql-test/main/rowid_filter_innodb.test +++ b/mysql-test/main/rowid_filter_innodb.test @@ -2,7 +2,13 @@ SET SESSION DEFAULT_STORAGE_ENGINE='InnoDB'; +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; + --source rowid_filter.test + +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; + --source include/have_sequence.inc --echo # @@ -12,7 +18,7 @@ SET SESSION DEFAULT_STORAGE_ENGINE='InnoDB'; create table t1 ( pk int not null primary key, f1 varchar(10), f2 varchar(30), a int(10), key (f1), key (f2) -) engine=innodb; +) engine=innodb stats_persistent=0; insert into t1 values (2,'a','a',2),(3,'a','a',null),(4,'a','a',55),(5,'a','a',4),(6,'a','a',0), @@ -265,7 +271,7 @@ CREATE TABLE t1 ( PRIMARY KEY (id), KEY ixEventWhoisDomainDomain (domain), KEY ixEventWhoisDomainTimestamp (timestamp) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB STATS_PERSISTENT=0 DEFAULT CHARSET=utf8; INSERT INTO t1 ( id, domain, registrant_name, registrant_organization, registrant_street1, diff --git a/mysql-test/main/rowid_order_innodb.result b/mysql-test/main/rowid_order_innodb.result index 9b32bf6018fa2..26fb8ebb7072a 100644 --- a/mysql-test/main/rowid_order_innodb.result +++ b/mysql-test/main/rowid_order_innodb.result @@ -1,3 +1,5 @@ +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; SET SESSION DEFAULT_STORAGE_ENGINE = InnoDB; drop table if exists t1, t2, t3,t4; create table t1 ( @@ -185,3 +187,4 @@ bb b--b 2 2 ccc c--c 2 2 dddd d--d 2 2 drop table t1; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/main/rowid_order_innodb.test b/mysql-test/main/rowid_order_innodb.test index 152eb28d38870..d60c29bebf794 100644 --- a/mysql-test/main/rowid_order_innodb.test +++ b/mysql-test/main/rowid_order_innodb.test @@ -10,5 +10,9 @@ --source include/have_innodb.inc let $engine_type= InnoDB; +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; --source include/rowid_order.inc + +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/main/selectivity_innodb.result b/mysql-test/main/selectivity_innodb.result index a1d227a9baa69..5457db2143655 100644 --- a/mysql-test/main/selectivity_innodb.result +++ b/mysql-test/main/selectivity_innodb.result @@ -1,6 +1,8 @@ SET SESSION DEFAULT_STORAGE_ENGINE='InnoDB'; set @save_optimizer_switch_for_selectivity_test=@@optimizer_switch; set optimizer_switch='extended_keys=on'; +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; drop table if exists t0,t1,t2,t3; select @@global.use_stat_tables; @@global.use_stat_tables @@ -2153,3 +2155,4 @@ set use_stat_tables= @tmp_ust; set optimizer_use_condition_selectivity= @tmp_oucs; set @@global.histogram_size=@save_histogram_size; SET SESSION DEFAULT_STORAGE_ENGINE=DEFAULT; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/main/selectivity_innodb.test b/mysql-test/main/selectivity_innodb.test index 4bcdb5d6ec987..c970e7d871d60 100644 --- a/mysql-test/main/selectivity_innodb.test +++ b/mysql-test/main/selectivity_innodb.test @@ -7,6 +7,8 @@ SET SESSION DEFAULT_STORAGE_ENGINE='InnoDB'; set @save_optimizer_switch_for_selectivity_test=@@optimizer_switch; set optimizer_switch='extended_keys=on'; +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; --source selectivity.test @@ -233,3 +235,4 @@ set use_stat_tables= @tmp_ust; set optimizer_use_condition_selectivity= @tmp_oucs; set @@global.histogram_size=@save_histogram_size; SET SESSION DEFAULT_STORAGE_ENGINE=DEFAULT; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/main/subselect-crash_15755.result b/mysql-test/main/subselect-crash_15755.result index 81b4bd16ab5b4..f7a07fff4adaa 100644 --- a/mysql-test/main/subselect-crash_15755.result +++ b/mysql-test/main/subselect-crash_15755.result @@ -1,7 +1,3 @@ -set global innodb_stats_persistent= 1; -drop table if exists t1; -Warnings: -Note 1051 Unknown table 'test.t1' create table t1 ( f1 bigint(20) default 0, f2 varchar(50) default '', @@ -49,7 +45,7 @@ f43 varchar(50) default '', f44 varchar(50) default '', f45 int(10) default 0, f46 tinyint(1) default 0 -) engine=innodb row_format=dynamic; +) engine=innodb stats_persistent=1 row_format=dynamic; insert into t1 () values (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(); insert into t1 select * from t1; insert into t1 select * from t1; @@ -314,4 +310,3 @@ f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17 f18 f19 f20 f21 f22 f 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 drop table t1; -set global innodb_stats_persistent= 0; diff --git a/mysql-test/main/subselect-crash_15755.test b/mysql-test/main/subselect-crash_15755.test index 79e259d63371d..47879d1bd4d0e 100644 --- a/mysql-test/main/subselect-crash_15755.test +++ b/mysql-test/main/subselect-crash_15755.test @@ -1,6 +1,4 @@ --source include/have_innodb.inc -set global innodb_stats_persistent= 1; -drop table if exists t1; create table t1 ( f1 bigint(20) default 0, f2 varchar(50) default '', @@ -48,8 +46,7 @@ create table t1 ( f44 varchar(50) default '', f45 int(10) default 0, f46 tinyint(1) default 0 -) engine=innodb row_format=dynamic; - +) engine=innodb stats_persistent=1 row_format=dynamic; insert into t1 () values (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(); insert into t1 select * from t1; insert into t1 select * from t1; @@ -57,4 +54,3 @@ insert into t1 select * from t1; insert into t1 select * from t1; select * from t1 where f2 in (select f2 from t1 group by f2 having count(distinct f3) = 1); drop table t1; -set global innodb_stats_persistent= 0; diff --git a/mysql-test/main/subselect_innodb.result b/mysql-test/main/subselect_innodb.result index 73ca264049176..abc429fb55081 100644 --- a/mysql-test/main/subselect_innodb.result +++ b/mysql-test/main/subselect_innodb.result @@ -1,6 +1,7 @@ set @subselect_innodb_tmp=@@optimizer_switch; set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; -drop table if exists t1,t2,t3; +SET @saved_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; CREATE TABLE t1 ( FOLDERID VARCHAR(32)BINARY NOT NULL @@ -663,3 +664,4 @@ execute stmt; a b drop table t1,t2; # End of 10.4 tests +SET GLOBAL innodb_stats_persistent = @saved_stats_persistent; diff --git a/mysql-test/main/subselect_innodb.test b/mysql-test/main/subselect_innodb.test index 37f8f40200e22..19871e14008ba 100644 --- a/mysql-test/main/subselect_innodb.test +++ b/mysql-test/main/subselect_innodb.test @@ -4,9 +4,8 @@ # settings are not relevant. set @subselect_innodb_tmp=@@optimizer_switch; set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; ---disable_warnings -drop table if exists t1,t2,t3; ---enable_warnings +SET @saved_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; # # key field overflow test @@ -662,3 +661,5 @@ execute stmt; drop table t1,t2; --echo # End of 10.4 tests + +SET GLOBAL innodb_stats_persistent = @saved_stats_persistent; diff --git a/mysql-test/main/type_bit_innodb.result b/mysql-test/main/type_bit_innodb.result index 9b186207f3fcc..a3ac23ebb71cf 100644 --- a/mysql-test/main/type_bit_innodb.result +++ b/mysql-test/main/type_bit_innodb.result @@ -1,3 +1,5 @@ +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; select 0 + b'1'; 0 + b'1' 1 @@ -34,7 +36,6 @@ select 0 + b'1111111111111111'; select 0 + b'1000000000000001'; 0 + b'1000000000000001' 32769 -drop table if exists t1; create table t1 (a bit(65)) engine=innodb; ERROR 42000: Display width out of range for 'a' (max = 64) create table t1 (a bit(0)) engine=innodb; @@ -422,3 +423,4 @@ hex(f1) hex(f2) 0 0 0 0 drop table t1; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/main/type_bit_innodb.test b/mysql-test/main/type_bit_innodb.test index 4c6f9bc1b49bc..6317bbc3a2d22 100644 --- a/mysql-test/main/type_bit_innodb.test +++ b/mysql-test/main/type_bit_innodb.test @@ -1,4 +1,7 @@ --source include/have_innodb.inc +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; + # # testing of the BIT column type # @@ -16,10 +19,6 @@ select 0 + b'1000000000000000'; select 0 + b'1111111111111111'; select 0 + b'1000000000000001'; ---disable_warnings -drop table if exists t1; ---enable_warnings - --error 1439 create table t1 (a bit(65)) engine=innodb; @@ -157,3 +156,5 @@ insert into t1 (f1) values (default); insert into t1 values (b'',b''),('',''); select hex(f1), hex(f2) from t1; drop table t1; + +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/main/update_use_source.result b/mysql-test/main/update_use_source.result index 9e43b54d81c75..2774e7ee92d67 100644 --- a/mysql-test/main/update_use_source.result +++ b/mysql-test/main/update_use_source.result @@ -1,4 +1,4 @@ -create table t1 (old_c1 integer, old_c2 integer,c1 integer, c2 integer, c3 integer) engine=InnoDb; +create table t1 (old_c1 integer, old_c2 integer,c1 integer, c2 integer, c3 integer) engine=InnoDB STATS_PERSISTENT=0; create view v1 as select * from t1 where c2=2; create trigger trg_t1 before update on t1 for each row begin diff --git a/mysql-test/main/update_use_source.test b/mysql-test/main/update_use_source.test index 7ed5f95d68d9d..d446bd512dd30 100644 --- a/mysql-test/main/update_use_source.test +++ b/mysql-test/main/update_use_source.test @@ -1,7 +1,7 @@ --source include/have_sequence.inc --source include/have_innodb.inc -create table t1 (old_c1 integer, old_c2 integer,c1 integer, c2 integer, c3 integer) engine=InnoDb; +create table t1 (old_c1 integer, old_c2 integer,c1 integer, c2 integer, c3 integer) engine=InnoDB STATS_PERSISTENT=0; create view v1 as select * from t1 where c2=2; delimiter /; create trigger trg_t1 before update on t1 for each row diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result index f83dc8fbdc099..8cc020311b966 100644 --- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result +++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result @@ -1,3 +1,5 @@ +SET @save_stats_auto_recalc=@@GLOBAL.innodb_stats_auto_recalc; +SET GLOBAL innodb_stats_auto_recalc=OFF; set sql_mode=""; SET NAMES 'utf8'; # @@ -6372,3 +6374,4 @@ ROLLBACK /* added by mysqlbinlog */; # Cleanup. # DROP TABLE t1; +SET GLOBAL innodb_stats_auto_recalc=@save_stats_auto_recalc; diff --git a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row_innodb.test b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row_innodb.test index cef1a712f7dcd..7bd72657f5ac8 100644 --- a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row_innodb.test +++ b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row_innodb.test @@ -12,6 +12,9 @@ --source include/have_innodb.inc let $engine_type=InnoDB; +SET @save_stats_auto_recalc=@@GLOBAL.innodb_stats_auto_recalc; +SET GLOBAL innodb_stats_auto_recalc=OFF; + # # The test case would also work with statement based or mixed mode logging. # But this would require different result files. To handle this with the @@ -22,3 +25,4 @@ let $engine_type=InnoDB; --source include/mysqlbinlog_row_engine.inc +SET GLOBAL innodb_stats_auto_recalc=@save_stats_auto_recalc; diff --git a/mysql-test/suite/engines/funcs/r/se_join_default.result b/mysql-test/suite/engines/funcs/r/se_join_default.result index a825ad314f33d..cc1271020bc47 100644 --- a/mysql-test/suite/engines/funcs/r/se_join_default.result +++ b/mysql-test/suite/engines/funcs/r/se_join_default.result @@ -14,47 +14,47 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 < t2.c1; c1 c1 0 1 0 2 -1 2 0 3 -1 3 -2 3 0 4 -1 4 -2 4 -3 4 0 5 -1 5 -2 5 -3 5 -4 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 0 9 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 5 +4 6 +4 7 +4 8 4 9 +5 6 +5 7 +5 8 5 9 +6 7 +6 8 6 9 +7 8 7 9 8 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -73,47 +73,47 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 < t2.c1; c1 c1 0 1 0 2 -1 2 0 3 -1 3 -2 3 0 4 -1 4 -2 4 -3 4 0 5 -1 5 -2 5 -3 5 -4 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 0 9 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 5 +4 6 +4 7 +4 8 4 9 +5 6 +5 7 +5 8 5 9 +6 7 +6 8 6 9 +7 8 7 9 8 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -132,47 +132,47 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 < t2.c1; c1 c1 0 1 0 2 -1 2 0 3 -1 3 -2 3 0 4 -1 4 -2 4 -3 4 0 5 -1 5 -2 5 -3 5 -4 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 0 9 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 5 +4 6 +4 7 +4 8 4 9 +5 6 +5 7 +5 8 5 9 +6 7 +6 8 6 9 +7 8 7 9 8 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -191,47 +191,47 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 < t2.c1; c1 c1 0 1 0 2 -1 2 0 3 -1 3 -2 3 0 4 -1 4 -2 4 -3 4 0 5 -1 5 -2 5 -3 5 -4 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 0 9 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 5 +4 6 +4 7 +4 8 4 9 +5 6 +5 7 +5 8 5 9 +6 7 +6 8 6 9 +7 8 7 9 8 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -250,47 +250,47 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 < t2.c1; c1 c1 0 1 0 2 -1 2 0 3 -1 3 -2 3 0 4 -1 4 -2 4 -3 4 0 5 -1 5 -2 5 -3 5 -4 5 0 6 +0 7 +0 8 +0 9 +1 2 +1 3 +1 4 +1 5 1 6 +1 7 +1 8 +1 9 +2 3 +2 4 +2 5 2 6 +2 7 +2 8 +2 9 +3 4 +3 5 3 6 +3 7 +3 8 +3 9 +4 5 4 6 -5 6 -0 7 -1 7 -2 7 -3 7 4 7 -5 7 -6 7 -0 8 -1 8 -2 8 -3 8 4 8 -5 8 -6 8 -7 8 -0 9 -1 9 -2 9 -3 9 4 9 +5 6 +5 7 +5 8 5 9 +6 7 +6 8 6 9 +7 8 7 9 8 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -309,47 +309,47 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 < t2.c1; c1 c1 0 1 0 2 -1 2 0 3 -1 3 -2 3 0 4 -1 4 -2 4 -3 4 0 5 -1 5 -2 5 -3 5 -4 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 0 9 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 5 +4 6 +4 7 +4 8 4 9 +5 6 +5 7 +5 8 5 9 +6 7 +6 8 6 9 +7 8 7 9 8 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -1214,57 +1214,57 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <= t2.c1; c1 c1 0 0 0 1 -1 1 0 2 -1 2 -2 2 0 3 -1 3 -2 3 -3 3 0 4 -1 4 -2 4 -3 4 -4 4 0 5 -1 5 -2 5 -3 5 -4 5 -5 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -6 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -7 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -8 8 0 9 +1 1 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 2 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 3 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 4 +4 5 +4 6 +4 7 +4 8 4 9 +5 5 +5 6 +5 7 +5 8 5 9 +6 6 +6 7 +6 8 6 9 +7 7 +7 8 7 9 +8 8 8 9 9 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -1283,57 +1283,57 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <= t2.c1; c1 c1 0 0 0 1 -1 1 0 2 -1 2 -2 2 0 3 -1 3 -2 3 -3 3 0 4 -1 4 -2 4 -3 4 -4 4 0 5 -1 5 -2 5 -3 5 -4 5 -5 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -6 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -7 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -8 8 0 9 +1 1 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 2 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 3 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 4 +4 5 +4 6 +4 7 +4 8 4 9 +5 5 +5 6 +5 7 +5 8 5 9 +6 6 +6 7 +6 8 6 9 +7 7 +7 8 7 9 +8 8 8 9 9 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -1352,57 +1352,57 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <= t2.c1; c1 c1 0 0 0 1 -1 1 0 2 -1 2 -2 2 0 3 -1 3 -2 3 -3 3 0 4 -1 4 -2 4 -3 4 -4 4 0 5 -1 5 -2 5 -3 5 -4 5 -5 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -6 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -7 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -8 8 0 9 +1 1 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 2 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 3 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 4 +4 5 +4 6 +4 7 +4 8 4 9 +5 5 +5 6 +5 7 +5 8 5 9 +6 6 +6 7 +6 8 6 9 +7 7 +7 8 7 9 +8 8 8 9 9 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -1421,57 +1421,57 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <= t2.c1; c1 c1 0 0 0 1 -1 1 0 2 -1 2 -2 2 0 3 -1 3 -2 3 -3 3 0 4 -1 4 -2 4 -3 4 -4 4 0 5 -1 5 -2 5 -3 5 -4 5 -5 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -6 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -7 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -8 8 0 9 +1 1 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 2 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 3 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 4 +4 5 +4 6 +4 7 +4 8 4 9 +5 5 +5 6 +5 7 +5 8 5 9 +6 6 +6 7 +6 8 6 9 +7 7 +7 8 7 9 +8 8 8 9 9 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -1490,57 +1490,57 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <= t2.c1; c1 c1 0 0 0 1 -1 1 0 2 -1 2 -2 2 0 3 -1 3 -2 3 -3 3 0 4 -1 4 -2 4 -3 4 -4 4 0 5 -1 5 -2 5 -3 5 -4 5 -5 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -6 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -7 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -8 8 0 9 +1 1 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 2 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 3 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 4 +4 5 +4 6 +4 7 +4 8 4 9 +5 5 +5 6 +5 7 +5 8 5 9 +6 6 +6 7 +6 8 6 9 +7 7 +7 8 7 9 +8 8 8 9 9 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -1559,57 +1559,57 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <= t2.c1; c1 c1 0 0 0 1 -1 1 0 2 -1 2 -2 2 0 3 -1 3 -2 3 -3 3 0 4 -1 4 -2 4 -3 4 -4 4 0 5 -1 5 -2 5 -3 5 -4 5 -5 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -6 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -7 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -8 8 0 9 +1 1 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 2 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 3 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 4 +4 5 +4 6 +4 7 +4 8 4 9 +5 5 +5 6 +5 7 +5 8 5 9 +6 6 +6 7 +6 8 6 9 +7 7 +7 8 7 9 +8 8 8 9 9 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -3014,57 +3014,57 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 >= t2.c1; c1 c1 0 0 1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 1 1 +2 0 2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 2 2 +3 0 +3 1 3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 3 3 +4 0 +4 1 +4 2 4 3 -5 3 -6 3 -7 3 -8 3 -9 3 4 4 +5 0 +5 1 +5 2 +5 3 5 4 -6 4 -7 4 -8 4 -9 4 5 5 +6 0 +6 1 +6 2 +6 3 +6 4 6 5 -7 5 -8 5 -9 5 6 6 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 7 6 -8 6 -9 6 7 7 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 8 7 -9 7 8 8 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 9 8 9 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -3083,57 +3083,57 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 >= t2.c1; c1 c1 0 0 1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 1 1 +2 0 2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 2 2 +3 0 +3 1 3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 3 3 +4 0 +4 1 +4 2 4 3 -5 3 -6 3 -7 3 -8 3 -9 3 4 4 +5 0 +5 1 +5 2 +5 3 5 4 -6 4 -7 4 -8 4 -9 4 5 5 +6 0 +6 1 +6 2 +6 3 +6 4 6 5 -7 5 -8 5 -9 5 6 6 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 7 6 -8 6 -9 6 7 7 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 8 7 -9 7 8 8 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 9 8 9 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -3152,57 +3152,57 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 >= t2.c1; c1 c1 0 0 1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 1 1 +2 0 2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 2 2 +3 0 +3 1 3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 3 3 +4 0 +4 1 +4 2 4 3 -5 3 -6 3 -7 3 -8 3 -9 3 4 4 +5 0 +5 1 +5 2 +5 3 5 4 -6 4 -7 4 -8 4 -9 4 5 5 +6 0 +6 1 +6 2 +6 3 +6 4 6 5 -7 5 -8 5 -9 5 6 6 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 7 6 -8 6 -9 6 7 7 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 8 7 -9 7 8 8 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 9 8 9 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -3221,57 +3221,57 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 >= t2.c1; c1 c1 0 0 1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 1 1 +2 0 2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 2 2 +3 0 +3 1 3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 3 3 +4 0 +4 1 +4 2 4 3 -5 3 -6 3 -7 3 -8 3 -9 3 4 4 +5 0 +5 1 +5 2 +5 3 5 4 -6 4 -7 4 -8 4 -9 4 5 5 +6 0 +6 1 +6 2 +6 3 +6 4 6 5 -7 5 -8 5 -9 5 6 6 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 7 6 -8 6 -9 6 7 7 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 8 7 -9 7 8 8 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 9 8 9 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -3290,57 +3290,57 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 >= t2.c1; c1 c1 0 0 1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 1 1 +2 0 2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 2 2 +3 0 +3 1 3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 3 3 +4 0 +4 1 +4 2 4 3 -5 3 -6 3 -7 3 -8 3 -9 3 4 4 +5 0 +5 1 +5 2 +5 3 5 4 -6 4 -7 4 -8 4 -9 4 5 5 +6 0 +6 1 +6 2 +6 3 +6 4 6 5 -7 5 -8 5 -9 5 6 6 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 7 6 -8 6 -9 6 7 7 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 8 7 -9 7 8 8 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 9 8 9 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -3359,57 +3359,57 @@ SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 >= t2.c1; c1 c1 0 0 1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 1 1 +2 0 2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 2 2 +3 0 +3 1 3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 3 3 +4 0 +4 1 +4 2 4 3 -5 3 -6 3 -7 3 -8 3 -9 3 4 4 +5 0 +5 1 +5 2 +5 3 5 4 -6 4 -7 4 -8 4 -9 4 5 5 +6 0 +6 1 +6 2 +6 3 +6 4 6 5 -7 5 -8 5 -9 5 6 6 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 7 6 -8 6 -9 6 7 7 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 8 7 -9 7 8 8 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 9 8 9 9 DROP TABLE t1,t2,t3,t4,t5,t6; @@ -3912,96 +3912,96 @@ INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; c1 c1 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 0 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 0 2 -1 2 -3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 0 3 -1 3 -2 3 -4 3 -5 3 -6 3 -7 3 -8 3 -9 3 0 4 -1 4 -2 4 -3 4 -5 4 -6 4 -7 4 -8 4 -9 4 0 5 -1 5 -2 5 -3 5 -4 5 -6 5 -7 5 -8 5 -9 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -7 6 -8 6 -9 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -8 7 -9 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -9 8 0 9 -1 9 -2 9 -3 9 -4 9 -5 9 -6 9 -7 9 +1 0 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 +1 9 +2 0 +2 1 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 +2 9 +3 0 +3 1 +3 2 +3 4 +3 5 +3 6 +3 7 +3 8 +3 9 +4 0 +4 1 +4 2 +4 3 +4 5 +4 6 +4 7 +4 8 +4 9 +5 0 +5 1 +5 2 +5 3 +5 4 +5 6 +5 7 +5 8 +5 9 +6 0 +6 1 +6 2 +6 3 +6 4 +6 5 +6 7 +6 8 +6 9 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 +7 6 +7 8 +7 9 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 +8 7 8 9 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 +9 8 DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); CREATE TABLE t2 (c1 SMALLINT NOT NULL); @@ -4016,96 +4016,96 @@ INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; c1 c1 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 0 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 0 2 -1 2 -3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 0 3 -1 3 -2 3 -4 3 -5 3 -6 3 -7 3 -8 3 -9 3 0 4 -1 4 -2 4 -3 4 -5 4 -6 4 -7 4 -8 4 -9 4 0 5 -1 5 -2 5 -3 5 -4 5 -6 5 -7 5 -8 5 -9 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -7 6 -8 6 -9 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -8 7 -9 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -9 8 0 9 +1 0 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 0 +2 1 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 0 +3 1 +3 2 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 0 +4 1 +4 2 +4 3 +4 5 +4 6 +4 7 +4 8 4 9 +5 0 +5 1 +5 2 +5 3 +5 4 +5 6 +5 7 +5 8 5 9 +6 0 +6 1 +6 2 +6 3 +6 4 +6 5 +6 7 +6 8 6 9 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 +7 6 +7 8 7 9 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 +8 7 8 9 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 +9 8 DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); CREATE TABLE t2 (c1 MEDIUMINT NOT NULL); @@ -4120,96 +4120,96 @@ INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; c1 c1 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 0 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 0 2 -1 2 -3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 0 3 -1 3 -2 3 -4 3 -5 3 -6 3 -7 3 -8 3 -9 3 0 4 -1 4 -2 4 -3 4 -5 4 -6 4 -7 4 -8 4 -9 4 0 5 -1 5 -2 5 -3 5 -4 5 -6 5 -7 5 -8 5 -9 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -7 6 -8 6 -9 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -8 7 -9 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -9 8 0 9 +1 0 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 0 +2 1 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 0 +3 1 +3 2 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 0 +4 1 +4 2 +4 3 +4 5 +4 6 +4 7 +4 8 4 9 +5 0 +5 1 +5 2 +5 3 +5 4 +5 6 +5 7 +5 8 5 9 +6 0 +6 1 +6 2 +6 3 +6 4 +6 5 +6 7 +6 8 6 9 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 +7 6 +7 8 7 9 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 +8 7 8 9 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 +9 8 DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); CREATE TABLE t2 (c1 INT NOT NULL); @@ -4224,207 +4224,103 @@ INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; c1 c1 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 0 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 0 2 -1 2 -3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 0 3 -1 3 -2 3 -4 3 -5 3 -6 3 -7 3 -8 3 -9 3 0 4 -1 4 -2 4 -3 4 -5 4 -6 4 -7 4 -8 4 -9 4 0 5 -1 5 -2 5 -3 5 -4 5 -6 5 -7 5 -8 5 -9 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -7 6 -8 6 -9 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -8 7 -9 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -9 8 0 9 +1 0 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 0 +2 1 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 0 +3 1 +3 2 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 0 +4 1 +4 2 +4 3 +4 5 +4 6 +4 7 +4 8 4 9 +5 0 +5 1 +5 2 +5 3 +5 4 +5 6 +5 7 +5 8 5 9 +6 0 +6 1 +6 2 +6 3 +6 4 +6 5 +6 7 +6 8 6 9 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 +7 6 +7 8 7 9 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 +8 7 8 9 -DROP TABLE t1,t2,t3,t4,t5,t6; -CREATE TABLE t1 (c1 INTEGER NOT NULL); -CREATE TABLE t2 (c1 INTEGER NOT NULL); -CREATE TABLE t3 (c1 INTEGER NOT NULL); -CREATE TABLE t4 (c1 INTEGER NOT NULL); -CREATE TABLE t5 (c1 INTEGER NOT NULL); -CREATE TABLE t6 (c1 INTEGER NOT NULL); -INSERT INTO t1 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); -INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); -INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); -INSERT INTO t4 (c1) VALUES(10); -INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); -SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; -c1 c1 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 9 0 -0 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 9 1 -0 2 -1 2 -3 2 -4 2 -5 2 -6 2 -7 2 -8 2 9 2 -0 3 -1 3 -2 3 -4 3 -5 3 -6 3 -7 3 -8 3 9 3 -0 4 -1 4 -2 4 -3 4 -5 4 -6 4 -7 4 -8 4 9 4 -0 5 -1 5 -2 5 -3 5 -4 5 -6 5 -7 5 -8 5 9 5 -0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -7 6 -8 6 9 6 -0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -8 7 9 7 -0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 9 8 -0 9 -1 9 -2 9 -3 9 -4 9 -5 9 -6 9 -7 9 -8 9 DROP TABLE t1,t2,t3,t4,t5,t6; -CREATE TABLE t1 (c1 BIGINT NOT NULL); -CREATE TABLE t2 (c1 BIGINT NOT NULL); -CREATE TABLE t3 (c1 BIGINT NOT NULL); -CREATE TABLE t4 (c1 BIGINT NOT NULL); -CREATE TABLE t5 (c1 BIGINT NOT NULL); -CREATE TABLE t6 (c1 BIGINT NOT NULL); +CREATE TABLE t1 (c1 INTEGER NOT NULL); +CREATE TABLE t2 (c1 INTEGER NOT NULL); +CREATE TABLE t3 (c1 INTEGER NOT NULL); +CREATE TABLE t4 (c1 INTEGER NOT NULL); +CREATE TABLE t5 (c1 INTEGER NOT NULL); +CREATE TABLE t6 (c1 INTEGER NOT NULL); INSERT INTO t1 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); @@ -4432,167 +4328,271 @@ INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; c1 c1 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 0 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 0 2 -1 2 -3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 0 3 -1 3 -2 3 -4 3 -5 3 -6 3 -7 3 -8 3 -9 3 0 4 -1 4 -2 4 -3 4 -5 4 -6 4 -7 4 -8 4 -9 4 0 5 -1 5 -2 5 -3 5 -4 5 -6 5 -7 5 -8 5 -9 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -7 6 -8 6 -9 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -8 7 -9 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -9 8 -0 9 -1 9 -2 9 -3 9 -4 9 -5 9 -6 9 -7 9 -8 9 -DROP TABLE t1,t2,t3,t4,t5,t6; -CREATE TABLE t1 (c1 TINYINT NOT NULL); -CREATE TABLE t2 (c1 TINYINT NOT NULL); -CREATE TABLE t3 (c1 TINYINT NOT NULL); -CREATE TABLE t4 (c1 TINYINT NOT NULL); -CREATE TABLE t5 (c1 TINYINT NOT NULL); -CREATE TABLE t6 (c1 TINYINT NOT NULL); -INSERT INTO t1 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); -INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); -INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); -INSERT INTO t4 (c1) VALUES(10); -INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); -SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 != t3.c1; -c1 c1 -0 1 -0 3 -0 5 -0 7 0 9 +1 0 +1 2 1 3 +1 4 1 5 +1 6 1 7 +1 8 1 9 +2 0 2 1 2 3 +2 4 2 5 +2 6 2 7 +2 8 2 9 +3 0 3 1 +3 2 +3 4 3 5 +3 6 3 7 +3 8 3 9 +4 0 4 1 +4 2 4 3 4 5 +4 6 4 7 +4 8 4 9 +5 0 5 1 +5 2 5 3 +5 4 +5 6 5 7 +5 8 5 9 +6 0 6 1 +6 2 6 3 +6 4 6 5 6 7 +6 8 6 9 +7 0 7 1 +7 2 7 3 +7 4 7 5 +7 6 +7 8 7 9 +8 0 8 1 +8 2 8 3 +8 4 8 5 +8 6 8 7 8 9 +9 0 9 1 +9 2 9 3 +9 4 9 5 +9 6 9 7 +9 8 DROP TABLE t1,t2,t3,t4,t5,t6; -CREATE TABLE t1 (c1 SMALLINT NOT NULL); -CREATE TABLE t2 (c1 SMALLINT NOT NULL); -CREATE TABLE t3 (c1 SMALLINT NOT NULL); -CREATE TABLE t4 (c1 SMALLINT NOT NULL); -CREATE TABLE t5 (c1 SMALLINT NOT NULL); -CREATE TABLE t6 (c1 SMALLINT NOT NULL); -INSERT INTO t1 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); -INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); -INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); -INSERT INTO t4 (c1) VALUES(10); -INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +CREATE TABLE t1 (c1 BIGINT NOT NULL); +CREATE TABLE t2 (c1 BIGINT NOT NULL); +CREATE TABLE t3 (c1 BIGINT NOT NULL); +CREATE TABLE t4 (c1 BIGINT NOT NULL); +CREATE TABLE t5 (c1 BIGINT NOT NULL); +CREATE TABLE t6 (c1 BIGINT NOT NULL); +INSERT INTO t1 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); +INSERT INTO t4 (c1) VALUES(10); +INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; +c1 c1 +0 1 +0 2 +0 3 +0 4 +0 5 +0 6 +0 7 +0 8 +0 9 +1 0 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 +1 9 +2 0 +2 1 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 +2 9 +3 0 +3 1 +3 2 +3 4 +3 5 +3 6 +3 7 +3 8 +3 9 +4 0 +4 1 +4 2 +4 3 +4 5 +4 6 +4 7 +4 8 +4 9 +5 0 +5 1 +5 2 +5 3 +5 4 +5 6 +5 7 +5 8 +5 9 +6 0 +6 1 +6 2 +6 3 +6 4 +6 5 +6 7 +6 8 +6 9 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 +7 6 +7 8 +7 9 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 +8 7 +8 9 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 +9 8 +DROP TABLE t1,t2,t3,t4,t5,t6; +CREATE TABLE t1 (c1 TINYINT NOT NULL); +CREATE TABLE t2 (c1 TINYINT NOT NULL); +CREATE TABLE t3 (c1 TINYINT NOT NULL); +CREATE TABLE t4 (c1 TINYINT NOT NULL); +CREATE TABLE t5 (c1 TINYINT NOT NULL); +CREATE TABLE t6 (c1 TINYINT NOT NULL); +INSERT INTO t1 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); +INSERT INTO t4 (c1) VALUES(10); +INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 != t3.c1; +c1 c1 +0 1 +0 3 +0 5 +0 7 +0 9 +1 3 +1 5 +1 7 +1 9 +2 1 +2 3 +2 5 +2 7 +2 9 +3 1 +3 5 +3 7 +3 9 +4 1 +4 3 +4 5 +4 7 +4 9 +5 1 +5 3 +5 7 +5 9 +6 1 +6 3 +6 5 +6 7 +6 9 +7 1 +7 3 +7 5 +7 9 +8 1 +8 3 +8 5 +8 7 +8 9 +9 1 +9 3 +9 5 +9 7 +DROP TABLE t1,t2,t3,t4,t5,t6; +CREATE TABLE t1 (c1 SMALLINT NOT NULL); +CREATE TABLE t2 (c1 SMALLINT NOT NULL); +CREATE TABLE t3 (c1 SMALLINT NOT NULL); +CREATE TABLE t4 (c1 SMALLINT NOT NULL); +CREATE TABLE t5 (c1 SMALLINT NOT NULL); +CREATE TABLE t6 (c1 SMALLINT NOT NULL); +INSERT INTO t1 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); +INSERT INTO t4 (c1) VALUES(10); +INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 != t3.c1; c1 c1 0 1 @@ -5502,96 +5502,96 @@ INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <> t2.c1; c1 c1 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 0 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 0 2 -1 2 -3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 0 3 -1 3 -2 3 -4 3 -5 3 -6 3 -7 3 -8 3 -9 3 0 4 -1 4 -2 4 -3 4 -5 4 -6 4 -7 4 -8 4 -9 4 0 5 -1 5 -2 5 -3 5 -4 5 -6 5 -7 5 -8 5 -9 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -7 6 -8 6 -9 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -8 7 -9 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -9 8 0 9 +1 0 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 -2 9 +2 0 +2 1 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 +2 9 +3 0 +3 1 +3 2 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 0 +4 1 +4 2 +4 3 +4 5 +4 6 +4 7 +4 8 4 9 +5 0 +5 1 +5 2 +5 3 +5 4 +5 6 +5 7 +5 8 5 9 +6 0 +6 1 +6 2 +6 3 +6 4 +6 5 +6 7 +6 8 6 9 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 +7 6 +7 8 7 9 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 +8 7 8 9 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 +9 8 DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); CREATE TABLE t2 (c1 SMALLINT NOT NULL); @@ -5606,96 +5606,96 @@ INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <> t2.c1; c1 c1 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 0 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 0 2 -1 2 -3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 0 3 -1 3 -2 3 -4 3 -5 3 -6 3 -7 3 -8 3 -9 3 0 4 -1 4 -2 4 -3 4 -5 4 -6 4 -7 4 -8 4 -9 4 0 5 -1 5 -2 5 -3 5 -4 5 -6 5 -7 5 -8 5 -9 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -7 6 -8 6 -9 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -8 7 -9 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -9 8 0 9 +1 0 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 0 +2 1 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 0 +3 1 +3 2 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 0 +4 1 +4 2 +4 3 +4 5 +4 6 +4 7 +4 8 4 9 +5 0 +5 1 +5 2 +5 3 +5 4 +5 6 +5 7 +5 8 5 9 +6 0 +6 1 +6 2 +6 3 +6 4 +6 5 +6 7 +6 8 6 9 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 +7 6 +7 8 7 9 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 +8 7 8 9 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 +9 8 DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); CREATE TABLE t2 (c1 MEDIUMINT NOT NULL); @@ -5710,96 +5710,96 @@ INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <> t2.c1; c1 c1 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 0 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 0 2 -1 2 -3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 0 3 -1 3 -2 3 -4 3 -5 3 -6 3 -7 3 -8 3 -9 3 0 4 -1 4 -2 4 -3 4 -5 4 -6 4 -7 4 -8 4 -9 4 0 5 -1 5 -2 5 -3 5 -4 5 -6 5 -7 5 -8 5 -9 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -7 6 -8 6 -9 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -8 7 -9 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -9 8 0 9 +1 0 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 0 +2 1 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 0 +3 1 +3 2 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 0 +4 1 +4 2 +4 3 +4 5 +4 6 +4 7 +4 8 4 9 +5 0 +5 1 +5 2 +5 3 +5 4 +5 6 +5 7 +5 8 5 9 +6 0 +6 1 +6 2 +6 3 +6 4 +6 5 +6 7 +6 8 6 9 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 +7 6 +7 8 7 9 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 +8 7 8 9 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 +9 8 DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); CREATE TABLE t2 (c1 INT NOT NULL); @@ -5814,96 +5814,96 @@ INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <> t2.c1; c1 c1 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 0 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 0 2 -1 2 -3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 0 3 -1 3 -2 3 -4 3 -5 3 -6 3 -7 3 -8 3 -9 3 0 4 -1 4 -2 4 -3 4 -5 4 -6 4 -7 4 -8 4 -9 4 0 5 -1 5 -2 5 -3 5 -4 5 -6 5 -7 5 -8 5 -9 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -7 6 -8 6 -9 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -8 7 -9 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -9 8 0 9 +1 0 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 0 +2 1 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 0 +3 1 +3 2 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 0 +4 1 +4 2 +4 3 +4 5 +4 6 +4 7 +4 8 4 9 +5 0 +5 1 +5 2 +5 3 +5 4 +5 6 +5 7 +5 8 5 9 +6 0 +6 1 +6 2 +6 3 +6 4 +6 5 +6 7 +6 8 6 9 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 +7 6 +7 8 7 9 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 +8 7 8 9 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 +9 8 DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); CREATE TABLE t2 (c1 INTEGER NOT NULL); @@ -5918,96 +5918,96 @@ INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <> t2.c1; c1 c1 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 0 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 0 2 -1 2 -3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 0 3 -1 3 -2 3 -4 3 -5 3 -6 3 -7 3 -8 3 -9 3 0 4 -1 4 -2 4 -3 4 -5 4 -6 4 -7 4 -8 4 -9 4 0 5 -1 5 -2 5 -3 5 -4 5 -6 5 -7 5 -8 5 -9 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -7 6 -8 6 -9 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -8 7 -9 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -9 8 0 9 +1 0 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 0 +2 1 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 0 +3 1 +3 2 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 0 +4 1 +4 2 +4 3 +4 5 +4 6 +4 7 +4 8 4 9 +5 0 +5 1 +5 2 +5 3 +5 4 +5 6 +5 7 +5 8 5 9 +6 0 +6 1 +6 2 +6 3 +6 4 +6 5 +6 7 +6 8 6 9 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 +7 6 +7 8 7 9 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 +8 7 8 9 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 +9 8 DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); CREATE TABLE t2 (c1 BIGINT NOT NULL); @@ -6022,96 +6022,96 @@ INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <> t2.c1; c1 c1 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -8 0 -9 0 0 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -9 1 0 2 -1 2 -3 2 -4 2 -5 2 -6 2 -7 2 -8 2 -9 2 0 3 -1 3 -2 3 -4 3 -5 3 -6 3 -7 3 -8 3 -9 3 0 4 -1 4 -2 4 -3 4 -5 4 -6 4 -7 4 -8 4 -9 4 0 5 -1 5 -2 5 -3 5 -4 5 -6 5 -7 5 -8 5 -9 5 0 6 -1 6 -2 6 -3 6 -4 6 -5 6 -7 6 -8 6 -9 6 0 7 -1 7 -2 7 -3 7 -4 7 -5 7 -6 7 -8 7 -9 7 0 8 -1 8 -2 8 -3 8 -4 8 -5 8 -6 8 -7 8 -9 8 0 9 +1 0 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 1 9 +2 0 +2 1 +2 3 +2 4 +2 5 +2 6 +2 7 +2 8 2 9 +3 0 +3 1 +3 2 +3 4 +3 5 +3 6 +3 7 +3 8 3 9 +4 0 +4 1 +4 2 +4 3 +4 5 +4 6 +4 7 +4 8 4 9 +5 0 +5 1 +5 2 +5 3 +5 4 +5 6 +5 7 +5 8 5 9 +6 0 +6 1 +6 2 +6 3 +6 4 +6 5 +6 7 +6 8 6 9 +7 0 +7 1 +7 2 +7 3 +7 4 +7 5 +7 6 +7 8 7 9 +8 0 +8 1 +8 2 +8 3 +8 4 +8 5 +8 6 +8 7 8 9 +9 0 +9 1 +9 2 +9 3 +9 4 +9 5 +9 6 +9 7 +9 8 DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); CREATE TABLE t2 (c1 TINYINT NOT NULL); diff --git a/mysql-test/suite/engines/funcs/t/se_join_default.test b/mysql-test/suite/engines/funcs/t/se_join_default.test index 87e5a4d5b6ab5..16cdc12a01d65 100644 --- a/mysql-test/suite/engines/funcs/t/se_join_default.test +++ b/mysql-test/suite/engines/funcs/t/se_join_default.test @@ -12,6 +12,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 < t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -25,6 +26,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 < t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -38,6 +40,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 < t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -51,6 +54,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 < t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -64,6 +68,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 < t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -77,6 +82,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 < t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -90,6 +96,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 < t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -103,6 +110,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 < t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -116,6 +124,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 < t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -129,6 +138,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 < t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -142,6 +152,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 < t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -155,6 +166,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 < t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -168,6 +180,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 < t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -181,6 +194,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 < t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -194,6 +208,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 < t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -207,6 +222,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 < t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -220,6 +236,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 < t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -233,6 +250,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 < t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -246,6 +264,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 < t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -259,6 +278,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 < t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -272,6 +292,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 < t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -285,6 +306,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 < t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -298,6 +320,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 < t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -311,6 +334,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 < t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -324,6 +348,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 < t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -337,6 +362,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 < t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -350,6 +376,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 < t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -363,6 +390,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 < t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -376,6 +404,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 < t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -389,6 +418,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 < t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -402,6 +432,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <= t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -415,6 +446,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <= t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -428,6 +460,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <= t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -441,6 +474,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <= t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -454,6 +488,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <= t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -467,6 +502,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <= t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -480,6 +516,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <= t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -493,6 +530,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <= t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -506,6 +544,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <= t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -519,6 +558,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <= t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -532,6 +572,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <= t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -545,6 +586,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <= t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -558,6 +600,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <= t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -571,6 +614,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <= t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -584,6 +628,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <= t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -597,6 +642,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <= t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -610,6 +656,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <= t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -623,6 +670,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <= t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -636,6 +684,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <= t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -649,6 +698,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <= t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -662,6 +712,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <= t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -675,6 +726,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <= t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -688,6 +740,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <= t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -701,6 +754,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <= t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -714,6 +768,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <= t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -727,6 +782,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <= t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -740,6 +796,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <= t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -753,6 +810,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <= t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -766,6 +824,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <= t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -779,6 +838,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <= t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -792,6 +852,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 = t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -805,6 +866,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 = t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -818,6 +880,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 = t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -831,6 +894,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 = t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -844,6 +908,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 = t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -857,6 +922,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 = t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -870,6 +936,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 = t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -883,6 +950,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 = t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -896,6 +964,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 = t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -909,6 +978,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 = t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -922,6 +992,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 = t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -935,6 +1006,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 = t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -948,6 +1020,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 = t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -961,6 +1034,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 = t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -974,6 +1048,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 = t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -987,6 +1062,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 = t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1000,6 +1076,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 = t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1013,6 +1090,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 = t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1026,6 +1104,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 = t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1039,6 +1118,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 = t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1052,6 +1132,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 = t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -1065,6 +1146,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 = t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1078,6 +1160,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 = t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1091,6 +1174,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 = t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1104,6 +1188,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 = t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1117,6 +1202,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 = t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1130,6 +1216,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 = t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -1143,6 +1230,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 = t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1156,6 +1244,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 = t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1169,6 +1258,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 = t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1182,6 +1272,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 >= t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1195,6 +1286,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 >= t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1208,6 +1300,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 >= t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -1221,6 +1314,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 >= t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1234,6 +1328,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 >= t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1247,6 +1342,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 >= t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1260,6 +1356,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 >= t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1273,6 +1370,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 >= t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1286,6 +1384,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 >= t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -1299,6 +1398,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 >= t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1312,6 +1412,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 >= t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1325,6 +1426,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 >= t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1338,6 +1440,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 >= t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1351,6 +1454,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 >= t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1364,6 +1468,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 >= t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -1377,6 +1482,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 >= t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1390,6 +1496,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 >= t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1403,6 +1510,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 >= t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1416,6 +1524,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 >= t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1429,6 +1538,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 >= t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1442,6 +1552,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 >= t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -1455,6 +1566,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 >= t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1468,6 +1580,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 >= t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1481,6 +1594,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 >= t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1494,6 +1608,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 >= t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1507,6 +1622,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 >= t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1520,6 +1636,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 >= t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -1533,6 +1650,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 >= t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1546,6 +1664,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 >= t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1559,6 +1678,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 >= t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1572,6 +1692,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1585,6 +1706,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1598,6 +1720,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -1611,6 +1734,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1624,6 +1748,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1637,6 +1762,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 != t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1650,6 +1776,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 != t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1663,6 +1790,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 != t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1676,6 +1804,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 != t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -1689,6 +1818,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 != t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1702,6 +1832,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 != t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1715,6 +1846,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 != t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1728,6 +1860,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 != t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1741,6 +1874,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 != t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1754,6 +1888,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 != t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -1767,6 +1902,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 != t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1780,6 +1916,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 != t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1793,6 +1930,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 != t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1806,6 +1944,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 != t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1819,6 +1958,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 != t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1832,6 +1972,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 != t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -1845,6 +1986,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 != t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1858,6 +2000,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 != t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1871,6 +2014,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 != t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1884,6 +2028,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 != t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1897,6 +2042,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 != t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1910,6 +2056,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 != t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -1923,6 +2070,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 != t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -1936,6 +2084,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 != t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -1949,6 +2098,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 != t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -1962,6 +2112,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <> t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -1975,6 +2126,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <> t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -1988,6 +2140,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <> t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -2001,6 +2154,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <> t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -2014,6 +2168,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <> t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -2027,6 +2182,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <> t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -2040,6 +2196,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <> t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -2053,6 +2210,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <> t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -2066,6 +2224,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <> t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -2079,6 +2238,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <> t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -2092,6 +2252,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <> t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -2105,6 +2266,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <> t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -2118,6 +2280,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <> t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -2131,6 +2294,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <> t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -2144,6 +2308,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <> t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -2157,6 +2322,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <> t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -2170,6 +2336,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <> t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -2183,6 +2350,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <> t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -2196,6 +2364,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <> t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -2209,6 +2378,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <> t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -2222,6 +2392,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <> t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -2235,6 +2406,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <> t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -2248,6 +2420,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <> t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -2261,6 +2434,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <> t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -2274,6 +2448,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <> t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -2287,6 +2462,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <> t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -2300,6 +2476,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <> t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -2313,6 +2490,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <> t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -2326,6 +2504,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <> t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -2339,6 +2518,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <> t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -2352,6 +2532,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <=> t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -2365,6 +2546,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <=> t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -2378,6 +2560,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <=> t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -2391,6 +2574,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <=> t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -2404,6 +2588,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <=> t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -2417,6 +2602,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 <=> t2.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -2430,6 +2616,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <=> t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -2443,6 +2630,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <=> t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -2456,6 +2644,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <=> t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -2469,6 +2658,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <=> t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -2482,6 +2672,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <=> t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -2495,6 +2686,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t3.c1 FROM t1,t3 WHERE t1.c1 <=> t3.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -2508,6 +2700,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <=> t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -2521,6 +2714,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <=> t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -2534,6 +2728,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <=> t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -2547,6 +2742,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <=> t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -2560,6 +2756,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <=> t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -2573,6 +2770,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t4.c1 FROM t1,t4 WHERE t1.c1 <=> t4.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -2586,6 +2784,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <=> t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -2599,6 +2798,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <=> t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -2612,6 +2812,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <=> t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -2625,6 +2826,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <=> t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -2638,6 +2840,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <=> t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -2651,6 +2854,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t5.c1 FROM t1,t5 WHERE t1.c1 <=> t5.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 TINYINT NOT NULL); @@ -2664,6 +2868,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <=> t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 SMALLINT NOT NULL); @@ -2677,6 +2882,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <=> t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 MEDIUMINT NOT NULL); @@ -2690,6 +2896,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <=> t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INT NOT NULL); @@ -2703,6 +2910,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <=> t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 INTEGER NOT NULL); @@ -2716,6 +2924,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <=> t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (c1 BIGINT NOT NULL); @@ -2729,6 +2938,7 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9); INSERT INTO t4 (c1) VALUES(10); INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14); +--sorted_result SELECT t1.c1,t6.c1 FROM t1,t6 WHERE t1.c1 <=> t6.c1; DROP TABLE t1,t2,t3,t4,t5,t6; diff --git a/mysql-test/suite/gcol/inc/gcol_keys.inc b/mysql-test/suite/gcol/inc/gcol_keys.inc index cf0612b0d0cfc..e5ac0afd92a5f 100644 --- a/mysql-test/suite/gcol/inc/gcol_keys.inc +++ b/mysql-test/suite/gcol/inc/gcol_keys.inc @@ -203,7 +203,7 @@ INSERT INTO c ( col_time_nokey,col_datetime_nokey,col_varchar_nokey) values ('16:21:18.052408','2001-11-08 21:02:12.009395', 'x'), ('18:56:33.027423','2003-04-01 00:00:00', 'i'); ---replace_column 10 x 11 x +--replace_column 9 x 10 x EXPLAIN SELECT outr.col_time_key AS x FROM c as outr diff --git a/mysql-test/suite/gcol/inc/gcol_select.inc b/mysql-test/suite/gcol/inc/gcol_select.inc index 939d2f64e84e9..2386c55fdbc13 100644 --- a/mysql-test/suite/gcol/inc/gcol_select.inc +++ b/mysql-test/suite/gcol/inc/gcol_select.inc @@ -507,7 +507,7 @@ INSERT /*! IGNORE */ INTO cc ( (6, '2008-10-10', NULL, '2000-05-22 00:00:00', 'i'), (8, '2002-01-19', '05:18:40.006865', '2009-02-12 00:00:00', 'v'); ---replace_column 10 # 11 # +--replace_column 9 # 10 # EXPLAIN SELECT subquery2_t2.col_int_key AS subquery2_field1 FROM (c AS subquery2_t1 RIGHT JOIN @@ -544,10 +544,10 @@ CREATE TABLE cc ( KEY (col_int_key) ); INSERT INTO cc (col_int_nokey) VALUES (0),(1),(7),(0),(4),(5); ---replace_column 10 # 11 # +--replace_column 9 # 10 # EXPLAIN SELECT pk FROM cc WHERE col_int_key > 3; SELECT pk FROM cc WHERE col_int_key > 3; ---replace_column 10 # 11 # +--replace_column 9 # 10 # EXPLAIN SELECT pk FROM cc WHERE col_int_key > 3 ORDER BY 1; SELECT pk FROM cc WHERE col_int_key > 3 ORDER BY 1; DROP TABLE cc; @@ -601,7 +601,7 @@ INSERT INTO a ( ANALYZE TABLE a, c; ---replace_column 10 # +--replace_column 9 # --disable_warnings EXPLAIN SELECT @@ -675,7 +675,7 @@ col_varchar_nokey (5, 'b'),(8,'m'),(7, 'j'),(2, 'v'); ANALYZE TABLE c, cc; ---replace_column 10 # +--replace_column 9 # --disable_warnings let query=SELECT @@ -734,7 +734,7 @@ KEY cover_key1 (col_int, col_varchar_255_utf8_key)); INSERT INTO j(col_int, pk, col_varchar_10_utf8) VALUES(9, 1, '951910400'), (-1934295040, 2, '1235025920'),(-584581120, 3, '-1176633344'),(3, 4, '1074462720'); ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT col_varchar_255_utf8_key FROM j ORDER BY 1; SELECT col_varchar_255_utf8_key FROM j ORDER BY col_varchar_255_utf8_key; diff --git a/mysql-test/suite/gcol/inc/gcol_view.inc b/mysql-test/suite/gcol/inc/gcol_view.inc index 6f9ce67319933..85caa58c400a5 100644 --- a/mysql-test/suite/gcol/inc/gcol_view.inc +++ b/mysql-test/suite/gcol/inc/gcol_view.inc @@ -29,20 +29,20 @@ select d,e from v1; select is_updatable from information_schema.views where table_name='v1'; # view with different algorithms (explain output differs) ---replace_column 10 X +--replace_column 9 X explain select d,e from v1; create algorithm=temptable view v2 (d,e) as select abs(b), abs(c) from t1; show create view v2; --sorted_result select d,e from v2; ---replace_column 10 X +--replace_column 9 X explain select d,e from v2; # VIEW on VIEW test create view v3 (d,e) as select d*2, e*2 from v1; --sorted_result select * from v3; ---replace_column 10 X +--replace_column 9 X explain select * from v3; drop view v1,v2,v3; @@ -58,7 +58,7 @@ insert into t1 (a) values (1), (2), (3), (1), (2), (3); create view v1 as select distinct b from t1; --sorted_result select * from v1; ---replace_column 10 X +--replace_column 9 X explain select * from v1; --sorted_result select * from t1; @@ -66,7 +66,7 @@ drop view v1; create view v1 as select distinct c from t1; --sorted_result select * from v1; ---replace_column 10 X +--replace_column 9 X explain select * from v1; --sorted_result select * from t1; @@ -82,13 +82,13 @@ create table t1 (a int not null, insert into t1 (a) values (1), (2), (3), (4); create view v1 as select b+1 from t1 order by 1 desc limit 2; select * from v1; ---replace_column 10 X +--replace_column 9 X explain select * from v1; drop view v1; create view v1 as select c+1 from t1 order by 1 desc limit 2; --sorted_result select * from v1; ---replace_column 10 X +--replace_column 9 X explain select * from v1; drop view v1; drop table t1; diff --git a/mysql-test/suite/gcol/r/gcol_keys_innodb.result b/mysql-test/suite/gcol/r/gcol_keys_innodb.result index 196ceb5459e1d..edb20af7f1a7b 100644 --- a/mysql-test/suite/gcol/r/gcol_keys_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_keys_innodb.result @@ -205,7 +205,7 @@ outr.col_varchar_nokey in ('c', 'x', 'i') AND (outr.col_time_key IS NULL OR outr.col_datetime_key = '2009-09-27'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE outr index_merge col_time_key,col_datetime_key col_time_key,col_datetime_key 4,6 NULL 2 x +1 SIMPLE outr index_merge col_time_key,col_datetime_key col_time_key,col_datetime_key 4,6 NULL x x SELECT outr.col_time_key AS x FROM c AS outr diff --git a/mysql-test/suite/gcol/r/gcol_keys_myisam.result b/mysql-test/suite/gcol/r/gcol_keys_myisam.result index c3cb35416ef24..364d53afe1d8d 100644 --- a/mysql-test/suite/gcol/r/gcol_keys_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_keys_myisam.result @@ -205,7 +205,7 @@ outr.col_varchar_nokey in ('c', 'x', 'i') AND (outr.col_time_key IS NULL OR outr.col_datetime_key = '2009-09-27'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE outr index_merge col_time_key,col_datetime_key col_time_key,col_datetime_key 4,6 NULL 2 x +1 SIMPLE outr index_merge col_time_key,col_datetime_key col_time_key,col_datetime_key 4,6 NULL x x SELECT outr.col_time_key AS x FROM c AS outr diff --git a/mysql-test/suite/gcol/r/gcol_select_myisam.result b/mysql-test/suite/gcol/r/gcol_select_myisam.result index 77ab0cdb926f0..67c495f6a6e78 100644 --- a/mysql-test/suite/gcol/r/gcol_select_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_select_myisam.result @@ -591,9 +591,9 @@ FROM (c AS subquery2_t1 RIGHT JOIN (subquery2_t3.col_varchar_key = subquery2_t2.col_varchar_key)) ORDER BY subquery2_field1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE subquery2_t2 index NULL col_int_key_2 10 NULL 20 # -1 SIMPLE subquery2_t3 ALL NULL NULL NULL NULL 20 # -1 SIMPLE subquery2_t1 index NULL PRIMARY 4 NULL 20 # +1 SIMPLE subquery2_t2 index NULL col_int_key_2 10 NULL # # +1 SIMPLE subquery2_t3 ALL NULL NULL NULL NULL # # +1 SIMPLE subquery2_t1 index NULL PRIMARY 4 NULL # # SELECT subquery2_t2.col_int_key AS subquery2_field1 FROM (c AS subquery2_t1 RIGHT JOIN (c AS subquery2_t2 LEFT JOIN cc AS subquery2_t3 ON @@ -794,7 +794,7 @@ KEY (col_int_key) INSERT INTO cc (col_int_nokey) VALUES (0),(1),(7),(0),(4),(5); EXPLAIN SELECT pk FROM cc WHERE col_int_key > 3; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE cc range col_int_key col_int_key 5 NULL 3 # +1 SIMPLE cc range col_int_key col_int_key 5 NULL # # SELECT pk FROM cc WHERE col_int_key > 3; pk 5 @@ -802,7 +802,7 @@ pk 3 EXPLAIN SELECT pk FROM cc WHERE col_int_key > 3 ORDER BY 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE cc range col_int_key col_int_key 5 NULL 3 # +1 SIMPLE cc range col_int_key col_int_key 5 NULL # # SELECT pk FROM cc WHERE col_int_key > 3 ORDER BY 1; pk 3 @@ -876,12 +876,12 @@ ON (table3.col_int_key = table2.col_int_key ) ) ) ON (table3.col_int_nokey = table2.pk ) ) GROUP BY field1, field2; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY table1 system NULL NULL NULL NULL 1 # -1 PRIMARY table2 ALL PRIMARY,col_int_key,col_int_key_2 NULL NULL NULL 19 # -1 PRIMARY ref key0 key0 9 test.table2.pk,test.table2.col_int_key 10 # -2 DERIVED SUBQUERY1_t2 ALL PRIMARY,col_int_key,col_varchar_key,col_int_key_2 NULL NULL NULL 19 # -2 DERIVED SUBQUERY1_t3 ref PRIMARY,col_varchar_key col_varchar_key 5 test.SUBQUERY1_t2.col_varchar_key 1 # -2 DERIVED SUBQUERY1_t1 ALL col_int_key,col_int_key_2 NULL NULL NULL 19 # +1 PRIMARY table1 system NULL NULL NULL NULL # +1 PRIMARY table2 ALL PRIMARY,col_int_key,col_int_key_2 NULL NULL NULL # Using where +1 PRIMARY ref key0 key0 9 test.table2.pk,test.table2.col_int_key # +2 DERIVED SUBQUERY1_t2 ALL PRIMARY,col_int_key,col_varchar_key,col_int_key_2 NULL NULL NULL # Using where +2 DERIVED SUBQUERY1_t3 ref PRIMARY,col_varchar_key col_varchar_key 5 test.SUBQUERY1_t2.col_varchar_key # +2 DERIVED SUBQUERY1_t1 ALL col_int_key,col_int_key_2 NULL NULL NULL # Using where; Using join buffer (flat, BNL join) SELECT table1.pk AS field1 , table1.col_datetime_key AS field2 @@ -955,10 +955,10 @@ GROUP BY SQ1_field1 , SQ1_field2 ) GROUP BY field1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY alias1 index NULL col_int_key_3 10 NULL 20 # -1 PRIMARY alias2 index NULL col_int_key_2 10 NULL 20 # -2 MATERIALIZED SQ1_alias1 index col_int_key,col_int_key_2,col_int_key_3 col_int_key 5 NULL 20 # -2 MATERIALIZED SQ1_alias2 ALL NULL NULL NULL NULL 20 # +1 PRIMARY alias1 index NULL col_int_key_3 10 NULL # Using index; Using temporary; Using filesort +1 PRIMARY alias2 index NULL col_int_key_2 10 NULL # Using where; Using index; Using join buffer (flat, BNL join) +2 MATERIALIZED SQ1_alias1 index col_int_key,col_int_key_2,col_int_key_3 col_int_key 5 NULL # Using index +2 MATERIALIZED SQ1_alias2 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join) SELECT alias2 . col_varchar_key AS field1 FROM ( cc AS alias1 , cc AS alias2 ) @@ -1018,7 +1018,7 @@ INSERT INTO j(col_int, pk, col_varchar_10_utf8) VALUES(9, 1, '951910400'), (-1934295040, 2, '1235025920'),(-584581120, 3, '-1176633344'),(3, 4, '1074462720'); EXPLAIN SELECT col_varchar_255_utf8_key FROM j ORDER BY 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE j index NULL cover_key1 773 NULL 4 # +1 SIMPLE j index NULL cover_key1 773 NULL # Using index; Using filesort SELECT col_varchar_255_utf8_key FROM j ORDER BY col_varchar_255_utf8_key; col_varchar_255_utf8_key -117663334 diff --git a/mysql-test/suite/gcol/r/gcol_view_innodb.result b/mysql-test/suite/gcol/r/gcol_view_innodb.result index ac23d64bceef3..15e1cfeb983cb 100644 --- a/mysql-test/suite/gcol/r/gcol_view_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_view_innodb.result @@ -20,7 +20,7 @@ is_updatable NO explain select d,e from v1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 5 X +1 SIMPLE t1 ALL NULL NULL NULL NULL X create algorithm=temptable view v2 (d,e) as select abs(b), abs(c) from t1; show create view v2; View Create View character_set_client collation_connection @@ -34,8 +34,8 @@ d e 3 3 explain select d,e from v2; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 5 X -2 DERIVED t1 ALL NULL NULL NULL NULL 5 X +1 PRIMARY ALL NULL NULL NULL NULL X +2 DERIVED t1 ALL NULL NULL NULL NULL X create view v3 (d,e) as select d*2, e*2 from v1; select * from v3; d e @@ -46,7 +46,7 @@ d e 6 6 explain select * from v3; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 5 X +1 SIMPLE t1 ALL NULL NULL NULL NULL X drop view v1,v2,v3; drop table t1; create table t1 (a int not null, @@ -61,8 +61,8 @@ b -3 explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 6 X -2 DERIVED t1 ALL NULL NULL NULL NULL 6 X +1 PRIMARY ALL NULL NULL NULL NULL X +2 DERIVED t1 ALL NULL NULL NULL NULL X Using temporary select * from t1; a b c 1 -1 -1 @@ -80,8 +80,8 @@ c -3 explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 6 X -2 DERIVED t1 ALL NULL NULL NULL NULL 6 X +1 PRIMARY ALL NULL NULL NULL NULL X +2 DERIVED t1 ALL NULL NULL NULL NULL X Using temporary select * from t1; a b c 1 -1 -1 @@ -103,8 +103,8 @@ b+1 -1 explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 2 X -2 DERIVED t1 ALL NULL NULL NULL NULL 4 X +1 PRIMARY ALL NULL NULL NULL NULL X +2 DERIVED t1 ALL NULL NULL NULL NULL X Using filesort drop view v1; create view v1 as select c+1 from t1 order by 1 desc limit 2; select * from v1; @@ -113,8 +113,8 @@ c+1 0 explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 2 X -2 DERIVED t1 ALL NULL NULL NULL NULL 4 X +1 PRIMARY ALL NULL NULL NULL NULL X +2 DERIVED t1 ALL NULL NULL NULL NULL X Using filesort drop view v1; drop table t1; create table t1 (a int, diff --git a/mysql-test/suite/gcol/r/gcol_view_myisam.result b/mysql-test/suite/gcol/r/gcol_view_myisam.result index ddbbf44222c72..d266405dc6644 100644 --- a/mysql-test/suite/gcol/r/gcol_view_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_view_myisam.result @@ -20,7 +20,7 @@ is_updatable NO explain select d,e from v1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 5 X +1 SIMPLE t1 ALL NULL NULL NULL NULL X create algorithm=temptable view v2 (d,e) as select abs(b), abs(c) from t1; show create view v2; View Create View character_set_client collation_connection @@ -34,8 +34,8 @@ d e 3 3 explain select d,e from v2; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 5 X -2 DERIVED t1 ALL NULL NULL NULL NULL 5 X +1 PRIMARY ALL NULL NULL NULL NULL X +2 DERIVED t1 ALL NULL NULL NULL NULL X create view v3 (d,e) as select d*2, e*2 from v1; select * from v3; d e @@ -46,7 +46,7 @@ d e 6 6 explain select * from v3; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 5 X +1 SIMPLE t1 ALL NULL NULL NULL NULL X drop view v1,v2,v3; drop table t1; create table t1 (a int not null, @@ -61,8 +61,8 @@ b -3 explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 6 X -2 DERIVED t1 ALL NULL NULL NULL NULL 6 X +1 PRIMARY ALL NULL NULL NULL NULL X +2 DERIVED t1 ALL NULL NULL NULL NULL X Using temporary select * from t1; a b c 1 -1 -1 @@ -80,8 +80,8 @@ c -3 explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 6 X -2 DERIVED t1 ALL NULL NULL NULL NULL 6 X +1 PRIMARY ALL NULL NULL NULL NULL X +2 DERIVED t1 ALL NULL NULL NULL NULL X Using temporary select * from t1; a b c 1 -1 -1 @@ -103,8 +103,8 @@ b+1 -1 explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 2 X -2 DERIVED t1 ALL NULL NULL NULL NULL 4 X +1 PRIMARY ALL NULL NULL NULL NULL X +2 DERIVED t1 ALL NULL NULL NULL NULL X Using filesort drop view v1; create view v1 as select c+1 from t1 order by 1 desc limit 2; select * from v1; @@ -113,8 +113,8 @@ c+1 0 explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 2 X -2 DERIVED t1 ALL NULL NULL NULL NULL 4 X +1 PRIMARY ALL NULL NULL NULL NULL X +2 DERIVED t1 ALL NULL NULL NULL NULL X Using filesort drop view v1; drop table t1; create table t1 (a int, diff --git a/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result b/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result index 3658e38125f4f..93bba0039f9ed 100644 --- a/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result +++ b/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result @@ -2,6 +2,8 @@ set default_storage_engine=innodb; set @old_dbug=@@global.debug_dbug; SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; +SET @saved_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; CREATE TABLE `t` ( `a` BLOB, `b` BLOB, @@ -206,3 +208,4 @@ connection default; DROP TABLE t1, t2; set debug_sync=reset; SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; +SET GLOBAL innodb_stats_persistent = @saved_stats_persistent; diff --git a/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test b/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test index cdec810709516..2f1f8b29abac2 100644 --- a/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test +++ b/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test @@ -8,6 +8,8 @@ set @old_dbug=@@global.debug_dbug; # Ensure that the history list length will actually be decremented by purge. SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; +SET @saved_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; CREATE TABLE `t` ( `a` BLOB, @@ -263,3 +265,4 @@ DROP TABLE t1, t2; set debug_sync=reset; SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; +SET GLOBAL innodb_stats_persistent = @saved_stats_persistent; diff --git a/mysql-test/suite/innodb/r/doublewrite.result b/mysql-test/suite/innodb/r/doublewrite.result index 322385088b24b..234d58012d380 100644 --- a/mysql-test/suite/innodb/r/doublewrite.result +++ b/mysql-test/suite/innodb/r/doublewrite.result @@ -17,7 +17,7 @@ innodb_saved_page_number_debug 0 connect stop_purge,localhost,root,,; START TRANSACTION WITH CONSISTENT SNAPSHOT; connection default; -create table t1 (f1 int primary key, f2 blob) engine=innodb; +create table t1 (f1 int primary key, f2 blob) engine=innodb stats_persistent=0; start transaction; insert into t1 values(1, repeat('#',12)); insert into t1 values(2, repeat('+',12)); diff --git a/mysql-test/suite/innodb/r/innodb-16k.result b/mysql-test/suite/innodb/r/innodb-16k.result index 3cf72975cdc0e..84b1eb6d3d342 100644 --- a/mysql-test/suite/innodb/r/innodb-16k.result +++ b/mysql-test/suite/innodb/r/innodb-16k.result @@ -1,4 +1,6 @@ call mtr.add_suppression("InnoDB: Cannot add field .* in table"); +SET @save_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; +SET GLOBAL innodb_purge_rseg_truncate_frequency=1; # Test 1) Show the page size from Information Schema SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_page_size'; @@ -164,13 +166,15 @@ INSERT INTO t2 VALUES ('jejdkrun87'),('adfd72nh9k'), CREATE TABLE t1(a int, b blob, c text, d text NOT NULL) ENGINE=innodb DEFAULT CHARSET=utf8; INSERT INTO t1 -SELECT a,LEFT(REPEAT(d,100*a),65535),REPEAT(d,20*a),d FROM t2,t3; +SELECT a,LEFT(REPEAT(d,100*a),65535),REPEAT(d,20*a),d FROM t2,t3 +ORDER BY a,d; DROP TABLE t2, t3; SELECT COUNT(*) FROM t1 WHERE a=44; COUNT(*) 5 SELECT a, -LENGTH(b),b=LEFT(REPEAT(d,100*a),65535),LENGTH(c),c=REPEAT(d,20*a),d FROM t1; +LENGTH(b),b=LEFT(REPEAT(d,100*a),65535),LENGTH(c),c=REPEAT(d,20*a),d FROM t1 +ORDER BY a,d; a LENGTH(b) b=LEFT(REPEAT(d,100*a),65535) LENGTH(c) c=REPEAT(d,20*a) d 22 22000 1 4400 1 adfd72nh9k 22 35200 1 7040 1 adfdijn0loKNHJik @@ -211,7 +215,8 @@ SELECT COUNT(*) FROM t1 WHERE a=44; COUNT(*) 5 SELECT a, -LENGTH(b), b=LEFT(REPEAT(d,100*a), 65535),LENGTH(c), c=REPEAT(d,20*a), d FROM t1; +LENGTH(b), b=LEFT(REPEAT(d,100*a), 65535),LENGTH(c), c=REPEAT(d,20*a), d FROM t1 +ORDER BY a,d; a LENGTH(b) b=LEFT(REPEAT(d,100*a), 65535) LENGTH(c) c=REPEAT(d,20*a) d 22 22000 1 4400 1 adfd72nh9k 22 35200 1 7040 1 adfdijn0loKNHJik @@ -498,7 +503,9 @@ ERROR 42000: Row size too large (> 8126). Changing some columns to TEXT or BLOB CREATE TABLE t1(c text, PRIMARY KEY (c(438))) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII; INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512)); +InnoDB 0 transactions not purged DROP TABLE t1; DROP TABLE t1_purge, t2_purge, t3_purge, t4_purge; DROP TABLE tlong; DROP TABLE tlong2; +SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency; diff --git a/mysql-test/suite/innodb/r/innodb-32k.result b/mysql-test/suite/innodb/r/innodb-32k.result index 184d7fde052d5..3660fac3a2f2e 100644 --- a/mysql-test/suite/innodb/r/innodb-32k.result +++ b/mysql-test/suite/innodb/r/innodb-32k.result @@ -1,3 +1,4 @@ +SET GLOBAL innodb_purge_rseg_truncate_frequency=1; call mtr.add_suppression("Innodb: Cannot add field.*row size is"); # Test 1) Show the page size from Information Schema SELECT variable_value FROM information_schema.global_status @@ -283,6 +284,7 @@ Level Code Message UPDATE t3 SET c = REPEAT('b',32800); SHOW WARNINGS; Level Code Message +InnoDB 0 transactions not purged DROP TABLE t3; DROP TABLE t1_purge, t2_purge, t3_purge, t4_purge; DROP TABLE tlong; diff --git a/mysql-test/suite/innodb/r/innodb-alter-tempfile.result b/mysql-test/suite/innodb/r/innodb-alter-tempfile.result index bc40e5f4b711b..a64b2339a3901 100644 --- a/mysql-test/suite/innodb/r/innodb-alter-tempfile.result +++ b/mysql-test/suite/innodb/r/innodb-alter-tempfile.result @@ -45,7 +45,7 @@ set DEBUG_SYNC="now WAIT_FOR default_signal"; disconnect con1; SHOW KEYS FROM t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Ignored -t1 1 f1 1 f1 A 2 NULL NULL BTREE NO +t1 1 f1 1 f1 A # NULL NULL BTREE NO DROP TABLE t1; # # MDEV-25503 InnoDB hangs on startup during recovery diff --git a/mysql-test/suite/innodb/r/innodb-dict.result b/mysql-test/suite/innodb/r/innodb-dict.result index e3b2f0d5288e7..d56fec0f9af9f 100644 --- a/mysql-test/suite/innodb/r/innodb-dict.result +++ b/mysql-test/suite/innodb/r/innodb-dict.result @@ -24,6 +24,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref my_d my_d 5 const 128 Using index ALTER TABLE t1 DROP INDEX my_d; ALTER TABLE t1 MODIFY COLUMN D INT; +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK ALTER TABLE t1 ADD INDEX my_d (D); EXPLAIN SELECT d FROM t1 WHERE d = 5; id select_type table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/suite/innodb/r/innodb-index-online.result b/mysql-test/suite/innodb/r/innodb-index-online.result index 92a2f57397c2c..6ad5c20ffedf1 100644 --- a/mysql-test/suite/innodb/r/innodb-index-online.result +++ b/mysql-test/suite/innodb/r/innodb-index-online.result @@ -148,6 +148,9 @@ database_name table_name index_name last_update stat_name stat_value sample_size test t1 PRIMARY LAST_UPDATE n_diff_pfx01 5 1 c1 test t1 PRIMARY LAST_UPDATE n_leaf_pages 1 NULL Number of leaf pages in the index test t1 PRIMARY LAST_UPDATE size 1 NULL Number of pages in the index +test t1_c2_stats GEN_CLUST_INDEX LAST_UPDATE n_diff_pfx01 3 1 DB_ROW_ID +test t1_c2_stats GEN_CLUST_INDEX LAST_UPDATE n_leaf_pages 1 NULL Number of leaf pages in the index +test t1_c2_stats GEN_CLUST_INDEX LAST_UPDATE size 1 NULL Number of pages in the index connection con1; KILL QUERY @id; ERROR 70100: Query execution was interrupted diff --git a/mysql-test/suite/innodb/r/innodb-isolation.result b/mysql-test/suite/innodb/r/innodb-isolation.result index ce9c530ff44d4..b6e512cc6de42 100644 --- a/mysql-test/suite/innodb/r/innodb-isolation.result +++ b/mysql-test/suite/innodb/r/innodb-isolation.result @@ -939,40 +939,40 @@ COUNT(*) # EXPLAIN SELECT * FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 12 # +1 SIMPLE t1 ALL NULL NULL NULL NULL # EXPLAIN SELECT COUNT(*) FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL k2 5 NULL 12 Using index +1 SIMPLE t1 index NULL k2 5 NULL # Using index EXPLAIN SELECT COUNT(c1) FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL k2 5 NULL 12 Using index +1 SIMPLE t1 index NULL k2 5 NULL # Using index EXPLAIN SELECT COUNT(c2) FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL k2 5 NULL 12 # +1 SIMPLE t1 index NULL k2 5 NULL # Using index EXPLAIN SELECT COUNT(c3) FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 12 # +1 SIMPLE t1 ALL NULL NULL NULL NULL # EXPLAIN SELECT SUM(c1) FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL k2 5 NULL 12 # +1 SIMPLE t1 index NULL k2 5 NULL # Using index EXPLAIN SELECT SUM(c2) FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL k2 5 NULL 12 # +1 SIMPLE t1 index NULL k2 5 NULL # Using index EXPLAIN SELECT AVG(c1), MAX(c1), MIN(c2), AVG(c3), SUM(c4) FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 12 # +1 SIMPLE t1 ALL NULL NULL NULL NULL # EXPLAIN SELECT c1, c2 FROM t1 WHERE c1 > ((SELECT COUNT(*) FROM t1) / 2); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 range PRIMARY PRIMARY 4 NULL 8 # -2 SUBQUERY t1 index NULL k2 5 NULL 12 # +1 PRIMARY t1 range PRIMARY PRIMARY 4 NULL # Using where +2 SUBQUERY t1 index NULL k2 5 NULL # Using index EXPLAIN SELECT COUNT(c2) FROM t1 WHERE c1 > ((SELECT COUNT(*) FROM t1) / 2); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 range PRIMARY PRIMARY 4 NULL 8 # -2 SUBQUERY t1 index NULL k2 5 NULL 12 # +1 PRIMARY t1 range PRIMARY PRIMARY 4 NULL # Using where +2 SUBQUERY t1 index NULL k2 5 NULL # Using index EXPLAIN SELECT COUNT(*) FROM t1 WHERE c1 > (SELECT AVG(c1) FROM t1); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 range PRIMARY PRIMARY 4 NULL 7 # -2 SUBQUERY t1 index NULL k2 5 NULL 12 # +1 PRIMARY t1 range PRIMARY PRIMARY 4 NULL # Using where; Using index +2 SUBQUERY t1 index NULL k2 5 NULL # Using index # # Make all indexes in t2 obsolete to the active repeatable read transaction # in the default connection. @@ -1395,11 +1395,11 @@ disconnect con3; CREATE TABLE t1(c1 INT NOT NULL PRIMARY KEY, c2 INT NOT NULL DEFAULT 1, c3 char(20) DEFAULT '', -KEY c2_idx (c2)) ENGINE=InnoDB; +KEY c2_idx (c2)) ENGINE=InnoDB STATS_PERSISTENT=0; INSERT INTO t1(c1) VALUES (1), (2), (3); INSERT INTO t1(c1) SELECT c1 + 10 FROM t1; INSERT INTO t1(c1) SELECT c1 + 100 FROM t1; -CREATE TABLE t2 SELECT * FROM t1; +CREATE TABLE t2 STATS_PERSISTENT=0 SELECT * FROM t1; EXPLAIN SELECT COUNT(*) FROM t1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL c2_idx 4 NULL 12 Using index diff --git a/mysql-test/suite/innodb/r/innodb-wl5522-debug.result b/mysql-test/suite/innodb/r/innodb-wl5522-debug.result index 2109d47bf4b78..5236ae750c8b9 100644 --- a/mysql-test/suite/innodb/r/innodb-wl5522-debug.result +++ b/mysql-test/suite/innodb/r/innodb-wl5522-debug.result @@ -8,6 +8,7 @@ call mtr.add_suppression("InnoDB: Page 0 at offset 0 looks corrupted in file"); call mtr.add_suppression("InnoDB: Page for tablespace "); call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS="); call mtr.add_suppression("InnoDB: Unknown index id .* on page"); +call mtr.add_suppression("InnoDB: Cannot save statistics for table `test`\\.`t1` because the \\.ibd file is missing"); FLUSH TABLES; SET GLOBAL innodb_file_per_table = 1; CREATE TABLE t1 (c1 INT) ENGINE = InnoDB; diff --git a/mysql-test/suite/innodb/r/innodb-wl5522.result b/mysql-test/suite/innodb/r/innodb-wl5522.result index 16cbc11326779..dc03bd914240e 100644 --- a/mysql-test/suite/innodb/r/innodb-wl5522.result +++ b/mysql-test/suite/innodb/r/innodb-wl5522.result @@ -1,5 +1,6 @@ call mtr.add_suppression("InnoDB: Unable to import tablespace .* because it already exists. Please DISCARD the tablespace before IMPORT\\."); call mtr.add_suppression("Index for table 't2' is corrupt; try to repair it"); +call mtr.add_suppression("InnoDB: Cannot save statistics for table `test`\\.`t1` because the \\.ibd file is missing"); FLUSH TABLES; CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result index 7cb8602412a97..d799cbb8fd9cc 100644 --- a/mysql-test/suite/innodb/r/innodb.result +++ b/mysql-test/suite/innodb/r/innodb.result @@ -45,7 +45,7 @@ level tinyint(4) DEFAULT '0' NOT NULL, PRIMARY KEY (id), KEY parent_id (parent_id), KEY level (level) -) engine=innodb; +) engine=innodb stats_persistent=0; INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1),(179,5,2); update t1 set parent_id=parent_id+100; select * from t1 where parent_id=102; diff --git a/mysql-test/suite/innodb/r/innodb_bug84958.result b/mysql-test/suite/innodb/r/innodb_bug84958.result index b721c73a0fc83..a216dde1648fd 100644 --- a/mysql-test/suite/innodb/r/innodb_bug84958.result +++ b/mysql-test/suite/innodb/r/innodb_bug84958.result @@ -29,7 +29,7 @@ END~~ # Create a table with one record in it and start an RR transaction # CREATE TABLE t1 (a INT, b INT, c INT, PRIMARY KEY(a,b), KEY (b,c)) -ENGINE=InnoDB; +ENGINE=InnoDB STATS_PERSISTENT=0; BEGIN; SELECT * FROM t1; a b c diff --git a/mysql-test/suite/innodb/r/innodb_defrag_stats.result b/mysql-test/suite/innodb/r/innodb_defrag_stats.result index 2dae62ebbda39..4fdcf42faa13e 100644 --- a/mysql-test/suite/innodb/r/innodb_defrag_stats.result +++ b/mysql-test/suite/innodb/r/innodb_defrag_stats.result @@ -1,6 +1,6 @@ select @@global.innodb_stats_persistent; @@global.innodb_stats_persistent -0 +1 set global innodb_defragment_stats_accuracy = 20; CREATE TABLE t1(a INT PRIMARY KEY, b VARCHAR(256), KEY SECOND(a, b)) ENGINE=INNODB; @@ -116,7 +116,6 @@ select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't count(stat_value) > 0 1 # Clean up -ALTER TABLE t2 STATS_PERSISTENT=1; DROP TABLE t2; select * from mysql.innodb_index_stats where table_name = 't2'; database_name table_name index_name last_update stat_name stat_value sample_size stat_description diff --git a/mysql-test/suite/innodb/r/monitor.result b/mysql-test/suite/innodb/r/monitor.result index 0b2b0049f684b..2e5e5e2241a88 100644 --- a/mysql-test/suite/innodb/r/monitor.result +++ b/mysql-test/suite/innodb/r/monitor.result @@ -578,7 +578,7 @@ set global innodb_monitor_reset_all = default; # Bug#22576241 SETTING INNODB_MONITOR_ENABLE TO ALL DOES NOT ENABLE ALL # MONITORS # -CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=0; SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; NAME COUNT > 0 diff --git a/mysql-test/suite/innodb/r/update_time.result b/mysql-test/suite/innodb/r/update_time.result index c2a842b7bfc52..a1da8cc422a23 100644 --- a/mysql-test/suite/innodb/r/update_time.result +++ b/mysql-test/suite/innodb/r/update_time.result @@ -2,7 +2,7 @@ # Test that INFORMATION_SCHEMA.TABLES.UPDATE_TIME is filled # correctly for InnoDB tables. # -CREATE TABLE t (a INT) ENGINE=INNODB; +CREATE TABLE t (a INT) ENGINE=INNODB STATS_PERSISTENT=0; SELECT update_time FROM information_schema.tables WHERE table_name = 't'; update_time NULL diff --git a/mysql-test/suite/innodb/t/doublewrite.test b/mysql-test/suite/innodb/t/doublewrite.test index fac1812e565fe..cedd2c9942b55 100644 --- a/mysql-test/suite/innodb/t/doublewrite.test +++ b/mysql-test/suite/innodb/t/doublewrite.test @@ -38,7 +38,7 @@ connect (stop_purge,localhost,root,,); START TRANSACTION WITH CONSISTENT SNAPSHOT; connection default; -create table t1 (f1 int primary key, f2 blob) engine=innodb; +create table t1 (f1 int primary key, f2 blob) engine=innodb stats_persistent=0; start transaction; insert into t1 values(1, repeat('#',12)); diff --git a/mysql-test/suite/innodb/t/innodb-16k.test b/mysql-test/suite/innodb/t/innodb-16k.test index 89819ba7b6d8c..c059f62385b21 100644 --- a/mysql-test/suite/innodb/t/innodb-16k.test +++ b/mysql-test/suite/innodb/t/innodb-16k.test @@ -4,6 +4,8 @@ --source include/have_innodb_16k.inc call mtr.add_suppression("InnoDB: Cannot add field .* in table"); +SET @save_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; +SET GLOBAL innodb_purge_rseg_truncate_frequency=1; let $MYSQLD_DATADIR= `select @@datadir`; @@ -183,11 +185,13 @@ INSERT INTO t2 VALUES ('jejdkrun87'),('adfd72nh9k'), CREATE TABLE t1(a int, b blob, c text, d text NOT NULL) ENGINE=innodb DEFAULT CHARSET=utf8; INSERT INTO t1 -SELECT a,LEFT(REPEAT(d,100*a),65535),REPEAT(d,20*a),d FROM t2,t3; +SELECT a,LEFT(REPEAT(d,100*a),65535),REPEAT(d,20*a),d FROM t2,t3 +ORDER BY a,d; DROP TABLE t2, t3; SELECT COUNT(*) FROM t1 WHERE a=44; SELECT a, -LENGTH(b),b=LEFT(REPEAT(d,100*a),65535),LENGTH(c),c=REPEAT(d,20*a),d FROM t1; +LENGTH(b),b=LEFT(REPEAT(d,100*a),65535),LENGTH(c),c=REPEAT(d,20*a),d FROM t1 +ORDER BY a,d; # in-place alter table should trigger ER_PRIMARY_CANT_HAVE_NULL --error ER_DUP_ENTRY @@ -200,7 +204,8 @@ CHECK TABLE t1; ALTER TABLE t1 ADD PRIMARY KEY (a,b(255),c(255)), ADD KEY (b(767)); SELECT COUNT(*) FROM t1 WHERE a=44; SELECT a, -LENGTH(b), b=LEFT(REPEAT(d,100*a), 65535),LENGTH(c), c=REPEAT(d,20*a), d FROM t1; +LENGTH(b), b=LEFT(REPEAT(d,100*a), 65535),LENGTH(c), c=REPEAT(d,20*a), d FROM t1 +ORDER BY a,d; SHOW CREATE TABLE t1; CHECK TABLE t1; DROP TABLE t1; @@ -450,13 +455,11 @@ ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII; INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512)); -DROP TABLE t1; - -# The tests that uses these tables required the purge thread to run. -# Just in case it has not by now, provide a 10 second wait. - ---sleep 10 +--source include/wait_all_purged.inc +DROP TABLE t1; DROP TABLE t1_purge, t2_purge, t3_purge, t4_purge; DROP TABLE tlong; DROP TABLE tlong2; + +SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency; \ No newline at end of file diff --git a/mysql-test/suite/innodb/t/innodb-32k.test b/mysql-test/suite/innodb/t/innodb-32k.test index 983ba88370a65..07c6c10d01370 100644 --- a/mysql-test/suite/innodb/t/innodb-32k.test +++ b/mysql-test/suite/innodb/t/innodb-32k.test @@ -3,6 +3,8 @@ --source include/have_innodb.inc --source include/have_innodb_32k.inc +SET GLOBAL innodb_purge_rseg_truncate_frequency=1; + call mtr.add_suppression("Innodb: Cannot add field.*row size is"); let $MYSQLD_DATADIR= `select @@datadir`; @@ -334,13 +336,10 @@ UPDATE t3 SET c = REPEAT('b',16928); SHOW WARNINGS; UPDATE t3 SET c = REPEAT('b',32800); SHOW WARNINGS; -DROP TABLE t3; -# The tests that uses these tables required the purge thread to run. -# Just in case it has not by now, provide a 10 second wait. - ---sleep 10 +--source include/wait_all_purged.inc +DROP TABLE t3; DROP TABLE t1_purge, t2_purge, t3_purge, t4_purge; DROP TABLE tlong; DROP TABLE tlong2; diff --git a/mysql-test/suite/innodb/t/innodb-alter-tempfile.test b/mysql-test/suite/innodb/t/innodb-alter-tempfile.test index 979005f641071..769ac8fa4bc23 100644 --- a/mysql-test/suite/innodb/t/innodb-alter-tempfile.test +++ b/mysql-test/suite/innodb/t/innodb-alter-tempfile.test @@ -65,6 +65,7 @@ set DEBUG_SYNC="now WAIT_FOR default_signal"; --let $shutdown_timeout=0 --source include/restart_mysqld.inc disconnect con1; +--replace_column 7 # SHOW KEYS FROM t1; DROP TABLE t1; remove_files_wildcard $datadir/test #sql-*.frm; diff --git a/mysql-test/suite/innodb/t/innodb-dict.test b/mysql-test/suite/innodb/t/innodb-dict.test index 25a284569dbd7..13472f016eab6 100644 --- a/mysql-test/suite/innodb/t/innodb-dict.test +++ b/mysql-test/suite/innodb/t/innodb-dict.test @@ -24,6 +24,7 @@ EXPLAIN SELECT d FROM t1 WHERE d = 5; EXPLAIN SELECT D FROM t1 WHERE D = 5; ALTER TABLE t1 DROP INDEX my_d; ALTER TABLE t1 MODIFY COLUMN D INT; +ANALYZE TABLE t1; ALTER TABLE t1 ADD INDEX my_d (D); EXPLAIN SELECT d FROM t1 WHERE d = 5; EXPLAIN SELECT D FROM t1 WHERE D = 5; diff --git a/mysql-test/suite/innodb/t/innodb-index.opt b/mysql-test/suite/innodb/t/innodb-index.opt new file mode 100644 index 0000000000000..1a01b4018c6e2 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-index.opt @@ -0,0 +1 @@ +--skip-innodb-stats-persistent diff --git a/mysql-test/suite/innodb/t/innodb-index_ucs2.opt b/mysql-test/suite/innodb/t/innodb-index_ucs2.opt new file mode 100644 index 0000000000000..1a01b4018c6e2 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-index_ucs2.opt @@ -0,0 +1 @@ +--skip-innodb-stats-persistent diff --git a/mysql-test/suite/innodb/t/innodb-isolation.test b/mysql-test/suite/innodb/t/innodb-isolation.test index d00fefb9fc643..6d347dc71af42 100644 --- a/mysql-test/suite/innodb/t/innodb-isolation.test +++ b/mysql-test/suite/innodb/t/innodb-isolation.test @@ -162,28 +162,30 @@ COMMIT; --echo # --echo # Show The EXPLAIN output for these queries; --echo # -# column 10 is the row count provided by handler::info(). In InnoDB, this is +# column 9 is the row count provided by handler::info(). In InnoDB, this is # a statistical estimate. After the multi-transactional changes above, # Solaris reports 10 rows which is correct, but other OSes report 9. ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT * FROM t1; +--replace_column 9 # EXPLAIN SELECT COUNT(*) FROM t1; +--replace_column 9 # EXPLAIN SELECT COUNT(c1) FROM t1; ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT COUNT(c2) FROM t1; ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT COUNT(c3) FROM t1; ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT SUM(c1) FROM t1; ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT SUM(c2) FROM t1; ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT AVG(c1), MAX(c1), MIN(c2), AVG(c3), SUM(c4) FROM t1; ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT c1, c2 FROM t1 WHERE c1 > ((SELECT COUNT(*) FROM t1) / 2); ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT COUNT(c2) FROM t1 WHERE c1 > ((SELECT COUNT(*) FROM t1) / 2); ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT COUNT(*) FROM t1 WHERE c1 > (SELECT AVG(c1) FROM t1); --echo # @@ -334,13 +336,13 @@ eval set global innodb_lock_wait_timeout=$initial_timeout; CREATE TABLE t1(c1 INT NOT NULL PRIMARY KEY, c2 INT NOT NULL DEFAULT 1, c3 char(20) DEFAULT '', - KEY c2_idx (c2)) ENGINE=InnoDB; + KEY c2_idx (c2)) ENGINE=InnoDB STATS_PERSISTENT=0; INSERT INTO t1(c1) VALUES (1), (2), (3); INSERT INTO t1(c1) SELECT c1 + 10 FROM t1; INSERT INTO t1(c1) SELECT c1 + 100 FROM t1; -CREATE TABLE t2 SELECT * FROM t1; +CREATE TABLE t2 STATS_PERSISTENT=0 SELECT * FROM t1; let query1= SELECT COUNT(*) FROM t1; let query2= SELECT COUNT(*) FROM t1 FORCE INDEX(c2_idx); diff --git a/mysql-test/suite/innodb/t/innodb-stats-modified-counter.opt b/mysql-test/suite/innodb/t/innodb-stats-modified-counter.opt index 3e5b41c6db9aa..1cfd8e7112efa 100644 --- a/mysql-test/suite/innodb/t/innodb-stats-modified-counter.opt +++ b/mysql-test/suite/innodb/t/innodb-stats-modified-counter.opt @@ -1 +1 @@ ---loose-innodb-sys-tablestats +--loose-innodb-sys-tablestats --skip-innodb-stats-persistent diff --git a/mysql-test/suite/innodb/t/innodb-wl5522-debug.test b/mysql-test/suite/innodb/t/innodb-wl5522-debug.test index 7256e2f23e064..0adf0eaf43b1f 100644 --- a/mysql-test/suite/innodb/t/innodb-wl5522-debug.test +++ b/mysql-test/suite/innodb/t/innodb-wl5522-debug.test @@ -28,6 +28,7 @@ call mtr.add_suppression("InnoDB: Page 0 at offset 0 looks corrupted in file"); call mtr.add_suppression("InnoDB: Page for tablespace "); call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS="); call mtr.add_suppression("InnoDB: Unknown index id .* on page"); +call mtr.add_suppression("InnoDB: Cannot save statistics for table `test`\\.`t1` because the \\.ibd file is missing"); FLUSH TABLES; let MYSQLD_DATADIR =`SELECT @@datadir`; diff --git a/mysql-test/suite/innodb/t/innodb-wl5522.test b/mysql-test/suite/innodb/t/innodb-wl5522.test index 9b18b29fc200a..a70ae86f1cd45 100644 --- a/mysql-test/suite/innodb/t/innodb-wl5522.test +++ b/mysql-test/suite/innodb/t/innodb-wl5522.test @@ -7,6 +7,8 @@ call mtr.add_suppression("InnoDB: Unable to import tablespace .* because it already exists. Please DISCARD the tablespace before IMPORT\\."); call mtr.add_suppression("Index for table 't2' is corrupt; try to repair it"); +call mtr.add_suppression("InnoDB: Cannot save statistics for table `test`\\.`t1` because the \\.ibd file is missing"); + FLUSH TABLES; let $MYSQLD_TMPDIR = `SELECT @@tmpdir`; diff --git a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test index a50d3b7d9afa0..3a8c12dfbbd4c 100644 --- a/mysql-test/suite/innodb/t/innodb.test +++ b/mysql-test/suite/innodb/t/innodb.test @@ -79,7 +79,7 @@ CREATE TABLE t1 ( PRIMARY KEY (id), KEY parent_id (parent_id), KEY level (level) -) engine=innodb; +) engine=innodb stats_persistent=0; INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1),(179,5,2); update t1 set parent_id=parent_id+100; select * from t1 where parent_id=102; diff --git a/mysql-test/suite/innodb/t/innodb_bug57252.test b/mysql-test/suite/innodb/t/innodb_bug57252.test index 5a4ca1ab6d88b..eafcaee19bd88 100644 --- a/mysql-test/suite/innodb/t/innodb_bug57252.test +++ b/mysql-test/suite/innodb/t/innodb_bug57252.test @@ -9,7 +9,7 @@ SET @innodb_stats_on_metadata_orig = @@innodb_stats_on_metadata; -CREATE TABLE bug57252 (a INT, KEY akey (a)) ENGINE=INNODB; +CREATE TABLE bug57252 (a INT, KEY akey (a)) ENGINE=INNODB STATS_PERSISTENT=0; BEGIN; let $i = 10; diff --git a/mysql-test/suite/innodb/t/innodb_bug84958.test b/mysql-test/suite/innodb/t/innodb_bug84958.test index cbcc5d1abc6fb..f895c8d12458b 100644 --- a/mysql-test/suite/innodb/t/innodb_bug84958.test +++ b/mysql-test/suite/innodb/t/innodb_bug84958.test @@ -36,7 +36,7 @@ DELIMITER ;~~ --echo # Create a table with one record in it and start an RR transaction --echo # CREATE TABLE t1 (a INT, b INT, c INT, PRIMARY KEY(a,b), KEY (b,c)) -ENGINE=InnoDB; +ENGINE=InnoDB STATS_PERSISTENT=0; BEGIN; SELECT * FROM t1; diff --git a/mysql-test/suite/innodb/t/innodb_defrag_stats.test b/mysql-test/suite/innodb/t/innodb_defrag_stats.test index 2dc5e65309152..248fd24f0c897 100644 --- a/mysql-test/suite/innodb/t/innodb_defrag_stats.test +++ b/mysql-test/suite/innodb/t/innodb_defrag_stats.test @@ -82,8 +82,6 @@ select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_leaf_pages_defrag'); --echo # Clean up -# DROP TABLE will not touch persistent statistics if the table has none! -ALTER TABLE t2 STATS_PERSISTENT=1; DROP TABLE t2; select * from mysql.innodb_index_stats where table_name = 't2'; diff --git a/mysql-test/suite/innodb/t/instant_alter.opt b/mysql-test/suite/innodb/t/instant_alter.opt index 99bf0e5a28b2b..1f0d2d43ddf0a 100644 --- a/mysql-test/suite/innodb/t/instant_alter.opt +++ b/mysql-test/suite/innodb/t/instant_alter.opt @@ -1 +1 @@ ---innodb-sys-tablestats +--innodb-sys-tablestats --skip-innodb-stats-persistent diff --git a/mysql-test/suite/innodb/t/instant_alter_debug.combinations b/mysql-test/suite/innodb/t/instant_alter_debug.combinations index f3bc2cc0c2564..5f98b128ab689 100644 --- a/mysql-test/suite/innodb/t/instant_alter_debug.combinations +++ b/mysql-test/suite/innodb/t/instant_alter_debug.combinations @@ -1,4 +1,6 @@ [redundant] innodb_default_row_format=redundant +innodb_stats_persistent=off [dynamic] innodb_default_row_format=dynamic +innodb_stats_persistent=off diff --git a/mysql-test/suite/innodb/t/monitor.test b/mysql-test/suite/innodb/t/monitor.test index b80d9deabc137..3a004b22751e7 100644 --- a/mysql-test/suite/innodb/t/monitor.test +++ b/mysql-test/suite/innodb/t/monitor.test @@ -394,7 +394,7 @@ set global innodb_monitor_reset_all = default; --echo # Bug#22576241 SETTING INNODB_MONITOR_ENABLE TO ALL DOES NOT ENABLE ALL --echo # MONITORS --echo # -CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=0; let $innodb_monitor_enable = `SELECT @@innodb_monitor_enable`; diff --git a/mysql-test/suite/innodb/t/purge_secondary.opt b/mysql-test/suite/innodb/t/purge_secondary.opt index e98e639d5f473..2821c98397c15 100644 --- a/mysql-test/suite/innodb/t/purge_secondary.opt +++ b/mysql-test/suite/innodb/t/purge_secondary.opt @@ -1,3 +1,4 @@ --innodb-sys-tablestats --innodb_buffer_pool_size=5M --innodb_monitor_enable=module_buffer +--skip-innodb-stats-persistent diff --git a/mysql-test/suite/innodb/t/update_time.test b/mysql-test/suite/innodb/t/update_time.test index a95c5171e9ba2..8ccf7c0d532a3 100644 --- a/mysql-test/suite/innodb/t/update_time.test +++ b/mysql-test/suite/innodb/t/update_time.test @@ -11,7 +11,7 @@ # This test is slow on buildbot. --source include/big_test.inc -CREATE TABLE t (a INT) ENGINE=INNODB; +CREATE TABLE t (a INT) ENGINE=INNODB STATS_PERSISTENT=0; SELECT update_time FROM information_schema.tables WHERE table_name = 't'; diff --git a/mysql-test/suite/innodb_fts/r/misc_debug.result b/mysql-test/suite/innodb_fts/r/misc_debug.result index e8a462f2751e3..d012fa5a9c833 100644 --- a/mysql-test/suite/innodb_fts/r/misc_debug.result +++ b/mysql-test/suite/innodb_fts/r/misc_debug.result @@ -55,6 +55,7 @@ DROP TABLE t1; # MDEV-25663 Double free of transaction during TRUNCATE # call mtr.add_suppression("InnoDB: \\(Too many concurrent transactions\\)"); +call mtr.add_suppression("InnoDB: Cannot save table statistics for table `test`\\.`t1`: Too many concurrent transactions"); CREATE TABLE t1 (b CHAR(12), FULLTEXT KEY(b)) engine=InnoDB; SET debug_dbug='+d,ib_create_table_fail_too_many_trx'; TRUNCATE t1; diff --git a/mysql-test/suite/innodb_fts/t/misc_debug.test b/mysql-test/suite/innodb_fts/t/misc_debug.test index b1193d0ec3cdc..bbf3afe69e557 100644 --- a/mysql-test/suite/innodb_fts/t/misc_debug.test +++ b/mysql-test/suite/innodb_fts/t/misc_debug.test @@ -85,6 +85,7 @@ DROP TABLE t1; --echo # MDEV-25663 Double free of transaction during TRUNCATE --echo # call mtr.add_suppression("InnoDB: \\(Too many concurrent transactions\\)"); +call mtr.add_suppression("InnoDB: Cannot save table statistics for table `test`\\.`t1`: Too many concurrent transactions"); CREATE TABLE t1 (b CHAR(12), FULLTEXT KEY(b)) engine=InnoDB; SET debug_dbug='+d,ib_create_table_fail_too_many_trx'; diff --git a/mysql-test/suite/innodb_gis/r/1.result b/mysql-test/suite/innodb_gis/r/1.result index 26fdf39baf374..f8db53a4ca904 100644 --- a/mysql-test/suite/innodb_gis/r/1.result +++ b/mysql-test/suite/innodb_gis/r/1.result @@ -227,7 +227,7 @@ fid ST_AsText(ST_Envelope(g)) 121 POLYGON((3 6,44 6,44 9,3 9,3 6)) explain extended select ST_Dimension(g), ST_GeometryType(g), ST_IsEmpty(g), ST_AsText(ST_Envelope(g)) from gis_geometry; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_geometry ALL NULL NULL NULL NULL 21 # +1 SIMPLE gis_geometry ALL NULL NULL NULL NULL # # Warnings: Note 1003 select st_dimension(`test`.`gis_geometry`.`g`) AS `ST_Dimension(g)`,st_geometrytype(`test`.`gis_geometry`.`g`) AS `ST_GeometryType(g)`,st_isempty(`test`.`gis_geometry`.`g`) AS `ST_IsEmpty(g)`,st_astext(st_envelope(`test`.`gis_geometry`.`g`)) AS `ST_AsText(ST_Envelope(g))` from `test`.`gis_geometry` SELECT fid, ST_X(g) FROM gis_point; @@ -244,7 +244,7 @@ fid ST_Y(g) 104 20 explain extended select ST_X(g),ST_Y(g) FROM gis_point; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_point ALL NULL NULL NULL NULL 4 # +1 SIMPLE gis_point ALL NULL NULL NULL NULL # # Warnings: Note 1003 select st_x(`test`.`gis_point`.`g`) AS `ST_X(g)`,st_y(`test`.`gis_point`.`g`) AS `ST_Y(g)` from `test`.`gis_point` SELECT fid, ST_AsText(ST_StartPoint(g)) FROM gis_line; @@ -279,7 +279,7 @@ fid ST_IsClosed(g) 107 0 explain extended select ST_AsText(ST_StartPoint(g)),ST_AsText(ST_EndPoint(g)),ST_Length(g),ST_NumPoints(g),ST_AsText(ST_PointN(g, 2)),ST_IsClosed(g) FROM gis_line; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_line ALL NULL NULL NULL NULL 3 # +1 SIMPLE gis_line ALL NULL NULL NULL NULL # # Warnings: Note 1003 select st_astext(st_startpoint(`test`.`gis_line`.`g`)) AS `ST_AsText(ST_StartPoint(g))`,st_astext(st_endpoint(`test`.`gis_line`.`g`)) AS `ST_AsText(ST_EndPoint(g))`,st_length(`test`.`gis_line`.`g`) AS `ST_Length(g)`,st_numpoints(`test`.`gis_line`.`g`) AS `ST_NumPoints(g)`,st_astext(st_pointn(`test`.`gis_line`.`g`,2)) AS `ST_AsText(ST_PointN(g, 2))`,st_isclosed(`test`.`gis_line`.`g`) AS `ST_IsClosed(g)` from `test`.`gis_line` SELECT fid, ST_AsText(ST_Centroid(g)) FROM gis_polygon; @@ -309,7 +309,7 @@ fid ST_AsText(ST_InteriorRingN(g, 1)) 110 NULL explain extended select ST_AsText(ST_Centroid(g)),ST_Area(g),ST_AsText(ST_ExteriorRing(g)),ST_NumInteriorRings(g),ST_AsText(ST_InteriorRingN(g, 1)) FROM gis_polygon; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_polygon ALL NULL NULL NULL NULL 3 # +1 SIMPLE gis_polygon ALL NULL NULL NULL NULL # # Warnings: Note 1003 select st_astext(st_centroid(`test`.`gis_polygon`.`g`)) AS `ST_AsText(ST_Centroid(g))`,st_area(`test`.`gis_polygon`.`g`) AS `ST_Area(g)`,st_astext(st_exteriorring(`test`.`gis_polygon`.`g`)) AS `ST_AsText(ST_ExteriorRing(g))`,st_numinteriorrings(`test`.`gis_polygon`.`g`) AS `ST_NumInteriorRings(g)`,st_astext(st_interiorringn(`test`.`gis_polygon`.`g`,1)) AS `ST_AsText(ST_InteriorRingN(g, 1))` from `test`.`gis_polygon` SELECT fid, ST_IsClosed(g) FROM gis_multi_line; @@ -348,7 +348,7 @@ fid ST_NumGeometries(g) 121 2 explain extended SELECT fid, ST_NumGeometries(g) from gis_multi_point; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL 3 # +1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL # # Warnings: Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,st_numgeometries(`test`.`gis_multi_point`.`g`) AS `ST_NumGeometries(g)` from `test`.`gis_multi_point` SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_point; @@ -376,7 +376,7 @@ fid ST_AsText(ST_GeometryN(g, 1)) 121 POINT(44 6) explain extended SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_point; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL 3 # +1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL # # Warnings: Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,st_astext(st_geometryn(`test`.`gis_multi_point`.`g`,2)) AS `ST_AsText(ST_GeometryN(g, 2))` from `test`.`gis_multi_point` SELECT g1.fid as first, g2.fid as second, @@ -395,8 +395,8 @@ MBREquals(g1.g, g2.g) as e, MBRDisjoint(g1.g, g2.g) as d, ST_Touches(g1.g, g2.g) MBRIntersects(g1.g, g2.g) as i, ST_Crosses(g1.g, g2.g) as r FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE g1 ALL NULL NULL NULL NULL 2 # Using temporary; Using filesort -1 SIMPLE g2 ALL NULL NULL NULL NULL 2 # Using join buffer (flat, BNL join) +1 SIMPLE g1 ALL NULL NULL NULL NULL # # Using temporary; Using filesort +1 SIMPLE g2 ALL NULL NULL NULL NULL # # Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`g1`.`fid` AS `first`,`test`.`g2`.`fid` AS `second`,mbrwithin(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `w`,mbrcontains(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `c`,mbroverlaps(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `o`,mbrequals(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `e`,mbrdisjoint(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `d`,st_touches(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `t`,mbrintersects(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `i`,st_crosses(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `r` from `test`.`gis_geometrycollection` `g1` join `test`.`gis_geometrycollection` `g2` order by `test`.`g1`.`fid`,`test`.`g2`.`fid` DROP TABLE gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry; diff --git a/mysql-test/suite/innodb_gis/r/geometry.result b/mysql-test/suite/innodb_gis/r/geometry.result index 70e0f04cdf154..437ff23e334b6 100644 --- a/mysql-test/suite/innodb_gis/r/geometry.result +++ b/mysql-test/suite/innodb_gis/r/geometry.result @@ -1,5 +1,7 @@ SET default_storage_engine=InnoDB; SET innodb_strict_mode=OFF; +SET @save_innodb_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; CREATE TABLE gis_point (fid INTEGER NOT NULL PRIMARY KEY, g POINT) ENGINE=InnoDB; CREATE TABLE gis_line (fid INTEGER NOT NULL PRIMARY KEY, g LINESTRING) ENGINE=InnoDB; CREATE TABLE gis_polygon (fid INTEGER NOT NULL PRIMARY KEY, g POLYGON) ENGINE=InnoDB; @@ -179,39 +181,39 @@ CREATE UNIQUE INDEX idx2 on tab(c8(5) ASC) ; EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab WHERE c2=ST_LineFromText('LINESTRING(10 10,20 20,30 30)'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab ref idx1 idx1 8 const 1 # +1 SIMPLE tab ref idx1 idx1 8 const # Using where #check index with WKB function EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab WHERE c2=ST_LineStringFromWKB(ST_AsWKB(ST_LineFromText('LINESTRING(10 10,20 20,30 30)'))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab ref idx1 idx1 8 const 1 # +1 SIMPLE tab ref idx1 idx1 8 const # Using where #check index with WKT function EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab WHERE c3=ST_PolyFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab ref idx3 idx3 8 const 1 # +1 SIMPLE tab ref idx3 idx3 8 const # Using where #check index with WKB function EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab WHERE c3=ST_PolyFromWKB(ST_AsWkB(ST_PolyFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab ref idx3 idx3 8 const 1 # +1 SIMPLE tab ref idx3 idx3 8 const # Using where #check index with WKT function EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab WHERE c8=ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab const idx2 idx2 8 const 1 # +1 SIMPLE tab const idx2 idx2 8 const # #check index with WKB function EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab WHERE c8=ST_GeometryFromWKB(ST_AsWKB(ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab const idx2 idx2 8 const 1 # +1 SIMPLE tab const idx2 idx2 8 const # #check index with DELETE operation EXPLAIN DELETE FROM tab WHERE c8=ST_GeometryFromWKB(ST_AsWKB(ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab range idx2 idx2 8 NULL 1 # +1 SIMPLE tab range idx2 idx2 8 NULL # Using where #check the spatial values SELECT ST_AsText(c1) FROM tab; ST_AsText(c1) @@ -703,39 +705,39 @@ CREATE UNIQUE INDEX idx2 on tab3(c8(5) ASC) ; EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c2=ST_LineFromText('LINESTRING(10 10,20 20,30 30)'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab3 ref idx1 idx1 8 const 1 # +1 SIMPLE tab3 ref idx1 idx1 8 const # Using where #check index with WKB function EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c2=ST_LineStringFromWKB(ST_AsWKB(ST_LineFromText('LINESTRING(10 10,20 20,30 30)'))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab3 ref idx1 idx1 8 const 1 # +1 SIMPLE tab3 ref idx1 idx1 8 const # Using where #check index with WKT function EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c3=ST_PolyFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab3 ref idx3 idx3 8 const 1 # +1 SIMPLE tab3 ref idx3 idx3 8 const # Using where #check index with WKB function EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c3=ST_PolyFromWKB(ST_AsWkB(ST_PolyFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab3 ref idx3 idx3 8 const 1 # +1 SIMPLE tab3 ref idx3 idx3 8 const # Using where #check index with WKT function EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c8=ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab3 const idx2 idx2 8 const 1 # +1 SIMPLE tab3 const idx2 idx2 8 const # #check index with WKB function EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c8=ST_GeometryFromWKB(ST_AsWKB(ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab3 const idx2 idx2 8 const 1 # +1 SIMPLE tab3 const idx2 idx2 8 const # #check index with DELETE operation EXPLAIN DELETE FROM tab3 WHERE c8=ST_GeometryFromWKB(ST_AsWKB(ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab3 range idx2 idx2 8 NULL 1 # +1 SIMPLE tab3 range idx2 idx2 8 NULL # Using where #check the spatial values SELECT ST_AsText(c1) FROM tab3; ST_AsText(c1) @@ -783,12 +785,12 @@ tab3 CREATE TABLE `tab3` ( EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c2=ST_LineStringFromWKB(ST_AsWKB(ST_LineFromText('LINESTRING(10 10,20 20,30 30)'))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab3 ref idx1 idx1 8 const 1 # +1 SIMPLE tab3 ref idx1 idx1 8 const # Using where #check index with WKT function EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c3=ST_PolyFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE tab3 ref idx3 idx3 8 const 1 # +1 SIMPLE tab3 ref idx3 idx3 8 const # Using where #check the Geometry property functions SELECT fid, ST_Dimension(g) FROM gis_geometry; fid ST_Dimension(g) @@ -888,7 +890,7 @@ fid ST_AsText(ST_Envelope(g)) 122 POLYGON((3 6,44 6,44 9,3 9,3 6)) explain extended select ST_Dimension(g), ST_GeometryType(g), ST_IsEmpty(g), ST_AsText(ST_Envelope(g)) from gis_geometry; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_geometry ALL NULL NULL NULL NULL 22 # +1 SIMPLE gis_geometry ALL NULL NULL NULL NULL # 100.00 Warnings: Note 1003 select st_dimension(`test`.`gis_geometry`.`g`) AS `ST_Dimension(g)`,st_geometrytype(`test`.`gis_geometry`.`g`) AS `ST_GeometryType(g)`,st_isempty(`test`.`gis_geometry`.`g`) AS `ST_IsEmpty(g)`,st_astext(st_envelope(`test`.`gis_geometry`.`g`)) AS `ST_AsText(ST_Envelope(g))` from `test`.`gis_geometry` #check Geometry point functions @@ -906,7 +908,7 @@ fid ST_Y(g) 104 20 explain extended select ST_X(g),ST_Y(g) FROM gis_point; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_point ALL NULL NULL NULL NULL 4 # +1 SIMPLE gis_point ALL NULL NULL NULL NULL # 100.00 Warnings: Note 1003 select st_x(`test`.`gis_point`.`g`) AS `ST_X(g)`,st_y(`test`.`gis_point`.`g`) AS `ST_Y(g)` from `test`.`gis_point` SELECT fid, ST_AsText(ST_StartPoint(g)) FROM gis_line; @@ -942,7 +944,7 @@ fid ST_IsClosed(g) explain extended select ST_AsText(ST_StartPoint(g)),ST_AsText(ST_EndPoint(g)), ST_Length(g),ST_NumPoints(g),ST_AsText(ST_PointN(g, 2)),ST_IsClosed(g) FROM gis_line; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_line ALL NULL NULL NULL NULL 3 # +1 SIMPLE gis_line ALL NULL NULL NULL NULL # 100.00 Warnings: Note 1003 select st_astext(st_startpoint(`test`.`gis_line`.`g`)) AS `ST_AsText(ST_StartPoint(g))`,st_astext(st_endpoint(`test`.`gis_line`.`g`)) AS `ST_AsText(ST_EndPoint(g))`,st_length(`test`.`gis_line`.`g`) AS `ST_Length(g)`,st_numpoints(`test`.`gis_line`.`g`) AS `ST_NumPoints(g)`,st_astext(st_pointn(`test`.`gis_line`.`g`,2)) AS `ST_AsText(ST_PointN(g, 2))`,st_isclosed(`test`.`gis_line`.`g`) AS `ST_IsClosed(g)` from `test`.`gis_line` SELECT fid, ST_AsText(ST_Centroid(g)) FROM gis_polygon; @@ -973,7 +975,7 @@ fid ST_AsText(ST_InteriorRingN(g, 1)) explain extended select ST_AsText(ST_Centroid(g)),ST_Area(g),ST_AsText(ST_ExteriorRing(g)), ST_NumInteriorRings(g),ST_AsText(ST_InteriorRingN(g, 1)) FROM gis_polygon; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_polygon ALL NULL NULL NULL NULL 3 # +1 SIMPLE gis_polygon ALL NULL NULL NULL NULL # 100.00 Warnings: Note 1003 select st_astext(st_centroid(`test`.`gis_polygon`.`g`)) AS `ST_AsText(ST_Centroid(g))`,st_area(`test`.`gis_polygon`.`g`) AS `ST_Area(g)`,st_astext(st_exteriorring(`test`.`gis_polygon`.`g`)) AS `ST_AsText(ST_ExteriorRing(g))`,st_numinteriorrings(`test`.`gis_polygon`.`g`) AS `ST_NumInteriorRings(g)`,st_astext(st_interiorringn(`test`.`gis_polygon`.`g`,1)) AS `ST_AsText(ST_InteriorRingN(g, 1))` from `test`.`gis_polygon` SELECT fid, ST_IsClosed(g) FROM gis_multi_line; @@ -1013,7 +1015,7 @@ fid ST_NumGeometries(g) 122 2 explain extended SELECT fid, ST_NumGeometries(g) from gis_multi_point; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL 3 # +1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL # 100.00 Warnings: Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,st_numgeometries(`test`.`gis_multi_point`.`g`) AS `ST_NumGeometries(g)` from `test`.`gis_multi_point` SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_point; @@ -1043,7 +1045,7 @@ fid ST_AsText(ST_GeometryN(g, 1)) 122 POINT(44 6) explain extended SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_point; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL 3 # +1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL # 100.00 Warnings: Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,st_astext(st_geometryn(`test`.`gis_multi_point`.`g`,2)) AS `ST_AsText(ST_GeometryN(g, 2))` from `test`.`gis_multi_point` SELECT g1.fid as first, g2.fid as second, @@ -1067,8 +1069,8 @@ MBREquals(g1.g, g2.g) as e, MBRDisjoint(g1.g, g2.g) as d, ST_Touches(g1.g, g2.g) MBRIntersects(g1.g, g2.g) as i, ST_Crosses(g1.g, g2.g) as r FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE g1 ALL NULL NULL NULL NULL 3 # Using temporary; Using filesort -1 SIMPLE g2 ALL NULL NULL NULL NULL 3 # Using join buffer (flat, BNL join) +1 SIMPLE g1 ALL NULL NULL NULL NULL # 100.00 Using temporary; Using filesort +1 SIMPLE g2 ALL NULL NULL NULL NULL # 100.00 Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`g1`.`fid` AS `first`,`test`.`g2`.`fid` AS `second`,mbrwithin(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `w`,mbrcontains(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `c`,mbroverlaps(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `o`,mbrequals(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `e`,mbrdisjoint(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `d`,st_touches(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `t`,mbrintersects(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `i`,st_crosses(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `r` from `test`.`gis_geometrycollection` `g1` join `test`.`gis_geometrycollection` `g2` order by `test`.`g1`.`fid`,`test`.`g2`.`fid` # check support of Foreign Key constraint @@ -1113,3 +1115,4 @@ DROP TABLE tab,tab2,tab3,parent; DROP PROCEDURE geominout; DROP PROCEDURE geom_insert; DROP PROCEDURE geom_cursor; +SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent; diff --git a/mysql-test/suite/innodb_gis/r/gis.result b/mysql-test/suite/innodb_gis/r/gis.result index e673d92f5c6ee..f41fcab5bbbb1 100644 --- a/mysql-test/suite/innodb_gis/r/gis.result +++ b/mysql-test/suite/innodb_gis/r/gis.result @@ -1,5 +1,6 @@ SET default_storage_engine=InnoDB; -DROP TABLE IF EXISTS t1, gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry; +SET @save_innodb_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; CREATE TABLE gis_point (fid INTEGER NOT NULL PRIMARY KEY, g POINT); CREATE TABLE gis_line (fid INTEGER NOT NULL PRIMARY KEY, g LINESTRING); CREATE TABLE gis_polygon (fid INTEGER NOT NULL PRIMARY KEY, g POLYGON); @@ -227,7 +228,7 @@ fid ST_AsText(ST_Envelope(g)) 121 POLYGON((3 6,44 6,44 9,3 9,3 6)) explain extended select ST_Dimension(g), ST_GeometryType(g), ST_IsEmpty(g), ST_AsText(ST_Envelope(g)) from gis_geometry; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_geometry ALL NULL NULL NULL NULL 21 # +1 SIMPLE gis_geometry ALL NULL NULL NULL NULL # 100.00 Warnings: Note 1003 select st_dimension(`test`.`gis_geometry`.`g`) AS `ST_Dimension(g)`,st_geometrytype(`test`.`gis_geometry`.`g`) AS `ST_GeometryType(g)`,st_isempty(`test`.`gis_geometry`.`g`) AS `ST_IsEmpty(g)`,st_astext(st_envelope(`test`.`gis_geometry`.`g`)) AS `ST_AsText(ST_Envelope(g))` from `test`.`gis_geometry` SELECT fid, ST_X(g) FROM gis_point; @@ -244,7 +245,7 @@ fid ST_Y(g) 104 20 explain extended select ST_X(g),ST_Y(g) FROM gis_point; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_point ALL NULL NULL NULL NULL 4 # +1 SIMPLE gis_point ALL NULL NULL NULL NULL # 100.00 Warnings: Note 1003 select st_x(`test`.`gis_point`.`g`) AS `ST_X(g)`,st_y(`test`.`gis_point`.`g`) AS `ST_Y(g)` from `test`.`gis_point` SELECT fid, ST_AsText(ST_StartPoint(g)) FROM gis_line; @@ -279,7 +280,7 @@ fid ST_IsClosed(g) 107 0 explain extended select ST_AsText(ST_StartPoint(g)),ST_AsText(ST_EndPoint(g)),ST_Length(g),ST_NumPoints(g),ST_AsText(ST_PointN(g, 2)),ST_IsClosed(g) FROM gis_line; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_line ALL NULL NULL NULL NULL 3 # +1 SIMPLE gis_line ALL NULL NULL NULL NULL # 100.00 Warnings: Note 1003 select st_astext(st_startpoint(`test`.`gis_line`.`g`)) AS `ST_AsText(ST_StartPoint(g))`,st_astext(st_endpoint(`test`.`gis_line`.`g`)) AS `ST_AsText(ST_EndPoint(g))`,st_length(`test`.`gis_line`.`g`) AS `ST_Length(g)`,st_numpoints(`test`.`gis_line`.`g`) AS `ST_NumPoints(g)`,st_astext(st_pointn(`test`.`gis_line`.`g`,2)) AS `ST_AsText(ST_PointN(g, 2))`,st_isclosed(`test`.`gis_line`.`g`) AS `ST_IsClosed(g)` from `test`.`gis_line` SELECT fid, ST_AsText(ST_Centroid(g)) FROM gis_polygon; @@ -309,7 +310,7 @@ fid ST_AsText(ST_InteriorRingN(g, 1)) 110 NULL explain extended select ST_AsText(ST_Centroid(g)),ST_Area(g),ST_AsText(ST_ExteriorRing(g)),ST_NumInteriorRings(g),ST_AsText(ST_InteriorRingN(g, 1)) FROM gis_polygon; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_polygon ALL NULL NULL NULL NULL 3 # +1 SIMPLE gis_polygon ALL NULL NULL NULL NULL # 100.00 Warnings: Note 1003 select st_astext(st_centroid(`test`.`gis_polygon`.`g`)) AS `ST_AsText(ST_Centroid(g))`,st_area(`test`.`gis_polygon`.`g`) AS `ST_Area(g)`,st_astext(st_exteriorring(`test`.`gis_polygon`.`g`)) AS `ST_AsText(ST_ExteriorRing(g))`,st_numinteriorrings(`test`.`gis_polygon`.`g`) AS `ST_NumInteriorRings(g)`,st_astext(st_interiorringn(`test`.`gis_polygon`.`g`,1)) AS `ST_AsText(ST_InteriorRingN(g, 1))` from `test`.`gis_polygon` SELECT fid, ST_IsClosed(g) FROM gis_multi_line; @@ -348,7 +349,7 @@ fid ST_NumGeometries(g) 121 2 explain extended SELECT fid, ST_NumGeometries(g) from gis_multi_point; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL 3 # +1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL # 100.00 Warnings: Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,st_numgeometries(`test`.`gis_multi_point`.`g`) AS `ST_NumGeometries(g)` from `test`.`gis_multi_point` SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_point; @@ -376,7 +377,7 @@ fid ST_AsText(ST_GeometryN(g, 1)) 121 POINT(44 6) explain extended SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_point; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL 3 # +1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL # 100.00 Warnings: Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,st_astext(st_geometryn(`test`.`gis_multi_point`.`g`,2)) AS `ST_AsText(ST_GeometryN(g, 2))` from `test`.`gis_multi_point` SELECT g1.fid as first, g2.fid as second, @@ -395,8 +396,8 @@ MBREquals(g1.g, g2.g) as e, MBRDisjoint(g1.g, g2.g) as d, ST_Touches(g1.g, g2.g) MBRIntersects(g1.g, g2.g) as i, ST_Crosses(g1.g, g2.g) as r FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE g1 ALL NULL NULL NULL NULL 2 # Using temporary; Using filesort -1 SIMPLE g2 ALL NULL NULL NULL NULL 2 # Using join buffer (flat, BNL join) +1 SIMPLE g1 ALL NULL NULL NULL NULL # 100.00 Using temporary; Using filesort +1 SIMPLE g2 ALL NULL NULL NULL NULL # 100.00 Using join buffer (flat, BNL join) Warnings: Note 1003 select `test`.`g1`.`fid` AS `first`,`test`.`g2`.`fid` AS `second`,mbrwithin(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `w`,mbrcontains(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `c`,mbroverlaps(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `o`,mbrequals(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `e`,mbrdisjoint(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `d`,st_touches(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `t`,mbrintersects(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `i`,st_crosses(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `r` from `test`.`gis_geometrycollection` `g1` join `test`.`gis_geometrycollection` `g2` order by `test`.`g1`.`fid`,`test`.`g2`.`fid` DROP TABLE gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry; @@ -1497,3 +1498,4 @@ COUNT(*) 1 DROP TABLE t1; DROP DATABASE gis_ogs; +SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent; diff --git a/mysql-test/suite/innodb_gis/r/point_basic.result b/mysql-test/suite/innodb_gis/r/point_basic.result index 4842c72d99ccb..14f07d4facfcb 100644 --- a/mysql-test/suite/innodb_gis/r/point_basic.result +++ b/mysql-test/suite/innodb_gis/r/point_basic.result @@ -25,7 +25,7 @@ INSERT INTO gis_point VALUES (ST_PointFromText('POINT(100.32374832 101.23741821)'), ST_PointFromText('POINT(100.32374832 101.98527111)')); EXPLAIN SELECT ST_AsText(p1), ST_AsText(p2) FROM gis_point GROUP BY p1, p2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE gis_point ALL NULL NULL NULL NULL 4 # +1 SIMPLE gis_point ALL NULL NULL NULL NULL # Using temporary; Using filesort SELECT ST_AsText(p1), ST_AsText(p2) FROM gis_point GROUP BY p1, p2; ST_AsText(p1) ST_AsText(p2) POINT(100.32374832 101.23741821) POINT(100.32374832 101.98527111) @@ -277,7 +277,7 @@ DROP TABLE t1; # # Test when the POINT is on B-TREE # -CREATE TABLE gis_point(fid INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, p POINT, KEY(p)) ENGINE=InnoDB; +CREATE TABLE gis_point(fid INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, p POINT, KEY(p)) ENGINE=InnoDB STATS_PERSISTENT=0; INSERT INTO gis_point VALUES (101, ST_PointFromText('POINT(10 10)')), (102, ST_PointFromText('POINT(20 10)')), @@ -302,7 +302,7 @@ INSERT INTO gis_point VALUES 'The ORDER BY will use filesort' EXPLAIN SELECT ST_AsText(p) FROM gis_point ORDER BY p; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE gis_point ALL NULL NULL NULL NULL 10 # +1 SIMPLE gis_point ALL NULL NULL NULL NULL # Using filesort SELECT ST_AsText(p) FROM gis_point ORDER BY p; ST_AsText(p) POINT(10 10) @@ -1326,7 +1326,7 @@ test.gis_point check status OK The ORDER BY for spatial index will use filesort EXPLAIN SELECT ST_AsText(p1), ST_AsText(p2) FROM gis_point ORDER BY p1, p2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE gis_point ALL NULL NULL NULL NULL 13 # +1 SIMPLE gis_point ALL NULL NULL NULL NULL # Using filesort SELECT ST_AsText(p1), ST_AsText(p2) FROM gis_point ORDER BY p1, p2; ST_AsText(p1) ST_AsText(p2) POINT(2 4) POINT(-2 -6) @@ -1488,7 +1488,7 @@ a ST_AsText(p) ST_AsText(l) ST_AsText(g) 2 POINT(20 20) LINESTRING(2 3,7 8,9 10,15 16) POLYGON((10 30,30 40,40 50,40 30,30 20,10 30)) EXPLAIN UPDATE t1 SET p = ST_GeomFromText('POINT(30 30)') WHERE p = ST_GeomFromText('POINT(20 20)'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 27 NULL 1 # +1 SIMPLE t1 range PRIMARY PRIMARY 27 NULL # Using where UPDATE t1 SET p = ST_GeomFromText('POINT(30 30)') WHERE p = ST_GeomFromText('POINT(20 20)'); SELECT a, ST_AsText(p), ST_AsText(l), ST_AsText(g) FROM t1; a ST_AsText(p) ST_AsText(l) ST_AsText(g) @@ -1526,7 +1526,7 @@ ALTER TABLE t1 DROP PRIMARY KEY; ALTER TABLE t1 ADD PRIMARY KEY(p); EXPLAIN SELECT a, ST_AsText(p) FROM t1 WHERE a = 2 AND p = ST_GeomFromText('POINT(30 30)'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 const PRIMARY,idx2 PRIMARY 27 const 1 # +1 SIMPLE t1 const PRIMARY,idx2 PRIMARY 27 const # SELECT a, ST_AsText(p) FROM t1 WHERE a = 2 AND p = ST_GeomFromText('POINT(30 30)'); a ST_AsText(p) 2 POINT(30 30) diff --git a/mysql-test/suite/innodb_gis/r/point_big.result b/mysql-test/suite/innodb_gis/r/point_big.result index c471ab6adb2da..7248c55bafe4b 100644 --- a/mysql-test/suite/innodb_gis/r/point_big.result +++ b/mysql-test/suite/innodb_gis/r/point_big.result @@ -260,7 +260,7 @@ INSERT INTO gis_point VALUES 'The ORDER BY for spatial index will use filesort' EXPLAIN SELECT ST_AsText(p1), ST_AsText(p2) FROM gis_point ORDER BY p1, p2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE gis_point ALL NULL NULL NULL NULL 13 # +1 SIMPLE gis_point ALL NULL NULL NULL NULL # Using filesort SELECT ST_AsText(p1), ST_AsText(p2) FROM gis_point ORDER BY p1, p2; ST_AsText(p1) ST_AsText(p2) POINT(2 4) POINT(-2 -6) diff --git a/mysql-test/suite/innodb_gis/r/rt_precise.result b/mysql-test/suite/innodb_gis/r/rt_precise.result index c83b88b568c02..4929dfc99a845 100644 --- a/mysql-test/suite/innodb_gis/r/rt_precise.result +++ b/mysql-test/suite/innodb_gis/r/rt_precise.result @@ -22,7 +22,7 @@ test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK EXPLAIN SELECT fid, ST_AsText(g) FROM t1 WHERE ST_Within(g, ST_GeomFromText('Polygon((140 140,160 140,160 160,140 140))')); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL gis_key NULL NULL NULL 150 # +1 SIMPLE t1 ALL gis_key NULL NULL NULL # Using where SELECT fid, ST_AsText(g) FROM t1 WHERE ST_Within(g, ST_GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))')) ORDER BY fid; fid ST_AsText(g) 1 LINESTRING(150 150,150 150) diff --git a/mysql-test/suite/innodb_gis/r/types.result b/mysql-test/suite/innodb_gis/r/types.result index 9eb40dc4231a2..a337ee10e3d94 100644 --- a/mysql-test/suite/innodb_gis/r/types.result +++ b/mysql-test/suite/innodb_gis/r/types.result @@ -33,7 +33,7 @@ GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(2 2,3 3)) CREATE INDEX i_p ON t_wl6455 (g(10)); EXPLAIN SELECT ST_AsText(g) FROM t_wl6455 WHERE g = POINT(2,2); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t_wl6455 ref i_p i_p 12 const 2 # +1 SIMPLE t_wl6455 ref i_p i_p 12 const # Using where SELECT ST_AsText(g) FROM t_wl6455 WHERE g = POINT(2,2); ST_AsText(g) POINT(2 2) diff --git a/mysql-test/suite/innodb_gis/t/1.test b/mysql-test/suite/innodb_gis/t/1.test index f08fdaddbda6e..950db3607941e 100644 --- a/mysql-test/suite/innodb_gis/t/1.test +++ b/mysql-test/suite/innodb_gis/t/1.test @@ -91,12 +91,12 @@ SELECT fid, ST_Dimension(g) FROM gis_geometry; SELECT fid, ST_GeometryType(g) FROM gis_geometry; SELECT fid, ST_IsEmpty(g) FROM gis_geometry; SELECT fid, ST_AsText(ST_Envelope(g)) FROM gis_geometry; ---replace_column 10 # +--replace_column 9 # 10 # explain extended select ST_Dimension(g), ST_GeometryType(g), ST_IsEmpty(g), ST_AsText(ST_Envelope(g)) from gis_geometry; SELECT fid, ST_X(g) FROM gis_point; SELECT fid, ST_Y(g) FROM gis_point; ---replace_column 10 # +--replace_column 9 # 10 # explain extended select ST_X(g),ST_Y(g) FROM gis_point; SELECT fid, ST_AsText(ST_StartPoint(g)) FROM gis_line; @@ -105,7 +105,7 @@ SELECT fid, ST_Length(g) FROM gis_line; SELECT fid, ST_NumPoints(g) FROM gis_line; SELECT fid, ST_AsText(ST_PointN(g, 2)) FROM gis_line; SELECT fid, ST_IsClosed(g) FROM gis_line; ---replace_column 10 # +--replace_column 9 # 10 # explain extended select ST_AsText(ST_StartPoint(g)),ST_AsText(ST_EndPoint(g)),ST_Length(g),ST_NumPoints(g),ST_AsText(ST_PointN(g, 2)),ST_IsClosed(g) FROM gis_line; SELECT fid, ST_AsText(ST_Centroid(g)) FROM gis_polygon; @@ -113,7 +113,7 @@ SELECT fid, ST_Area(g) FROM gis_polygon; SELECT fid, ST_AsText(ST_ExteriorRing(g)) FROM gis_polygon; SELECT fid, ST_NumInteriorRings(g) FROM gis_polygon; SELECT fid, ST_AsText(ST_InteriorRingN(g, 1)) FROM gis_polygon; ---replace_column 10 # +--replace_column 9 # 10 # explain extended select ST_AsText(ST_Centroid(g)),ST_Area(g),ST_AsText(ST_ExteriorRing(g)),ST_NumInteriorRings(g),ST_AsText(ST_InteriorRingN(g, 1)) FROM gis_polygon; SELECT fid, ST_IsClosed(g) FROM gis_multi_line; @@ -125,7 +125,7 @@ SELECT fid, ST_NumGeometries(g) from gis_multi_point; SELECT fid, ST_NumGeometries(g) from gis_multi_line; SELECT fid, ST_NumGeometries(g) from gis_multi_polygon; SELECT fid, ST_NumGeometries(g) from gis_geometrycollection; ---replace_column 10 # +--replace_column 9 # 10 # explain extended SELECT fid, ST_NumGeometries(g) from gis_multi_point; SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_point; @@ -133,7 +133,7 @@ SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_line; SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_polygon; SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_geometrycollection; SELECT fid, ST_AsText(ST_GeometryN(g, 1)) from gis_geometrycollection; ---replace_column 10 # +--replace_column 9 # 10 # explain extended SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_point; SELECT g1.fid as first, g2.fid as second, @@ -141,7 +141,7 @@ MBRWithin(g1.g, g2.g) as w, MBRContains(g1.g, g2.g) as c, MBROverlaps(g1.g, g2.g MBREquals(g1.g, g2.g) as e, MBRDisjoint(g1.g, g2.g) as d, ST_Touches(g1.g, g2.g) as t, MBRIntersects(g1.g, g2.g) as i, ST_Crosses(g1.g, g2.g) as r FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second; ---replace_column 10 # +--replace_column 9 # 10 # explain extended SELECT g1.fid as first, g2.fid as second, MBRWithin(g1.g, g2.g) as w, MBRContains(g1.g, g2.g) as c, MBROverlaps(g1.g, g2.g) as o, MBREquals(g1.g, g2.g) as e, MBRDisjoint(g1.g, g2.g) as d, ST_Touches(g1.g, g2.g) as t, diff --git a/mysql-test/suite/innodb_gis/t/geometry.test b/mysql-test/suite/innodb_gis/t/geometry.test index 3efc664fbd293..4e8f0f729b538 100644 --- a/mysql-test/suite/innodb_gis/t/geometry.test +++ b/mysql-test/suite/innodb_gis/t/geometry.test @@ -14,6 +14,8 @@ SET default_storage_engine=InnoDB; SET innodb_strict_mode=OFF; +SET @save_innodb_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; # # Spatial objects @@ -132,55 +134,55 @@ CREATE INDEX idx3 on tab(c3(5) ASC) USING BTREE; CREATE UNIQUE INDEX idx2 on tab(c8(5) ASC) ; --echo #check equality predicate on the index columns ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab WHERE c2=ST_LineFromText('LINESTRING(10 10,20 20,30 30)'); --echo #check index with WKB function ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab WHERE c2=ST_LineStringFromWKB(ST_AsWKB(ST_LineFromText('LINESTRING(10 10,20 20,30 30)'))); --echo #check index with WKT function ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab WHERE c3=ST_PolyFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'); --echo #check index with WKB function ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab WHERE c3=ST_PolyFromWKB(ST_AsWkB(ST_PolyFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'))); --echo #check index with WKT function ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab WHERE c8=ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'); --echo #check index with WKB function ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab WHERE c8=ST_GeometryFromWKB(ST_AsWKB(ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'))); #--echo #check range predicate on the index columns -#--replace_column 10 # +#--replace_column 9 # #--error ER_WRONG_ARGUMENTS #EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab #WHERE c2>=ST_LineFromText('LINESTRING(10 10,20 20,30 30)'); # -#--replace_column 10 # +#--replace_column 9 # #--error ER_WRONG_ARGUMENTS #EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab #WHERE c3>=ST_PolyFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'); # -#--replace_column 10 # +#--replace_column 9 # #--error ER_WRONG_ARGUMENTS #EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab #WHERE c8>=ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'); --echo #check index with DELETE operation ---replace_column 10 # +--replace_column 9 # EXPLAIN DELETE FROM tab WHERE c8=ST_GeometryFromWKB(ST_AsWKB(ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'))); @@ -487,55 +489,55 @@ CREATE UNIQUE INDEX idx2 on tab3(c8(5) ASC) ; --enable_warnings --echo #check equality predicate on the index columns ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c2=ST_LineFromText('LINESTRING(10 10,20 20,30 30)'); --echo #check index with WKB function ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c2=ST_LineStringFromWKB(ST_AsWKB(ST_LineFromText('LINESTRING(10 10,20 20,30 30)'))); --echo #check index with WKT function ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c3=ST_PolyFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'); --echo #check index with WKB function ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c3=ST_PolyFromWKB(ST_AsWkB(ST_PolyFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'))); --echo #check index with WKT function ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c8=ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'); --echo #check index with WKB function ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c8=ST_GeometryFromWKB(ST_AsWKB(ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'))); # --echo #check range predicate on the index columns -# --replace_column 10 # +# --replace_column 9 # # --error ER_WRONG_ARGUMENTS # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 # WHERE c2>=ST_LineFromText('LINESTRING(10 10,20 20,30 30)'); # -# --replace_column 10 # +# --replace_column 9 # # --error ER_WRONG_ARGUMENTS # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 # WHERE c3>=ST_PolyFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'); -# --replace_column 10 # +# --replace_column 9 # # --error ER_WRONG_ARGUMENTS # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 # WHERE c8>=ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'); --echo #check index with DELETE operation ---replace_column 10 # +--replace_column 9 # EXPLAIN DELETE FROM tab3 WHERE c8=ST_GeometryFromWKB(ST_AsWKB(ST_GeomCollFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'))); @@ -559,12 +561,12 @@ ALTER TABLE tab3 ROW_FORMAT=Dynamic; SHOW CREATE TABLE tab3; --echo #check index with WKB function ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c2=ST_LineStringFromWKB(ST_AsWKB(ST_LineFromText('LINESTRING(10 10,20 20,30 30)'))); --echo #check index with WKT function ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_ASText(c1),ST_AsText(c2),ST_AsText(c8) FROM tab3 WHERE c3=ST_PolyFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'); @@ -575,13 +577,13 @@ SELECT fid, ST_Dimension(g) FROM gis_geometry; SELECT fid, ST_GeometryType(g) FROM gis_geometry; SELECT fid, ST_IsEmpty(g) FROM gis_geometry; SELECT fid, ST_AsText(ST_Envelope(g)) FROM gis_geometry; ---replace_column 10 # +--replace_column 9 # explain extended select ST_Dimension(g), ST_GeometryType(g), ST_IsEmpty(g), ST_AsText(ST_Envelope(g)) from gis_geometry; --echo #check Geometry point functions SELECT fid, ST_X(g) FROM gis_point; SELECT fid, ST_Y(g) FROM gis_point; ---replace_column 10 # +--replace_column 9 # explain extended select ST_X(g),ST_Y(g) FROM gis_point; SELECT fid, ST_AsText(ST_StartPoint(g)) FROM gis_line; @@ -590,7 +592,7 @@ SELECT fid, ST_Length(g) FROM gis_line; SELECT fid, ST_NumPoints(g) FROM gis_line; SELECT fid, ST_AsText(ST_PointN(g, 2)) FROM gis_line; SELECT fid, ST_IsClosed(g) FROM gis_line; ---replace_column 10 # +--replace_column 9 # explain extended select ST_AsText(ST_StartPoint(g)),ST_AsText(ST_EndPoint(g)), ST_Length(g),ST_NumPoints(g),ST_AsText(ST_PointN(g, 2)),ST_IsClosed(g) FROM gis_line; @@ -599,7 +601,7 @@ SELECT fid, ST_Area(g) FROM gis_polygon; SELECT fid, ST_AsText(ST_ExteriorRing(g)) FROM gis_polygon; SELECT fid, ST_NumInteriorRings(g) FROM gis_polygon; SELECT fid, ST_AsText(ST_InteriorRingN(g, 1)) FROM gis_polygon; ---replace_column 10 # +--replace_column 9 # explain extended select ST_AsText(ST_Centroid(g)),ST_Area(g),ST_AsText(ST_ExteriorRing(g)), ST_NumInteriorRings(g),ST_AsText(ST_InteriorRingN(g, 1)) FROM gis_polygon; @@ -612,7 +614,7 @@ SELECT fid, ST_NumGeometries(g) from gis_multi_point; SELECT fid, ST_NumGeometries(g) from gis_multi_line; SELECT fid, ST_NumGeometries(g) from gis_multi_polygon; SELECT fid, ST_NumGeometries(g) from gis_geometrycollection; ---replace_column 10 # +--replace_column 9 # explain extended SELECT fid, ST_NumGeometries(g) from gis_multi_point; SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_point; @@ -620,7 +622,7 @@ SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_line; SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_polygon; SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_geometrycollection; SELECT fid, ST_AsText(ST_GeometryN(g, 1)) from gis_geometrycollection; ---replace_column 10 # +--replace_column 9 # explain extended SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_point; SELECT g1.fid as first, g2.fid as second, @@ -628,7 +630,7 @@ MBRWithin(g1.g, g2.g) as w, MBRContains(g1.g, g2.g) as c, MBROverlaps(g1.g, g2.g MBREquals(g1.g, g2.g) as e, MBRDisjoint(g1.g, g2.g) as d, ST_Touches(g1.g, g2.g) as t, MBRIntersects(g1.g, g2.g) as i, ST_Crosses(g1.g, g2.g) as r FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second; ---replace_column 10 # +--replace_column 9 # explain extended SELECT g1.fid as first, g2.fid as second, MBRWithin(g1.g, g2.g) as w, MBRContains(g1.g, g2.g) as c, MBROverlaps(g1.g, g2.g) as o, MBREquals(g1.g, g2.g) as e, MBRDisjoint(g1.g, g2.g) as d, ST_Touches(g1.g, g2.g) as t, @@ -680,3 +682,5 @@ DROP TABLE tab,tab2,tab3,parent; DROP PROCEDURE geominout; DROP PROCEDURE geom_insert; DROP PROCEDURE geom_cursor; + +SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent; diff --git a/mysql-test/suite/innodb_gis/t/gis.test b/mysql-test/suite/innodb_gis/t/gis.test index 2963c033d80ec..966aea7bc7737 100644 --- a/mysql-test/suite/innodb_gis/t/gis.test +++ b/mysql-test/suite/innodb_gis/t/gis.test @@ -5,15 +5,13 @@ --source include/have_sequence.inc SET default_storage_engine=InnoDB; +SET @save_innodb_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; # # Spatial objects # ---disable_warnings -DROP TABLE IF EXISTS t1, gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry; ---enable_warnings - CREATE TABLE gis_point (fid INTEGER NOT NULL PRIMARY KEY, g POINT); CREATE TABLE gis_line (fid INTEGER NOT NULL PRIMARY KEY, g LINESTRING); CREATE TABLE gis_polygon (fid INTEGER NOT NULL PRIMARY KEY, g POLYGON); @@ -90,12 +88,12 @@ SELECT fid, ST_Dimension(g) FROM gis_geometry; SELECT fid, ST_GeometryType(g) FROM gis_geometry; SELECT fid, ST_IsEmpty(g) FROM gis_geometry; SELECT fid, ST_AsText(ST_Envelope(g)) FROM gis_geometry; ---replace_column 10 # +--replace_column 9 # explain extended select ST_Dimension(g), ST_GeometryType(g), ST_IsEmpty(g), ST_AsText(ST_Envelope(g)) from gis_geometry; SELECT fid, ST_X(g) FROM gis_point; SELECT fid, ST_Y(g) FROM gis_point; ---replace_column 10 # +--replace_column 9 # explain extended select ST_X(g),ST_Y(g) FROM gis_point; SELECT fid, ST_AsText(ST_StartPoint(g)) FROM gis_line; @@ -104,7 +102,7 @@ SELECT fid, ST_Length(g) FROM gis_line; SELECT fid, ST_NumPoints(g) FROM gis_line; SELECT fid, ST_AsText(ST_PointN(g, 2)) FROM gis_line; SELECT fid, ST_IsClosed(g) FROM gis_line; ---replace_column 10 # +--replace_column 9 # explain extended select ST_AsText(ST_StartPoint(g)),ST_AsText(ST_EndPoint(g)),ST_Length(g),ST_NumPoints(g),ST_AsText(ST_PointN(g, 2)),ST_IsClosed(g) FROM gis_line; SELECT fid, ST_AsText(ST_Centroid(g)) FROM gis_polygon; @@ -112,7 +110,7 @@ SELECT fid, ST_Area(g) FROM gis_polygon; SELECT fid, ST_AsText(ST_ExteriorRing(g)) FROM gis_polygon; SELECT fid, ST_NumInteriorRings(g) FROM gis_polygon; SELECT fid, ST_AsText(ST_InteriorRingN(g, 1)) FROM gis_polygon; ---replace_column 10 # +--replace_column 9 # explain extended select ST_AsText(ST_Centroid(g)),ST_Area(g),ST_AsText(ST_ExteriorRing(g)),ST_NumInteriorRings(g),ST_AsText(ST_InteriorRingN(g, 1)) FROM gis_polygon; SELECT fid, ST_IsClosed(g) FROM gis_multi_line; @@ -124,7 +122,7 @@ SELECT fid, ST_NumGeometries(g) from gis_multi_point; SELECT fid, ST_NumGeometries(g) from gis_multi_line; SELECT fid, ST_NumGeometries(g) from gis_multi_polygon; SELECT fid, ST_NumGeometries(g) from gis_geometrycollection; ---replace_column 10 # +--replace_column 9 # explain extended SELECT fid, ST_NumGeometries(g) from gis_multi_point; SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_point; @@ -132,7 +130,7 @@ SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_line; SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_polygon; SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_geometrycollection; SELECT fid, ST_AsText(ST_GeometryN(g, 1)) from gis_geometrycollection; ---replace_column 10 # +--replace_column 9 # explain extended SELECT fid, ST_AsText(ST_GeometryN(g, 2)) from gis_multi_point; SELECT g1.fid as first, g2.fid as second, @@ -140,7 +138,7 @@ MBRWithin(g1.g, g2.g) as w, MBRContains(g1.g, g2.g) as c, MBROverlaps(g1.g, g2.g MBREquals(g1.g, g2.g) as e, MBRDisjoint(g1.g, g2.g) as d, ST_Touches(g1.g, g2.g) as t, MBRIntersects(g1.g, g2.g) as i, ST_Crosses(g1.g, g2.g) as r FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second; ---replace_column 10 # +--replace_column 9 # explain extended SELECT g1.fid as first, g2.fid as second, MBRWithin(g1.g, g2.g) as w, MBRContains(g1.g, g2.g) as c, MBROverlaps(g1.g, g2.g) as o, MBREquals(g1.g, g2.g) as e, MBRDisjoint(g1.g, g2.g) as d, ST_Touches(g1.g, g2.g) as t, @@ -1443,3 +1441,5 @@ SELECT COUNT(*) FROM t1 WHERE MBRIntersects(GeomFromText('Polygon((0 0,0 10,10 1 DROP TABLE t1; DROP DATABASE gis_ogs; + +SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent; diff --git a/mysql-test/suite/innodb_gis/t/point_basic.test b/mysql-test/suite/innodb_gis/t/point_basic.test index 3ab1ab5c9023b..f6bc6d234a726 100644 --- a/mysql-test/suite/innodb_gis/t/point_basic.test +++ b/mysql-test/suite/innodb_gis/t/point_basic.test @@ -31,7 +31,7 @@ INSERT INTO gis_point VALUES (ST_PointFromText('POINT(100.32374832 101.23741821)'), ST_PointFromText('POINT(200.32247328 101.86728201)')), (ST_PointFromText('POINT(100.32374832 101.23741821)'), ST_PointFromText('POINT(100.32374832 101.98527111)')); ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_AsText(p1), ST_AsText(p2) FROM gis_point GROUP BY p1, p2; SELECT ST_AsText(p1), ST_AsText(p2) FROM gis_point GROUP BY p1, p2; @@ -196,7 +196,7 @@ DROP TABLE t1; --echo # --echo # Test when the POINT is on B-TREE --echo # -CREATE TABLE gis_point(fid INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, p POINT, KEY(p)) ENGINE=InnoDB; +CREATE TABLE gis_point(fid INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, p POINT, KEY(p)) ENGINE=InnoDB STATS_PERSISTENT=0; INSERT INTO gis_point VALUES (101, ST_PointFromText('POINT(10 10)')), @@ -216,7 +216,7 @@ INSERT INTO gis_point VALUES (206, ST_PointFromWKB(ST_AsWKB(ST_PointFromText('POINT(103.43718640 105.248206478)')))); -- echo 'The ORDER BY will use filesort' ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_AsText(p) FROM gis_point ORDER BY p; SELECT ST_AsText(p) FROM gis_point ORDER BY p; @@ -640,7 +640,7 @@ ALTER TABLE gis_point ENGINE InnoDB; CHECK TABLE gis_point; -- echo The ORDER BY for spatial index will use filesort ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_AsText(p1), ST_AsText(p2) FROM gis_point ORDER BY p1, p2; SELECT ST_AsText(p1), ST_AsText(p2) FROM gis_point ORDER BY p1, p2; @@ -766,7 +766,7 @@ ST_GeomFromText('POLYGON((10 30, 30 40, 40 50, 40 30, 30 20, 10 30))')); SELECT a, ST_AsText(p), ST_AsText(l), ST_AsText(g) FROM t1; ---replace_column 10 # +--replace_column 9 # EXPLAIN UPDATE t1 SET p = ST_GeomFromText('POINT(30 30)') WHERE p = ST_GeomFromText('POINT(20 20)'); UPDATE t1 SET p = ST_GeomFromText('POINT(30 30)') WHERE p = ST_GeomFromText('POINT(20 20)'); @@ -807,7 +807,7 @@ SELECT a, ST_AsText(p), ST_AsText(l), ST_AsText(g) FROM t1; ALTER TABLE t1 DROP PRIMARY KEY; ALTER TABLE t1 ADD PRIMARY KEY(p); ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT a, ST_AsText(p) FROM t1 WHERE a = 2 AND p = ST_GeomFromText('POINT(30 30)'); SELECT a, ST_AsText(p) FROM t1 WHERE a = 2 AND p = ST_GeomFromText('POINT(30 30)'); diff --git a/mysql-test/suite/innodb_gis/t/point_big.test b/mysql-test/suite/innodb_gis/t/point_big.test index d9a00474d89d1..d46fc5d913946 100644 --- a/mysql-test/suite/innodb_gis/t/point_big.test +++ b/mysql-test/suite/innodb_gis/t/point_big.test @@ -145,7 +145,7 @@ INSERT INTO gis_point VALUES (ST_PointFromText('POINT(32.1234 64.2468)'), ST_PointFromText('POINT(-1 -1)')); -- echo 'The ORDER BY for spatial index will use filesort' ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_AsText(p1), ST_AsText(p2) FROM gis_point ORDER BY p1, p2; SELECT ST_AsText(p1), ST_AsText(p2) FROM gis_point ORDER BY p1, p2; diff --git a/mysql-test/suite/innodb_gis/t/rt_precise.test b/mysql-test/suite/innodb_gis/t/rt_precise.test index 8049ff02ff153..2f155814eb6d4 100644 --- a/mysql-test/suite/innodb_gis/t/rt_precise.test +++ b/mysql-test/suite/innodb_gis/t/rt_precise.test @@ -37,7 +37,7 @@ SELECT count(*) FROM t1; ANALYZE TABLE t1; ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT fid, ST_AsText(g) FROM t1 WHERE ST_Within(g, ST_GeomFromText('Polygon((140 140,160 140,160 160,140 140))')); SELECT fid, ST_AsText(g) FROM t1 WHERE ST_Within(g, ST_GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))')) ORDER BY fid; diff --git a/mysql-test/suite/innodb_gis/t/types.test b/mysql-test/suite/innodb_gis/t/types.test index 0db836b94ba8d..1303e4c487ba8 100644 --- a/mysql-test/suite/innodb_gis/t/types.test +++ b/mysql-test/suite/innodb_gis/t/types.test @@ -48,7 +48,7 @@ SELECT ST_AsText(g) FROM t_wl6455; CREATE INDEX i_p ON t_wl6455 (g(10)); # Select on prefix index. ---replace_column 10 # +--replace_column 9 # EXPLAIN SELECT ST_AsText(g) FROM t_wl6455 WHERE g = POINT(2,2); SELECT ST_AsText(g) FROM t_wl6455 WHERE g = POINT(2,2); diff --git a/mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result b/mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result index 7221358efee50..4c36f9d38720f 100644 --- a/mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result +++ b/mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result @@ -8,6 +8,7 @@ call mtr.add_suppression("InnoDB: Operating system error number"); call mtr.add_suppression("InnoDB: The error means"); call mtr.add_suppression("InnoDB: Cannot open datafile .*t1\\.ibd"); call mtr.add_suppression("InnoDB: Ignoring tablespace for test/t1 "); +call mtr.add_suppression("InnoDB: Cannot save statistics for table `test`\\.`t1` because the \\.ibd file is missing"); FLUSH TABLES; SET SESSION innodb_strict_mode=1; CREATE TABLE t1 (c1 INT) ENGINE = Innodb diff --git a/mysql-test/suite/innodb_zip/r/wl5522_zip.result b/mysql-test/suite/innodb_zip/r/wl5522_zip.result index c0fddf7e8ed36..4d6d23a3bff07 100644 --- a/mysql-test/suite/innodb_zip/r/wl5522_zip.result +++ b/mysql-test/suite/innodb_zip/r/wl5522_zip.result @@ -1,4 +1,5 @@ call mtr.add_suppression("InnoDB: Unable to import tablespace .* because it already exists. Please DISCARD the tablespace before IMPORT\\."); +call mtr.add_suppression("InnoDB: Cannot save statistics for table `test`\\.`t1` because the \\.ibd file is missing"); SET SESSION innodb_strict_mode=1; CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, diff --git a/mysql-test/suite/innodb_zip/r/wl6344_compress_level.result b/mysql-test/suite/innodb_zip/r/wl6344_compress_level.result index b33d9c0c8dea2..3798d0679db36 100644 --- a/mysql-test/suite/innodb_zip/r/wl6344_compress_level.result +++ b/mysql-test/suite/innodb_zip/r/wl6344_compress_level.result @@ -1,4 +1,5 @@ -SET GLOBAL Innodb_file_per_table=on; +SET @save_innodb_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; SET @save_innodb_compression_level = @@global.innodb_compression_level; SET global innodb_compression_level=0; #create table with 1K block size @@ -107,3 +108,4 @@ SELECT @size >= 0; 1 DROP TABLE tab5, tab6; SET GLOBAL innodb_compression_level = @save_innodb_compression_level; +SET GLOBAL innodb_stats_persistent = @save_innodb_stats_persistent; diff --git a/mysql-test/suite/innodb_zip/t/wl5522_debug_zip.test b/mysql-test/suite/innodb_zip/t/wl5522_debug_zip.test index 42f76a78ed95b..1f2b00610ce1e 100644 --- a/mysql-test/suite/innodb_zip/t/wl5522_debug_zip.test +++ b/mysql-test/suite/innodb_zip/t/wl5522_debug_zip.test @@ -24,6 +24,7 @@ call mtr.add_suppression("InnoDB: Operating system error number"); call mtr.add_suppression("InnoDB: The error means"); call mtr.add_suppression("InnoDB: Cannot open datafile .*t1\\.ibd"); call mtr.add_suppression("InnoDB: Ignoring tablespace for test/t1 "); +call mtr.add_suppression("InnoDB: Cannot save statistics for table `test`\\.`t1` because the \\.ibd file is missing"); FLUSH TABLES; let MYSQLD_DATADIR =`SELECT @@datadir`; diff --git a/mysql-test/suite/innodb_zip/t/wl5522_zip.test b/mysql-test/suite/innodb_zip/t/wl5522_zip.test index d5e6bc6e725ef..dbb698cc545f3 100644 --- a/mysql-test/suite/innodb_zip/t/wl5522_zip.test +++ b/mysql-test/suite/innodb_zip/t/wl5522_zip.test @@ -5,6 +5,7 @@ -- source include/have_sequence.inc call mtr.add_suppression("InnoDB: Unable to import tablespace .* because it already exists. Please DISCARD the tablespace before IMPORT\\."); +call mtr.add_suppression("InnoDB: Cannot save statistics for table `test`\\.`t1` because the \\.ibd file is missing"); SET SESSION innodb_strict_mode=1; diff --git a/mysql-test/suite/innodb_zip/t/wl6344_compress_level.test b/mysql-test/suite/innodb_zip/t/wl6344_compress_level.test index 690efffed56ee..f0ddb35aa4a72 100644 --- a/mysql-test/suite/innodb_zip/t/wl6344_compress_level.test +++ b/mysql-test/suite/innodb_zip/t/wl6344_compress_level.test @@ -11,9 +11,9 @@ #******************************************************************* --source include/innodb_page_size_small.inc -SET GLOBAL Innodb_file_per_table=on; +SET @save_innodb_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; SET @save_innodb_compression_level = @@global.innodb_compression_level; - SET global innodb_compression_level=0; -- echo #create table with 1K block size @@ -106,3 +106,4 @@ SELECT @size >= 0; DROP TABLE tab5, tab6; SET GLOBAL innodb_compression_level = @save_innodb_compression_level; +SET GLOBAL innodb_stats_persistent = @save_innodb_stats_persistent; diff --git a/mysql-test/suite/parts/r/longname.result b/mysql-test/suite/parts/r/longname.result index 1b8f823c98f62..a54de1e295dfc 100644 --- a/mysql-test/suite/parts/r/longname.result +++ b/mysql-test/suite/parts/r/longname.result @@ -14,6 +14,10 @@ PARTITION test_jfg_partition_name_with_60_chars_1234567890123456789012 VALUES LE PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = InnoDB); select database_name, table_name, length(table_name) from mysql.innodb_table_stats where database_name = 'mysqltest1'; database_name table_name length(table_name) +mysqltest1 test_jfg_table_name_with_64_chars_123456789012345678901234567890#P#pmax#SP#pmaxsp0 82 +mysqltest1 test_jfg_table_name_with_64_chars_123456789012345678901234567890#P#pmax#SP#pmaxsp1 82 +mysqltest1 test_jfg_table_name_with_64_chars_123456789012345678901234567890#P#test_jfg_partition_name_with_60_chars_1234567890123456789012#SP#test_jfg_partition_name_with_60_chars_1234567890123456789012sp0 194 +mysqltest1 test_jfg_table_name_with_64_chars_123456789012345678901234567890#P#test_jfg_partition_name_with_60_chars_1234567890123456789012#SP#test_jfg_partition_name_with_60_chars_1234567890123456789012sp1 194 CREATE TABLE mysqltest1.éééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééé ( id int(10) unsigned NOT NULL, id2 int(10) unsigned NOT NULL, diff --git a/mysql-test/suite/parts/r/partition_alter1_2_innodb.result b/mysql-test/suite/parts/r/partition_alter1_2_innodb.result index 3f720024f729b..a71cae0ca17f4 100644 --- a/mysql-test/suite/parts/r/partition_alter1_2_innodb.result +++ b/mysql-test/suite/parts/r/partition_alter1_2_innodb.result @@ -1,4 +1,6 @@ SET @max_row = 20; +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; SET @@session.default_storage_engine = 'InnoDB'; #------------------------------------------------------------------------ @@ -36634,3 +36636,4 @@ DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t0_aux; DROP TABLE IF EXISTS t0_definition; DROP TABLE IF EXISTS t0_template; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/suite/parts/r/partition_alter3_innodb.result b/mysql-test/suite/parts/r/partition_alter3_innodb.result index a859f8200c001..66531c2b699a4 100644 --- a/mysql-test/suite/parts/r/partition_alter3_innodb.result +++ b/mysql-test/suite/parts/r/partition_alter3_innodb.result @@ -1,4 +1,6 @@ SET @max_row = 20; +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; SET @@session.default_storage_engine = 'InnoDB'; #------------------------------------------------------------------------ @@ -808,3 +810,4 @@ DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t0_aux; DROP TABLE IF EXISTS t0_definition; DROP TABLE IF EXISTS t0_template; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/suite/parts/r/partition_debug_sync_innodb.result b/mysql-test/suite/parts/r/partition_debug_sync_innodb.result index 4841c93e29fe8..7388eb73ea809 100644 --- a/mysql-test/suite/parts/r/partition_debug_sync_innodb.result +++ b/mysql-test/suite/parts/r/partition_debug_sync_innodb.result @@ -36,7 +36,7 @@ DROP TABLE t1; # Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with # concurrent I_S query create table t1 (a int) -engine = innodb +engine = innodb stats_persistent=0 partition by range (a) (partition p0 values less than MAXVALUE); insert into t1 values (1), (11), (21), (33); @@ -50,7 +50,7 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 +) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=0 PARTITION BY RANGE (`a`) (PARTITION `p0` VALUES LESS THAN MAXVALUE ENGINE = InnoDB) db.opt @@ -89,7 +89,7 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 +) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=0 PARTITION BY RANGE (`a`) (PARTITION `p0` VALUES LESS THAN (10) ENGINE = InnoDB, PARTITION `p10` VALUES LESS THAN MAXVALUE ENGINE = InnoDB) diff --git a/mysql-test/suite/parts/t/partition_alter1_2_innodb.test b/mysql-test/suite/parts/t/partition_alter1_2_innodb.test index 71f9d33c72b20..5293e547dbf4c 100644 --- a/mysql-test/suite/parts/t/partition_alter1_2_innodb.test +++ b/mysql-test/suite/parts/t/partition_alter1_2_innodb.test @@ -71,6 +71,9 @@ let $do_pk_tests= 1; # and smaller than the maximum value of SIGNED INTEGER let $MAX_VALUE= (2147483646); +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; + # Generate the prerequisites ($variables, @variables, tables) needed --source suite/parts/inc/partition.pre @@ -87,3 +90,5 @@ let $MAX_VALUE= (2147483646); #------------------------------------------------------------------------------# # Cleanup --source suite/parts/inc/partition_cleanup.inc + +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/suite/parts/t/partition_alter3_innodb.test b/mysql-test/suite/parts/t/partition_alter3_innodb.test index c63cf00bc533d..d86c0e1122d90 100644 --- a/mysql-test/suite/parts/t/partition_alter3_innodb.test +++ b/mysql-test/suite/parts/t/partition_alter3_innodb.test @@ -63,6 +63,9 @@ let $do_pk_tests= 1; # and smaller than the maximum value of SIGNED INTEGER let $MAX_VALUE= (2147483646); +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; + # Generate the prerequisites ($variables, @variables, tables) needed --source suite/parts/inc/partition.pre @@ -79,3 +82,5 @@ let $MAX_VALUE= (2147483646); #------------------------------------------------------------------------------# # Cleanup --source suite/parts/inc/partition_cleanup.inc + +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/suite/parts/t/partition_debug_sync_innodb.test b/mysql-test/suite/parts/t/partition_debug_sync_innodb.test index d73333c3b8dff..9d2557a64e6c1 100644 --- a/mysql-test/suite/parts/t/partition_debug_sync_innodb.test +++ b/mysql-test/suite/parts/t/partition_debug_sync_innodb.test @@ -45,7 +45,7 @@ DROP TABLE t1; --echo # Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with --echo # concurrent I_S query create table t1 (a int) -engine = innodb +engine = innodb stats_persistent=0 partition by range (a) (partition p0 values less than MAXVALUE); insert into t1 values (1), (11), (21), (33); diff --git a/mysql-test/suite/sys_vars/r/innodb_stats_persistent_basic.result b/mysql-test/suite/sys_vars/r/innodb_stats_persistent_basic.result index 94de032a0fd8f..c7dccdd2398ae 100644 --- a/mysql-test/suite/sys_vars/r/innodb_stats_persistent_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_stats_persistent_basic.result @@ -1,6 +1,7 @@ +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; SELECT @@innodb_stats_persistent; @@innodb_stats_persistent -0 +1 SET GLOBAL innodb_stats_persistent=ON; SELECT @@innodb_stats_persistent; @@innodb_stats_persistent @@ -21,4 +22,4 @@ SET GLOBAL innodb_stats_persistent=123; ERROR 42000: Variable 'innodb_stats_persistent' can't be set to the value of '123' SET GLOBAL innodb_stats_persistent='foo'; ERROR 42000: Variable 'innodb_stats_persistent' can't be set to the value of 'foo' -SET GLOBAL innodb_stats_persistent=OFF; +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/suite/sys_vars/t/innodb_stats_persistent_basic.test b/mysql-test/suite/sys_vars/t/innodb_stats_persistent_basic.test index c5f977321b728..e1b650184ac89 100644 --- a/mysql-test/suite/sys_vars/t/innodb_stats_persistent_basic.test +++ b/mysql-test/suite/sys_vars/t/innodb_stats_persistent_basic.test @@ -4,6 +4,7 @@ -- source include/have_innodb.inc +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; # show the default value SELECT @@innodb_stats_persistent; @@ -28,4 +29,4 @@ SET GLOBAL innodb_stats_persistent=123; SET GLOBAL innodb_stats_persistent='foo'; # restore the environment -SET GLOBAL innodb_stats_persistent=OFF; \ No newline at end of file +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/suite/vcol/r/vcol_select_innodb.result b/mysql-test/suite/vcol/r/vcol_select_innodb.result index e275a66091cf5..40308b6e072b1 100644 --- a/mysql-test/suite/vcol/r/vcol_select_innodb.result +++ b/mysql-test/suite/vcol/r/vcol_select_innodb.result @@ -1,4 +1,6 @@ SET @@session.default_storage_engine = 'InnoDB'; +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; create table t1 (a int, b int as (-a), c int as (-a) persistent, @@ -265,3 +267,4 @@ NULL explain select sum(c) from t1 group by b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; diff --git a/mysql-test/suite/vcol/r/vcol_view_innodb.result b/mysql-test/suite/vcol/r/vcol_view_innodb.result index e6895243371ba..53ef6e0709c59 100644 --- a/mysql-test/suite/vcol/r/vcol_view_innodb.result +++ b/mysql-test/suite/vcol/r/vcol_view_innodb.result @@ -1,4 +1,6 @@ SET @@session.default_storage_engine = 'InnoDB'; +SET @save_innodb_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; create table t1 (a int not null, b int as (-a), c int as (-a) persistent); @@ -281,3 +283,4 @@ a b c 0 0 0 drop view v1; drop table t1; +SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent; diff --git a/mysql-test/suite/vcol/t/vcol_select_innodb.test b/mysql-test/suite/vcol/t/vcol_select_innodb.test index 606801a213aa5..5b04096a5a550 100644 --- a/mysql-test/suite/vcol/t/vcol_select_innodb.test +++ b/mysql-test/suite/vcol/t/vcol_select_innodb.test @@ -36,6 +36,8 @@ # Set the session storage engine --source include/have_innodb.inc eval SET @@session.default_storage_engine = 'InnoDB'; +SET @save_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; ##### Workarounds for known open engine specific bugs # none @@ -47,6 +49,8 @@ eval SET @@session.default_storage_engine = 'InnoDB'; #------------------------------------------------------------------------------# # Execute storage engine specific tests +SET GLOBAL innodb_stats_persistent=@save_stats_persistent; + #------------------------------------------------------------------------------# # Cleanup --source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/vcol/t/vcol_view_innodb.test b/mysql-test/suite/vcol/t/vcol_view_innodb.test index fd77489f5dcaa..3b869425ecb23 100644 --- a/mysql-test/suite/vcol/t/vcol_view_innodb.test +++ b/mysql-test/suite/vcol/t/vcol_view_innodb.test @@ -35,6 +35,8 @@ # Set the session storage engine --source include/have_innodb.inc eval SET @@session.default_storage_engine = 'InnoDB'; +SET @save_innodb_stats_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; ##### Workarounds for known open engine specific bugs # none @@ -46,6 +48,8 @@ eval SET @@session.default_storage_engine = 'InnoDB'; #------------------------------------------------------------------------------# # Execute storage engine specific tests +SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent; + #------------------------------------------------------------------------------# # Cleanup --source suite/vcol/inc/vcol_cleanup.inc diff --git a/mysql-test/suite/versioning/r/cte.result b/mysql-test/suite/versioning/r/cte.result index 4c0867d579b20..6ca9c238d45e0 100644 --- a/mysql-test/suite/versioning/r/cte.result +++ b/mysql-test/suite/versioning/r/cte.result @@ -1,3 +1,5 @@ +SET @saved_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; set time_zone="+00:00"; set default_storage_engine=innodb; create or replace table dept ( @@ -311,3 +313,4 @@ emp_id name mgr address drop table emp; drop table dept; drop table addr; +SET GLOBAL innodb_stats_persistent = @saved_stats_persistent; diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index d6e6d827ddcf4..f651d25ce7c7f 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -1,3 +1,5 @@ +SET @save_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; call mtr.add_suppression("need more HISTORY partitions"); set system_versioning_alter_history=keep; # Check conventional partitioning on temporal tables @@ -1281,3 +1283,5 @@ drop tables t1; # # End of 10.5 tests # +SET GLOBAL innodb_stats_persistent=@save_persistent; +# End of 10.6 tests diff --git a/mysql-test/suite/versioning/r/select.result b/mysql-test/suite/versioning/r/select.result index 6df18403ee32f..90c99d1bf0e96 100644 --- a/mysql-test/suite/versioning/r/select.result +++ b/mysql-test/suite/versioning/r/select.result @@ -1,3 +1,5 @@ +SET @saved_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; create or replace table t1 ( x int unsigned, y int unsigned, @@ -705,3 +707,4 @@ No A B C D 32 1 1 1 1 33 1 1 1 1 34 1 1 1 1 +SET GLOBAL innodb_stats_persistent = @saved_stats_persistent; diff --git a/mysql-test/suite/versioning/t/cte.test b/mysql-test/suite/versioning/t/cte.test index 5f2a709eebe94..025e1b2319d60 100644 --- a/mysql-test/suite/versioning/t/cte.test +++ b/mysql-test/suite/versioning/t/cte.test @@ -5,6 +5,9 @@ if (`SELECT $PS_PROTOCOL != 0`) --source include/have_innodb.inc --source include/default_optimizer_switch.inc +SET @saved_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; + set time_zone="+00:00"; set default_storage_engine=innodb; create or replace table dept ( @@ -230,3 +233,5 @@ select * from (select * from emp natural join addr) for system_time all as t; drop table emp; drop table dept; drop table addr; + +SET GLOBAL innodb_stats_persistent = @saved_stats_persistent; diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test index 61cfe702f8a85..044c0d64d37d4 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -2,6 +2,9 @@ -- source suite/versioning/common.inc -- source suite/versioning/engines.inc +SET @save_persistent=@@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=0; + call mtr.add_suppression("need more HISTORY partitions"); --enable_prepare_warnings @@ -1102,4 +1105,8 @@ drop tables t1; --echo # End of 10.5 tests --echo # +SET GLOBAL innodb_stats_persistent=@save_persistent; + +--echo # End of 10.6 tests + --source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/select.test b/mysql-test/suite/versioning/t/select.test index bf27723adeef6..9142a8fae8ab9 100644 --- a/mysql-test/suite/versioning/t/select.test +++ b/mysql-test/suite/versioning/t/select.test @@ -6,6 +6,9 @@ if (`SELECT $PS_PROTOCOL != 0`) --source suite/versioning/common.inc --source include/default_optimizer_switch.inc +SET @saved_stats_persistent = @@GLOBAL.innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent = OFF; + --enable_prepare_warnings # test_01 @@ -482,4 +485,6 @@ drop tables x, x_p; call verify_trt_dummy(34); --disable_prepare_warnings +SET GLOBAL innodb_stats_persistent = @saved_stats_persistent; + -- source suite/versioning/common_finish.inc diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_spatial.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_spatial.result index fa42d4a1fd39f..5c66485da7a30 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_spatial.result +++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/alter_table_spatial.result @@ -114,7 +114,8 @@ VALUES ('hiiragi', ST_GeomFromText('POINT(139.711517 35.647701)')); ALTER TABLE shops ADD SPATIAL KEY location_index (location); SELECT id, name, ST_AsText(location) AS location_text FROM shops -WHERE MBRContains(ST_GeomFromText('LineString(139.7727 35.6684, 139.7038 35.7121)'), location); +WHERE MBRContains(ST_GeomFromText('LineString(139.7727 35.6684, 139.7038 35.7121)'), location) +ORDER BY id; id name location_text 14 tetsuji POINT(139.76857 35.680912) 19 daruma POINT(139.770599 35.681461) diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_spatial.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_spatial.test index 727557f88fa4e..c762b7ff15729 100644 --- a/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_spatial.test +++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/alter_table_spatial.test @@ -142,7 +142,8 @@ INSERT INTO shops (name, location) ALTER TABLE shops ADD SPATIAL KEY location_index (location); SELECT id, name, ST_AsText(location) AS location_text FROM shops - WHERE MBRContains(ST_GeomFromText('LineString(139.7727 35.6684, 139.7038 35.7121)'), location); + WHERE MBRContains(ST_GeomFromText('LineString(139.7727 35.6684, 139.7038 35.7121)'), location) + ORDER BY id; DROP TABLE shops;