From 6d4841ae26a8c62b2645b9a0e9c0a9e44e460354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 8 Jan 2025 13:29:16 +0200 Subject: [PATCH 001/213] =?UTF-8?q?MDEV-35647=20Possible=20hang=20during?= =?UTF-8?q?=20CREATE=20TABLE=E2=80=A6SELECT=20error=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ha_innobase::delete_table(): Clear trx->dict_operation_lock_mode after, not before invoking trx->rollback(), so that row_undo_mod_parse_undo_rec() will be invoked with dict_locked=true and dict_sys_t::freeze() will not be invoked for loading a table definition. Inside dict_sys_t::freeze(), an assertion !have_any() would fail when the current thread is already holding the latch. This fixes up commit c5fd9aa562fb15e8d6ededceccbec0c9792a3243 (MDEV-25919). Reviewed by: Debarun Banerjee --- .../suite/innodb/r/create_select.result | 24 +++++++++++- mysql-test/suite/innodb/t/create_select.test | 38 ++++++++++++++++++- storage/innobase/handler/ha_innodb.cc | 3 +- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/mysql-test/suite/innodb/r/create_select.result b/mysql-test/suite/innodb/r/create_select.result index 183705680bd..e3c130c3ad1 100644 --- a/mysql-test/suite/innodb/r/create_select.result +++ b/mysql-test/suite/innodb/r/create_select.result @@ -3,7 +3,6 @@ connection default; CREATE TABLE t1 ENGINE=InnoDB SELECT * FROM seq_1_to_100000000; connection con1; KILL QUERY @id; -disconnect con1; connection default; ERROR 70100: Query execution was interrupted CREATE TABLE t1 (a SERIAL) ENGINE=InnoDB; @@ -18,3 +17,26 @@ execute stmt; execute stmt; drop table t; # End of 10.5 tests +# +# MDEV-35647 Possible hang during CREATE TABLE…SELECT error handling +# +call mtr.add_suppression("InnoDB: DROP TABLE `test`\\.`t4`: Record changed"); +SET @save_debug= @@GLOBAL.innodb_evict_tables_on_commit_debug; +SET GLOBAL innodb_evict_tables_on_commit_debug=on; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +SET GLOBAL innodb_evict_tables_on_commit_debug=@save_debug; +connection con1; +CREATE TABLE t2 (b BLOB) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1),('2025-01-21 00:00:00'); +SET STATEMENT innodb_snapshot_isolation=ON FOR +CREATE TABLE t3 ENGINE=InnoDB AS SELECT * FROM t1; +connection default; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +SET STATEMENT innodb_snapshot_isolation=ON FOR +CREATE TABLE t4 (b BLOB CHECK (b)) ENGINE=InnoDB AS SELECT b FROM t2; +ERROR 22007: Truncated incorrect DOUBLE value: '2025-01-21 00:00:00' +connection con1; +disconnect con1; +connection default; +DROP TABLE t3,t2,t1; +# End of 10.6 tests diff --git a/mysql-test/suite/innodb/t/create_select.test b/mysql-test/suite/innodb/t/create_select.test index 053db79b8f4..46f793295bf 100644 --- a/mysql-test/suite/innodb/t/create_select.test +++ b/mysql-test/suite/innodb/t/create_select.test @@ -1,6 +1,7 @@ --source include/have_innodb.inc --source include/have_sequence.inc --source include/count_sessions.inc +--source include/maybe_debug.inc let $ID= `SELECT @id := CONNECTION_ID()`; @@ -17,7 +18,6 @@ let $wait_condition= and info = 'CREATE TABLE t1 ENGINE=InnoDB SELECT * FROM seq_1_to_100000000'; --source include/wait_condition.inc KILL QUERY @id; -disconnect con1; connection default; --error ER_QUERY_INTERRUPTED @@ -25,7 +25,6 @@ reap; CREATE TABLE t1 (a SERIAL) ENGINE=InnoDB; DROP TABLE t1; ---source include/wait_until_count_sessions.inc --echo # End of 10.2 tests @@ -39,3 +38,38 @@ execute stmt; drop table t; --echo # End of 10.5 tests + +--echo # +--echo # MDEV-35647 Possible hang during CREATE TABLE…SELECT error handling +--echo # +call mtr.add_suppression("InnoDB: DROP TABLE `test`\\.`t4`: Record changed"); + +--error 0,ER_UNKNOWN_SYSTEM_VARIABLE +SET @save_debug= @@GLOBAL.innodb_evict_tables_on_commit_debug; +--error 0,ER_UNKNOWN_SYSTEM_VARIABLE +SET GLOBAL innodb_evict_tables_on_commit_debug=on; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +--error 0,ER_UNKNOWN_SYSTEM_VARIABLE +SET GLOBAL innodb_evict_tables_on_commit_debug=@save_debug; + +connection con1; +CREATE TABLE t2 (b BLOB) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1),('2025-01-21 00:00:00'); +--send +SET STATEMENT innodb_snapshot_isolation=ON FOR +CREATE TABLE t3 ENGINE=InnoDB AS SELECT * FROM t1; + +connection default; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +--error ER_TRUNCATED_WRONG_VALUE +SET STATEMENT innodb_snapshot_isolation=ON FOR +CREATE TABLE t4 (b BLOB CHECK (b)) ENGINE=InnoDB AS SELECT b FROM t2; +connection con1; +reap; +disconnect con1; +connection default; +DROP TABLE t3,t2,t1; + +--source include/wait_until_count_sessions.inc + +--echo # End of 10.6 tests diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 447d1533b6c..aff63d4f74a 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -13798,7 +13798,6 @@ int ha_innobase::delete_table(const char *name) if (err != DB_SUCCESS) { err_exit: - trx->dict_operation_lock_mode= false; trx->rollback(); switch (err) { case DB_CANNOT_DROP_CONSTRAINT: @@ -13820,7 +13819,7 @@ err_exit: dict_table_close(table_stats, true, thd, mdl_table); if (index_stats) dict_table_close(index_stats, true, thd, mdl_index); - dict_sys.unlock(); + row_mysql_unlock_data_dictionary(trx); if (trx != parent_trx) trx->free(); DBUG_RETURN(convert_error_code_to_mysql(err, 0, NULL)); From 39f93b6eab9ade51de6ce7f68be033378799a232 Mon Sep 17 00:00:00 2001 From: Kristian Nielsen Date: Mon, 21 Oct 2024 16:56:35 +0200 Subject: [PATCH 002/213] MDEV-29744: Fix incorrect locking order of LOCK_log/LOCK_commit_ordered and LOCK_global_system_variables The LOCK_global_system_variables must not be held when taking mutexes such as LOCK_commit_ordered and LOCK_log, as this causes inconsistent mutex locking order that can theoretically cause the server to deadlock. To avoid this, temporarily release LOCK_global_system_variables in two system variable update functions, like it is done in many other places. Enforce the correct locking order at server startup, to more easily catch (in debug builds) any remaining wrong orders that may be hidden elsewhere in the code. Note that when this is merged to 11.4, similar unlock/lock of LOCK_global_system_variables must be added in update_binlog_space_limit() as is done in binlog_checksum_update() and fix_max_binlog_size(), as this is a new function added in 11.4 that also needs the same fix. Tests will fail with wrong mutex order until this is done. Reviewed-by: Sergei Golubchik Signed-off-by: Kristian Nielsen --- sql/log.cc | 5 +++++ sql/sys_vars.cc | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/sql/log.cc b/sql/log.cc index 56450d4a076..8f4f293a3d0 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -3595,6 +3595,9 @@ void MYSQL_BIN_LOG::init_pthread_objects() mysql_mutex_init(m_key_LOCK_binlog_end_pos, &LOCK_binlog_end_pos, MY_MUTEX_INIT_SLOW); + + /* Fix correct mutex order to catch violations quicker (MDEV-35197). */ + mysql_mutex_record_order(&LOCK_log, &LOCK_global_system_variables); } @@ -11753,6 +11756,7 @@ binlog_checksum_update(MYSQL_THD thd, struct st_mysql_sys_var *var, bool check_purge= false; ulong UNINIT_VAR(prev_binlog_id); + mysql_mutex_unlock(&LOCK_global_system_variables); mysql_mutex_lock(mysql_bin_log.get_log_lock()); if(mysql_bin_log.is_open()) { @@ -11771,6 +11775,7 @@ binlog_checksum_update(MYSQL_THD thd, struct st_mysql_sys_var *var, mysql_mutex_unlock(mysql_bin_log.get_log_lock()); if (check_purge) mysql_bin_log.checkpoint_and_purge(prev_binlog_id); + mysql_mutex_lock(&LOCK_global_system_variables); } diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index b9d944ab3ee..19176ba6858 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1660,7 +1660,10 @@ Sys_max_binlog_stmt_cache_size( static bool fix_max_binlog_size(sys_var *self, THD *thd, enum_var_type type) { - mysql_bin_log.set_max_size(max_binlog_size); + ulong saved= max_binlog_size; + mysql_mutex_unlock(&LOCK_global_system_variables); + mysql_bin_log.set_max_size(saved); + mysql_mutex_lock(&LOCK_global_system_variables); return false; } static Sys_var_on_access_global Date: Thu, 26 Dec 2024 17:30:11 +0700 Subject: [PATCH 003/213] MDEV-32411 Item_sum arguments incorrectly reset to temp table fields which causes crash The issue is caused by a logic error in Item_sum::get_tmp_table_item() method: it resets arguments of the item to point to the result fields during change_ref_to_tmp_fields() call. However, Item_sum arguments must not be modified. It is enough for Item_sum objects to call ancestor's implementation Item::get_tmp_table_item(). This fix is in accordance with MySQL commit 2e3dc09087c24798c90e05163ed3d931f6b93db3 Reviewer: Oleksandr Byelkin --- mysql-test/main/win_sum.result | 9 +++++++++ mysql-test/main/win_sum.test | 11 +++++++++++ sql/item_sum.cc | 21 --------------------- sql/item_sum.h | 1 - 4 files changed, 20 insertions(+), 22 deletions(-) diff --git a/mysql-test/main/win_sum.result b/mysql-test/main/win_sum.result index a17c17845af..aa376ecf7ba 100644 --- a/mysql-test/main/win_sum.result +++ b/mysql-test/main/win_sum.result @@ -105,3 +105,12 @@ EXISTS (SELECT 1 ORDER BY 1+sum(2) OVER ()) # # End of 10.4 tests # +# +# MDEV-32411 Item_sum arguments incorrectly reset to temp table fields which causes crash +# +CREATE TABLE t1 (a INT NOT NULL) ; +INSERT INTO t1 VALUES (EXISTS(SELECT avg(3) OVER (ORDER BY COUNT(DISTINCT a, HEX(a))))); +DROP TABLE t1; +# +# End of 10.5 tests +# diff --git a/mysql-test/main/win_sum.test b/mysql-test/main/win_sum.test index 9800174f54c..d3924435949 100644 --- a/mysql-test/main/win_sum.test +++ b/mysql-test/main/win_sum.test @@ -57,3 +57,14 @@ SELECT EXISTS (SELECT 1 ORDER BY 1+sum(2) OVER ()); --echo # --echo # End of 10.4 tests --echo # + +--echo # +--echo # MDEV-32411 Item_sum arguments incorrectly reset to temp table fields which causes crash +--echo # +CREATE TABLE t1 (a INT NOT NULL) ; +INSERT INTO t1 VALUES (EXISTS(SELECT avg(3) OVER (ORDER BY COUNT(DISTINCT a, HEX(a))))); +DROP TABLE t1; + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 3b3661004c1..0acf4595058 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -527,27 +527,6 @@ void Item_sum::fix_num_length_and_dec() max_length=float_length(decimals); } -Item *Item_sum::get_tmp_table_item(THD *thd) -{ - Item_sum* sum_item= (Item_sum *) copy_or_same(thd); - if (sum_item && sum_item->result_field) // If not a const sum func - { - Field *result_field_tmp= sum_item->result_field; - for (uint i=0 ; i < sum_item->arg_count ; i++) - { - Item *arg= sum_item->args[i]; - if (!arg->const_item()) - { - if (arg->type() == Item::FIELD_ITEM) - ((Item_field*) arg)->field= result_field_tmp++; - else - sum_item->args[i]= new (thd->mem_root) Item_temptable_field(thd, result_field_tmp++); - } - } - } - return sum_item; -} - void Item_sum::update_used_tables () { diff --git a/sql/item_sum.h b/sql/item_sum.h index 2ebe0b554fb..56a926c841d 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -521,7 +521,6 @@ public: aggregator_clear(); } virtual void make_unique() { force_copy_fields= TRUE; } - Item *get_tmp_table_item(THD *thd) override; virtual Field *create_tmp_field(MEM_ROOT *root, bool group, TABLE *table); Field *create_tmp_field_ex(MEM_ROOT *root, TABLE *table, Tmp_field_src *src, const Tmp_field_param *param) override From 990b010b0954c6005eaaa1055d69f36a3d56cd99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 9 Jan 2025 07:43:24 +0200 Subject: [PATCH 004/213] MDEV-35438 Annotate InnoDB I/O functions with noexcept Most InnoDB functions do not throw any exceptions, not even indirectly std::bad_alloc, which could be thrown by a C++ memory allocation function. Let us annotate many functions with noexcept in order to reduce the code footprint related to exception handling. Reviewed by: Thirunarayanan Balathandayuthapani --- storage/innobase/btr/btr0sea.cc | 4 +- storage/innobase/buf/buf0buf.cc | 93 ++++--- storage/innobase/buf/buf0dblwr.cc | 60 +++-- storage/innobase/buf/buf0flu.cc | 112 ++++---- storage/innobase/buf/buf0rea.cc | 15 +- storage/innobase/fil/fil0crypt.cc | 6 +- storage/innobase/fil/fil0fil.cc | 190 ++++---------- storage/innobase/handler/ha_innodb.cc | 4 +- storage/innobase/include/buf0buf.h | 355 +++++++++++++------------- storage/innobase/include/buf0dblwr.h | 38 +-- storage/innobase/include/buf0flu.h | 41 ++- storage/innobase/include/buf0rea.h | 10 +- storage/innobase/include/buf0types.h | 86 ++++--- storage/innobase/include/fil0fil.h | 287 ++++++++++----------- storage/innobase/include/os0file.h | 112 ++++---- storage/innobase/log/log0recv.cc | 8 +- storage/innobase/mtr/mtr0mtr.cc | 2 +- storage/innobase/os/os0file.cc | 192 ++++---------- 18 files changed, 730 insertions(+), 885 deletions(-) diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc index 7203809f036..c74b7fdfc3f 100644 --- a/storage/innobase/btr/btr0sea.cc +++ b/storage/innobase/btr/btr0sea.cc @@ -938,7 +938,7 @@ btr_search_failure(btr_search_t* info, btr_cur_t* cursor) } /** Clear the adaptive hash index on all pages in the buffer pool. */ -inline void buf_pool_t::clear_hash_index() +inline void buf_pool_t::clear_hash_index() noexcept { ut_ad(!resizing); ut_ad(!btr_search_enabled); @@ -990,7 +990,7 @@ inline void buf_pool_t::clear_hash_index() This function does not return if the block is not identified. @param ptr pointer to within a page frame @return pointer to block, never NULL */ -inline buf_block_t* buf_pool_t::block_from_ahi(const byte *ptr) const +inline buf_block_t* buf_pool_t::block_from_ahi(const byte *ptr) const noexcept { chunk_t::map *chunk_map = chunk_t::map_ref; ut_ad(chunk_t::map_ref == chunk_t::map_reg); diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 0e4c2c5b0f2..f9388a11d23 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -278,7 +278,7 @@ the read requests for the whole area. #ifndef UNIV_INNOCHECKSUM # ifdef SUX_LOCK_GENERIC -void page_hash_latch::read_lock_wait() +void page_hash_latch::read_lock_wait() noexcept { /* First, try busy spinning for a while. */ for (auto spin= srv_n_spin_wait_rounds; spin--; ) @@ -293,7 +293,7 @@ void page_hash_latch::read_lock_wait() while (!read_trylock()); } -void page_hash_latch::write_lock_wait() +void page_hash_latch::write_lock_wait() noexcept { write_lock_wait_start(); @@ -487,7 +487,7 @@ bool buf_page_is_checksum_valid_crc32( const byte* read_buf, ulint checksum_field1, - ulint checksum_field2) + ulint checksum_field2) noexcept { const uint32_t crc32 = buf_calc_page_crc32(read_buf); @@ -555,7 +555,7 @@ static bool buf_page_check_lsn(bool check_lsn, const byte *read_buf) /** Check if a buffer is all zeroes. @param[in] buf data to check @return whether the buffer is all zeroes */ -bool buf_is_zeroes(span buf) +bool buf_is_zeroes(span buf) noexcept { ut_ad(buf.size() <= UNIV_PAGE_SIZE_MAX); return memcmp(buf.data(), field_ref_zero, buf.size()) == 0; @@ -570,7 +570,7 @@ buf_page_is_corrupted_reason buf_page_is_corrupted( bool check_lsn, const byte* read_buf, - ulint fsp_flags) + ulint fsp_flags) noexcept { if (fil_space_t::full_crc32(fsp_flags)) { bool compressed = false, corrupted = false; @@ -828,7 +828,7 @@ static inline byte hex_to_ascii(byte hex_digit) @param[in] read_buf database page @param[in] zip_size compressed page size, or 0 */ ATTRIBUTE_COLD -void buf_page_print(const byte *read_buf, ulint zip_size) +void buf_page_print(const byte *read_buf, ulint zip_size) noexcept { #ifndef UNIV_DEBUG const size_t size = zip_size ? zip_size : srv_page_size; @@ -887,7 +887,7 @@ buf_block_init(buf_block_t* block, byte* frame) /** Allocate a chunk of buffer frames. @param bytes requested size @return whether the allocation succeeded */ -inline bool buf_pool_t::chunk_t::create(size_t bytes) +inline bool buf_pool_t::chunk_t::create(size_t bytes) noexcept { DBUG_EXECUTE_IF("ib_buf_chunk_init_fails", return false;); /* Round down to a multiple of page size, although it already should be. */ @@ -973,7 +973,7 @@ inline bool buf_pool_t::chunk_t::create(size_t bytes) /** Check that all file pages in the buffer chunk are in a replaceable state. @return address of a non-free block @retval nullptr if all freed */ -inline const buf_block_t *buf_pool_t::chunk_t::not_freed() const +inline const buf_block_t *buf_pool_t::chunk_t::not_freed() const noexcept { buf_block_t *block= blocks; for (auto i= size; i--; block++) @@ -1013,7 +1013,7 @@ inline const buf_block_t *buf_pool_t::chunk_t::not_freed() const /** Create the hash table. @param n the lower bound of n_cells */ -void buf_pool_t::page_hash_table::create(ulint n) +void buf_pool_t::page_hash_table::create(ulint n) noexcept { n_cells= ut_find_prime(n); const size_t size= MY_ALIGN(pad(n_cells) * sizeof *array, @@ -1142,7 +1142,7 @@ bool buf_pool_t::create() } /** Clean up after successful create() */ -void buf_pool_t::close() +void buf_pool_t::close() noexcept { ut_ad(this == &buf_pool); if (!is_initialised()) @@ -1202,7 +1202,7 @@ void buf_pool_t::close() /** Try to reallocate a control block. @param block control block to reallocate @return whether the reallocation succeeded */ -inline bool buf_pool_t::realloc(buf_block_t *block) +inline bool buf_pool_t::realloc(buf_block_t *block) noexcept { buf_block_t* new_block; @@ -1318,7 +1318,7 @@ inline bool buf_pool_t::realloc(buf_block_t *block) return(true); /* free_list was enough */ } -void buf_pool_t::io_buf_t::create(ulint n_slots) +void buf_pool_t::io_buf_t::create(ulint n_slots) noexcept { this->n_slots= n_slots; slots= static_cast @@ -1326,7 +1326,7 @@ void buf_pool_t::io_buf_t::create(ulint n_slots) memset((void*) slots, 0, n_slots * sizeof *slots); } -void buf_pool_t::io_buf_t::close() +void buf_pool_t::io_buf_t::close() noexcept { for (buf_tmp_buffer_t *s= slots, *e= slots + n_slots; s != e; s++) { @@ -1338,7 +1338,7 @@ void buf_pool_t::io_buf_t::close() n_slots= 0; } -buf_tmp_buffer_t *buf_pool_t::io_buf_t::reserve(bool wait_for_reads) +buf_tmp_buffer_t *buf_pool_t::io_buf_t::reserve(bool wait_for_reads) noexcept { for (;;) { @@ -1383,7 +1383,7 @@ buf_resize_status( /** Withdraw blocks from the buffer pool until meeting withdraw_target. @return whether retry is needed */ -inline bool buf_pool_t::withdraw_blocks() +inline bool buf_pool_t::withdraw_blocks() noexcept { buf_block_t* block; ulint loop_count = 0; @@ -1512,7 +1512,7 @@ realloc_frame: -inline void buf_pool_t::page_hash_table::write_lock_all() +inline void buf_pool_t::page_hash_table::write_lock_all() noexcept { for (auto n= pad(n_cells) & ~ELEMENTS_PER_LATCH;; n-= ELEMENTS_PER_LATCH + 1) { @@ -1523,7 +1523,7 @@ inline void buf_pool_t::page_hash_table::write_lock_all() } -inline void buf_pool_t::page_hash_table::write_unlock_all() +inline void buf_pool_t::page_hash_table::write_unlock_all() noexcept { for (auto n= pad(n_cells) & ~ELEMENTS_PER_LATCH;; n-= ELEMENTS_PER_LATCH + 1) { @@ -2016,7 +2016,7 @@ static void buf_relocate(buf_page_t *bpage, buf_page_t *dpage) } buf_page_t *buf_pool_t::watch_set(const page_id_t id, - buf_pool_t::hash_chain &chain) + buf_pool_t::hash_chain &chain) noexcept { ut_ad(&chain == &page_hash.cell_get(id.fold())); page_hash.lock_get(chain).lock(); @@ -2087,6 +2087,7 @@ watch_set(id) must have returned nullptr before. @param chain unlocked hash table chain */ TRANSACTIONAL_TARGET void buf_pool_t::watch_unset(const page_id_t id, buf_pool_t::hash_chain &chain) + noexcept { mysql_mutex_assert_not_owner(&mutex); buf_page_t *w; @@ -2200,7 +2201,7 @@ static void buf_inc_get(ha_handler_stats *stats) } TRANSACTIONAL_TARGET -buf_page_t *buf_page_get_zip(const page_id_t page_id) +buf_page_t *buf_page_get_zip(const page_id_t page_id) noexcept { ha_handler_stats *const stats= mariadb_stats; buf_inc_get(stats); @@ -2310,14 +2311,7 @@ buf_block_init_low( #endif /* BTR_CUR_HASH_ADAPT */ } -/********************************************************************//** -Decompress a block. -@return true if successful */ -bool -buf_zip_decompress( -/*===============*/ - buf_block_t* block, /*!< in/out: block */ - ibool check) /*!< in: TRUE=verify the page checksum */ +bool buf_zip_decompress(buf_block_t *block, bool check) noexcept { const byte* frame = block->page.zip.data; ulint size = page_zip_get_size(&block->page.zip); @@ -2468,6 +2462,7 @@ static bool buf_page_ibuf_merge_try(buf_block_t *block, ulint rw_latch, ATTRIBUTE_COLD buf_block_t *buf_pool_t::unzip(buf_page_t *b, buf_pool_t::hash_chain &chain) + noexcept { buf_block_t *block= buf_LRU_get_free_block(false); buf_block_init_low(block); @@ -2558,7 +2553,7 @@ buf_block_t *buf_pool_t::unzip(buf_page_t *b, buf_pool_t::hash_chain &chain) buf_block_t *buf_pool_t::page_fix(const page_id_t id, dberr_t *err, - buf_pool_t::page_fix_conflicts c) + buf_pool_t::page_fix_conflicts c) noexcept { ha_handler_stats *const stats= mariadb_stats; buf_inc_get(stats); @@ -2689,7 +2684,7 @@ buf_page_get_low( ulint mode, mtr_t* mtr, dberr_t* err, - bool allow_ibuf_merge) + bool allow_ibuf_merge) noexcept { ulint retries = 0; @@ -3047,7 +3042,7 @@ buf_page_get_gen( ulint mode, mtr_t* mtr, dberr_t* err, - bool allow_ibuf_merge) + bool allow_ibuf_merge) noexcept { buf_block_t *block= recv_sys.recover(page_id); if (UNIV_LIKELY(!block)) @@ -3127,7 +3122,7 @@ buf_page_get_gen( } TRANSACTIONAL_TARGET -buf_block_t *buf_page_optimistic_fix(buf_block_t *block, page_id_t id) +buf_block_t *buf_page_optimistic_fix(buf_block_t *block, page_id_t id) noexcept { buf_pool_t::hash_chain &chain= buf_pool.page_hash.cell_get(id.fold()); transactional_shared_lock_guard g @@ -3145,7 +3140,8 @@ buf_block_t *buf_page_optimistic_fix(buf_block_t *block, page_id_t id) buf_block_t *buf_page_optimistic_get(buf_block_t *block, rw_lock_type_t rw_latch, - uint64_t modify_clock, mtr_t *mtr) + uint64_t modify_clock, + mtr_t *mtr) noexcept { ut_ad(mtr->is_active()); ut_ad(rw_latch == RW_S_LATCH || rw_latch == RW_X_LATCH); @@ -3215,7 +3211,7 @@ Suitable for using when holding the lock_sys latches (as it avoids deadlock). @return the block @retval nullptr if an S-latch cannot be granted immediately */ TRANSACTIONAL_TARGET -buf_block_t *buf_page_try_get(const page_id_t page_id, mtr_t *mtr) +buf_block_t *buf_page_try_get(const page_id_t page_id, mtr_t *mtr) noexcept { ut_ad(mtr); ut_ad(mtr->is_active()); @@ -3250,7 +3246,7 @@ buf_block_t *buf_page_try_get(const page_id_t page_id, mtr_t *mtr) @param zip_size ROW_FORMAT=COMPRESSED page size, or 0 @param fix initial buf_fix_count() */ void buf_block_t::initialise(const page_id_t page_id, ulint zip_size, - uint32_t fix) + uint32_t fix) noexcept { ut_ad(!page.in_file()); buf_block_init_low(this); @@ -3261,6 +3257,7 @@ void buf_block_t::initialise(const page_id_t page_id, ulint zip_size, TRANSACTIONAL_TARGET static buf_block_t *buf_page_create_low(page_id_t page_id, ulint zip_size, mtr_t *mtr, buf_block_t *free_block) + noexcept { ut_ad(mtr->is_active()); ut_ad(page_id.space() != 0 || !zip_size); @@ -3474,7 +3471,7 @@ FILE_PAGE (the other is buf_page_get_gen). @return pointer to the block, page bufferfixed */ buf_block_t* buf_page_create(fil_space_t *space, uint32_t offset, - ulint zip_size, mtr_t *mtr, buf_block_t *free_block) + ulint zip_size, mtr_t *mtr, buf_block_t *free_block) noexcept { space->free_page(offset, false); return buf_page_create_low({space->id, offset}, zip_size, mtr, free_block); @@ -3488,7 +3485,8 @@ deferred tablespace @param free_block pre-allocated buffer block @return pointer to the block, page bufferfixed */ buf_block_t* buf_page_create_deferred(uint32_t space_id, ulint zip_size, - mtr_t *mtr, buf_block_t *free_block) + mtr_t *mtr, + buf_block_t *free_block) noexcept { return buf_page_create_low({space_id, 0}, zip_size, mtr, free_block); } @@ -3497,7 +3495,8 @@ buf_block_t* buf_page_create_deferred(uint32_t space_id, ulint zip_size, counter value in MONITOR_MODULE_BUF_PAGE. @param bpage buffer page whose read or write was completed @param read true=read, false=write */ -ATTRIBUTE_COLD void buf_page_monitor(const buf_page_t &bpage, bool read) +ATTRIBUTE_COLD +void buf_page_monitor(const buf_page_t &bpage, bool read) noexcept { monitor_id_t counter; @@ -3590,7 +3589,7 @@ ATTRIBUTE_COLD void buf_page_monitor(const buf_page_t &bpage, bool read) @param[in] is_compressed compressed page @return true if page is corrupted or false if it isn't */ static bool buf_page_full_crc32_is_corrupted(ulint space_id, const byte* d, - bool is_compressed) + bool is_compressed) noexcept { if (space_id != mach_read_from_4(d + FIL_PAGE_SPACE_ID)) return true; @@ -3680,7 +3679,7 @@ static dberr_t buf_page_check_corrupt(buf_page_t *bpage, @return whether the operation succeeded @retval DB_PAGE_CORRUPTED if the checksum or the page ID is incorrect @retval DB_DECRYPTION_FAILED if the page cannot be decrypted */ -dberr_t buf_page_t::read_complete(const fil_node_t &node) +dberr_t buf_page_t::read_complete(const fil_node_t &node) noexcept { const page_id_t expected_id{id()}; ut_ad(is_read_fixed()); @@ -3834,7 +3833,7 @@ success_page: /** Check that all blocks are in a replaceable state. @return address of a non-free block @retval nullptr if all freed */ -void buf_pool_t::assert_all_freed() +void buf_pool_t::assert_all_freed() noexcept { mysql_mutex_lock(&mutex); const chunk_t *chunk= chunks; @@ -3846,7 +3845,7 @@ void buf_pool_t::assert_all_freed() #endif /* UNIV_DEBUG */ /** Refresh the statistics used to print per-second averages. */ -void buf_refresh_io_stats() +void buf_refresh_io_stats() noexcept { buf_pool.last_printout_time = time(NULL); buf_pool.old_stat = buf_pool.stat; @@ -3854,7 +3853,7 @@ void buf_refresh_io_stats() /** Invalidate all pages in the buffer pool. All pages must be in a replaceable state (not modified or latched). */ -void buf_pool_invalidate() +void buf_pool_invalidate() noexcept { /* It is possible that a write batch that has been posted earlier is still not complete. For buffer pool invalidation to @@ -3881,7 +3880,7 @@ void buf_pool_invalidate() #ifdef UNIV_DEBUG /** Validate the buffer pool. */ -void buf_pool_t::validate() +void buf_pool_t::validate() noexcept { ulint n_lru = 0; ulint n_flushing = 0; @@ -3976,7 +3975,7 @@ void buf_pool_t::validate() #if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG /** Write information of the buf_pool to the error log. */ -void buf_pool_t::print() +void buf_pool_t::print() noexcept { index_id_t* index_ids; ulint* counts; @@ -4080,7 +4079,7 @@ void buf_pool_t::print() #ifdef UNIV_DEBUG /** @return the number of latched pages in the buffer pool */ -ulint buf_get_latched_pages_number() +ulint buf_get_latched_pages_number() noexcept { ulint fixed_pages_number= 0; @@ -4099,7 +4098,7 @@ ulint buf_get_latched_pages_number() /** Collect buffer pool metadata. @param[out] pool_info buffer pool metadata */ -void buf_stats_get_pool_info(buf_pool_info_t *pool_info) +void buf_stats_get_pool_info(buf_pool_info_t *pool_info) noexcept { time_t current_time; double time_elapsed; @@ -4332,7 +4331,7 @@ This function should be called only if tablespace contains crypt data metadata. @param[in] page page frame @param[in] fsp_flags tablespace flags @return true if true if page is encrypted and OK, false otherwise */ -bool buf_page_verify_crypt_checksum(const byte* page, ulint fsp_flags) +bool buf_page_verify_crypt_checksum(const byte* page, ulint fsp_flags) noexcept { if (!fil_space_t::full_crc32(fsp_flags)) { return fil_space_verify_crypt_checksum( diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index 96d4c5e7c5e..9165f8e4a02 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -41,13 +41,13 @@ using st_::span; buf_dblwr_t buf_dblwr; /** @return the TRX_SYS page */ -inline buf_block_t *buf_dblwr_trx_sys_get(mtr_t *mtr) +inline buf_block_t *buf_dblwr_trx_sys_get(mtr_t *mtr) noexcept { return buf_page_get(page_id_t(TRX_SYS_SPACE, TRX_SYS_PAGE_NO), 0, RW_X_LATCH, mtr); } -void buf_dblwr_t::init() +void buf_dblwr_t::init() noexcept { if (!active_slot) { @@ -59,7 +59,7 @@ void buf_dblwr_t::init() /** Initialise the persistent storage of the doublewrite buffer. @param header doublewrite page header in the TRX_SYS page */ -inline void buf_dblwr_t::init(const byte *header) +inline void buf_dblwr_t::init(const byte *header) noexcept { ut_ad(!active_slot->first_free); ut_ad(!active_slot->reserved); @@ -81,7 +81,7 @@ inline void buf_dblwr_t::init(const byte *header) /** Create or restore the doublewrite buffer in the TRX_SYS page. @return whether the operation succeeded */ -bool buf_dblwr_t::create() +bool buf_dblwr_t::create() noexcept { if (is_created()) return true; @@ -113,9 +113,9 @@ start_again: if (UT_LIST_GET_FIRST(fil_system.sys_space->chain)->size < 3 * size) { - ib::error() << "Cannot create doublewrite buffer: " - "the first file in innodb_data_file_path must be at least " - << (3 * (size >> (20U - srv_page_size_shift))) << "M."; + sql_print_error("InnoDB: Cannot create doublewrite buffer: " + "the first file in innodb_data_file_path must be at least " + "%zuM.", 3 * (size >> (20U - srv_page_size_shift))); fail: mtr.commit(); return false; @@ -127,11 +127,13 @@ fail: &mtr, &err, false, trx_sys_block); if (!b) { - ib::error() << "Cannot create doublewrite buffer: " << err; + sql_print_error("InnoDB: Cannot create doublewrite buffer: %s", + ut_strerr(err)); goto fail; } - ib::info() << "Doublewrite buffer not found: creating new"; + sql_print_information("InnoDB: Doublewrite buffer not found:" + " creating new"); /* FIXME: After this point, the doublewrite buffer creation is not atomic. The doublewrite buffer should not exist in @@ -150,9 +152,9 @@ fail: false, &mtr, &mtr, &err); if (!new_block) { - ib::error() << "Cannot create doublewrite buffer: " + sql_print_error("InnoDB: Cannot create doublewrite buffer: " " you must increase your tablespace size." - " Cannot continue operation."; + " Cannot continue operation."); /* This may essentially corrupt the doublewrite buffer. However, usually the doublewrite buffer is created at database initialization, and it @@ -239,7 +241,7 @@ fail: /* Remove doublewrite pages from LRU */ buf_pool_invalidate(); - ib::info() << "Doublewrite buffer created"; + sql_print_information("InnoDB: Doublewrite buffer created"); goto start_again; } @@ -252,6 +254,7 @@ loads the pages from double write buffer into memory. @param path Path name of file @return DB_SUCCESS or error code */ dberr_t buf_dblwr_t::init_or_load_pages(pfs_os_file_t file, const char *path) + noexcept { ut_ad(this == &buf_dblwr); const uint32_t size= block_size(); @@ -266,7 +269,8 @@ dberr_t buf_dblwr_t::init_or_load_pages(pfs_os_file_t file, const char *path) if (err != DB_SUCCESS) { - ib::error() << "Failed to read the system tablespace header page"; + sql_print_error("InnoDB: Failed to read the system tablespace" + " header page"); func_exit: aligned_free(read_buf); return err; @@ -298,7 +302,8 @@ func_exit: if (err != DB_SUCCESS) { - ib::error() << "Failed to read the first double write buffer extent"; + sql_print_error("InnoDB: Failed to read" + " the first double write buffer extent"); goto func_exit; } @@ -308,7 +313,8 @@ func_exit: size << srv_page_size_shift, nullptr); if (err != DB_SUCCESS) { - ib::error() << "Failed to read the second double write buffer extent"; + sql_print_error("InnoDB: Failed to read" + " the second double write buffer extent"); goto func_exit; } @@ -316,7 +322,8 @@ func_exit: if (UNIV_UNLIKELY(upgrade_to_innodb_file_per_table)) { - ib::info() << "Resetting space id's in the doublewrite buffer"; + sql_print_information("InnoDB: Resetting space id's in " + "the doublewrite buffer"); for (ulint i= 0; i < size * 2; i++, page += srv_page_size) { @@ -332,7 +339,7 @@ func_exit: source_page_no << srv_page_size_shift, srv_page_size); if (err != DB_SUCCESS) { - ib::error() << "Failed to upgrade the double write buffer"; + sql_print_error("InnoDB: Failed to upgrade the double write buffer"); goto func_exit; } } @@ -352,7 +359,7 @@ func_exit: } /** Process and remove the double write buffer pages for all tablespaces. */ -void buf_dblwr_t::recover() +void buf_dblwr_t::recover() noexcept { ut_ad(recv_sys.parse_start_lsn); if (!is_created()) @@ -481,7 +488,7 @@ next_page: } /** Free the doublewrite buffer. */ -void buf_dblwr_t::close() +void buf_dblwr_t::close() noexcept { if (!active_slot) return; @@ -502,7 +509,7 @@ void buf_dblwr_t::close() } /** Update the doublewrite buffer on write completion. */ -void buf_dblwr_t::write_completed() +void buf_dblwr_t::write_completed() noexcept { ut_ad(this == &buf_dblwr); ut_ad(!srv_read_only_mode); @@ -537,6 +544,7 @@ void buf_dblwr_t::write_completed() @param[in] page page to check @param[in] s tablespace */ static void buf_dblwr_check_page_lsn(const page_t* page, const fil_space_t& s) + noexcept { /* Ignore page_compressed or encrypted pages */ if (s.is_compressed() || buf_page_get_key_version(page, s.flags)) @@ -552,6 +560,7 @@ static void buf_dblwr_check_page_lsn(const page_t* page, const fil_space_t& s) } static void buf_dblwr_check_page_lsn(const buf_page_t &b, const byte *page) + noexcept { if (fil_space_t *space= fil_space_t::get_for_write(b.id().space())) { @@ -561,7 +570,7 @@ static void buf_dblwr_check_page_lsn(const buf_page_t &b, const byte *page) } /** Check the LSN values on the page with which this block is associated. */ -static void buf_dblwr_check_block(const buf_page_t *bpage) +static void buf_dblwr_check_block(const buf_page_t *bpage) noexcept { ut_ad(bpage->in_file()); const page_t *page= bpage->frame; @@ -593,7 +602,7 @@ static void buf_dblwr_check_block(const buf_page_t *bpage) } #endif /* UNIV_DEBUG */ -bool buf_dblwr_t::flush_buffered_writes(const ulint size) +bool buf_dblwr_t::flush_buffered_writes(const ulint size) noexcept { mysql_mutex_assert_owner(&mutex); ut_ad(size == block_size()); @@ -658,7 +667,7 @@ bool buf_dblwr_t::flush_buffered_writes(const ulint size) return true; } -static void *get_frame(const IORequest &request) +static void *get_frame(const IORequest &request) noexcept { if (request.slot) return request.slot->out_buf; @@ -667,6 +676,7 @@ static void *get_frame(const IORequest &request) } void buf_dblwr_t::flush_buffered_writes_completed(const IORequest &request) + noexcept { ut_ad(this == &buf_dblwr); ut_ad(srv_use_doublewrite_buf); @@ -734,7 +744,7 @@ void buf_dblwr_t::flush_buffered_writes_completed(const IORequest &request) It is very important to call this function after a batch of writes has been posted, and also when we may have to wait for a page latch! Otherwise a deadlock of threads can occur. */ -void buf_dblwr_t::flush_buffered_writes() +void buf_dblwr_t::flush_buffered_writes() noexcept { if (!is_created() || !srv_use_doublewrite_buf) { @@ -754,7 +764,7 @@ void buf_dblwr_t::flush_buffered_writes() flush_buffered_writes() will be invoked to make space. @param request asynchronous write request @param size payload size in bytes */ -void buf_dblwr_t::add_to_batch(const IORequest &request, size_t size) +void buf_dblwr_t::add_to_batch(const IORequest &request, size_t size) noexcept { ut_ad(request.is_async()); ut_ad(request.is_write()); diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index 024866f4f75..f62d9dc0f3c 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -88,10 +88,10 @@ static struct #ifdef UNIV_DEBUG /** Validate the flush list. */ -static void buf_flush_validate_low(); +static void buf_flush_validate_low() noexcept; /** Validates the flush list some of the time. */ -static void buf_flush_validate_skip() +static void buf_flush_validate_skip() noexcept { /** Try buf_flush_validate_low() every this many times */ # define BUF_FLUSH_VALIDATE_SKIP 23 @@ -113,7 +113,7 @@ static void buf_flush_validate_skip() } #endif /* UNIV_DEBUG */ -void buf_pool_t::page_cleaner_wakeup(bool for_LRU) +void buf_pool_t::page_cleaner_wakeup(bool for_LRU) noexcept { if (!page_cleaner_idle()) { @@ -161,7 +161,7 @@ void buf_pool_t::page_cleaner_wakeup(bool for_LRU) } } -inline void buf_pool_t::delete_from_flush_list_low(buf_page_t *bpage) +inline void buf_pool_t::delete_from_flush_list_low(buf_page_t *bpage) noexcept { ut_ad(!fsp_is_system_temporary(bpage->id().space())); mysql_mutex_assert_owner(&flush_list_mutex); @@ -172,7 +172,7 @@ inline void buf_pool_t::delete_from_flush_list_low(buf_page_t *bpage) /** Insert a modified block into the flush list. @param block modified block @param lsn start LSN of the mini-transaction that modified the block */ -void buf_pool_t::insert_into_flush_list(buf_block_t *block, lsn_t lsn) +void buf_pool_t::insert_into_flush_list(buf_block_t *block, lsn_t lsn) noexcept { mysql_mutex_assert_not_owner(&mutex); mysql_mutex_assert_owner(&log_sys.flush_order_mutex); @@ -201,7 +201,7 @@ void buf_pool_t::insert_into_flush_list(buf_block_t *block, lsn_t lsn) /** Remove a block from flush_list. @param bpage buffer pool page */ -void buf_pool_t::delete_from_flush_list(buf_page_t *bpage) +void buf_pool_t::delete_from_flush_list(buf_page_t *bpage) noexcept { delete_from_flush_list_low(bpage); flush_list_bytes-= bpage->physical_size(); @@ -216,7 +216,7 @@ deleting the data file of that tablespace. The pages still remain a part of LRU and are evicted from the list as they age towards the tail of the LRU. @param id tablespace identifier */ -void buf_flush_remove_pages(ulint id) +void buf_flush_remove_pages(ulint id) noexcept { const page_id_t first(id, 0), end(id + 1, 0); ut_ad(id); @@ -273,6 +273,7 @@ buf_flush_relocate_on_flush_list( /*=============================*/ buf_page_t* bpage, /*!< in/out: control block being moved */ buf_page_t* dpage) /*!< in/out: destination block */ + noexcept { buf_page_t* prev; @@ -313,6 +314,7 @@ buf_flush_relocate_on_flush_list( } void buf_page_t::write_complete(bool persistent, bool error, uint32_t state) + noexcept { ut_ad(!persistent == fsp_is_system_temporary(id().space())); ut_ad(state >= WRITE_FIX); @@ -333,13 +335,13 @@ void buf_page_t::write_complete(bool persistent, bool error, uint32_t state) lock.u_unlock(true); } -inline void buf_pool_t::n_flush_inc() +inline void buf_pool_t::n_flush_inc() noexcept { mysql_mutex_assert_owner(&flush_list_mutex); page_cleaner_status+= LRU_FLUSH; } -inline void buf_pool_t::n_flush_dec() +inline void buf_pool_t::n_flush_dec() noexcept { mysql_mutex_assert_owner(&flush_list_mutex); ut_ad(page_cleaner_status >= LRU_FLUSH); @@ -350,7 +352,7 @@ inline void buf_pool_t::n_flush_dec() /** Complete write of a file page from buf_pool. @param request write request @param error whether the write may have failed */ -void buf_page_write_complete(const IORequest &request, bool error) +void buf_page_write_complete(const IORequest &request, bool error) noexcept { ut_ad(request.is_write()); ut_ad(!srv_read_only_mode); @@ -400,7 +402,7 @@ void buf_page_write_complete(const IORequest &request, bool error) /** Calculate a ROW_FORMAT=COMPRESSED page checksum and update the page. @param[in,out] page page to update @param[in] size compressed page size */ -void buf_flush_update_zip_checksum(buf_frame_t *page, ulint size) +void buf_flush_update_zip_checksum(buf_frame_t *page, ulint size) noexcept { ut_ad(size > 0); mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, @@ -409,7 +411,7 @@ void buf_flush_update_zip_checksum(buf_frame_t *page, ulint size) /** Assign the full crc32 checksum for non-compressed page. @param[in,out] page page to be updated */ -void buf_flush_assign_full_crc32_checksum(byte* page) +void buf_flush_assign_full_crc32_checksum(byte* page) noexcept { ut_d(bool compressed = false); ut_d(bool corrupted = false); @@ -434,7 +436,7 @@ buf_flush_init_for_writing( const buf_block_t* block, byte* page, void* page_zip_, - bool use_full_checksum) + bool use_full_checksum) noexcept { if (block && block->page.frame != page) { /* If page is encrypted in full crc32 format then @@ -502,8 +504,8 @@ buf_flush_init_for_writing( /* The page type could be garbage in old files created before MySQL 5.5. Such files always had a page size of 16 kilobytes. */ - ulint page_type = fil_page_get_type(page); - ulint reset_type = page_type; + uint16_t page_type = fil_page_get_type(page); + uint16_t reset_type = page_type; switch (block->page.id().page_no() % 16384) { case 0: @@ -566,7 +568,7 @@ buf_flush_init_for_writing( /** Reserve a buffer for compression. @param[in,out] slot reserved slot */ -static void buf_tmp_reserve_compression_buf(buf_tmp_buffer_t* slot) +static void buf_tmp_reserve_compression_buf(buf_tmp_buffer_t* slot) noexcept { if (slot->comp_buf) return; @@ -586,7 +588,8 @@ static void buf_tmp_reserve_compression_buf(buf_tmp_buffer_t* slot) @param[in] s Page to encrypt @param[in,out] d Output buffer @return encrypted buffer or NULL */ -static byte* buf_tmp_page_encrypt(ulint offset, const byte* s, byte* d) +static byte *buf_tmp_page_encrypt(ulint offset, const byte *s, byte *d) + noexcept { /* Calculate the start offset in a page */ uint srclen= static_cast(srv_page_size) - @@ -616,8 +619,8 @@ a page is written to disk. @param[in,out] size payload size in bytes @return page frame to be written to file (may be src_frame or an encrypted/compressed copy of it) */ -static byte *buf_page_encrypt(fil_space_t* space, buf_page_t* bpage, byte* s, - buf_tmp_buffer_t **slot, size_t *size) +static byte *buf_page_encrypt(fil_space_t *space, buf_page_t *bpage, byte *s, + buf_tmp_buffer_t **slot, size_t *size) noexcept { ut_ad(!bpage->is_freed()); ut_ad(space->id == bpage->id().space()); @@ -738,7 +741,7 @@ not_compressed: } /** Free a page whose underlying file page has been freed. */ -ATTRIBUTE_COLD void buf_pool_t::release_freed_page(buf_page_t *bpage) +ATTRIBUTE_COLD void buf_pool_t::release_freed_page(buf_page_t *bpage) noexcept { mysql_mutex_assert_owner(&mutex); ut_d(const lsn_t oldest_modification= bpage->oldest_modification();) @@ -763,7 +766,7 @@ ATTRIBUTE_COLD void buf_pool_t::release_freed_page(buf_page_t *bpage) /** Write a flushable page to a file or free a freeable block. @param space tablespace @return whether a page write was initiated and buf_pool.mutex released */ -bool buf_page_t::flush(fil_space_t *space) +bool buf_page_t::flush(fil_space_t *space) noexcept { mysql_mutex_assert_not_owner(&buf_pool.flush_list_mutex); ut_ad(in_file()); @@ -900,7 +903,7 @@ bool buf_page_t::flush(fil_space_t *space) @param id page identifier @param fold id.fold() @return whether the page can be flushed */ -static bool buf_flush_check_neighbor(const page_id_t id, ulint fold) +static bool buf_flush_check_neighbor(const page_id_t id, ulint fold) noexcept { mysql_mutex_assert_owner(&buf_pool.mutex); ut_ad(fold == id.fold()); @@ -919,6 +922,7 @@ static bool buf_flush_check_neighbor(const page_id_t id, ulint fold) @return last page number that can be flushed */ static page_id_t buf_flush_check_neighbors(const fil_space_t &space, page_id_t &id, bool contiguous) + noexcept { ut_ad(id.page_no() < space.size + (space.physical_size() == 2048 ? 1 @@ -979,7 +983,7 @@ MY_ATTRIBUTE((warn_unused_result)) /** Apply freed_ranges to the file. @param writable whether the file is writable @return number of pages written or hole-punched */ -uint32_t fil_space_t::flush_freed(bool writable) +uint32_t fil_space_t::flush_freed(bool writable) noexcept { const bool punch_hole= chain.start->punch_hole == 1; if (!punch_hole && !srv_immediate_scrub_data_uncompressed) @@ -1051,7 +1055,8 @@ static ulint buf_flush_try_neighbors(fil_space_t *space, const page_id_t page_id, buf_page_t *bpage, bool contiguous, - ulint n_flushed, ulint n_to_flush) + ulint n_flushed, + ulint n_to_flush) noexcept { ut_ad(space->id == page_id.space()); ut_ad(bpage->id() == page_id); @@ -1149,7 +1154,7 @@ Note that this function does not actually flush any data to disk. It just detaches the uncompressed frames from the compressed pages at the tail of the unzip_LRU and puts those freed frames in the free list. @return number of blocks moved to the free list. */ -static ulint buf_free_from_unzip_LRU_list_batch() +static ulint buf_free_from_unzip_LRU_list_batch() noexcept { ulint scanned = 0; ulint count = 0; @@ -1191,7 +1196,7 @@ static ulint buf_free_from_unzip_LRU_list_batch() @param id tablespace identifier @return tablespace @retval nullptr if the tablespace is missing or inaccessible */ -fil_space_t *fil_space_t::get_for_write(ulint id) +fil_space_t *fil_space_t::get_for_write(ulint id) noexcept { mysql_mutex_lock(&fil_system.mutex); fil_space_t *space= fil_space_get_by_id(id); @@ -1210,6 +1215,7 @@ fil_space_t *fil_space_t::get_for_write(ulint id) @param id tablespace identifier @return tablespace and number of pages written */ static std::pair buf_flush_space(const uint32_t id) + noexcept { if (fil_space_t *space= fil_space_t::get_for_write(id)) return {space, space->flush_freed(true)}; @@ -1226,7 +1232,7 @@ struct flush_counters_t /** Discard a dirty page, and release buf_pool.flush_list_mutex. @param bpage dirty page whose tablespace is not accessible */ -static void buf_flush_discard_page(buf_page_t *bpage) +static void buf_flush_discard_page(buf_page_t *bpage) noexcept { ut_ad(bpage->in_file()); ut_ad(bpage->oldest_modification()); @@ -1245,7 +1251,7 @@ static void buf_flush_discard_page(buf_page_t *bpage) and move clean blocks to buf_pool.free. @param max maximum number of blocks to flush @param n counts of flushed and evicted pages */ -static void buf_flush_LRU_list_batch(ulint max, flush_counters_t *n) +static void buf_flush_LRU_list_batch(ulint max, flush_counters_t *n) noexcept { ulint scanned= 0; mysql_mutex_assert_owner(&buf_pool.mutex); @@ -1402,7 +1408,7 @@ static void buf_flush_LRU_list_batch(ulint max, flush_counters_t *n) Whether LRU or unzip_LRU is used depends on the state of the system. @param max maximum number of blocks to flush @param n counts of flushed and evicted pages */ -static void buf_do_LRU_batch(ulint max, flush_counters_t *n) +static void buf_do_LRU_batch(ulint max, flush_counters_t *n) noexcept { if (buf_LRU_evict_from_unzip_LRU()) buf_free_from_unzip_LRU_list_batch(); @@ -1421,7 +1427,7 @@ The calling thread is not allowed to own any latches on pages! @param max_n maximum mumber of blocks to flush @param lsn once an oldest_modification>=lsn is found, terminate the batch @return number of blocks for which the write request was queued */ -static ulint buf_do_flush_list_batch(ulint max_n, lsn_t lsn) +static ulint buf_do_flush_list_batch(ulint max_n, lsn_t lsn) noexcept { ulint count= 0; ulint scanned= 0; @@ -1551,7 +1557,7 @@ static ulint buf_do_flush_list_batch(ulint max_n, lsn_t lsn) } /** Wait until a LRU flush batch ends. */ -void buf_flush_wait_LRU_batch_end() +void buf_flush_wait_LRU_batch_end() noexcept { mysql_mutex_assert_owner(&buf_pool.flush_list_mutex); mysql_mutex_assert_not_owner(&buf_pool.mutex); @@ -1577,7 +1583,7 @@ after releasing buf_pool.mutex. @return the number of processed pages @retval 0 if a buf_pool.flush_list batch is already running */ static ulint buf_flush_list_holding_mutex(ulint max_n= ULINT_UNDEFINED, - lsn_t lsn= LSN_MAX) + lsn_t lsn= LSN_MAX) noexcept { ut_ad(lsn); mysql_mutex_assert_owner(&buf_pool.mutex); @@ -1618,7 +1624,7 @@ nothing_to_do: @return the number of processed pages @retval 0 if a buf_pool.flush_list batch is already running */ static ulint buf_flush_list(ulint max_n= ULINT_UNDEFINED, - lsn_t lsn= LSN_MAX) + lsn_t lsn= LSN_MAX) noexcept { mysql_mutex_lock(&buf_pool.mutex); ulint n= buf_flush_list_holding_mutex(max_n, lsn); @@ -1631,7 +1637,7 @@ static ulint buf_flush_list(ulint max_n= ULINT_UNDEFINED, @param space tablespace @param n_flushed number of pages written @return whether the flush for some pages might not have been initiated */ -bool buf_flush_list_space(fil_space_t *space, ulint *n_flushed) +bool buf_flush_list_space(fil_space_t *space, ulint *n_flushed) noexcept { const auto space_id= space->id; ut_ad(space_id <= SRV_SPACE_ID_UPPER_BOUND); @@ -1749,7 +1755,7 @@ The caller must invoke buf_dblwr.flush_buffered_writes() after releasing buf_pool.mutex. @param max_n wished maximum mumber of blocks flushed @return number of pages written */ -static ulint buf_flush_LRU(ulint max_n) +static ulint buf_flush_LRU(ulint max_n) noexcept { mysql_mutex_assert_owner(&buf_pool.mutex); @@ -1786,7 +1792,7 @@ static ulint buf_flush_LRU(ulint max_n) @param oldest_lsn the checkpoint LSN @param end_lsn log_sys.get_lsn() @return true if success, false if a checkpoint write was already running */ -static bool log_checkpoint_low(lsn_t oldest_lsn, lsn_t end_lsn) +static bool log_checkpoint_low(lsn_t oldest_lsn, lsn_t end_lsn) noexcept { ut_ad(!srv_read_only_mode); mysql_mutex_assert_owner(&log_sys.mutex); @@ -1868,7 +1874,7 @@ modification in the pool, and writes information about the lsn in log file. Use log_make_checkpoint() to flush also the pool. @retval true if the checkpoint was or had been made @retval false if a checkpoint write was already running */ -static bool log_checkpoint() +static bool log_checkpoint() noexcept { if (recv_recovery_is_on()) recv_sys.apply(true); @@ -1900,7 +1906,7 @@ ATTRIBUTE_COLD void log_make_checkpoint() /** Wait for all dirty pages up to an LSN to be written out. NOTE: The calling thread is not allowed to hold any buffer page latches! */ -static void buf_flush_wait(lsn_t lsn) +static void buf_flush_wait(lsn_t lsn) noexcept { ut_ad(lsn <= log_sys.get_lsn()); @@ -1933,7 +1939,7 @@ static void buf_flush_wait(lsn_t lsn) /** Wait until all persistent pages are flushed up to a limit. @param sync_lsn buf_pool.get_oldest_modification(LSN_MAX) to wait for */ -ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn) +ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn) noexcept { ut_ad(sync_lsn); ut_ad(sync_lsn < LSN_MAX); @@ -1996,7 +2002,7 @@ ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn) /** Initiate more eager page flushing if the log checkpoint age is too old. @param lsn buf_pool.get_oldest_modification(LSN_MAX) target @param furious true=furious flushing, false=limit to innodb_io_capacity */ -ATTRIBUTE_COLD void buf_flush_ahead(lsn_t lsn, bool furious) +ATTRIBUTE_COLD void buf_flush_ahead(lsn_t lsn, bool furious) noexcept { mysql_mutex_assert_not_owner(&log_sys.mutex); ut_ad(!srv_read_only_mode); @@ -2026,7 +2032,7 @@ ATTRIBUTE_COLD void buf_flush_ahead(lsn_t lsn, bool furious) and try to initiate checkpoints until the target is met. @param lsn minimum value of buf_pool.get_oldest_modification(LSN_MAX) */ ATTRIBUTE_COLD ATTRIBUTE_NOINLINE -static void buf_flush_sync_for_checkpoint(lsn_t lsn) +static void buf_flush_sync_for_checkpoint(lsn_t lsn) noexcept { ut_ad(!srv_read_only_mode); mysql_mutex_assert_not_owner(&buf_pool.flush_list_mutex); @@ -2119,7 +2125,7 @@ static void buf_flush_sync_for_checkpoint(lsn_t lsn) redo log capacity filled threshold. @param oldest_lsn buf_pool.get_oldest_modification() @return true if adaptive flushing is recommended. */ -static bool af_needed_for_redo(lsn_t oldest_lsn) +static bool af_needed_for_redo(lsn_t oldest_lsn) noexcept { lsn_t age= (log_sys.get_lsn() - oldest_lsn); lsn_t af_lwm= static_cast(srv_adaptive_flushing_lwm * @@ -2171,7 +2177,7 @@ static ulint page_cleaner_flush_pages_recommendation(ulint last_pages_in, lsn_t oldest_lsn, double pct_lwm, ulint dirty_blocks, - double dirty_pct) + double dirty_pct) noexcept { static lsn_t prev_lsn = 0; static ulint sum_pages = 0; @@ -2293,7 +2299,7 @@ func_exit: } TPOOL_SUPPRESS_TSAN -bool buf_pool_t::need_LRU_eviction() const +bool buf_pool_t::need_LRU_eviction() const noexcept { /* try_LRU_scan==false means that buf_LRU_get_free_block() is waiting for buf_flush_page_cleaner() to evict some blocks */ @@ -2304,7 +2310,7 @@ bool buf_pool_t::need_LRU_eviction() const /** page_cleaner thread tasked with flushing dirty pages from the buffer pools. As of now we'll have only one coordinator. */ -static void buf_flush_page_cleaner() +static void buf_flush_page_cleaner() noexcept { my_thread_init(); #ifdef UNIV_PFS_THREAD @@ -2562,7 +2568,7 @@ static void buf_flush_page_cleaner() #endif } -ATTRIBUTE_COLD void buf_pool_t::LRU_warn() +ATTRIBUTE_COLD void buf_pool_t::LRU_warn() noexcept { mysql_mutex_assert_owner(&mutex); try_LRU_scan= false; @@ -2574,7 +2580,7 @@ ATTRIBUTE_COLD void buf_pool_t::LRU_warn() } /** Initialize page_cleaner. */ -ATTRIBUTE_COLD void buf_flush_page_cleaner_init() +ATTRIBUTE_COLD void buf_flush_page_cleaner_init() noexcept { ut_ad(!buf_page_cleaner_is_active); ut_ad(srv_operation <= SRV_OPERATION_EXPORT_RESTORED || @@ -2587,7 +2593,7 @@ ATTRIBUTE_COLD void buf_flush_page_cleaner_init() } /** Flush the buffer pool on shutdown. */ -ATTRIBUTE_COLD void buf_flush_buffer_pool() +ATTRIBUTE_COLD void buf_flush_buffer_pool() noexcept { ut_ad(!buf_page_cleaner_is_active); ut_ad(!buf_flush_sync_lsn); @@ -2615,7 +2621,7 @@ ATTRIBUTE_COLD void buf_flush_buffer_pool() /** Synchronously flush dirty blocks during recv_sys_t::apply(). NOTE: The calling thread is not allowed to hold any buffer page latches! */ -void buf_flush_sync_batch(lsn_t lsn) +void buf_flush_sync_batch(lsn_t lsn) noexcept { lsn= std::max(lsn, log_sys.get_lsn()); mysql_mutex_lock(&buf_pool.flush_list_mutex); @@ -2625,7 +2631,7 @@ void buf_flush_sync_batch(lsn_t lsn) /** Synchronously flush dirty blocks. NOTE: The calling thread is not allowed to hold any buffer page latches! */ -void buf_flush_sync() +void buf_flush_sync() noexcept { if (recv_recovery_is_on()) recv_sys.apply(true); @@ -2653,7 +2659,7 @@ void buf_flush_sync() #ifdef UNIV_DEBUG /** Functor to validate the flush list. */ struct Check { - void operator()(const buf_page_t* elem) const + void operator()(const buf_page_t* elem) const noexcept { ut_ad(elem->oldest_modification()); ut_ad(!fsp_is_system_temporary(elem->id().space())); @@ -2661,7 +2667,7 @@ struct Check { }; /** Validate the flush list. */ -static void buf_flush_validate_low() +static void buf_flush_validate_low() noexcept { buf_page_t* bpage; @@ -2690,7 +2696,7 @@ static void buf_flush_validate_low() } /** Validate the flush list. */ -void buf_flush_validate() +void buf_flush_validate() noexcept { mysql_mutex_lock(&buf_pool.flush_list_mutex); buf_flush_validate_low(); diff --git a/storage/innobase/buf/buf0rea.cc b/storage/innobase/buf/buf0rea.cc index 26cd261ab4d..09c30504f52 100644 --- a/storage/innobase/buf/buf0rea.cc +++ b/storage/innobase/buf/buf0rea.cc @@ -57,6 +57,7 @@ that the block has been replaced with the real block. @return w->state() */ inline uint32_t buf_pool_t::watch_remove(buf_page_t *w, buf_pool_t::hash_chain &chain) + noexcept { mysql_mutex_assert_owner(&buf_pool.mutex); ut_ad(xtest() || page_hash.lock_get(chain).is_write_locked()); @@ -95,7 +96,7 @@ and the lock released later. @retval NULL in case of an error */ TRANSACTIONAL_TARGET static buf_page_t* buf_page_init_for_read(ulint mode, const page_id_t page_id, - ulint zip_size, bool unzip) + ulint zip_size, bool unzip) noexcept { mtr_t mtr; @@ -266,7 +267,7 @@ buf_read_page_low( ulint mode, const page_id_t page_id, ulint zip_size, - bool unzip) + bool unzip) noexcept { buf_page_t* bpage; @@ -357,7 +358,7 @@ wants to access pages, it may happen that the page at the given page number does not get read even if we return a positive value! */ TRANSACTIONAL_TARGET -ulint buf_read_ahead_random(const page_id_t page_id, bool ibuf) +ulint buf_read_ahead_random(const page_id_t page_id, bool ibuf) noexcept { if (!srv_random_read_ahead || page_id.space() >= SRV_TMP_SPACE_ID) /* Disable the read-ahead for temporary tablespace */ @@ -447,7 +448,7 @@ read_ahead: return count; } -dberr_t buf_read_page(const page_id_t page_id, bool unzip) +dberr_t buf_read_page(const page_id_t page_id, bool unzip) noexcept { fil_space_t *space= fil_space_t::get(page_id.space()); if (UNIV_UNLIKELY(!space)) @@ -473,7 +474,7 @@ released by the i/o-handler thread. @param[in] page_id page id @param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0 */ void buf_read_page_background(fil_space_t *space, const page_id_t page_id, - ulint zip_size) + ulint zip_size) noexcept { buf_read_page_low(space, false, BUF_READ_ANY_PAGE, page_id, zip_size, false); @@ -512,7 +513,7 @@ which could result in a deadlock if the OS does not support asynchronous io. @param[in] ibuf whether if we are inside ibuf routine @return number of page read requests issued */ TRANSACTIONAL_TARGET -ulint buf_read_ahead_linear(const page_id_t page_id, bool ibuf) +ulint buf_read_ahead_linear(const page_id_t page_id, bool ibuf) noexcept { /* check if readahead is disabled. Disable the read ahead logic for temporary tablespace */ @@ -689,7 +690,7 @@ failed: @param recs log records @param init page initialization, or nullptr if the page needs to be read */ void buf_read_recover(fil_space_t *space, const page_id_t page_id, - page_recv_t &recs, recv_init *init) + page_recv_t &recs, recv_init *init) noexcept { ut_ad(space->id == page_id.space()); space->reacquire(); diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 842f79569d9..bfaaaafc359 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -1364,7 +1364,7 @@ the encryption parameters were changed @retval nullptr upon reaching the end of the iteration */ inline fil_space_t *fil_system_t::default_encrypt_next(fil_space_t *space, bool recheck, - bool encrypt) + bool encrypt) noexcept { mysql_mutex_assert_owner(&mutex); @@ -1431,7 +1431,7 @@ encryption parameters were changed @retval fil_system.temp_space if there is no work to do @retval end() upon reaching the end of the iteration */ space_list_t::iterator fil_space_t::next(space_list_t::iterator space, - bool recheck, bool encrypt) + bool recheck, bool encrypt) noexcept { mysql_mutex_lock(&fil_system.mutex); @@ -1480,7 +1480,7 @@ space_list_t::iterator fil_space_t::next(space_list_t::iterator space, static bool fil_crypt_find_space_to_rotate( key_state_t* key_state, rotate_thread_t* state, - bool* recheck) + bool* recheck) noexcept { /* we need iops to start rotating */ do { diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 6403485ab3d..37bc74233de 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -66,7 +66,7 @@ ATTRIBUTE_COLD bool fil_space_t::set_corrupted() const noexcept /** Determine if the space id is a user tablespace id or not. @param space_id tablespace identifier @return true if it is a user tablespace ID */ -inline bool fil_is_user_tablespace_id(ulint space_id) +inline bool fil_is_user_tablespace_id(ulint space_id) noexcept { return space_id != TRX_SYS_SPACE && space_id != SRV_TMP_SPACE_ID && !srv_is_undo_tablespace(space_id); @@ -77,6 +77,7 @@ inline bool fil_is_user_tablespace_id(ulint space_id) @param print_info whether to diagnose why a file cannot be closed @return whether a file was closed */ bool fil_space_t::try_to_close(fil_space_t *ignore_space, bool print_info) + noexcept { mysql_mutex_assert_owner(&fil_system.mutex); for (fil_space_t &space : fil_system.space_list) @@ -206,10 +207,7 @@ extern uint srv_fil_crypt_rotate_key_age; /******************************************************************//** Checks the consistency of the tablespace cache some of the time. @return true if ok or the check was skipped */ -static -bool -fil_validate_skip(void) -/*===================*/ +static bool fil_validate_skip() noexcept { /** The fil_validate() call skip counter. */ static Atomic_counter fil_validate_count; @@ -228,17 +226,7 @@ fil_space_t *fil_space_get_by_id(ulint id) noexcept (&fil_space_t::hash, [id](const fil_space_t *s) { return s->id == id; }); } -/** Look up a tablespace. -The caller should hold an InnoDB table lock or a MDL that prevents -the tablespace from being dropped during the operation, -or the caller should be in single-threaded crash recovery mode -(no user connections that could drop tablespaces). -Normally, fil_space_t::get() should be used instead. -@param[in] id tablespace ID -@return tablespace, or NULL if not found */ -fil_space_t* -fil_space_get( - ulint id) +fil_space_t *fil_space_get(ulint id) noexcept { mysql_mutex_lock(&fil_system.mutex); fil_space_t* space = fil_space_get_by_id(id); @@ -294,7 +282,7 @@ or UINT32_MAX for unlimited @return file object */ fil_node_t* fil_space_t::add(const char* name, pfs_os_file_t handle, uint32_t size, bool is_raw, bool atomic_write, - uint32_t max_pages) + uint32_t max_pages) noexcept { mysql_mutex_assert_owner(&fil_system.mutex); @@ -460,7 +448,7 @@ static bool fil_node_open_file(fil_node_t *node, const byte *page, bool no_lsn) } /** Close the file handle. */ -void fil_node_t::close() +void fil_node_t::close() noexcept { prepare_to_close_or_detach(); @@ -470,7 +458,7 @@ void fil_node_t::close() handle= OS_FILE_CLOSED; } -pfs_os_file_t fil_node_t::detach() +pfs_os_file_t fil_node_t::detach() noexcept { prepare_to_close_or_detach(); @@ -479,7 +467,7 @@ pfs_os_file_t fil_node_t::detach() return result; } -void fil_node_t::prepare_to_close_or_detach() +void fil_node_t::prepare_to_close_or_detach() noexcept { mysql_mutex_assert_owner(&fil_system.mutex); ut_ad(space->is_ready_to_close() || srv_operation == SRV_OPERATION_BACKUP || @@ -494,7 +482,7 @@ void fil_node_t::prepare_to_close_or_detach() } /** Flush any writes cached by the file system. */ -void fil_space_t::flush_low() +void fil_space_t::flush_low() noexcept { mysql_mutex_assert_not_owner(&fil_system.mutex); @@ -550,7 +538,7 @@ fil_space_extend_must_retry( fil_space_t* space, fil_node_t* node, uint32_t size, - bool* success) + bool* success) noexcept { mysql_mutex_assert_owner(&fil_system.mutex); ut_ad(UT_LIST_GET_LAST(space->chain) == node); @@ -658,7 +646,7 @@ fil_space_extend_must_retry( } /** @return whether the file is usable for io() */ -ATTRIBUTE_COLD bool fil_space_t::prepare_acquired() +ATTRIBUTE_COLD bool fil_space_t::prepare_acquired() noexcept { ut_ad(referenced()); mysql_mutex_assert_owner(&fil_system.mutex); @@ -710,7 +698,7 @@ clear: } /** @return whether the file is usable for io() */ -ATTRIBUTE_COLD bool fil_space_t::acquire_and_prepare() +ATTRIBUTE_COLD bool fil_space_t::acquire_and_prepare() noexcept { mysql_mutex_lock(&fil_system.mutex); const auto flags= acquire_low() & (STOPPING | CLOSING); @@ -723,7 +711,7 @@ ATTRIBUTE_COLD bool fil_space_t::acquire_and_prepare() @param[in,out] space tablespace @param[in] size desired size in pages @return whether the tablespace is at least as big as requested */ -bool fil_space_extend(fil_space_t *space, uint32_t size) +bool fil_space_extend(fil_space_t *space, uint32_t size) noexcept { ut_ad(!srv_read_only_mode || space->is_temporary()); bool success= false; @@ -740,7 +728,7 @@ bool fil_space_extend(fil_space_t *space, uint32_t size) } /** Prepare to free a file from fil_system. */ -inline pfs_os_file_t fil_node_t::close_to_free(bool detach_handle) +inline pfs_os_file_t fil_node_t::close_to_free(bool detach_handle) noexcept { mysql_mutex_assert_owner(&fil_system.mutex); ut_a(!being_extended); @@ -787,6 +775,7 @@ inline pfs_os_file_t fil_node_t::close_to_free(bool detach_handle) @return detached handle @retval OS_FILE_CLOSED if no handle was detached */ pfs_os_file_t fil_system_t::detach(fil_space_t *space, bool detach_handle) + noexcept { mysql_mutex_assert_owner(&fil_system.mutex); spaces.cell_get(space->id)->remove(*space, &fil_space_t::hash); @@ -852,10 +841,7 @@ pfs_os_file_t fil_system_t::detach(fil_space_t *space, bool detach_handle) /** Free a tablespace object on which fil_system_t::detach() was invoked. There must not be any pending i/o's or flushes on the files. @param[in,out] space tablespace */ -static -void -fil_space_free_low( - fil_space_t* space) +static void fil_space_free_low(fil_space_t *space) noexcept { /* The tablespace must not be in fil_system.named_spaces. */ ut_ad(srv_fast_shutdown == 2 || !srv_was_started @@ -885,16 +871,7 @@ fil_space_free_low( ut_free(space); } -/** Frees a space object from the tablespace memory cache. -Closes the files in the chain but does not delete them. -There must not be any pending i/o's or flushes on the files. -@param[in] id tablespace identifier -@param[in] x_latched whether the caller holds X-mode space->latch -@return true if success */ -bool -fil_space_free( - ulint id, - bool x_latched) +bool fil_space_free(ulint id, bool x_latched) noexcept { ut_ad(id != TRX_SYS_SPACE); @@ -1014,15 +991,7 @@ fil_space_t *fil_space_t::create(uint32_t id, ulint flags, return space; } -/*******************************************************************//** -Assigns a new space id for a new single-table tablespace. This works simply by -incrementing the global counter. If 4 billion id's is not enough, we may need -to recycle id's. -@return true if assigned, false if not */ -bool -fil_assign_new_space_id( -/*====================*/ - ulint* space_id) /*!< in/out: space id */ +bool fil_assign_new_space_id(ulint *space_id) noexcept { ulint id; bool success; @@ -1091,6 +1060,7 @@ bool fil_space_t::read_page0(const byte *dpage, bool no_lsn) noexcept } void fil_space_set_recv_size_and_flags(ulint id, uint32_t size, uint32_t flags) + noexcept { ut_ad(id < SRV_SPACE_ID_UPPER_BOUND); mysql_mutex_assert_owner(&recv_sys.mutex); @@ -1269,7 +1239,7 @@ void fil_system_t::create(ulint hash_size) #endif } -void fil_system_t::close() +void fil_system_t::close() noexcept { ut_ad(this == &fil_system); ut_a(unflushed_spaces.empty()); @@ -1293,7 +1263,7 @@ void fil_system_t::close() #endif /* __linux__ */ } -void fil_system_t::add_opened_last_to_space_list(fil_space_t *space) +void fil_system_t::add_opened_last_to_space_list(fil_space_t *space) noexcept { if (UNIV_LIKELY(space_list_last_opened != nullptr)) space_list.insert(++space_list_t::iterator(space_list_last_opened), *space); @@ -1303,7 +1273,7 @@ void fil_system_t::add_opened_last_to_space_list(fil_space_t *space) } /** Extend all open data files to the recovered size */ -ATTRIBUTE_COLD void fil_system_t::extend_to_recv_size() +ATTRIBUTE_COLD void fil_system_t::extend_to_recv_size() noexcept { ut_ad(is_initialised()); mysql_mutex_lock(&mutex); @@ -1329,7 +1299,7 @@ ATTRIBUTE_COLD void fil_system_t::extend_to_recv_size() } /** Close all tablespace files at shutdown */ -void fil_space_t::close_all() +void fil_space_t::close_all() noexcept { if (!fil_system.is_initialised()) return; @@ -1388,13 +1358,7 @@ void fil_space_t::close_all() fil_system.named_spaces.empty()); } -/*******************************************************************//** -Sets the max tablespace id counter if the given number is bigger than the -previous value. */ -void -fil_set_max_space_id_if_bigger( -/*===========================*/ - ulint max_id) /*!< in: maximum known id */ +void fil_set_max_space_id_if_bigger(ulint max_id) noexcept { ut_a(max_id < SRV_SPACE_ID_UPPER_BOUND); @@ -1408,13 +1372,7 @@ fil_set_max_space_id_if_bigger( mysql_mutex_unlock(&fil_system.mutex); } -/** Write the flushed LSN to the page header of the first page in the -system tablespace. -@param[in] lsn flushed LSN -@return DB_SUCCESS or error number */ -dberr_t -fil_write_flushed_lsn( - lsn_t lsn) +dberr_t fil_write_flushed_lsn(lsn_t lsn) noexcept { byte* buf; ut_ad(!srv_read_only_mode); @@ -1448,11 +1406,7 @@ fil_write_flushed_lsn( return fio.err; } -/** Acquire a tablespace reference. -@param id tablespace identifier -@return tablespace -@retval nullptr if the tablespace is missing or inaccessible */ -fil_space_t *fil_space_t::get(ulint id) +fil_space_t *fil_space_t::get(ulint id) noexcept { mysql_mutex_lock(&fil_system.mutex); fil_space_t *space= fil_space_get_by_id(id); @@ -1644,10 +1598,7 @@ fil_space_t *fil_space_t::drop(ulint id, pfs_os_file_t *detached_handle) return space; } -/** Close a single-table tablespace on failed IMPORT TABLESPACE. -The tablespace must be cached in the memory cache. -Free all pages used by the tablespace. */ -void fil_close_tablespace(ulint id) +void fil_close_tablespace(ulint id) noexcept { ut_ad(!is_system_tablespace(id)); fil_space_t* space = fil_space_t::drop(id, nullptr); @@ -1675,11 +1626,7 @@ void fil_close_tablespace(ulint id) fil_space_free_low(space); } -/** Delete a tablespace and associated .ibd file. -@param id tablespace identifier -@return detached file handle (to be closed by the caller) -@return OS_FILE_CLOSED if no file existed */ -pfs_os_file_t fil_delete_tablespace(ulint id) +pfs_os_file_t fil_delete_tablespace(ulint id) noexcept { ut_ad(!is_system_tablespace(id)); pfs_os_file_t handle= OS_FILE_CLOSED; @@ -1688,17 +1635,9 @@ pfs_os_file_t fil_delete_tablespace(ulint id) return handle; } -/*******************************************************************//** -Allocates and builds a file name from a path, a table or tablespace name -and a suffix. The string must be freed by caller with ut_free(). -@param[in] path nullptr or the directory path or the full path and filename -@param[in] name {} if path is full, or Table/Tablespace name -@param[in] extension the file extension to use -@param[in] trim_name true if the last name on the path should be trimmed -@return own: file name */ char* fil_make_filepath_low(const char *path, const fil_space_t::name_type &name, - ib_extention extension, bool trim_name) + ib_extention extension, bool trim_name) noexcept { /* The path may contain the basename of the file, if so we do not need the name. If the path is NULL, we can use the default path, @@ -1792,7 +1731,7 @@ char* fil_make_filepath_low(const char *path, } char *fil_make_filepath(const char* path, const table_name_t name, - ib_extention suffix, bool strip_name) + ib_extention suffix, bool strip_name) noexcept { return fil_make_filepath_low(path, {name.m_name, strlen(name.m_name)}, suffix, strip_name); @@ -1801,12 +1740,12 @@ char *fil_make_filepath(const char* path, const table_name_t name, /** Wrapper function over fil_make_filepath_low() to build directory name. @param path the directory path or the full path and filename @return own: directory name */ -static inline char *fil_make_dirpath(const char *path) +static inline char *fil_make_dirpath(const char *path) noexcept { return fil_make_filepath_low(path, fil_space_t::name_type{}, NO_EXT, true); } -dberr_t fil_space_t::rename(const char *path, bool log, bool replace) +dberr_t fil_space_t::rename(const char *path, bool log, bool replace) noexcept { ut_ad(UT_LIST_GET_LEN(chain) == 1); ut_ad(!is_predefined_tablespace(id)); @@ -2408,6 +2347,7 @@ fil_ibd_discover( } bool fil_crypt_check(fil_space_crypt_t *crypt_data, const char *f_name) + noexcept { if (crypt_data->is_key_found()) return true; @@ -2639,6 +2579,7 @@ startup, there may be many tablespaces which are not yet in the memory cache. @return the tablespace @retval NULL if no matching tablespace exists in the memory cache */ fil_space_t *fil_space_for_table_exists_in_mem(ulint id, ulint table_flags) + noexcept { const ulint expected_flags = dict_tf_to_fsp_flags(table_flags); @@ -2675,7 +2616,7 @@ func_exit: ATTRIBUTE_COLD static void fil_invalid_page_access_msg(const char *name, os_offset_t offset, ulint len, - bool is_read) + bool is_read) noexcept { sql_print_error("%s %zu bytes at " UINT64PF " outside the bounds of the file: %s", @@ -2687,7 +2628,7 @@ static void fil_invalid_page_access_msg(const char *name, } /** Update the data structures on write completion */ -inline void fil_node_t::complete_write() +inline void fil_node_t::complete_write() noexcept { mysql_mutex_assert_not_owner(&fil_system.mutex); @@ -2713,7 +2654,7 @@ inline void fil_node_t::complete_write() @param bpage buffer block (for type.is_async() completion callback) @return status and file descriptor */ fil_io_t fil_space_t::io(const IORequest &type, os_offset_t offset, size_t len, - void *buf, buf_page_t *bpage) + void *buf, buf_page_t *bpage) noexcept { ut_ad(referenced()); ut_ad(offset % OS_FILE_LOG_BLOCK_SIZE == 0); @@ -2815,7 +2756,7 @@ func_exit: #include -void IORequest::write_complete(int io_error) const +void IORequest::write_complete(int io_error) const noexcept { ut_ad(fil_validate_skip()); ut_ad(node); @@ -2836,7 +2777,7 @@ void IORequest::write_complete(int io_error) const node->space->release(); } -void IORequest::read_complete(int io_error) const +void IORequest::read_complete(int io_error) const noexcept { ut_ad(fil_validate_skip()); ut_ad(node); @@ -2871,7 +2812,7 @@ void IORequest::read_complete(int io_error) const /** Flush to disk the writes in file spaces of the given type possibly cached by the OS. */ -void fil_flush_file_spaces() +void fil_flush_file_spaces() noexcept { if (srv_file_flush_method == SRV_O_DIRECT_NO_FSYNC) { @@ -2911,7 +2852,7 @@ struct Check { /** Visit a file node @param[in] elem file node to visit */ - void operator()(const fil_node_t* elem) + void operator()(const fil_node_t* elem) noexcept { n_open += elem->is_open(); size += elem->size; @@ -2920,7 +2861,7 @@ struct Check { /** Validate a tablespace. @param[in] space tablespace to validate @return number of open file nodes */ - static ulint validate(const fil_space_t* space) + static ulint validate(const fil_space_t* space) noexcept { mysql_mutex_assert_owner(&fil_system.mutex); Check check; @@ -2947,7 +2888,7 @@ struct Check { /******************************************************************//** Checks the consistency of the tablespace cache. @return true if ok */ -bool fil_validate() +bool fil_validate() noexcept { ulint n_open = 0; @@ -2964,24 +2905,11 @@ bool fil_validate() return(true); } -/*********************************************************************//** -Sets the file page type. */ -void -fil_page_set_type( -/*==============*/ - byte* page, /*!< in/out: file page */ - ulint type) /*!< in: type */ -{ - ut_ad(page); - - mach_write_to_2(page + FIL_PAGE_TYPE, type); -} - /********************************************************************//** Delete the tablespace file and any related files like .cfg. This should not be called for temporary tables. @param[in] ibd_filepath File path of the IBD tablespace */ -void fil_delete_file(const char *ibd_filepath) +void fil_delete_file(const char *ibd_filepath) noexcept { ib::info() << "Deleting " << ibd_filepath; os_file_delete_if_exists(innodb_data_file_key, ibd_filepath, nullptr); @@ -2999,9 +2927,7 @@ void fil_delete_file(const char *ibd_filepath) /** Check that a tablespace is valid for mtr_commit(). @param[in] space persistent tablespace that has been changed */ static -void -fil_space_validate_for_mtr_commit( - const fil_space_t* space) +void fil_space_validate_for_mtr_commit(const fil_space_t *space) noexcept { mysql_mutex_assert_not_owner(&fil_system.mutex); ut_ad(space != NULL); @@ -3020,9 +2946,7 @@ fil_space_validate_for_mtr_commit( @param[in,out] mtr mini-transaction */ static void -fil_names_write( - const fil_space_t* space, - mtr_t* mtr) +fil_names_write(const fil_space_t *space, mtr_t *mtr) noexcept { ut_ad(UT_LIST_GET_LEN(space->chain) == 1); fil_name_write(space->id, UT_LIST_GET_FIRST(space->chain)->name, mtr); @@ -3031,9 +2955,7 @@ fil_names_write( /** Note that a non-predefined persistent tablespace has been modified by redo log. @param[in,out] space tablespace */ -void -fil_names_dirty( - fil_space_t* space) +void fil_names_dirty(fil_space_t *space) noexcept { mysql_mutex_assert_owner(&log_sys.mutex); ut_ad(recv_recovery_is_on()); @@ -3049,7 +2971,7 @@ fil_names_dirty( tablespace was modified for the first time since the latest fil_names_clear(). @param[in,out] space tablespace */ -void fil_names_dirty_and_write(fil_space_t* space) +void fil_names_dirty_and_write(fil_space_t *space) noexcept { mysql_mutex_assert_owner(&log_sys.mutex); ut_d(fil_space_validate_for_mtr_commit(space)); @@ -3078,10 +3000,7 @@ and write out FILE_MODIFY and FILE_CHECKPOINT if needed. @return whether anything was written to the redo log @retval false if no flags were set and nothing written @retval true if anything was written to the redo log */ -bool -fil_names_clear( - lsn_t lsn, - bool do_write) +bool fil_names_clear(lsn_t lsn, bool do_write) noexcept { mtr_t mtr; @@ -3185,6 +3104,7 @@ test_make_filepath() @param[in] offset page number @return block size */ ulint fil_space_get_block_size(const fil_space_t *space, unsigned offset) + noexcept { ulint block_size = 512; @@ -3209,7 +3129,7 @@ ulint fil_space_get_block_size(const fil_space_t *space, unsigned offset) } /** @return the tablespace name (databasename/tablename) */ -fil_space_t::name_type fil_space_t::name() const +fil_space_t::name_type fil_space_t::name() const noexcept { switch (id) { case 0: @@ -3247,7 +3167,7 @@ fil_space_t::name_type fil_space_t::name() const #ifdef UNIV_DEBUG -fil_space_t *fil_space_t::next_in_space_list() +fil_space_t *fil_space_t::next_in_space_list() noexcept { space_list_t::iterator it(this); auto end= fil_system.space_list.end(); @@ -3257,7 +3177,7 @@ fil_space_t *fil_space_t::next_in_space_list() return it == end ? nullptr : &*it; } -fil_space_t *fil_space_t::prev_in_space_list() +fil_space_t *fil_space_t::prev_in_space_list() noexcept { space_list_t::iterator it(this); if (it == fil_system.space_list.begin()) @@ -3266,7 +3186,7 @@ fil_space_t *fil_space_t::prev_in_space_list() return &*it; } -fil_space_t *fil_space_t::next_in_unflushed_spaces() +fil_space_t *fil_space_t::next_in_unflushed_spaces() noexcept { sized_ilist::iterator it(this); auto end= fil_system.unflushed_spaces.end(); @@ -3276,7 +3196,7 @@ fil_space_t *fil_space_t::next_in_unflushed_spaces() return it == end ? nullptr : &*it; } -fil_space_t *fil_space_t::prev_in_unflushed_spaces() +fil_space_t *fil_space_t::prev_in_unflushed_spaces() noexcept { sized_ilist::iterator it(this); if (it == fil_system.unflushed_spaces.begin()) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index aff63d4f74a..214144b86ac 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -21399,9 +21399,7 @@ void ins_node_t::vers_update_end(row_prebuilt_t *prebuilt, bool history_row) if needed. @param[in] size size in bytes @return aligned size */ -ulint -buf_pool_size_align( - ulint size) +ulint buf_pool_size_align(ulint size) noexcept { const ulong m = srv_buf_pool_chunk_unit; size = ut_max((size_t) size, (size_t) MYSQL_SYSVAR_NAME(buffer_pool_size).min_val); diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index cb44cafa673..0dc50638315 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -153,7 +153,7 @@ operator<<( @param id expected block->page.id() @return block if it was buffer-fixed @retval nullptr if the block no longer is valid */ -buf_block_t *buf_page_optimistic_fix(buf_block_t *block, page_id_t id) +buf_block_t *buf_page_optimistic_fix(buf_block_t *block, page_id_t id) noexcept MY_ATTRIBUTE((nonnull, warn_unused_result)); /** Try to acquire a page latch after buf_page_optimistic_fix(). @@ -165,7 +165,8 @@ buf_block_t *buf_page_optimistic_fix(buf_block_t *block, page_id_t id) @retval nullptr if block->unfix() was called because it no longer is valid */ buf_block_t *buf_page_optimistic_get(buf_block_t *block, rw_lock_type_t rw_latch, - uint64_t modify_clock, mtr_t *mtr) + uint64_t modify_clock, + mtr_t *mtr) noexcept MY_ATTRIBUTE((nonnull, warn_unused_result)); /** Try to S-latch a page. @@ -174,14 +175,14 @@ Suitable for using when holding the lock_sys latches (as it avoids deadlock). @param[in,out] mtr mini-transaction @return the block @retval nullptr if an S-latch cannot be granted immediately */ -buf_block_t *buf_page_try_get(const page_id_t page_id, mtr_t *mtr); +buf_block_t *buf_page_try_get(const page_id_t page_id, mtr_t *mtr) noexcept; /** Get read access to a compressed page (usually of type FIL_PAGE_TYPE_ZBLOB or FIL_PAGE_TYPE_ZBLOB2). The page must be released with s_unlock(). @param page_id page identifier @return pointer to the block, s-latched */ -buf_page_t *buf_page_get_zip(const page_id_t page_id); +buf_page_t *buf_page_get_zip(const page_id_t page_id) noexcept; /** Get access to a database page. Buffered redo log may be applied. @param[in] page_id page id @@ -204,7 +205,7 @@ buf_page_get_gen( ulint mode, mtr_t* mtr, dberr_t* err = nullptr, - bool allow_ibuf_merge = false) + bool allow_ibuf_merge = false) noexcept MY_ATTRIBUTE((nonnull(6), warn_unused_result)); /** This is the low level function used to get access to a database page. @@ -229,7 +230,7 @@ buf_page_get_low( ulint mode, mtr_t* mtr, dberr_t* err, - bool allow_ibuf_merge) + bool allow_ibuf_merge) noexcept MY_ATTRIBUTE((nonnull(6), warn_unused_result)); /** Initialize a page in the buffer pool. The page is usually not read @@ -244,7 +245,8 @@ of the functions which perform to a block a state transition NOT_USED => LRU @return pointer to the block, page bufferfixed */ buf_block_t* buf_page_create(fil_space_t *space, uint32_t offset, - ulint zip_size, mtr_t *mtr, buf_block_t *free_block); + ulint zip_size, mtr_t *mtr, buf_block_t *free_block) + noexcept; /** Initialize a page in buffer pool while initializing the deferred tablespace @@ -255,7 +257,7 @@ deferred tablespace @return pointer to the block, page bufferfixed */ buf_block_t* buf_page_create_deferred(uint32_t space_id, ulint zip_size, mtr_t *mtr, - buf_block_t *free_block); + buf_block_t *free_block) noexcept; /** Mark the page status as FREED for the given tablespace and page number. @param[in,out] space tablespace @@ -292,7 +294,7 @@ buf_block_modify_clock_inc( /** Check if a buffer is all zeroes. @param[in] buf data to check @return whether the buffer is all zeroes */ -bool buf_is_zeroes(st_::span buf); +bool buf_is_zeroes(st_::span buf) noexcept; /** Reason why buf_page_is_corrupted() fails */ enum buf_page_is_corrupted_reason @@ -311,7 +313,7 @@ buf_page_is_corrupted_reason buf_page_is_corrupted( bool check_lsn, const byte* read_buf, - ulint fsp_flags) + ulint fsp_flags) noexcept MY_ATTRIBUTE((warn_unused_result)); /** Read the key version from the page. In full crc32 format, @@ -320,7 +322,8 @@ stored in 26th position. @param[in] read_buf database page @param[in] fsp_flags tablespace flags @return key version of the page. */ -inline uint32_t buf_page_get_key_version(const byte* read_buf, ulint fsp_flags) +inline uint32_t buf_page_get_key_version(const byte *read_buf, ulint fsp_flags) + noexcept { static_assert(FIL_PAGE_FCRC32_KEY_VERSION == 0, "compatibility"); return fil_space_t::full_crc32(fsp_flags) @@ -335,7 +338,8 @@ stored in page type. @param[in] read_buf database page @param[in] fsp_flags tablespace flags @return true if page is compressed. */ -inline bool buf_page_is_compressed(const byte* read_buf, ulint fsp_flags) +inline bool buf_page_is_compressed(const byte *read_buf, ulint fsp_flags) + noexcept { uint16_t page_type= fil_page_get_type(read_buf); return fil_space_t::full_crc32(fsp_flags) @@ -348,7 +352,8 @@ inline bool buf_page_is_compressed(const byte* read_buf, ulint fsp_flags) @param[out] comp whether the page could be compressed @param[out] cr whether the page could be corrupted @return the payload size in the file page */ -inline uint buf_page_full_crc32_size(const byte* buf, bool* comp, bool* cr) +inline uint buf_page_full_crc32_size(const byte *buf, bool *comp, bool *cr) + noexcept { uint t = fil_page_get_type(buf); uint page_size = uint(srv_page_size); @@ -376,20 +381,17 @@ inline uint buf_page_full_crc32_size(const byte* buf, bool* comp, bool* cr) /** Dump a page to stderr. @param[in] read_buf database page @param[in] zip_size compressed page size, or 0 */ -void buf_page_print(const byte* read_buf, ulint zip_size = 0) +void buf_page_print(const byte* read_buf, ulint zip_size = 0) noexcept ATTRIBUTE_COLD __attribute__((nonnull)); -/********************************************************************//** -Decompress a block. +/** Decompress a ROW_FORMAT=COMPRESSED block. +@param block buffer page +@param check whether to verify the page checksum @return true if successful */ -bool -buf_zip_decompress( -/*===============*/ - buf_block_t* block, /*!< in/out: block */ - ibool check); /*!< in: TRUE=verify the page checksum */ +bool buf_zip_decompress(buf_block_t *block, bool check) noexcept; #ifdef UNIV_DEBUG /** @return the number of latched pages in the buffer pool */ -ulint buf_get_latched_pages_number(); +ulint buf_get_latched_pages_number() noexcept; #endif /* UNIV_DEBUG */ /*********************************************************************//** Prints info of the buffer i/o. */ @@ -399,14 +401,14 @@ buf_print_io( FILE* file); /*!< in: file where to print */ /** Collect buffer pool metadata. @param[out] pool_info buffer pool metadata */ -void buf_stats_get_pool_info(buf_pool_info_t *pool_info); +void buf_stats_get_pool_info(buf_pool_info_t *pool_info) noexcept; /** Refresh the statistics used to print per-second averages. */ -void buf_refresh_io_stats(); +void buf_refresh_io_stats() noexcept; /** Invalidate all pages in the buffer pool. All pages must be in a replaceable state (not modified or latched). */ -void buf_pool_invalidate(); +void buf_pool_invalidate() noexcept; /*======================================================================== --------------------------- LOWER LEVEL ROUTINES ------------------------- @@ -426,15 +428,14 @@ if applicable. */ counter value in MONITOR_MODULE_BUF_PAGE. @param bpage buffer page whose read or write was completed @param read true=read, false=write */ -ATTRIBUTE_COLD void buf_page_monitor(const buf_page_t &bpage, bool read); +ATTRIBUTE_COLD void buf_page_monitor(const buf_page_t &bpage, bool read) + noexcept; /** Calculate aligned buffer pool size based on srv_buf_pool_chunk_unit, if needed. @param[in] size size in bytes @return aligned size */ -ulint -buf_pool_size_align( - ulint size); +ulint buf_pool_size_align(ulint size) noexcept; /** Verify that post encryption checksum match with the calculated checksum. This function should be called only if tablespace contains crypt data metadata. @@ -443,12 +444,12 @@ This function should be called only if tablespace contains crypt data metadata. @return true if page is encrypted and OK, false otherwise */ bool buf_page_verify_crypt_checksum( const byte* page, - ulint fsp_flags); + ulint fsp_flags) noexcept; /** Calculate a ROW_FORMAT=COMPRESSED page checksum and update the page. @param[in,out] page page to update @param[in] size compressed page size */ -void buf_flush_update_zip_checksum(buf_frame_t* page, ulint size); +void buf_flush_update_zip_checksum(buf_frame_t* page, ulint size) noexcept; /** @brief The temporary memory structure. @@ -471,14 +472,15 @@ public: byte *out_buf; /** Release the slot */ - void release() { reserved.store(false, std::memory_order_relaxed); } + void release() noexcept { reserved.store(false, std::memory_order_relaxed); } /** Acquire the slot @return whether the slot was acquired */ - bool acquire() { return !reserved.exchange(true, std::memory_order_relaxed);} + bool acquire() noexcept + { return !reserved.exchange(true, std::memory_order_relaxed);} /** Allocate a buffer for encryption, decryption or decompression. */ - void allocate() + void allocate() noexcept { if (!crypt_buf) crypt_buf= static_cast @@ -629,7 +631,7 @@ public: } /** Initialize some more fields */ - void init(uint32_t state, page_id_t id) + void init(uint32_t state, page_id_t id) noexcept { ut_ad(state < REMOVE_HASH || state >= UNFIXED); ut_ad(!lock.is_locked_or_waiting()); @@ -646,45 +648,46 @@ public: } public: - const page_id_t &id() const { return id_; } - uint32_t state() const { return zip.fix; } - static uint32_t buf_fix_count(uint32_t s) + const page_id_t &id() const noexcept { return id_; } + uint32_t state() const noexcept { return zip.fix; } + static uint32_t buf_fix_count(uint32_t s) noexcept { ut_ad(s >= FREED); return s < UNFIXED ? (s - FREED) : (~LRU_MASK & s); } uint32_t buf_fix_count() const { return buf_fix_count(state()); } /** Check if a file block is io-fixed. @param s state() @return whether s corresponds to an io-fixed block */ - static bool is_io_fixed(uint32_t s) + static bool is_io_fixed(uint32_t s) noexcept { ut_ad(s >= FREED); return s >= READ_FIX; } /** Check if a file block is read-fixed. @param s state() @return whether s corresponds to a read-fixed block */ - static bool is_read_fixed(uint32_t s) + static bool is_read_fixed(uint32_t s) noexcept { return is_io_fixed(s) && s < WRITE_FIX; } /** Check if a file block is write-fixed. @param s state() @return whether s corresponds to a write-fixed block */ - static bool is_write_fixed(uint32_t s) + static bool is_write_fixed(uint32_t s) noexcept { ut_ad(s >= FREED); return s >= WRITE_FIX; } /** @return whether this block is read or write fixed; read_complete() or write_complete() will always release the io-fix before releasing U-lock or X-lock */ - bool is_io_fixed() const { return is_io_fixed(state()); } + bool is_io_fixed() const noexcept { return is_io_fixed(state()); } /** @return whether this block is write fixed; write_complete() will always release the write-fix before releasing U-lock */ - bool is_write_fixed() const { return is_write_fixed(state()); } + bool is_write_fixed() const noexcept { return is_write_fixed(state()); } /** @return whether this block is read fixed */ - bool is_read_fixed() const { return is_read_fixed(state()); } + bool is_read_fixed() const noexcept { return is_read_fixed(state()); } /** @return if this belongs to buf_pool.unzip_LRU */ - bool belongs_to_unzip_LRU() const + bool belongs_to_unzip_LRU() const noexcept { return UNIV_LIKELY_NULL(zip.data) && frame; } - static bool is_freed(uint32_t s) { ut_ad(s >= FREED); return s < UNFIXED; } - bool is_freed() const { return is_freed(state()); } - static bool is_ibuf_exist(uint32_t s) + static bool is_freed(uint32_t s) noexcept + { ut_ad(s >= FREED); return s < UNFIXED; } + bool is_freed() const noexcept { return is_freed(state()); } + static bool is_ibuf_exist(uint32_t s) noexcept { ut_ad(s >= UNFIXED); ut_ad(s < READ_FIX); @@ -693,7 +696,7 @@ public: bool is_ibuf_exist() const { return is_ibuf_exist(state()); } bool is_reinit() const { return !(~state() & REINIT); } - void set_reinit(uint32_t prev_state) + void set_reinit(uint32_t prev_state) noexcept { ut_ad(prev_state < READ_FIX); ut_d(const auto s=) zip.fix.fetch_add(REINIT - prev_state); @@ -701,7 +704,7 @@ public: ut_ad(s < prev_state + UNFIXED); } - void set_ibuf_exist() + void set_ibuf_exist() noexcept { ut_ad(lock.is_write_locked()); ut_ad(id() < page_id_t(SRV_SPACE_ID_UPPER_BOUND, 0)); @@ -711,7 +714,7 @@ public: ut_ad(s < IBUF_EXIST || s >= REINIT); zip.fix.fetch_add(IBUF_EXIST - (LRU_MASK & s)); } - void clear_ibuf_exist() + void clear_ibuf_exist() noexcept { ut_ad(lock.is_write_locked()); ut_ad(id() < page_id_t(SRV_SPACE_ID_UPPER_BOUND, 0)); @@ -720,7 +723,7 @@ public: ut_ad(s < REINIT); } - uint32_t read_unfix(uint32_t s) + uint32_t read_unfix(uint32_t s) noexcept { ut_ad(lock.is_write_locked()); ut_ad(s == UNFIXED + 1 || s == IBUF_EXIST + 1 || s == REINIT + 1); @@ -730,7 +733,7 @@ public: return old_state + (s - READ_FIX); } - void set_freed(uint32_t prev_state, uint32_t count= 0) + void set_freed(uint32_t prev_state, uint32_t count= 0) noexcept { ut_ad(lock.is_write_locked()); ut_ad(prev_state >= UNFIXED); @@ -739,28 +742,28 @@ public: ut_ad(!((prev_state ^ s) & LRU_MASK)); } - inline void set_state(uint32_t s); - inline void set_corrupt_id(); + inline void set_state(uint32_t s) noexcept; + inline void set_corrupt_id() noexcept; /** @return the log sequence number of the oldest pending modification @retval 0 if the block is being removed from (or not in) buf_pool.flush_list @retval 1 if the block is in buf_pool.flush_list but not modified @retval 2 if the block belongs to the temporary tablespace and has unwritten changes */ - lsn_t oldest_modification() const { return oldest_modification_; } + lsn_t oldest_modification() const noexcept { return oldest_modification_; } /** @return the log sequence number of the oldest pending modification, @retval 0 if the block is definitely not in buf_pool.flush_list @retval 1 if the block is in buf_pool.flush_list but not modified @retval 2 if the block belongs to the temporary tablespace and has unwritten changes */ - lsn_t oldest_modification_acquire() const + lsn_t oldest_modification_acquire() const noexcept { return oldest_modification_.load(std::memory_order_acquire); } /** Set oldest_modification when adding to buf_pool.flush_list */ - inline void set_oldest_modification(lsn_t lsn); + inline void set_oldest_modification(lsn_t lsn) noexcept; /** Clear oldest_modification after removing from buf_pool.flush_list */ - inline void clear_oldest_modification(); + inline void clear_oldest_modification() noexcept; /** Reset the oldest_modification when marking a persistent page freed */ - void reset_oldest_modification() + void reset_oldest_modification() noexcept { ut_ad(oldest_modification() > 2); oldest_modification_.store(1, std::memory_order_release); @@ -771,21 +774,21 @@ public: @return whether the operation succeeded @retval DB_PAGE_CORRUPTED if the checksum or the page ID is incorrect @retval DB_DECRYPTION_FAILED if the page cannot be decrypted */ - dberr_t read_complete(const fil_node_t &node); + dberr_t read_complete(const fil_node_t &node) noexcept; /** Release a write fix after a page write was completed. @param persistent whether the page belongs to a persistent tablespace @param error whether an error may have occurred while writing @param state recently read state() value with the correct io-fix */ - void write_complete(bool persistent, bool error, uint32_t state); + void write_complete(bool persistent, bool error, uint32_t state) noexcept; /** Write a flushable page to a file or free a freeable block. @param space tablespace @return whether a page write was initiated and buf_pool.mutex released */ - bool flush(fil_space_t *space); + bool flush(fil_space_t *space) noexcept; /** Notify that a page in a temporary tablespace has been modified. */ - void set_temp_modified() + void set_temp_modified() noexcept { ut_ad(fsp_is_system_temporary(id().space())); ut_ad(in_file()); @@ -794,7 +797,7 @@ public: } /** Prepare to release a file page to buf_pool.free. */ - void free_file_page() + void free_file_page() noexcept { ut_ad((zip.fix.fetch_sub(REMOVE_HASH - MEMORY)) == REMOVE_HASH); /* buf_LRU_block_free_non_file_page() asserts !oldest_modification() */ @@ -802,14 +805,14 @@ public: id_= page_id_t(~0ULL); } - void fix_on_recovery() + void fix_on_recovery() noexcept { ut_d(const auto f=) zip.fix.fetch_sub(READ_FIX - UNFIXED - 1); ut_ad(f >= READ_FIX); ut_ad(f < WRITE_FIX); } - uint32_t fix(uint32_t count= 1) + uint32_t fix(uint32_t count= 1) noexcept { ut_ad(count); ut_ad(count < IBUF_EXIST); @@ -819,7 +822,7 @@ public: return f; } - uint32_t unfix() + uint32_t unfix() noexcept { uint32_t f= zip.fix.fetch_sub(1); ut_ad(f > FREED); @@ -828,20 +831,20 @@ public: } /** @return the physical size, in bytes */ - ulint physical_size() const + ulint physical_size() const noexcept { return zip.ssize ? (UNIV_ZIP_SIZE_MIN >> 1) << zip.ssize : srv_page_size; } /** @return the ROW_FORMAT=COMPRESSED physical size, in bytes @retval 0 if not compressed */ - ulint zip_size() const + ulint zip_size() const noexcept { return zip.ssize ? (UNIV_ZIP_SIZE_MIN >> 1) << zip.ssize : 0; } /** @return the byte offset of the page within a file */ - os_offset_t physical_offset() const + os_offset_t physical_offset() const noexcept { os_offset_t o= id().page_no(); return zip.ssize @@ -850,18 +853,18 @@ public: } /** @return whether the block is mapped to a data file */ - bool in_file() const { return state() >= FREED; } + bool in_file() const noexcept { return state() >= FREED; } /** @return whether the block can be relocated in memory. The block can be dirty, but it must not be I/O-fixed or bufferfixed. */ - inline bool can_relocate() const; + inline bool can_relocate() const noexcept; /** @return whether the block has been flagged old in buf_pool.LRU */ - inline bool is_old() const; + inline bool is_old() const noexcept; /** Set whether a block is old in buf_pool.LRU */ - inline void set_old(bool old); + inline void set_old(bool old) noexcept; /** Flag a page accessed in buf_pool @return whether this is not the first access */ - bool set_accessed() + bool set_accessed() noexcept { if (is_accessed()) return true; access_time= static_cast(ut_time_ms()); @@ -869,7 +872,8 @@ public: } /** @return ut_time_ms() at the time of first access of a block in buf_pool @retval 0 if not accessed */ - unsigned is_accessed() const { ut_ad(in_file()); return access_time; } + unsigned is_accessed() const noexcept + { ut_ad(in_file()); return access_time; } }; /** The buffer control block structure */ @@ -999,21 +1003,22 @@ struct buf_block_t{ # define assert_block_ahi_empty_on_init(block) /* nothing */ # define assert_block_ahi_valid(block) /* nothing */ #endif /* BTR_CUR_HASH_ADAPT */ - void fix() { page.fix(); } - uint32_t unfix() { return page.unfix(); } + void fix() noexcept { page.fix(); } + uint32_t unfix() noexcept { return page.unfix(); } /** @return the physical size, in bytes */ - ulint physical_size() const { return page.physical_size(); } + ulint physical_size() const noexcept { return page.physical_size(); } /** @return the ROW_FORMAT=COMPRESSED physical size, in bytes @retval 0 if not compressed */ - ulint zip_size() const { return page.zip_size(); } + ulint zip_size() const noexcept { return page.zip_size(); } /** Initialize the block. @param page_id page identifier @param zip_size ROW_FORMAT=COMPRESSED page size, or 0 @param state initial state() */ - void initialise(const page_id_t page_id, ulint zip_size, uint32_t state); + void initialise(const page_id_t page_id, ulint zip_size, uint32_t state) + noexcept; }; /**********************************************************************//** @@ -1034,11 +1039,12 @@ public: virtual ~HazardPointer() = default; /** @return current value */ - buf_page_t *get() const { mysql_mutex_assert_owner(m_mutex); return m_hp; } + buf_page_t *get() const noexcept + { mysql_mutex_assert_owner(m_mutex); return m_hp; } /** Set current value @param bpage buffer block to be set as hp */ - void set(buf_page_t *bpage) + void set(buf_page_t *bpage) noexcept { mysql_mutex_assert_owner(m_mutex); ut_ad(!bpage || bpage->in_file()); @@ -1048,13 +1054,13 @@ public: /** Checks if a bpage is the hp @param bpage buffer block to be compared @return true if it is hp */ - bool is_hp(const buf_page_t *bpage) const + bool is_hp(const buf_page_t *bpage) const noexcept { mysql_mutex_assert_owner(m_mutex); return bpage == m_hp; } /** Adjust the value of hp. This happens when some other thread working on the same list attempts to remove the hp from the list. */ - virtual void adjust(const buf_page_t*) = 0; + virtual void adjust(const buf_page_t*) noexcept = 0; #ifdef UNIV_DEBUG /** mutex that protects access to the m_hp. */ @@ -1077,7 +1083,7 @@ public: remove the hp from the list. @param bpage buffer block to be compared */ MY_ATTRIBUTE((nonnull)) - void adjust(const buf_page_t *bpage) override + void adjust(const buf_page_t *bpage) noexcept override { /* We only support reverse traversal for now. */ if (is_hp(bpage)) @@ -1097,7 +1103,7 @@ public: remove the hp from the list. @param bpage buffer block to be compared */ MY_ATTRIBUTE((nonnull)) - void adjust(const buf_page_t *bpage) override + void adjust(const buf_page_t *bpage) noexcept override { /** We only support reverse traversal for now. */ if (is_hp(bpage)) @@ -1119,7 +1125,7 @@ public: too deep into the LRU list it resets the value to the tail of the LRU list. @return buf_page_t from where to start scan. */ - inline buf_page_t *start(); + inline buf_page_t *start() noexcept; }; /** Struct that is embedded in the free zip blocks */ @@ -1146,7 +1152,7 @@ struct buf_buddy_free_t { protected by buf_pool.mutex unless otherwise noted. */ struct buf_pool_stat_t{ /** Initialize the counters */ - void init() { memset((void*) this, 0, sizeof *this); } + void init() noexcept { memset((void*) this, 0, sizeof *this); } ib_counter_t n_page_gets; /*!< number of page gets performed; @@ -1210,22 +1216,23 @@ class buf_pool_t static map *map_ref; /** @return the memory size bytes. */ - size_t mem_size() const { return mem_pfx.m_size; } + size_t mem_size() const noexcept { return mem_pfx.m_size; } /** Register the chunk */ - void reg() { map_reg->emplace(map::value_type(blocks->page.frame, this)); } + void reg() noexcept + { map_reg->emplace(map::value_type(blocks->page.frame, this)); } /** Allocate a chunk of buffer frames. @param bytes requested size @return whether the allocation succeeded */ - inline bool create(size_t bytes); + inline bool create(size_t bytes) noexcept; #ifdef UNIV_DEBUG /** Find a block that points to a ROW_FORMAT=COMPRESSED page @param data pointer to the start of a ROW_FORMAT=COMPRESSED page frame @return the block @retval nullptr if not found */ - const buf_block_t *contains_zip(const void *data) const + const buf_block_t *contains_zip(const void *data) const noexcept { const buf_block_t *block= blocks; for (auto i= size; i--; block++) @@ -1237,7 +1244,7 @@ class buf_pool_t /** Check that all blocks are in a replaceable state. @return address of a non-free block @retval nullptr if all freed */ - inline const buf_block_t *not_freed() const; + inline const buf_block_t *not_freed() const noexcept; #endif /* UNIV_DEBUG */ }; public: @@ -1250,13 +1257,13 @@ public: private: /** Withdraw blocks from the buffer pool until meeting withdraw_target. @return whether retry is needed */ - inline bool withdraw_blocks(); + inline bool withdraw_blocks() noexcept; /** Determine if a pointer belongs to a buf_block_t. It can be a pointer to the buf_block_t itself or a member of it. @param ptr a pointer that will not be dereferenced @return whether the ptr belongs to a buf_block_t struct */ - bool is_block_field(const void *ptr) const + bool is_block_field(const void *ptr) const noexcept { const chunk_t *chunk= chunks; const chunk_t *const echunk= chunk + ut_min(n_chunks, n_chunks_new); @@ -1273,29 +1280,29 @@ private: /** Try to reallocate a control block. @param block control block to reallocate @return whether the reallocation succeeded */ - inline bool realloc(buf_block_t *block); + inline bool realloc(buf_block_t *block) noexcept; public: - bool is_initialised() const { return chunks != nullptr; } + bool is_initialised() const noexcept { return chunks != nullptr; } /** Create the buffer pool. @return whether the creation failed */ bool create(); /** Clean up after successful create() */ - void close(); + void close() noexcept; /** Resize from srv_buf_pool_old_size to srv_buf_pool_size. */ inline void resize(); /** @return whether resize() is in progress */ - bool resize_in_progress() const + bool resize_in_progress() const noexcept { return UNIV_UNLIKELY(resizing.load(std::memory_order_relaxed)); } /** @return the current size in blocks */ - size_t get_n_pages() const + size_t get_n_pages() const noexcept { ut_ad(is_initialised()); size_t size= 0; @@ -1307,7 +1314,7 @@ public: /** Determine whether a frame is intended to be withdrawn during resize(). @param ptr pointer within a buf_page_t::frame @return whether the frame will be withdrawn */ - bool will_be_withdrawn(const byte *ptr) const + bool will_be_withdrawn(const byte *ptr) const noexcept { ut_ad(n_chunks_new < n_chunks); #ifdef SAFE_MUTEX @@ -1327,7 +1334,7 @@ public: /** Determine whether a block is intended to be withdrawn during resize(). @param bpage buffer pool block @return whether the frame will be withdrawn */ - bool will_be_withdrawn(const buf_page_t &bpage) const + bool will_be_withdrawn(const buf_page_t &bpage) const noexcept { ut_ad(n_chunks_new < n_chunks); #ifdef SAFE_MUTEX @@ -1358,7 +1365,7 @@ public: @param data pointer to the start of a ROW_FORMAT=COMPRESSED page frame @return the block @retval nullptr if not found */ - const buf_block_t *contains_zip(const void *data) const + const buf_block_t *contains_zip(const void *data) const noexcept { mysql_mutex_assert_owner(&mutex); for (const chunk_t *chunk= chunks, * const end= chunks + n_chunks; @@ -1369,24 +1376,24 @@ public: } /** Assert that all buffer pool pages are in a replaceable state */ - void assert_all_freed(); + void assert_all_freed() noexcept; #endif /* UNIV_DEBUG */ #ifdef BTR_CUR_HASH_ADAPT /** Clear the adaptive hash index on all pages in the buffer pool. */ - inline void clear_hash_index(); + inline void clear_hash_index() noexcept; /** Get a buffer block from an adaptive hash index pointer. This function does not return if the block is not identified. @param ptr pointer to within a page frame @return pointer to block, never NULL */ - inline buf_block_t *block_from_ahi(const byte *ptr) const; + inline buf_block_t *block_from_ahi(const byte *ptr) const noexcept; #endif /* BTR_CUR_HASH_ADAPT */ /** @return the smallest oldest_modification lsn for any page @retval empty_lsn if all modified persistent pages have been flushed */ - lsn_t get_oldest_modification(lsn_t empty_lsn) + lsn_t get_oldest_modification(lsn_t empty_lsn) noexcept { mysql_mutex_assert_owner(&flush_list_mutex); while (buf_page_t *bpage= UT_LIST_GET_LAST(flush_list)) @@ -1406,7 +1413,7 @@ public: /** Determine if a buffer block was created by chunk_t::create(). @param block block descriptor (not dereferenced) @return whether block has been created by chunk_t::create() */ - bool is_uncompressed(const buf_block_t *block) const + bool is_uncompressed(const buf_block_t *block) const noexcept { return is_block_field(reinterpret_cast(block)); } @@ -1436,19 +1443,18 @@ public: @retval -1 if c=FIX_NOWAIT and buffer-fixing would require waiting @retval nullptr if the undo page was corrupted or freed */ buf_block_t *page_fix(const page_id_t id, dberr_t *err, - page_fix_conflicts c); + page_fix_conflicts c) noexcept; - buf_block_t *page_fix(const page_id_t id) + buf_block_t *page_fix(const page_id_t id) noexcept { return page_fix(id, nullptr, FIX_WAIT_READ); } - /** Decompress a page and relocate the block descriptor @param b buffer-fixed compressed-only ROW_FORMAT=COMPRESSED page @param chain hash table chain for b->id().fold() @return the decompressed block, x-latched and read-fixed @retval nullptr if the decompression failed (b->unfix() will be invoked) */ ATTRIBUTE_COLD __attribute__((nonnull, warn_unused_result)) - buf_block_t *unzip(buf_page_t *b, hash_chain &chain); + buf_block_t *unzip(buf_page_t *b, hash_chain &chain) noexcept; /** @return whether the buffer pool contains a page @tparam allow_watch whether to allow watch_is_sentinel() @@ -1456,7 +1462,7 @@ public: @param chain hash table chain for page_id.fold() */ template TRANSACTIONAL_INLINE - bool page_hash_contains(const page_id_t page_id, hash_chain &chain) + bool page_hash_contains(const page_id_t page_id, hash_chain &chain) noexcept { transactional_shared_lock_guard g {page_hash.lock_get(chain)}; @@ -1474,7 +1480,7 @@ public: /** Determine if a block is a sentinel for a buffer pool watch. @param bpage page descriptor @return whether bpage a sentinel for a buffer pool watch */ - bool watch_is_sentinel(const buf_page_t &bpage) + bool watch_is_sentinel(const buf_page_t &bpage) noexcept { #ifdef SAFE_MUTEX DBUG_ASSERT(mysql_mutex_is_owner(&mutex) || @@ -1494,7 +1500,7 @@ public: @param id page identifier @return whether the page was read to the buffer pool */ TRANSACTIONAL_INLINE - bool watch_occurred(const page_id_t id) + bool watch_occurred(const page_id_t id) noexcept { hash_chain &chain= page_hash.cell_get(id.fold()); transactional_shared_lock_guard g @@ -1508,13 +1514,13 @@ public: @param chain page_hash.cell_get(id.fold()) @return a buffer page corresponding to id @retval nullptr if the block was not present in page_hash */ - buf_page_t *watch_set(const page_id_t id, hash_chain &chain); + buf_page_t *watch_set(const page_id_t id, hash_chain &chain) noexcept; /** Stop watching whether a page has been read in. watch_set(id) must have returned nullptr before. @param id page identifier @param chain unlocked hash table chain */ - void watch_unset(const page_id_t id, hash_chain &chain); + void watch_unset(const page_id_t id, hash_chain &chain) noexcept; /** Remove the sentinel block for the watch before replacing it with a real block. watch_unset() or watch_occurred() will notice @@ -1522,11 +1528,11 @@ public: @param w sentinel @param chain locked hash table chain @return w->state() */ - inline uint32_t watch_remove(buf_page_t *w, hash_chain &chain); + inline uint32_t watch_remove(buf_page_t *w, hash_chain &chain) noexcept; /** @return whether less than 1/4 of the buffer pool is available */ TPOOL_SUPPRESS_TSAN - bool running_out() const + bool running_out() const noexcept { return !recv_recovery_is_on() && UT_LIST_GET_LEN(free) + UT_LIST_GET_LEN(LRU) < @@ -1534,26 +1540,26 @@ public: } /** @return whether the buffer pool is running low */ - bool need_LRU_eviction() const; + bool need_LRU_eviction() const noexcept; /** @return whether the buffer pool is shrinking */ - inline bool is_shrinking() const + inline bool is_shrinking() const noexcept { return n_chunks_new < n_chunks; } #ifdef UNIV_DEBUG /** Validate the buffer pool. */ - void validate(); + void validate() noexcept; #endif /* UNIV_DEBUG */ #if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG /** Write information of the buf_pool to the error log. */ - void print(); + void print() noexcept; #endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG */ /** Remove a block from the LRU list. @return the predecessor in the LRU list */ - buf_page_t *LRU_remove(buf_page_t *bpage) + buf_page_t *LRU_remove(buf_page_t *bpage) noexcept { mysql_mutex_assert_owner(&mutex); ut_ad(bpage->in_LRU_list); @@ -1621,15 +1627,16 @@ public: /** Create the hash table. @param n the lower bound of n_cells */ - void create(ulint n); + void create(ulint n) noexcept; /** Free the hash table. */ - void free() { aligned_free(array); array= nullptr; } + void free() noexcept { aligned_free(array); array= nullptr; } /** @return the index of an array element */ - ulint calc_hash(ulint fold) const { return calc_hash(fold, n_cells); } + ulint calc_hash(ulint fold) const noexcept + { return calc_hash(fold, n_cells); } /** @return raw array index converted to padded index */ - static ulint pad(ulint h) + static ulint pad(ulint h) noexcept { ulint latches= h / ELEMENTS_PER_LATCH; ulint empty_slots= latches * EMPTY_SLOTS_PER_LATCH; @@ -1643,7 +1650,7 @@ public: } public: /** @return the latch covering a hash table chain */ - static page_hash_latch &lock_get(hash_chain &chain) + static page_hash_latch &lock_get(hash_chain &chain) noexcept { static_assert(!((ELEMENTS_PER_LATCH + 1) & ELEMENTS_PER_LATCH), "must be one less than a power of 2"); @@ -1658,7 +1665,7 @@ public: { return array[calc_hash(fold, n_cells)]; } /** Append a block descriptor to a hash bucket chain. */ - void append(hash_chain &chain, buf_page_t *bpage) + void append(hash_chain &chain, buf_page_t *bpage) noexcept { ut_ad(!bpage->in_page_hash); ut_ad(!bpage->hash); @@ -1673,7 +1680,7 @@ public: } /** Remove a block descriptor from a hash bucket chain. */ - void remove(hash_chain &chain, buf_page_t *bpage) + void remove(hash_chain &chain, buf_page_t *bpage) noexcept { ut_ad(bpage->in_page_hash); buf_page_t **prev= &chain.first; @@ -1689,6 +1696,7 @@ public: /** Replace a block descriptor with another. */ void replace(hash_chain &chain, buf_page_t *old, buf_page_t *bpage) + noexcept { ut_ad(old->in_page_hash); ut_ad(bpage->in_page_hash); @@ -1705,13 +1713,14 @@ public: } /** Look up a page in a hash bucket chain. */ - inline buf_page_t *get(const page_id_t id, const hash_chain &chain) const; + inline buf_page_t *get(const page_id_t id, const hash_chain &chain) const + noexcept; /** Exclusively aqcuire all latches */ - inline void write_lock_all(); + inline void write_lock_all() noexcept; /** Release all latches */ - inline void write_unlock_all(); + inline void write_unlock_all() noexcept; }; /** Buffer pool mutex */ @@ -1778,45 +1787,45 @@ public: pthread_cond_t done_flush_list; /** @return number of pending LRU flush */ - unsigned n_flush() const + unsigned n_flush() const noexcept { mysql_mutex_assert_owner(&flush_list_mutex); return page_cleaner_status / LRU_FLUSH; } /** Increment the number of pending LRU flush */ - inline void n_flush_inc(); + inline void n_flush_inc() noexcept; /** Decrement the number of pending LRU flush */ - inline void n_flush_dec(); + inline void n_flush_dec() noexcept; /** @return whether flush_list flushing is active */ - bool flush_list_active() const + bool flush_list_active() const noexcept { mysql_mutex_assert_owner(&flush_list_mutex); return page_cleaner_status & FLUSH_LIST_ACTIVE; } - void flush_list_set_active() + void flush_list_set_active() noexcept { ut_ad(!flush_list_active()); page_cleaner_status+= FLUSH_LIST_ACTIVE; } - void flush_list_set_inactive() + void flush_list_set_inactive() noexcept { ut_ad(flush_list_active()); page_cleaner_status-= FLUSH_LIST_ACTIVE; } /** @return whether the page cleaner must sleep due to being idle */ - bool page_cleaner_idle() const + bool page_cleaner_idle() const noexcept { mysql_mutex_assert_owner(&flush_list_mutex); return page_cleaner_status & PAGE_CLEANER_IDLE; } /** @return whether the page cleaner may be initiating writes */ - bool page_cleaner_active() const + bool page_cleaner_active() const noexcept { mysql_mutex_assert_owner(&flush_list_mutex); static_assert(PAGE_CLEANER_IDLE == 1, "efficiency"); @@ -1825,10 +1834,10 @@ public: /** Wake up the page cleaner if needed. @param for_LRU whether to wake up for LRU eviction */ - void page_cleaner_wakeup(bool for_LRU= false); + void page_cleaner_wakeup(bool for_LRU= false) noexcept; /** Register whether an explicit wakeup of the page cleaner is needed */ - void page_cleaner_set_idle(bool deep_sleep) + void page_cleaner_set_idle(bool deep_sleep) noexcept { mysql_mutex_assert_owner(&flush_list_mutex); page_cleaner_status= (page_cleaner_status & ~PAGE_CLEANER_IDLE) | @@ -1836,7 +1845,7 @@ public: } /** Update server last activity count */ - void update_last_activity_count(ulint activity_count) + void update_last_activity_count(ulint activity_count) noexcept { mysql_mutex_assert_owner(&flush_list_mutex); last_activity_count= activity_count; @@ -1920,27 +1929,27 @@ public: a delete-buffering operation is pending. Protected by mutex. */ buf_page_t watch[innodb_purge_threads_MAX + 1]; /** Reserve a buffer. */ - buf_tmp_buffer_t *io_buf_reserve(bool wait_for_reads) + buf_tmp_buffer_t *io_buf_reserve(bool wait_for_reads) noexcept { return io_buf.reserve(wait_for_reads); } private: /** Remove a block from the flush list. */ - inline void delete_from_flush_list_low(buf_page_t *bpage); + inline void delete_from_flush_list_low(buf_page_t *bpage) noexcept; public: /** Remove a block from flush_list. @param bpage buffer pool page */ - void delete_from_flush_list(buf_page_t *bpage); + void delete_from_flush_list(buf_page_t *bpage) noexcept; /** Insert a modified block into the flush list. @param block modified block @param lsn start LSN of the mini-transaction that modified the block */ - void insert_into_flush_list(buf_block_t *block, lsn_t lsn); + void insert_into_flush_list(buf_block_t *block, lsn_t lsn) noexcept; /** Free a page whose underlying file page has been freed. */ - ATTRIBUTE_COLD void release_freed_page(buf_page_t *bpage); + ATTRIBUTE_COLD void release_freed_page(buf_page_t *bpage) noexcept; /** Issue a warning that we could not free up buffer pool pages. */ - ATTRIBUTE_COLD void LRU_warn(); + ATTRIBUTE_COLD void LRU_warn() noexcept; private: /** Temporary memory for page_compressed and encrypted I/O */ @@ -1951,12 +1960,12 @@ private: /** array of slots */ buf_tmp_buffer_t *slots; - void create(ulint n_slots); + void create(ulint n_slots) noexcept; - void close(); + void close() noexcept; /** Reserve a buffer */ - buf_tmp_buffer_t *reserve(bool wait_for_reads); + buf_tmp_buffer_t *reserve(bool wait_for_reads) noexcept; } io_buf; /** whether resize() is in the critical path */ @@ -1968,7 +1977,7 @@ extern buf_pool_t buf_pool; inline buf_page_t *buf_pool_t::page_hash_table::get(const page_id_t id, const hash_chain &chain) - const + const noexcept { #ifdef SAFE_MUTEX DBUG_ASSERT(mysql_mutex_is_owner(&buf_pool.mutex) || @@ -1985,21 +1994,21 @@ inline buf_page_t *buf_pool_t::page_hash_table::get(const page_id_t id, } #ifdef SUX_LOCK_GENERIC -inline void page_hash_latch::lock_shared() +inline void page_hash_latch::lock_shared() noexcept { mysql_mutex_assert_not_owner(&buf_pool.mutex); if (!read_trylock()) read_lock_wait(); } -inline void page_hash_latch::lock() +inline void page_hash_latch::lock() noexcept { if (!write_trylock()) write_lock_wait(); } #endif /* SUX_LOCK_GENERIC */ -inline void buf_page_t::set_state(uint32_t s) +inline void buf_page_t::set_state(uint32_t s) noexcept { mysql_mutex_assert_owner(&buf_pool.mutex); ut_ad(s <= REMOVE_HASH || s >= UNFIXED); @@ -2008,7 +2017,7 @@ inline void buf_page_t::set_state(uint32_t s) zip.fix= s; } -inline void buf_page_t::set_corrupt_id() +inline void buf_page_t::set_corrupt_id() noexcept { #ifdef UNIV_DEBUG switch (oldest_modification()) { @@ -2034,7 +2043,7 @@ inline void buf_page_t::set_corrupt_id() } /** Set oldest_modification when adding to buf_pool.flush_list */ -inline void buf_page_t::set_oldest_modification(lsn_t lsn) +inline void buf_page_t::set_oldest_modification(lsn_t lsn) noexcept { mysql_mutex_assert_owner(&buf_pool.flush_list_mutex); ut_ad(oldest_modification() <= 1); @@ -2043,7 +2052,7 @@ inline void buf_page_t::set_oldest_modification(lsn_t lsn) } /** Clear oldest_modification after removing from buf_pool.flush_list */ -inline void buf_page_t::clear_oldest_modification() +inline void buf_page_t::clear_oldest_modification() noexcept { #ifdef SAFE_MUTEX if (oldest_modification() != 2) @@ -2062,7 +2071,7 @@ inline void buf_page_t::clear_oldest_modification() /** @return whether the block can be relocated in memory. The block can be dirty, but it must not be I/O-fixed or bufferfixed. */ -inline bool buf_page_t::can_relocate() const +inline bool buf_page_t::can_relocate() const noexcept { mysql_mutex_assert_owner(&buf_pool.mutex); const auto f= state(); @@ -2073,7 +2082,7 @@ inline bool buf_page_t::can_relocate() const } /** @return whether the block has been flagged old in buf_pool.LRU */ -inline bool buf_page_t::is_old() const +inline bool buf_page_t::is_old() const noexcept { mysql_mutex_assert_owner(&buf_pool.mutex); ut_ad(in_file()); @@ -2082,7 +2091,7 @@ inline bool buf_page_t::is_old() const } /** Set whether a block is old in buf_pool.LRU */ -inline void buf_page_t::set_old(bool old) +inline void buf_page_t::set_old(bool old) noexcept { mysql_mutex_assert_owner(&buf_pool.mutex); ut_ad(in_LRU_list); @@ -2156,7 +2165,7 @@ REMOVE_HASH => NOT_USED (if and only if !oldest_modification()) too deep into the LRU list it resets the value to the tail of the LRU list. @return buf_page_t from where to start scan. */ -inline buf_page_t *LRUItr::start() +inline buf_page_t *LRUItr::start() noexcept { mysql_mutex_assert_owner(m_mutex); @@ -2169,12 +2178,12 @@ inline buf_page_t *LRUItr::start() #ifdef UNIV_DEBUG /** Functor to validate the LRU list. */ struct CheckInLRUList { - void operator()(const buf_page_t* elem) const + void operator()(const buf_page_t* elem) const noexcept { ut_a(elem->in_LRU_list); } - static void validate() + static void validate() noexcept { ut_list_validate(buf_pool.LRU, CheckInLRUList()); } @@ -2182,25 +2191,25 @@ struct CheckInLRUList { /** Functor to validate the LRU list. */ struct CheckInFreeList { - void operator()(const buf_page_t* elem) const + void operator()(const buf_page_t* elem) const noexcept { ut_a(elem->in_free_list); } - static void validate() + static void validate() noexcept { ut_list_validate(buf_pool.free, CheckInFreeList()); } }; struct CheckUnzipLRUAndLRUList { - void operator()(const buf_block_t* elem) const + void operator()(const buf_block_t* elem) const noexcept { ut_a(elem->page.in_LRU_list); ut_a(elem->in_unzip_LRU_list); } - static void validate() + static void validate() noexcept { ut_list_validate(buf_pool.unzip_LRU, CheckUnzipLRUAndLRUList()); diff --git a/storage/innobase/include/buf0dblwr.h b/storage/innobase/include/buf0dblwr.h index 6e7662d9b81..2737622a4d4 100644 --- a/storage/innobase/include/buf0dblwr.h +++ b/storage/innobase/include/buf0dblwr.h @@ -76,30 +76,30 @@ class buf_dblwr_t /** Initialise the persistent storage of the doublewrite buffer. @param header doublewrite page header in the TRX_SYS page */ - inline void init(const byte *header); + inline void init(const byte *header) noexcept; /** Flush possible buffered writes to persistent storage. */ - bool flush_buffered_writes(const ulint size); + bool flush_buffered_writes(const ulint size) noexcept; public: /** Initialise the doublewrite buffer data structures. */ - void init(); + void init() noexcept; /** Create or restore the doublewrite buffer in the TRX_SYS page. @return whether the operation succeeded */ - bool create(); + bool create() noexcept; /** Free the doublewrite buffer. */ - void close(); + void close() noexcept; /** Acquire the mutex */ - void lock() { mysql_mutex_lock(&mutex); } + void lock() noexcept { mysql_mutex_lock(&mutex); } /** @return the number of completed batches */ - ulint batches() const + ulint batches() const noexcept { mysql_mutex_assert_owner(&mutex); return writes_completed; } /** @return the number of final pages written */ - ulint written() const + ulint written() const noexcept { mysql_mutex_assert_owner(&mutex); return pages_written; } /** Release the mutex */ - void unlock() { mysql_mutex_unlock(&mutex); } + void unlock() noexcept { mysql_mutex_unlock(&mutex); } /** Initialize the doublewrite buffer memory structure on recovery. If we are upgrading from a version before MySQL 4.1, then this @@ -110,37 +110,37 @@ public: @param file File handle @param path Path name of file @return DB_SUCCESS or error code */ - dberr_t init_or_load_pages(pfs_os_file_t file, const char *path); + dberr_t init_or_load_pages(pfs_os_file_t file, const char *path) noexcept; /** Process and remove the double write buffer pages for all tablespaces. */ - void recover(); + void recover() noexcept; /** Update the doublewrite buffer on data page write completion. */ - void write_completed(); + void write_completed() noexcept; /** Flush possible buffered writes to persistent storage. It is very important to call this function after a batch of writes has been posted, and also when we may have to wait for a page latch! Otherwise a deadlock of threads can occur. */ - void flush_buffered_writes(); + void flush_buffered_writes() noexcept; /** Update the doublewrite buffer on write batch completion @param request the completed batch write request */ - void flush_buffered_writes_completed(const IORequest &request); + void flush_buffered_writes_completed(const IORequest &request) noexcept; /** Size of the doublewrite block in pages */ - uint32_t block_size() const { return FSP_EXTENT_SIZE; } + uint32_t block_size() const noexcept { return FSP_EXTENT_SIZE; } /** Schedule a page write. If the doublewrite memory buffer is full, flush_buffered_writes() will be invoked to make space. @param request asynchronous write request @param size payload size in bytes */ - void add_to_batch(const IORequest &request, size_t size); + void add_to_batch(const IORequest &request, size_t size) noexcept; /** Determine whether the doublewrite buffer has been created */ - bool is_created() const + bool is_created() const noexcept { return UNIV_LIKELY(block1 != page_id_t(0, 0)); } /** @return whether a page identifier is part of the doublewrite buffer */ - bool is_inside(const page_id_t id) const + bool is_inside(const page_id_t id) const noexcept { if (!is_created()) return false; @@ -152,7 +152,7 @@ public: } /** Wait for flush_buffered_writes() to be fully completed */ - void wait_flush_buffered_writes() + void wait_flush_buffered_writes() noexcept { mysql_mutex_lock(&mutex); while (batch_running) diff --git a/storage/innobase/include/buf0flu.h b/storage/innobase/include/buf0flu.h index 2e25b3aed08..aad42b77582 100644 --- a/storage/innobase/include/buf0flu.h +++ b/storage/innobase/include/buf0flu.h @@ -44,27 +44,22 @@ deleting the data file of that tablespace. The pages still remain a part of LRU and are evicted from the list as they age towards the tail of the LRU. @param id tablespace identifier */ -void buf_flush_remove_pages(ulint id); +void buf_flush_remove_pages(ulint id) noexcept; -/*******************************************************************//** -Relocates a buffer control block on the flush_list. -Note that it is assumed that the contents of bpage has already been -copied to dpage. */ +/** Relocate a buffer control block in buf_pool.flush_list. +@param bpage control block being moved +@param dpage destination block; the page contents has already been copied */ ATTRIBUTE_COLD -void -buf_flush_relocate_on_flush_list( -/*=============================*/ - buf_page_t* bpage, /*!< in/out: control block being moved */ - buf_page_t* dpage); /*!< in/out: destination block */ - +void buf_flush_relocate_on_flush_list(buf_page_t *bpage, buf_page_t *dpage) + noexcept; /** Complete write of a file page from buf_pool. @param request write request @param error whether the write may have failed */ -void buf_page_write_complete(const IORequest &request, bool error); +void buf_page_write_complete(const IORequest &request, bool error) noexcept; /** Assign the full crc32 checksum for non-compressed page. @param[in,out] page page to be updated */ -void buf_flush_assign_full_crc32_checksum(byte* page); +void buf_flush_assign_full_crc32_checksum(byte* page) noexcept; /** Initialize a page for writing to the tablespace. @param[in] block buffer block; NULL if bypassing the buffer pool @@ -76,30 +71,32 @@ buf_flush_init_for_writing( const buf_block_t* block, byte* page, void* page_zip_, - bool use_full_checksum); + bool use_full_checksum) noexcept; /** Try to flush dirty pages that belong to a given tablespace. @param space tablespace @param n_flushed number of pages written @return whether the flush for some pages might not have been initiated */ bool buf_flush_list_space(fil_space_t *space, ulint *n_flushed= nullptr) + noexcept MY_ATTRIBUTE((warn_unused_result)); /** Wait until a LRU flush batch ends. */ -void buf_flush_wait_LRU_batch_end(); +void buf_flush_wait_LRU_batch_end() noexcept; /** Wait until all persistent pages are flushed up to a limit. @param sync_lsn buf_pool.get_oldest_modification(LSN_MAX) to wait for */ -ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn); +ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn) noexcept; /** Initiate more eager page flushing if the log checkpoint age is too old. @param lsn buf_pool.get_oldest_modification(LSN_MAX) target @param furious true=furious flushing, false=limit to innodb_io_capacity */ -ATTRIBUTE_COLD void buf_flush_ahead(lsn_t lsn, bool furious); +ATTRIBUTE_COLD void buf_flush_ahead(lsn_t lsn, bool furious) noexcept; /********************************************************************//** This function should be called at a mini-transaction commit, if a page was modified in it. Puts the block to the list of modified blocks, if it not already in it. */ inline void buf_flush_note_modification(buf_block_t *b, lsn_t start, lsn_t end) + noexcept { ut_ad(!srv_read_only_mode); ut_d(const auto s= b->page.state()); @@ -121,20 +118,20 @@ inline void buf_flush_note_modification(buf_block_t *b, lsn_t start, lsn_t end) } /** Initialize page_cleaner. */ -ATTRIBUTE_COLD void buf_flush_page_cleaner_init(); +ATTRIBUTE_COLD void buf_flush_page_cleaner_init() noexcept; /** Flush the buffer pool on shutdown. */ -ATTRIBUTE_COLD void buf_flush_buffer_pool(); +ATTRIBUTE_COLD void buf_flush_buffer_pool() noexcept; #ifdef UNIV_DEBUG /** Validate the flush list. */ -void buf_flush_validate(); +void buf_flush_validate() noexcept; #endif /* UNIV_DEBUG */ /** Synchronously flush dirty blocks during recv_sys_t::apply(). NOTE: The calling thread is not allowed to hold any buffer page latches! */ -void buf_flush_sync_batch(lsn_t lsn); +void buf_flush_sync_batch(lsn_t lsn) noexcept; /** Synchronously flush dirty blocks. NOTE: The calling thread is not allowed to hold any buffer page latches! */ -void buf_flush_sync(); +void buf_flush_sync() noexcept; diff --git a/storage/innobase/include/buf0rea.h b/storage/innobase/include/buf0rea.h index e6309fdb363..4183cf2e80d 100644 --- a/storage/innobase/include/buf0rea.h +++ b/storage/innobase/include/buf0rea.h @@ -39,7 +39,7 @@ will be invoked on read completion. @retval DB_DECRYPTION_FAILED if page post encryption checksum matches but after decryption normal page checksum does not match. @retval DB_TABLESPACE_DELETED if tablespace .ibd file is missing */ -dberr_t buf_read_page(const page_id_t page_id, bool unzip= true); +dberr_t buf_read_page(const page_id_t page_id, bool unzip= true) noexcept; /** High-level function which reads a page asynchronously from a file to the buffer buf_pool if it is not already there. Sets the io_fix flag and sets @@ -49,7 +49,7 @@ released by the i/o-handler thread. @param[in] page_id page id @param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0 */ void buf_read_page_background(fil_space_t *space, const page_id_t page_id, - ulint zip_size) + ulint zip_size) noexcept MY_ATTRIBUTE((nonnull)); /** Applies a random read-ahead in buf_pool if there are at least a threshold @@ -67,7 +67,7 @@ wants to access @return number of page read requests issued; NOTE that if we read ibuf pages, it may happen that the page at the given page number does not get read even if we return a positive value! */ -ulint buf_read_ahead_random(const page_id_t page_id, bool ibuf); +ulint buf_read_ahead_random(const page_id_t page_id, bool ibuf) noexcept; /** Applies linear read-ahead if in the buf_pool the page is a border page of a linear read-ahead area and all the pages in the area have been accessed. @@ -95,7 +95,7 @@ which could result in a deadlock if the OS does not support asynchronous io. @param[in] ibuf whether if we are inside ibuf routine @return number of page read requests issued */ ulint -buf_read_ahead_linear(const page_id_t page_id, bool ibuf); +buf_read_ahead_linear(const page_id_t page_id, bool ibuf) noexcept; /** Schedule a page for recovery. @param space tablespace @@ -103,7 +103,7 @@ buf_read_ahead_linear(const page_id_t page_id, bool ibuf); @param recs log records @param init page initialization, or nullptr if the page needs to be read */ void buf_read_recover(fil_space_t *space, const page_id_t page_id, - page_recv_t &recs, recv_init *init); + page_recv_t &recs, recv_init *init) noexcept; /** @name Modes used in read-ahead @{ */ /** read only pages belonging to the insert buffer tree */ diff --git a/storage/innobase/include/buf0types.h b/storage/innobase/include/buf0types.h index c69c07d66e1..b27e8c3f8f9 100644 --- a/storage/innobase/include/buf0types.h +++ b/storage/innobase/include/buf0types.h @@ -54,12 +54,12 @@ enum srv_checksum_algorithm_t { SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32 }; -inline bool is_checksum_strict(srv_checksum_algorithm_t algo) +inline bool is_checksum_strict(srv_checksum_algorithm_t algo) noexcept { return algo == SRV_CHECKSUM_ALGORITHM_STRICT_CRC32; } -inline bool is_checksum_strict(ulint algo) +inline bool is_checksum_strict(ulint algo) noexcept { return algo == SRV_CHECKSUM_ALGORITHM_STRICT_CRC32; } @@ -96,31 +96,31 @@ public: m_id(uint64_t{space} << 32 | page_no) {} constexpr page_id_t(uint64_t id) : m_id(id) {} - constexpr bool operator==(const page_id_t& rhs) const + constexpr bool operator==(const page_id_t& rhs) const noexcept { return m_id == rhs.m_id; } - constexpr bool operator!=(const page_id_t& rhs) const + constexpr bool operator!=(const page_id_t& rhs) const noexcept { return m_id != rhs.m_id; } - constexpr bool operator<(const page_id_t& rhs) const + constexpr bool operator<(const page_id_t& rhs) const noexcept { return m_id < rhs.m_id; } - constexpr bool operator>(const page_id_t& rhs) const + constexpr bool operator>(const page_id_t& rhs) const noexcept { return m_id > rhs.m_id; } - constexpr bool operator<=(const page_id_t& rhs) const + constexpr bool operator<=(const page_id_t& rhs) const noexcept { return m_id <= rhs.m_id; } - constexpr bool operator>=(const page_id_t& rhs) const + constexpr bool operator>=(const page_id_t& rhs) const noexcept { return m_id >= rhs.m_id; } - page_id_t &operator--() { ut_ad(page_no()); m_id--; return *this; } - page_id_t &operator++() + page_id_t &operator--() noexcept { ut_ad(page_no()); m_id--; return *this; } + page_id_t &operator++() noexcept { ut_ad(page_no() < 0xFFFFFFFFU); m_id++; return *this; } - page_id_t operator-(uint32_t i) const + page_id_t operator-(uint32_t i) const noexcept { ut_ad(page_no() >= i); return page_id_t(m_id - i); } - page_id_t operator+(uint32_t i) const + page_id_t operator+(uint32_t i) const noexcept { ut_ad(page_no() < ~i); return page_id_t(m_id + i); @@ -128,28 +128,30 @@ public: /** Retrieve the tablespace id. @return tablespace id */ - constexpr uint32_t space() const { return static_cast(m_id >> 32); } + constexpr uint32_t space() const noexcept + { return static_cast(m_id >> 32); } /** Retrieve the page number. @return page number */ - constexpr uint32_t page_no() const { return static_cast(m_id); } + constexpr uint32_t page_no() const noexcept + { return static_cast(m_id); } /** Retrieve the fold value. @return fold value */ - constexpr ulint fold() const + constexpr ulint fold() const noexcept { return (ulint{space()} << 20) + space() + page_no(); } /** Reset the page number only. @param[in] page_no page number */ - void set_page_no(uint32_t page_no) + void set_page_no(uint32_t page_no) noexcept { m_id= (m_id & ~uint64_t{0} << 32) | page_no; } - constexpr ulonglong raw() const { return m_id; } + constexpr ulonglong raw() const noexcept { return m_id; } /** Flag the page identifier as corrupted. */ - void set_corrupted() { m_id= ~0ULL; } + void set_corrupted() noexcept { m_id= ~0ULL; } /** @return whether the page identifier belongs to a corrupted page */ constexpr bool is_corrupted() const { return m_id == ~0ULL; } @@ -182,53 +184,55 @@ enum rw_lock_type_t class page_hash_latch : private rw_lock { /** Wait for a shared lock */ - void read_lock_wait(); + void read_lock_wait() noexcept; /** Wait for an exclusive lock */ - void write_lock_wait(); + void write_lock_wait() noexcept; public: /** Acquire a shared lock */ - inline void lock_shared(); + inline void lock_shared() noexcept; /** Acquire an exclusive lock */ - inline void lock(); + inline void lock() noexcept; /** @return whether an exclusive lock is being held by any thread */ - bool is_write_locked() const { return rw_lock::is_write_locked(); } + bool is_write_locked() const noexcept { return rw_lock::is_write_locked(); } /** @return whether any lock is being held by any thread */ - bool is_locked() const { return rw_lock::is_locked(); } + bool is_locked() const noexcept { return rw_lock::is_locked(); } /** @return whether any lock is being held or waited for by any thread */ - bool is_locked_or_waiting() const { return rw_lock::is_locked_or_waiting(); } + bool is_locked_or_waiting() const noexcept + { return rw_lock::is_locked_or_waiting(); } /** Release a shared lock */ - void unlock_shared() { read_unlock(); } + void unlock_shared() noexcept { read_unlock(); } /** Release an exclusive lock */ - void unlock() { write_unlock(); } + void unlock() noexcept { write_unlock(); } }; #elif defined _WIN32 || SIZEOF_SIZE_T >= 8 class page_hash_latch { srw_spin_lock_low lk; public: - void lock_shared() { lk.rd_lock(); } - void unlock_shared() { lk.rd_unlock(); } - void lock() { lk.wr_lock(); } - void unlock() { lk.wr_unlock(); } - bool is_write_locked() const { return lk.is_write_locked(); } - bool is_locked() const { return lk.is_locked(); } - bool is_locked_or_waiting() const { return lk.is_locked_or_waiting(); } + void lock_shared() noexcept { lk.rd_lock(); } + void unlock_shared() noexcept { lk.rd_unlock(); } + void lock() noexcept { lk.wr_lock(); } + void unlock() noexcept { lk.wr_unlock(); } + bool is_write_locked() const noexcept { return lk.is_write_locked(); } + bool is_locked() const noexcept { return lk.is_locked(); } + bool is_locked_or_waiting() const noexcept + { return lk.is_locked_or_waiting(); } }; #else class page_hash_latch { srw_spin_mutex lk; public: - void lock_shared() { lock(); } - void unlock_shared() { unlock(); } - void lock() { lk.wr_lock(); } - void unlock() { lk.wr_unlock(); } - bool is_locked() const { return lk.is_locked(); } - bool is_write_locked() const { return is_locked(); } - bool is_locked_or_waiting() const { return is_locked(); } + void lock_shared() noexcept { lock(); } + void unlock_shared() noexcept { unlock(); } + void lock() noexcept { lk.wr_lock(); } + void unlock() noexcept { lk.wr_unlock(); } + bool is_locked() const noexcept { return lk.is_locked(); } + bool is_write_locked() const noexcept { return is_locked(); } + bool is_locked_or_waiting() const noexcept { return is_locked(); } }; #endif diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index ff627e81eb2..2260791cbe8 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -373,11 +373,11 @@ struct fil_space_t final uint32_t n_reserved_extents= 0; private: #ifdef UNIV_DEBUG - fil_space_t *next_in_space_list(); - fil_space_t *prev_in_space_list(); + fil_space_t *next_in_space_list() noexcept; + fil_space_t *prev_in_space_list() noexcept; - fil_space_t *next_in_unflushed_spaces(); - fil_space_t *prev_in_unflushed_spaces(); + fil_space_t *next_in_unflushed_spaces() noexcept; + fil_space_t *prev_in_unflushed_spaces() noexcept; #endif /** the committed size of the tablespace in pages */ @@ -444,21 +444,21 @@ public: { return UNIV_UNLIKELY(being_imported); } /** @return whether doublewrite buffering is needed */ - inline bool use_doublewrite() const; + inline bool use_doublewrite() const noexcept; /** @return whether a page has been freed */ - inline bool is_freed(uint32_t page); + inline bool is_freed(uint32_t page) noexcept; /** Set create_lsn. */ - inline void set_create_lsn(lsn_t lsn); + inline void set_create_lsn(lsn_t lsn) noexcept; /** @return the latest tablespace rebuild LSN, or 0 */ - lsn_t get_create_lsn() const { return create_lsn; } + lsn_t get_create_lsn() const noexcept { return create_lsn; } /** Apply freed_ranges to the file. @param writable whether the file is writable @return number of pages written or hole-punched */ - uint32_t flush_freed(bool writable); + uint32_t flush_freed(bool writable) noexcept; /** Append a file to the chain of files of a space. @param[in] name file name of a file that is not open @@ -471,7 +471,7 @@ public: @return file object */ fil_node_t* add(const char* name, pfs_os_file_t handle, uint32_t size, bool is_raw, bool atomic_write, - uint32_t max_pages = UINT32_MAX); + uint32_t max_pages = UINT32_MAX) noexcept; #ifdef UNIV_DEBUG /** Assert that the mini-transaction is compatible with updating an allocation bitmap page. @@ -484,6 +484,7 @@ public: @param[in] n_to_reserve number of extents to reserve @return whether the reservation succeeded */ bool reserve_free_extents(uint32_t n_free_now, uint32_t n_to_reserve) + noexcept { if (n_reserved_extents + n_to_reserve > n_free_now) { return false; @@ -495,7 +496,7 @@ public: /** Release the reserved free extents. @param[in] n_reserved number of reserved extents */ - void release_free_extents(uint32_t n_reserved) + void release_free_extents(uint32_t n_reserved) noexcept { if (!n_reserved) return; ut_a(n_reserved_extents >= n_reserved); @@ -508,20 +509,20 @@ public: @param[in] replace whether to ignore the existence of path @return error code @retval DB_SUCCESS on success */ - dberr_t rename(const char *path, bool log, bool replace= false) + dberr_t rename(const char *path, bool log, bool replace= false) noexcept MY_ATTRIBUTE((nonnull)); /** Note that the tablespace has been imported. Initially, purpose=IMPORT so that no redo log is written while the space ID is being updated in each page. */ - inline void set_imported(); + inline void set_imported() noexcept; /** Report the tablespace as corrupted @return whether this was the first call */ ATTRIBUTE_COLD bool set_corrupted() const noexcept; /** @return whether the storage device is rotational (HDD, not SSD) */ - inline bool is_rotational() const; + inline bool is_rotational() const noexcept; /** Open each file. Never invoked on .ibd files. @param create_new_db whether to skip the call to fil_node_t::read_page0() @@ -562,7 +563,7 @@ public: /** Acquire a tablespace reference for I/O. @param avoid when these flags are set, nothing will be acquired @return whether the file is usable */ - bool acquire(uint32_t avoid= STOPPING | CLOSING) + bool acquire(uint32_t avoid= STOPPING | CLOSING) noexcept { const auto flags= acquire_low(avoid) & (avoid); return UNIV_LIKELY(!flags) || (flags == CLOSING && acquire_and_prepare()); @@ -571,14 +572,15 @@ public: /** Acquire a tablespace reference for writing. @param avoid when these flags are set, nothing will be acquired @return whether the file is writable */ - bool acquire_for_write() { return acquire(STOPPING_WRITES | CLOSING); } + bool acquire_for_write() noexcept + { return acquire(STOPPING_WRITES | CLOSING); } /** Acquire another tablespace reference for I/O. */ - inline void reacquire(); + inline void reacquire() noexcept; /** Release a tablespace reference. @return whether this was the last reference */ - bool release() + bool release() noexcept { uint32_t n= n_pending.fetch_sub(1, std::memory_order_release); ut_ad(n & PENDING); @@ -586,43 +588,45 @@ public: } /** Clear the NEEDS_FSYNC flag */ - void clear_flush() + void clear_flush() noexcept { n_pending.fetch_and(~NEEDS_FSYNC, std::memory_order_release); } private: /** Clear the CLOSING flag */ - void clear_closing() + void clear_closing() noexcept { n_pending.fetch_and(~CLOSING, std::memory_order_relaxed); } /** @return pending operations (and flags) */ - uint32_t pending()const { return n_pending.load(std::memory_order_acquire); } + uint32_t pending() const noexcept + { return n_pending.load(std::memory_order_acquire); } public: /** @return whether close() of the file handle has been requested */ - bool is_closing() const { return pending() & CLOSING; } + bool is_closing() const noexcept { return pending() & CLOSING; } /** @return whether the tablespace is about to be dropped */ - bool is_stopping() const { return pending() & STOPPING; } + bool is_stopping() const noexcept { return pending() & STOPPING; } /** @return whether the tablespace is going to be dropped */ - bool is_stopping_writes() const { return pending() & STOPPING_WRITES; } + bool is_stopping_writes() const noexcept + { return pending() & STOPPING_WRITES; } /** @return number of pending operations */ - bool is_ready_to_close() const + bool is_ready_to_close() const noexcept { return (pending() & (PENDING | CLOSING)) == CLOSING; } /** @return whether fsync() or similar is needed */ - bool needs_flush() const { return pending() & NEEDS_FSYNC; } + bool needs_flush() const noexcept { return pending() & NEEDS_FSYNC; } /** @return whether fsync() or similar is needed, and the tablespace is not being dropped */ - bool needs_flush_not_stopping() const + bool needs_flush_not_stopping() const noexcept { return (pending() & (NEEDS_FSYNC | STOPPING_WRITES)) == NEEDS_FSYNC; } - uint32_t referenced() const { return pending() & PENDING; } + uint32_t referenced() const noexcept { return pending() & PENDING; } private: MY_ATTRIBUTE((warn_unused_result)) /** Prepare to close the file handle. @return number of pending operations, possibly with NEEDS_FSYNC flag */ - uint32_t set_closing() + uint32_t set_closing() noexcept { return n_pending.fetch_or(CLOSING, std::memory_order_acquire); } @@ -632,13 +636,14 @@ public: @param ignore_space Ignore the tablespace which is acquired by caller @param print_info whether to diagnose why a file cannot be closed @return whether a file was closed */ - static bool try_to_close(fil_space_t *ignore_space, bool print_info); + static bool try_to_close(fil_space_t *ignore_space, bool print_info) + noexcept; /** Close all tablespace files at shutdown */ - static void close_all(); + static void close_all() noexcept; /** Update last_freed_lsn */ - void update_last_freed_lsn(lsn_t lsn) + void update_last_freed_lsn(lsn_t lsn) noexcept { std::lock_guard freed_lock(freed_range_mutex); last_freed_lsn= lsn; @@ -646,7 +651,7 @@ public: /** Note that the file will need fsync(). @return whether this needs to be added to fil_system.unflushed_spaces */ - bool set_needs_flush() + bool set_needs_flush() noexcept { uint32_t n= 1; while (!n_pending.compare_exchange_strong(n, n | NEEDS_FSYNC, @@ -663,24 +668,23 @@ public: /** Clear all freed ranges for undo tablespace when InnoDB encounters TRIM redo log record */ - void clear_freed_ranges() + void clear_freed_ranges() noexcept { std::lock_guard freed_lock(freed_range_mutex); freed_ranges.clear(); } #endif /* !UNIV_INNOCHECKSUM */ - /** FSP_SPACE_FLAGS and FSP_FLAGS_MEM_ flags; - check fsp0types.h to more info about flags. */ - ulint flags; + /** FSP_SPACE_FLAGS and FSP_FLAGS_MEM_ flags; + check fsp0types.h to more info about flags. */ + ulint flags; - /** Determine if full_crc32 is used for a data file - @param[in] flags tablespace flags (FSP_SPACE_FLAGS) - @return whether the full_crc32 algorithm is active */ - static bool full_crc32(ulint flags) { - return flags & FSP_FLAGS_FCRC32_MASK_MARKER; - } + /** Determine if full_crc32 is used for a data file + @param flags tablespace flags (FSP_SPACE_FLAGS) + @return whether the full_crc32 algorithm is active */ + static bool full_crc32(ulint flags) noexcept + { return flags & FSP_FLAGS_FCRC32_MASK_MARKER; } /** Determine if full_crc32 is used along with compression */ - static bool is_full_crc32_compressed(ulint flags) + static bool is_full_crc32_compressed(ulint flags) noexcept { if (full_crc32(flags)) { @@ -691,13 +695,13 @@ public: return false; } - /** @return whether innodb_checksum_algorithm=full_crc32 is active */ - bool full_crc32() const { return full_crc32(flags); } + /** @return whether innodb_checksum_algorithm=full_crc32 is active */ + bool full_crc32() const noexcept { return full_crc32(flags); } /** Determine the logical page size. @param flags tablespace flags (FSP_FLAGS) @return the logical page size @retval 0 if the flags are invalid */ - static unsigned logical_size(ulint flags) { + static unsigned logical_size(ulint flags) noexcept { ulint page_ssize = 0; @@ -723,7 +727,7 @@ public: @param flags tablespace flags (FSP_FLAGS) @return the ROW_FORMAT=COMPRESSED page size @retval 0 if ROW_FORMAT=COMPRESSED is not used */ - static unsigned zip_size(ulint flags) { + static unsigned zip_size(ulint flags) noexcept { if (full_crc32(flags)) { return 0; @@ -736,7 +740,7 @@ public: /** Determine the physical page size. @param flags tablespace flags (FSP_FLAGS) @return the physical page size */ - static unsigned physical_size(ulint flags) { + static unsigned physical_size(ulint flags) noexcept { if (full_crc32(flags)) { return logical_size(flags); @@ -747,25 +751,25 @@ public: ? (UNIV_ZIP_SIZE_MIN >> 1) << zip_ssize : unsigned(srv_page_size); } - /** @return the ROW_FORMAT=COMPRESSED page size - @retval 0 if ROW_FORMAT=COMPRESSED is not used */ - unsigned zip_size() const { return zip_size(flags); } - /** @return the physical page size */ - unsigned physical_size() const { return physical_size(flags); } + /** @return the ROW_FORMAT=COMPRESSED page size + @retval 0 if ROW_FORMAT=COMPRESSED is not used */ + unsigned zip_size() const noexcept { return zip_size(flags); } + /** @return the physical page size */ + unsigned physical_size() const noexcept { return physical_size(flags); } /** Check whether the compression enabled in tablespace. @param[in] flags tablespace flags */ - static bool is_compressed(ulint flags) + static bool is_compressed(ulint flags) noexcept { return is_full_crc32_compressed(flags) || FSP_FLAGS_HAS_PAGE_COMPRESSION(flags); } /** @return whether the compression enabled for the tablespace. */ - bool is_compressed() const { return is_compressed(flags); } + bool is_compressed() const noexcept { return is_compressed(flags); } /** Get the compression algorithm for full crc32 format. @param[in] flags tablespace flags @return algorithm type of tablespace */ - static ulint get_compression_algo(ulint flags) + static ulint get_compression_algo(ulint flags) noexcept { return full_crc32(flags) ? FSP_FLAGS_FCRC32_GET_COMPRESSED_ALGO(flags) @@ -773,14 +777,14 @@ public: } /** @return the page_compressed algorithm @retval 0 if not page_compressed */ - ulint get_compression_algo() const { + ulint get_compression_algo() const noexcept { return fil_space_t::get_compression_algo(flags); } /** Determine if the page_compressed page contains an extra byte for exact compressed stream length @param[in] flags tablespace flags @return whether the extra byte is needed */ - static bool full_crc32_page_compressed_len(ulint flags) + static bool full_crc32_page_compressed_len(ulint flags) noexcept { DBUG_ASSERT(full_crc32(flags)); switch (get_compression_algo(flags)) { @@ -797,6 +801,7 @@ public: @param[in] expected expected flags @return true if it is equivalent */ static bool is_flags_full_crc32_equal(ulint flags, ulint expected) + noexcept { ut_ad(full_crc32(flags)); ulint fcrc32_psize = FSP_FLAGS_FCRC32_GET_PAGE_SSIZE(flags); @@ -826,6 +831,7 @@ public: @param[in] expected expected flags @return true if it is equivalent */ static bool is_flags_non_full_crc32_equal(ulint flags, ulint expected) + noexcept { ut_ad(!full_crc32(flags)); @@ -848,7 +854,7 @@ public: return true; } /** Whether both fsp flags are equivalent */ - static bool is_flags_equal(ulint flags, ulint expected) + static bool is_flags_equal(ulint flags, ulint expected) noexcept { if (!((flags ^ expected) & ~(1U << FSP_FLAGS_POS_RESERVED))) { return true; @@ -861,7 +867,7 @@ public: /** Validate the tablespace flags for full crc32 format. @param[in] flags the content of FSP_SPACE_FLAGS @return whether the flags are correct in full crc32 format */ - static bool is_fcrc32_valid_flags(ulint flags) + static bool is_fcrc32_valid_flags(ulint flags) noexcept { ut_ad(flags & FSP_FLAGS_FCRC32_MASK_MARKER); const ulint page_ssize = physical_size(flags); @@ -878,7 +884,7 @@ public: @param[in] is_ibd whether this is an .ibd file (not system tablespace) @return whether the flags are correct. */ - static bool is_valid_flags(ulint flags, bool is_ibd) + static bool is_valid_flags(ulint flags, bool is_ibd) noexcept { DBUG_EXECUTE_IF("fsp_flags_is_valid_failure", return false;); @@ -965,12 +971,12 @@ public: @param id tablespace identifier @return tablespace @retval nullptr if the tablespace is missing or inaccessible */ - static fil_space_t *get(ulint id); + static fil_space_t *get(ulint id) noexcept; /** Acquire a tablespace reference for writing. @param id tablespace identifier @return tablespace @retval nullptr if the tablespace is missing or inaccessible */ - static fil_space_t *get_for_write(ulint id); + static fil_space_t *get_for_write(ulint id) noexcept; /** Add/remove the free page in the freed ranges list. @param[in] offset page number to be added @@ -1002,20 +1008,20 @@ public: } /** Set the tablespace size in pages */ - void set_sizes(uint32_t s) + void set_sizes(uint32_t s) noexcept { ut_ad(id ? !size : (size >= s)); size= s; committed_size= s; } /** Update committed_size in mtr_t::commit() */ - void set_committed_size() { committed_size= size; } + void set_committed_size() noexcept { committed_size= size; } /** @return the last persisted page number */ - uint32_t last_page_number() const { return committed_size - 1; } + uint32_t last_page_number() const noexcept { return committed_size - 1; } /** @return the size in pages (0 if unreadable) */ - inline uint32_t get_size(); + inline uint32_t get_size() noexcept; /** Read or write data. @param type I/O context @@ -1025,11 +1031,11 @@ public: @param bpage buffer block (for type.is_async() completion callback) @return status and file descriptor */ fil_io_t io(const IORequest &type, os_offset_t offset, size_t len, - void *buf, buf_page_t *bpage= nullptr); + void *buf, buf_page_t *bpage= nullptr) noexcept; /** Flush pending writes from the file system cache to the file. */ - template inline void flush(); + template inline void flush() noexcept; /** Flush pending writes from the file system cache to the file. */ - void flush_low(); + void flush_low() noexcept; /** Read the first page of a data file. @param dpage copy of a first page, from the doublewrite buffer, or nullptr @@ -1045,19 +1051,19 @@ public: @return the next tablespace @retval nullptr upon reaching the end of the iteration */ static space_list_t::iterator next(space_list_t::iterator space, - bool recheck, bool encrypt); + bool recheck, bool encrypt) noexcept; #ifdef UNIV_DEBUG - bool is_latched() const { return latch.have_any(); } + bool is_latched() const noexcept { return latch.have_any(); } #endif - bool is_owner() const + bool is_owner() const noexcept { const bool owner{latch_owner == pthread_self()}; ut_ad(owner == latch.have_wr()); return owner; } /** Acquire the allocation latch in exclusive mode */ - void x_lock() + void x_lock() noexcept { latch.wr_lock(SRW_LOCK_CALL); ut_ad(!latch_owner); @@ -1071,14 +1077,14 @@ public: latch.wr_unlock(); } /** Acquire the allocation latch in shared mode */ - void s_lock() { latch.rd_lock(SRW_LOCK_CALL); } + void s_lock() noexcept { latch.rd_lock(SRW_LOCK_CALL); } /** Release the allocation latch from shared mode */ - void s_unlock() { latch.rd_unlock(); } + void s_unlock() noexcept { latch.rd_unlock(); } typedef span name_type; /** @return the tablespace name (databasename/tablename) */ - name_type name() const; + name_type name() const noexcept; /** How to validate tablespace files that are being opened */ enum validate { @@ -1094,9 +1100,9 @@ public: private: /** @return whether the file is usable for io() */ - ATTRIBUTE_COLD bool prepare_acquired(); + ATTRIBUTE_COLD bool prepare_acquired() noexcept; /** @return whether the file is usable for io() */ - ATTRIBUTE_COLD bool acquire_and_prepare(); + ATTRIBUTE_COLD bool acquire_and_prepare() noexcept; #endif /*!UNIV_INNOCHECKSUM */ }; @@ -1141,7 +1147,7 @@ struct fil_node_t final ulint block_size; /** @return whether this file is open */ - bool is_open() const { return handle != OS_FILE_CLOSED; } + bool is_open() const noexcept { return handle != OS_FILE_CLOSED; } /** Read the first page of a data file. @param dpage copy of a first page, from the doublewrite buffer, or nullptr @@ -1152,36 +1158,36 @@ struct fil_node_t final void find_metadata(IF_WIN(,bool create= false)) noexcept; /** Close the file handle. */ - void close(); + void close() noexcept; /** Same as close() but returns file handle instead of closing it. */ - pfs_os_file_t detach() MY_ATTRIBUTE((warn_unused_result)); + pfs_os_file_t detach() noexcept MY_ATTRIBUTE((warn_unused_result)); /** Prepare to free a file from fil_system. @param detach_handle whether to detach instead of closing a handle @return detached handle or OS_FILE_CLOSED */ - inline pfs_os_file_t close_to_free(bool detach_handle= false); + inline pfs_os_file_t close_to_free(bool detach_handle= false) noexcept; /** Update the data structures on write completion */ - inline void complete_write(); + inline void complete_write() noexcept; private: /** Does stuff common for close() and detach() */ - void prepare_to_close_or_detach(); + void prepare_to_close_or_detach() noexcept; }; -inline bool fil_space_t::use_doublewrite() const +inline bool fil_space_t::use_doublewrite() const noexcept { return !UT_LIST_GET_FIRST(chain)->atomic_write && srv_use_doublewrite_buf && buf_dblwr.is_created(); } -inline void fil_space_t::set_imported() +inline void fil_space_t::set_imported() noexcept { ut_ad(being_imported); being_imported= false; UT_LIST_GET_FIRST(chain)->find_metadata(); } -inline bool fil_space_t::is_rotational() const +inline bool fil_space_t::is_rotational() const noexcept { for (const fil_node_t *node= UT_LIST_GET_FIRST(chain); node; node= UT_LIST_GET_NEXT(chain, node)) @@ -1383,7 +1389,7 @@ constexpr uint16_t FIL_PAGE_COMPRESS_FCRC32_MARKER= 15; /* @} */ /** @return whether the page type is B-tree or R-tree index */ -inline bool fil_page_type_is_index(uint16_t page_type) +inline bool fil_page_type_is_index(uint16_t page_type) noexcept { switch (page_type) { case FIL_PAGE_TYPE_INSTANT: @@ -1402,7 +1408,7 @@ index */ /** Get the file page type. @param[in] page file page @return page type */ -inline uint16_t fil_page_get_type(const byte *page) +inline uint16_t fil_page_get_type(const byte *page) noexcept { return mach_read_from_2(my_assume_aligned<2>(page + FIL_PAGE_TYPE)); } @@ -1420,10 +1426,8 @@ or the caller should be in single-threaded crash recovery mode Normally, fil_space_t::get() should be used instead. @param[in] id tablespace ID @return tablespace, or NULL if not found */ -fil_space_t* -fil_space_get( - ulint id) - MY_ATTRIBUTE((warn_unused_result)); +fil_space_t *fil_space_get(ulint id) noexcept + MY_ATTRIBUTE((warn_unused_result)); /** The tablespace memory cache; also the totality of logs (the log data space) is stored here; below we talk about tablespaces */ @@ -1436,7 +1440,7 @@ struct fil_system_t { */ fil_system_t() : m_initialised(false) {} - bool is_initialised() const { return m_initialised; } + bool is_initialised() const noexcept { return m_initialised; } /** Create the file system interface at database start. @@ -1446,7 +1450,7 @@ struct fil_system_t { void create(ulint hash_size); /** Close the file system interface at shutdown */ - void close(); + void close() noexcept; private: bool m_initialised; @@ -1460,7 +1464,7 @@ private: std::vector ssd; public: /** @return whether a file system device is on non-rotational storage */ - bool is_ssd(dev_t dev) const + bool is_ssd(dev_t dev) const noexcept { /* Linux seems to allow up to 15 partitions per block device. If the detected ssd carries "partition number 0" (it is the whole device), @@ -1477,7 +1481,7 @@ public: @param detach_handle whether to detach the handle, instead of closing @return detached handle @retval OS_FILE_CLOSED if no handle was detached */ - pfs_os_file_t detach(fil_space_t *space, bool detach_handle= false); + pfs_os_file_t detach(fil_space_t *space, bool detach_handle= false) noexcept; /** the mutex protecting most data fields, and some fields of fil_space_t */ mysql_mutex_t mutex; @@ -1520,13 +1524,13 @@ public: fil_system.space_list, so that fil_space_t::try_to_close() should close it as a last resort. @param space space to add */ - void add_opened_last_to_space_list(fil_space_t *space); + void add_opened_last_to_space_list(fil_space_t *space) noexcept; /** Move the file to the end of opened spaces list in fil_system.space_list, so that fil_space_t::try_to_close() should close it as a last resort. @param space space to move */ - inline void move_opened_last_to_space_list(fil_space_t *space) + inline void move_opened_last_to_space_list(fil_space_t *space) noexcept { /* In the case when several files of the same space are added in a row, there is no need to remove and add a space to the same position @@ -1542,7 +1546,7 @@ public: fil_space_t::try_to_close() iterates opened files first in FIFO order, i.e. first opened, first closed. @param space space to move */ - void move_closed_last_to_space_list(fil_space_t *space) + void move_closed_last_to_space_list(fil_space_t *space) noexcept { if (UNIV_UNLIKELY(freeze_space_list)) return; @@ -1569,21 +1573,21 @@ public: @retval fil_system.temp_space if there is no work to do @retval nullptr upon reaching the end of the iteration */ inline fil_space_t* default_encrypt_next(fil_space_t *space, bool recheck, - bool encrypt); + bool encrypt) noexcept; /** Extend all open data files to the recovered size */ - ATTRIBUTE_COLD void extend_to_recv_size(); + ATTRIBUTE_COLD void extend_to_recv_size() noexcept; /** Determine if a tablespace associated with a file name exists. @param path tablespace file name to look for @return a matching tablespace */ - inline fil_space_t *find(const char *path) const; + inline fil_space_t *find(const char *path) const noexcept; }; /** The tablespace memory cache. */ extern fil_system_t fil_system; -inline void fil_space_t::reacquire() +inline void fil_space_t::reacquire() noexcept { ut_d(uint32_t n=) n_pending.fetch_add(1, std::memory_order_relaxed); #ifdef SAFE_MUTEX @@ -1594,7 +1598,7 @@ inline void fil_space_t::reacquire() } /** Flush pending writes from the file system cache to the file. */ -template inline void fil_space_t::flush() +template inline void fil_space_t::flush() noexcept { mysql_mutex_assert_not_owner(&fil_system.mutex); ut_ad(!have_reference || (pending() & PENDING)); @@ -1617,7 +1621,7 @@ template inline void fil_space_t::flush() } /** @return the size in pages (0 if unreadable) */ -inline uint32_t fil_space_t::get_size() +inline uint32_t fil_space_t::get_size() noexcept { if (!size) { @@ -1638,7 +1642,7 @@ to recycle id's. bool fil_assign_new_space_id( /*====================*/ - ulint* space_id); /*!< in/out: space id */ + ulint* space_id) noexcept; /*!< in/out: space id */ /** Frees a space object from the tablespace memory cache. Closes the files in the chain but does not delete them. @@ -1649,14 +1653,14 @@ There must not be any pending i/o's or flushes on the files. bool fil_space_free( ulint id, - bool x_latched); + bool x_latched) noexcept; /** Set the recovered size of a tablespace in pages. @param id tablespace ID @param size recovered size in pages @param flags tablespace flags */ void fil_space_set_recv_size_and_flags(ulint id, uint32_t size, - uint32_t flags); + uint32_t flags) noexcept; /*******************************************************************//** Sets the max tablespace id counter if the given number is bigger than the @@ -1664,7 +1668,7 @@ previous value. */ void fil_set_max_space_id_if_bigger( /*===========================*/ - ulint max_id);/*!< in: maximum known id */ + ulint max_id) noexcept;/*!< in: maximum known id */ /** Write the flushed LSN to the page header of the first page in the system tablespace. @@ -1672,7 +1676,7 @@ system tablespace. @return DB_SUCCESS or error number */ dberr_t fil_write_flushed_lsn( - lsn_t lsn) + lsn_t lsn) noexcept MY_ATTRIBUTE((warn_unused_result)); MY_ATTRIBUTE((warn_unused_result)) @@ -1680,12 +1684,12 @@ MY_ATTRIBUTE((warn_unused_result)) @param id tablespace identifier @return detached file handle (to be closed by the caller) @return OS_FILE_CLOSED if no file existed */ -pfs_os_file_t fil_delete_tablespace(ulint id); +pfs_os_file_t fil_delete_tablespace(ulint id) noexcept; /** Close a single-table tablespace on failed IMPORT TABLESPACE. The tablespace must be cached in the memory cache. Free all pages used by the tablespace. */ -void fil_close_tablespace(ulint id); +void fil_close_tablespace(ulint id) noexcept; /*******************************************************************//** Allocates and builds a file name from a path, a table or tablespace name @@ -1697,10 +1701,10 @@ and a suffix. The string must be freed by caller with ut_free(). @return own: file name */ char* fil_make_filepath_low(const char *path, const fil_space_t::name_type &name, - ib_extention extension, bool trim_name); + ib_extention extension, bool trim_name) noexcept; char *fil_make_filepath(const char* path, const table_name_t name, - ib_extention suffix, bool strip_name); + ib_extention suffix, bool strip_name) noexcept; /** Wrapper function over fil_make_filepath_low to build file name. @param path nullptr or the directory path or the full path and filename @@ -1710,7 +1714,7 @@ char *fil_make_filepath(const char* path, const table_name_t name, @return own: file name */ static inline char* fil_make_filepath(const char* path, const fil_space_t::name_type &name, - ib_extention extension, bool trim_name) + ib_extention extension, bool trim_name) noexcept { /* If we are going to strip a name off the path, there better be a path and a new name to put back on. */ @@ -1796,7 +1800,6 @@ fil_ibd_load( fil_space_t*& space) MY_ATTRIBUTE((warn_unused_result)); - /** Determine if a matching tablespace exists in the InnoDB tablespace memory cache. Note that if we have not done a crash recovery at the database startup, there may be many tablespaces which are not yet in the memory cache. @@ -1804,28 +1807,30 @@ startup, there may be many tablespaces which are not yet in the memory cache. @param[in] table_flags table flags @return the tablespace @retval NULL if no matching tablespace exists in the memory cache */ -fil_space_t *fil_space_for_table_exists_in_mem(ulint id, ulint table_flags); +fil_space_t *fil_space_for_table_exists_in_mem(ulint id, ulint table_flags) + noexcept; /** Try to extend a tablespace if it is smaller than the specified size. @param[in,out] space tablespace @param[in] size desired size in pages @return whether the tablespace is at least as big as requested */ -bool fil_space_extend(fil_space_t *space, uint32_t size); +bool fil_space_extend(fil_space_t *space, uint32_t size) noexcept; /** Flush to disk the writes in file spaces of the given type possibly cached by the OS. */ -void fil_flush_file_spaces(); +void fil_flush_file_spaces() noexcept; /******************************************************************//** Checks the consistency of the tablespace cache. @return true if ok */ -bool fil_validate(); -/*********************************************************************//** -Sets the file page type. */ -void -fil_page_set_type( -/*==============*/ - byte* page, /*!< in/out: file page */ - ulint type); /*!< in: type */ +bool fil_validate() noexcept; + +/** Set the file page type. +@param page file page +@param type FIL_PAGE_TYPE value */ +inline void fil_page_set_type(byte *page, uint16_t type) noexcept +{ + mach_write_to_2(page + FIL_PAGE_TYPE, type); +} /********************************************************************//** Delete the tablespace file and any related files like .cfg. @@ -1833,7 +1838,8 @@ This should not be called for temporary tables. */ void fil_delete_file( /*============*/ - const char* path); /*!< in: filepath of the ibd tablespace */ + const char* path) /*!< in: filepath of the ibd tablespace */ + noexcept; /** Look up a table space by a given id. @param id tablespace identifier @@ -1844,22 +1850,20 @@ fil_space_t *fil_space_get_by_id(ulint id) noexcept; /** Note that a non-predefined persistent tablespace has been modified by redo log. @param[in,out] space tablespace */ -void -fil_names_dirty( - fil_space_t* space); +void fil_names_dirty(fil_space_t *space) noexcept; /** Write FILE_MODIFY records when a non-predefined persistent tablespace was modified for the first time since the latest fil_names_clear(). @param[in,out] space tablespace */ -void fil_names_dirty_and_write(fil_space_t* space); +void fil_names_dirty_and_write(fil_space_t *space) noexcept; /** Write FILE_MODIFY records if a persistent tablespace was modified for the first time since the latest fil_names_clear(). @param[in,out] space tablespace @param[in,out] mtr mini-transaction @return whether any FILE_MODIFY record was written */ -inline bool fil_names_write_if_was_clean(fil_space_t* space) +inline bool fil_names_write_if_was_clean(fil_space_t* space) noexcept { mysql_mutex_assert_owner(&log_sys.mutex); @@ -1885,10 +1889,7 @@ and write out FILE_MODIFY and FILE_CHECKPOINT if needed. @return whether anything was written to the redo log @retval false if no flags were set and nothing written @retval true if anything was written to the redo log */ -bool -fil_names_clear( - lsn_t lsn, - bool do_write); +bool fil_names_clear(lsn_t lsn, bool do_write) noexcept; #ifdef UNIV_ENABLE_UNIT_TEST_MAKE_FILEPATH void test_make_filepath(); @@ -1898,12 +1899,14 @@ void test_make_filepath(); @param[in] space tablespace @param[in] offset page number @return block size */ -ulint fil_space_get_block_size(const fil_space_t* space, unsigned offset); +ulint fil_space_get_block_size(const fil_space_t* space, unsigned offset) + noexcept; /** Check whether encryption key found @param crypt_data Encryption data @param f_name File name @return encryption key found */ -bool fil_crypt_check(fil_space_crypt_t *crypt_data, const char *f_name); +bool fil_crypt_check(fil_space_crypt_t *crypt_data, const char *f_name) + noexcept; #endif /* UNIV_INNOCHECKSUM */ diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h index df5acfb9ace..837d22f2d3b 100644 --- a/storage/innobase/include/os0file.h +++ b/storage/innobase/include/os0file.h @@ -211,19 +211,20 @@ public: buf_tmp_buffer_t *slot= nullptr) : bpage(bpage), slot(slot), type(type) {} - bool is_read() const { return (type & READ_SYNC) != 0; } - bool is_write() const { return (type & WRITE_SYNC) != 0; } - bool is_async() const { return (type & (READ_SYNC ^ READ_ASYNC)) != 0; } + bool is_read() const noexcept { return (type & READ_SYNC) != 0; } + bool is_write() const noexcept { return (type & WRITE_SYNC) != 0; } + bool is_async() const noexcept + { return (type & (READ_SYNC ^ READ_ASYNC)) != 0; } - void write_complete(int io_error) const; - void read_complete(int io_error) const; - void fake_read_complete(os_offset_t offset) const; + void write_complete(int io_error) const noexcept; + void read_complete(int io_error) const noexcept; + void fake_read_complete(os_offset_t offset) const noexcept; /** If requested, free storage space associated with a section of the file. @param off byte offset from the start (SEEK_SET) @param len size of the hole in bytes @return DB_SUCCESS or error code */ - dberr_t maybe_punch_hole(os_offset_t off, ulint len) + dberr_t maybe_punch_hole(os_offset_t off, ulint len) noexcept { return off && len && node && (type & (PUNCH ^ WRITE_ASYNC)) ? punch_hole(off, len) @@ -235,7 +236,7 @@ private: @param off byte offset from the start (SEEK_SET) @param len size of the hole in bytes @return DB_SUCCESS or error code */ - dberr_t punch_hole(os_offset_t off, ulint len) const; + dberr_t punch_hole(os_offset_t off, ulint len) const noexcept; public: /** Page to be written on write operation */ @@ -318,8 +319,7 @@ struct os_file_stat_t { the temporary file is created in the in the mysql server configuration parameter (--tmpdir). @return temporary file handle, or NULL on error */ -FILE* -os_file_create_tmpfile(); +FILE *os_file_create_tmpfile() noexcept; /** This function attempts to create a directory named pathname. The new directory @@ -331,10 +331,8 @@ fail_if_exists arguments is true. @param[in] fail_if_exists if true, pre-existing directory is treated as an error. @return true if call succeeds, false on error */ -bool -os_file_create_directory( - const char* pathname, - bool fail_if_exists); +bool os_file_create_directory(const char *pathname, bool fail_if_exists) + noexcept; /** NOTE! Use the corresponding macro os_file_create_simple(), not directly this function! @@ -353,7 +351,7 @@ os_file_create_simple_func( ulint create_mode, ulint access_type, bool read_only, - bool* success); + bool* success) noexcept; /** NOTE! Use the corresponding macro os_file_create_simple_no_error_handling(), not directly this function! @@ -373,7 +371,7 @@ os_file_create_simple_no_error_handling_func( ulint create_mode, ulint access_type, bool read_only, - bool* success) + bool* success) noexcept MY_ATTRIBUTE((warn_unused_result)); #ifndef HAVE_FCNTL_DIRECT @@ -389,7 +387,7 @@ os_file_set_nocache( /*================*/ int fd, /*!< in: file descriptor to alter */ const char* file_name, - const char* operation_name); + const char* operation_name) noexcept; #endif #ifndef _WIN32 /* On Microsoft Windows, mandatory locking is used */ @@ -397,7 +395,7 @@ os_file_set_nocache( @param fd file descriptor @param name file name @return 0 on success */ -int os_file_lock(int fd, const char *name); +int os_file_lock(int fd, const char *name) noexcept; #endif /** NOTE! Use the corresponding macro os_file_create(), not directly @@ -417,7 +415,7 @@ os_file_create_func( ulint create_mode, ulint type, bool read_only, - bool* success) + bool* success) noexcept MY_ATTRIBUTE((warn_unused_result)); /** Deletes a file. The file has to be closed before calling this. @@ -859,9 +857,7 @@ to original un-instrumented file I/O APIs */ @param[in] file handle to a file @return file size if OK, else set m_total_size to ~0 and m_alloc_size to errno */ -os_file_size_t -os_file_get_size( - const char* filename) +os_file_size_t os_file_get_size(const char *filename) noexcept MY_ATTRIBUTE((warn_unused_result)); /** Determine the logical size of a file. @@ -876,9 +872,7 @@ os_offset_t os_file_get_size(os_file_t file) noexcept /** Truncates a file at its current position. @param[in/out] file file to be truncated @return true if success */ -bool -os_file_set_eof( - FILE* file); /*!< in: file to be truncated */ +bool os_file_set_eof(FILE *file) noexcept; /** Truncate a file to a specified size in bytes. @param[in] pathname file path @@ -891,16 +885,14 @@ os_file_truncate( const char* pathname, os_file_t file, os_offset_t size, - bool allow_shrink = false); + bool allow_shrink = false) noexcept; /** NOTE! Use the corresponding macro os_file_flush(), not directly this function! Flushes the write buffers of a given file to the disk. @param[in] file handle to a file @return true if success */ -bool -os_file_flush_func( - os_file_t file); +bool os_file_flush_func(os_file_t file) noexcept; /** Retrieves the last error number if an error occurs in a file io function. The number should be retrieved before any other OS calls (because they may @@ -912,7 +904,7 @@ the OS error number + OS_FILE_ERROR_MAX is returned. to the log @return error number, or OS error number + OS_FILE_ERROR_MAX */ ulint os_file_get_last_error(bool report_all_errors, - bool on_error_silent= false); + bool on_error_silent= false) noexcept; /** NOTE! Use the corresponding macro os_file_read(), not directly this function! @@ -931,7 +923,7 @@ os_file_read_func( void* buf, os_offset_t offset, ulint n, - ulint* o) + ulint* o) noexcept MY_ATTRIBUTE((warn_unused_result)); /** Rewind file to its start, read at most size - 1 bytes from it to str, and @@ -944,7 +936,7 @@ void os_file_read_string( FILE* file, char* str, - ulint size); + ulint size) noexcept; /** NOTE! Use the corresponding macro os_file_write(), not directly this function! @@ -974,7 +966,7 @@ bool os_file_status( const char* path, bool* exists, - os_file_type_t* type); + os_file_type_t* type) noexcept; /** This function reduces a null-terminated full remote path name into the path that is sent by MySQL for DATA DIRECTORY clause. It replaces @@ -988,34 +980,30 @@ This function manipulates that path in place. If the path format is not as expected, just return. The result is used to inform a SHOW CREATE TABLE command. @param[in,out] data_dir_path Full path/data_dir_path */ -void -os_file_make_data_dir_path( - char* data_dir_path); +void os_file_make_data_dir_path(char *data_dir_path) noexcept; /** Create all missing subdirectories along the given path. @return DB_SUCCESS if OK, otherwise error code. */ -dberr_t -os_file_create_subdirs_if_needed( - const char* path); +dberr_t os_file_create_subdirs_if_needed(const char* path) noexcept; #ifdef UNIV_ENABLE_UNIT_TEST_GET_PARENT_DIR /* Test the function os_file_get_parent_dir. */ void -unit_test_os_file_get_parent_dir(); +unit_test_os_file_get_parent_dir() noexcept; #endif /* UNIV_ENABLE_UNIT_TEST_GET_PARENT_DIR */ /** Initializes the asynchronous io system. */ -int os_aio_init(); +int os_aio_init() noexcept; /** Frees the asynchronous io system. */ -void os_aio_free(); +void os_aio_free() noexcept; /** Submit a fake read request during crash recovery. @param type fake read request @param offset additional context */ -void os_fake_read(const IORequest &type, os_offset_t offset); +void os_fake_read(const IORequest &type, os_offset_t offset) noexcept; /** Request a read or write. @param type I/O request @@ -1024,36 +1012,34 @@ void os_fake_read(const IORequest &type, os_offset_t offset); @param n number of bytes @retval DB_SUCCESS if request was queued successfully @retval DB_IO_ERROR on I/O error */ -dberr_t os_aio(const IORequest &type, void *buf, os_offset_t offset, size_t n); +dberr_t os_aio(const IORequest &type, void *buf, os_offset_t offset, size_t n) + noexcept; /** @return number of pending reads */ -size_t os_aio_pending_reads(); +size_t os_aio_pending_reads() noexcept; /** @return approximate number of pending reads */ -size_t os_aio_pending_reads_approx(); +size_t os_aio_pending_reads_approx() noexcept; /** @return number of pending writes */ -size_t os_aio_pending_writes(); +size_t os_aio_pending_writes() noexcept; /** Wait until there are no pending asynchronous writes. @param declare whether the wait will be declared in tpool */ -void os_aio_wait_until_no_pending_writes(bool declare); +void os_aio_wait_until_no_pending_writes(bool declare) noexcept; /** Wait until all pending asynchronous reads have completed. @param declare whether the wait will be declared in tpool */ -void os_aio_wait_until_no_pending_reads(bool declare); +void os_aio_wait_until_no_pending_reads(bool declare) noexcept; /** Prints info of the aio arrays. @param[in/out] file file where to print */ -void -os_aio_print(FILE* file); +void os_aio_print(FILE *file) noexcept; /** Refreshes the statistics used to print per-second averages. */ -void -os_aio_refresh_stats(); +void os_aio_refresh_stats() noexcept; /** Checks that all slots in the system have been freed, that is, there are no pending io operations. */ -bool -os_aio_all_slots_free(); +bool os_aio_all_slots_free() noexcept; /** This function returns information about the specified file @@ -1068,7 +1054,7 @@ os_file_get_status( const char* path, os_file_stat_t* stat_info, bool check_rw_perm, - bool read_only); + bool read_only) noexcept; #ifdef _WIN32 @@ -1079,7 +1065,7 @@ Make file sparse, on Windows. @param[in] is_sparse if true, make file sparse, otherwise "unsparse" the file @return true on success, false on error */ -bool os_file_set_sparse_win32(os_file_t file, bool is_sparse = true); +bool os_file_set_sparse_win32(os_file_t file, bool is_sparse = true) noexcept; /** Changes file size on Windows @@ -1096,14 +1082,12 @@ If file is normal, file system allocates storage. @param[in] file file handle @param[in] size size to preserve in bytes @return true if success */ -bool -os_file_set_size( - const char* pathname, - os_file_t file, - os_offset_t size); +bool os_file_set_size(const char *pathname, os_file_t file, os_offset_t size) + noexcept; inline bool os_file_set_size(const char* name, os_file_t file, os_offset_t size, bool) + noexcept { return os_file_set_size(name, file, size); } @@ -1127,14 +1111,14 @@ dberr_t os_file_punch_hole( os_file_t fh, os_offset_t off, - os_offset_t len) + os_offset_t len) noexcept MY_ATTRIBUTE((warn_unused_result)); /* Determine if a path is an absolute path or not. @param[in] OS directory or file path to evaluate @retval true if an absolute path @retval false if a relative path */ -inline bool is_absolute_path(const char *path) +inline bool is_absolute_path(const char *path) noexcept { switch (path[0]) { #ifdef _WIN32 diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 7b02de62119..96c964e6de7 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -3256,7 +3256,7 @@ func_exit: return success; } -void IORequest::fake_read_complete(os_offset_t offset) const +void IORequest::fake_read_complete(os_offset_t offset) const noexcept { ut_ad(node); ut_ad(is_read()); @@ -3297,7 +3297,7 @@ void IORequest::fake_read_complete(os_offset_t offset) const } /** @return whether a page has been freed */ -inline bool fil_space_t::is_freed(uint32_t page) +inline bool fil_space_t::is_freed(uint32_t page) noexcept { std::lock_guard freed_lock(freed_range_mutex); return freed_ranges.contains(page); @@ -3598,7 +3598,7 @@ ATTRIBUTE_COLD buf_block_t *recv_sys_t::recover_low(const page_id_t page_id) return nullptr; } -inline fil_space_t *fil_system_t::find(const char *path) const +inline fil_space_t *fil_system_t::find(const char *path) const noexcept { mysql_mutex_assert_owner(&mutex); for (fil_space_t &space : fil_system.space_list) @@ -3608,7 +3608,7 @@ inline fil_space_t *fil_system_t::find(const char *path) const } /** Thread-safe function which sorts flush_list by oldest_modification */ -static void log_sort_flush_list() +static void log_sort_flush_list() noexcept { /* Ensure that oldest_modification() cannot change during std::sort() */ { diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index 834bceaa8e2..bd0ef0eee1b 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -259,7 +259,7 @@ void mtr_t::rollback_to_savepoint(ulint begin, ulint end) } /** Set create_lsn. */ -inline void fil_space_t::set_create_lsn(lsn_t lsn) +inline void fil_space_t::set_create_lsn(lsn_t lsn) noexcept { ut_ad(latch.have_wr()); /* Concurrent log_checkpoint_low() must be impossible. */ diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 8f06f8dde87..67c1638afb7 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -176,7 +176,7 @@ os_file_handle_error_cond_exit( const char* name, const char* operation, bool should_abort, - bool on_error_silent); + bool on_error_silent) noexcept; /** Does error handling when a file operation fails. @param[in] name name of a file or NULL @@ -313,7 +313,7 @@ private: @param fd file descriptor @param name file name @return 0 on success */ -int os_file_lock(int fd, const char *name) +int os_file_lock(int fd, const char *name) noexcept { struct flock lk; @@ -342,13 +342,7 @@ int os_file_lock(int fd, const char *name) } #endif /* !_WIN32 */ - -/** Create a temporary file. This function is like tmpfile(3), but -the temporary file is created in the in the mysql server configuration -parameter (--tmpdir). -@return temporary file handle, or NULL on error */ -FILE* -os_file_create_tmpfile() +FILE *os_file_create_tmpfile() noexcept { FILE* file = NULL; File fd = mysql_tmpfile("ib"); @@ -381,7 +375,7 @@ void os_file_read_string( FILE* file, char* str, - ulint size) + ulint size) noexcept { if (size != 0) { rewind(file); @@ -392,21 +386,7 @@ os_file_read_string( } } -/** This function reduces a null-terminated full remote path name into -the path that is sent by MySQL for DATA DIRECTORY clause. It replaces -the 'databasename/tablename.ibd' found at the end of the path with just -'tablename'. - -Since the result is always smaller than the path sent in, no new memory -is allocated. The caller should allocate memory for the path sent in. -This function manipulates that path in place. - -If the path format is not as expected, just return. The result is used -to inform a SHOW CREATE TABLE command. -@param[in,out] data_dir_path Full path/data_dir_path */ -void -os_file_make_data_dir_path( - char* data_dir_path) +void os_file_make_data_dir_path(char *data_dir_path) noexcept { /* Replace the period before the extension with a null byte. */ char* ptr = strrchr(data_dir_path, '.'); @@ -455,11 +435,7 @@ to the last directory separator that the caller has fixed. @param[in] path path name @param[in] path last directory separator in the path @return true if this path is a drive root, false if not */ -UNIV_INLINE -bool -os_file_is_root( - const char* path, - const char* last_slash) +static bool os_file_is_root(const char *path, const char *last_slash) noexcept { return( #ifdef _WIN32 @@ -554,7 +530,7 @@ os_file_get_parent_dir( void test_os_file_get_parent_dir( const char* child_dir, - const char* expected_dir) + const char* expected_dir) noexcept { char* child = mem_strdup(child_dir); char* expected = expected_dir == NULL ? NULL @@ -577,7 +553,7 @@ test_os_file_get_parent_dir( /* Test the function os_file_get_parent_dir. */ void -unit_test_os_file_get_parent_dir() +unit_test_os_file_get_parent_dir() noexcept { test_os_file_get_parent_dir("/usr/lib/a", "/usr/lib"); test_os_file_get_parent_dir("/usr/", NULL); @@ -606,12 +582,7 @@ unit_test_os_file_get_parent_dir() #endif /* UNIV_ENABLE_UNIT_TEST_GET_PARENT_DIR */ -/** Creates all missing subdirectories along the given path. -@param[in] path Path name -@return DB_SUCCESS if OK, otherwise error code. */ -dberr_t -os_file_create_subdirs_if_needed( - const char* path) +dberr_t os_file_create_subdirs_if_needed(const char *path) noexcept { if (srv_read_only_mode) { @@ -737,6 +708,7 @@ the OS error number + 100 is returned. to the log @return error number, or OS error number + 100 */ ulint os_file_get_last_error(bool report_all_errors, bool on_error_silent) + noexcept { int err = errno; @@ -807,7 +779,7 @@ Returns the value 0 if successful; otherwise the value -1 is returned and the global variable errno is set to indicate the error. @param[in] file open file handle @return 0 if success, -1 otherwise */ -static int os_file_sync_posix(os_file_t file) +static int os_file_sync_posix(os_file_t file) noexcept { #if !defined(HAVE_FDATASYNC) || HAVE_DECL_FDATASYNC == 0 auto func= fsync; @@ -861,7 +833,7 @@ bool os_file_status_posix( const char* path, bool* exists, - os_file_type_t* type) + os_file_type_t* type) noexcept { struct stat statinfo; @@ -897,14 +869,7 @@ os_file_status_posix( return(true); } -/** NOTE! Use the corresponding macro os_file_flush(), not directly this -function! -Flushes the write buffers of a given file to the disk. -@param[in] file handle to a file -@return true if success */ -bool -os_file_flush_func( - os_file_t file) +bool os_file_flush_func(os_file_t file) noexcept { int ret; @@ -950,7 +915,7 @@ os_file_create_simple_func( ulint create_mode, ulint access_type, bool read_only, - bool* success) + bool* success) noexcept { pfs_os_file_t file; @@ -1058,20 +1023,8 @@ os_file_create_simple_func( return(file); } -/** This function attempts to create a directory named pathname. The new -directory gets default permissions. On Unix the permissions are -(0770 & ~umask). If the directory exists already, nothing is done and -the call succeeds, unless the fail_if_exists arguments is true. -If another error occurs, such as a permission error, this does not crash, -but reports the error and returns false. -@param[in] pathname directory name as null-terminated string -@param[in] fail_if_exists if true, pre-existing directory is treated as - an error. -@return true if call succeeds, false on error */ -bool -os_file_create_directory( - const char* pathname, - bool fail_if_exists) +bool os_file_create_directory(const char *pathname, bool fail_if_exists) + noexcept { int rcode; @@ -1104,7 +1057,7 @@ os_file_create_func( ulint create_mode, ulint type, bool read_only, - bool* success) + bool* success) noexcept { bool on_error_no_exit; bool on_error_silent; @@ -1273,7 +1226,7 @@ os_file_create_simple_no_error_handling_func( ulint create_mode, ulint access_type, bool read_only, - bool* success) + bool* success) noexcept { os_file_t file; int create_flag; @@ -1449,13 +1402,7 @@ os_offset_t os_file_get_size(os_file_t file) noexcept return lseek(file, 0, SEEK_END); } -/** Gets a file size. -@param[in] filename Full path to the filename to check -@return file size if OK, else set m_total_size to ~0 and m_alloc_size to - errno */ -os_file_size_t -os_file_get_size( - const char* filename) +os_file_size_t os_file_get_size(const char *filename) noexcept { struct stat s; os_file_size_t file_size; @@ -1576,11 +1523,7 @@ os_file_truncate_posix( return(res == 0); } -/** Truncates a file at its current position. -@return true if success */ -bool -os_file_set_eof( - FILE* file) /*!< in: file to be truncated */ +bool os_file_set_eof(FILE *file) noexcept { return(!ftruncate(fileno(file), ftell(file))); } @@ -1782,7 +1725,7 @@ function! Flushes the write buffers of a given file to the disk. @param[in] file handle to a file @return true if success */ -bool os_file_flush_func(os_file_t file) +bool os_file_flush_func(os_file_t file) noexcept { ++os_n_fsyncs; static bool disable_datasync; @@ -1829,7 +1772,7 @@ printed of all errors to the log @return error number, or OS error number + OS_FILE_ERROR_MAX */ ulint os_file_get_last_error(bool report_all_errors, bool on_error_silent) - + noexcept { ulint err = (ulint) GetLastError(); @@ -1936,7 +1879,7 @@ os_file_create_simple_func( ulint create_mode, ulint access_type, bool read_only, - bool* success) + bool* success) noexcept { os_file_t file; @@ -2045,20 +1988,8 @@ os_file_create_simple_func( return(file); } -/** This function attempts to create a directory named pathname. The new -directory gets default permissions. On Unix the permissions are -(0770 & ~umask). If the directory exists already, nothing is done and -the call succeeds, unless the fail_if_exists arguments is true. -If another error occurs, such as a permission error, this does not crash, -but reports the error and returns false. -@param[in] pathname directory name as null-terminated string -@param[in] fail_if_exists if true, pre-existing directory is treated - as an error. -@return true if call succeeds, false on error */ -bool -os_file_create_directory( - const char* pathname, - bool fail_if_exists) +bool os_file_create_directory(const char *pathname, bool fail_if_exists) + noexcept { BOOL rcode; @@ -2118,7 +2049,7 @@ os_file_create_func( ulint create_mode, ulint type, bool read_only, - bool* success) + bool* success) noexcept { os_file_t file; bool retry; @@ -2311,7 +2242,7 @@ os_file_create_simple_no_error_handling_func( ulint create_mode, ulint access_type, bool read_only, - bool* success) + bool* success) noexcept { os_file_t file; @@ -2566,13 +2497,7 @@ os_offset_t os_file_get_size(os_file_t file) noexcept return os_offset_t{low} | os_offset_t{high} << 32; } -/** Gets a file size. -@param[in] filename Full path to the filename to check -@return file size if OK, else set m_total_size to ~0 and m_alloc_size to - errno */ -os_file_size_t -os_file_get_size( - const char* filename) +os_file_size_t os_file_get_size(const char *filename) noexcept { struct __stat64 s; os_file_size_t file_size; @@ -2690,7 +2615,7 @@ Sets a sparse flag on Windows file. @return true on success, false on error */ #include -bool os_file_set_sparse_win32(os_file_t file, bool is_sparse) +bool os_file_set_sparse_win32(os_file_t file, bool is_sparse) noexcept { if (!is_sparse && !IsWindows8OrGreater()) { /* Cannot unset sparse flag on older Windows. @@ -2705,11 +2630,8 @@ bool os_file_set_sparse_win32(os_file_t file, bool is_sparse) FSCTL_SET_SPARSE, &sparse_buffer, sizeof(sparse_buffer), 0, 0,&temp); } -bool -os_file_set_size( - const char* pathname, - os_file_t file, - os_offset_t size) +bool os_file_set_size(const char *pathname, os_file_t file, os_offset_t size) + noexcept { LARGE_INTEGER length; @@ -2730,12 +2652,7 @@ os_file_set_size( return(success); } -/** Truncates a file at its current position. -@param[in] file Handle to be truncated -@return true if success */ -bool -os_file_set_eof( - FILE* file) +bool os_file_set_eof(FILE *file) noexcept { HANDLE h = (HANDLE) _get_osfhandle(fileno(file)); @@ -2952,7 +2869,7 @@ os_file_read_func( void* buf, os_offset_t offset, ulint n, - ulint* o) + ulint* o) noexcept { ut_ad(!type.node || type.node->handle == file); ut_ad(n); @@ -2990,7 +2907,7 @@ os_file_handle_error_cond_exit( const char* name, const char* operation, bool should_abort, - bool on_error_silent) + bool on_error_silent) noexcept { ulint err; @@ -3075,6 +2992,7 @@ os_file_handle_error_cond_exit( message */ void os_file_set_nocache(int fd, const char *file_name, const char *operation_name) + noexcept { const auto innodb_flush_method = srv_file_flush_method; switch (innodb_flush_method) { @@ -3109,7 +3027,7 @@ os_file_set_nocache(int fd, const char *file_name, const char *operation_name) /** Check if the file system supports sparse files. @param fh file handle @return true if the file system supports sparse files */ -static bool os_is_sparse_file_supported(os_file_t fh) +static bool os_is_sparse_file_supported(os_file_t fh) noexcept { #ifdef _WIN32 FILE_ATTRIBUTE_TAG_INFO info; @@ -3138,7 +3056,7 @@ os_file_truncate( const char* pathname, os_file_t file, os_offset_t size, - bool allow_shrink) + bool allow_shrink) noexcept { if (!allow_shrink) { /* Do nothing if the size preserved is larger than or @@ -3166,7 +3084,7 @@ bool os_file_status( const char* path, bool* exists, - os_file_type_t* type) + os_file_type_t* type) noexcept { #ifdef _WIN32 return(os_file_status_win32(path, exists, type)); @@ -3184,7 +3102,7 @@ dberr_t os_file_punch_hole( os_file_t fh, os_offset_t off, - os_offset_t len) + os_offset_t len) noexcept { #ifdef _WIN32 return os_file_punch_hole_win32(fh, off, len); @@ -3197,7 +3115,7 @@ os_file_punch_hole( @param off byte offset from the start (SEEK_SET) @param len size of the hole in bytes @return DB_SUCCESS or error code */ -dberr_t IORequest::punch_hole(os_offset_t off, ulint len) const +dberr_t IORequest::punch_hole(os_offset_t off, ulint len) const noexcept { ulint trim_len = bpage ? bpage->physical_size() - len : 0; @@ -3269,7 +3187,7 @@ os_file_get_status( const char* path, os_file_stat_t* stat_info, bool check_rw_perm, - bool read_only) + bool read_only) noexcept { dberr_t ret; @@ -3462,7 +3380,7 @@ static bool is_linux_native_aio_supported() } #endif -int os_aio_init() +int os_aio_init() noexcept { int max_write_events= int(srv_n_write_io_threads * OS_AIO_N_PENDING_IOS_PER_THREAD); @@ -3508,7 +3426,7 @@ disable: } -void os_aio_free() +void os_aio_free() noexcept { delete read_slots; delete write_slots; @@ -3518,7 +3436,7 @@ void os_aio_free() } /** Wait until there are no pending asynchronous writes. */ -static void os_aio_wait_until_no_pending_writes_low(bool declare) +static void os_aio_wait_until_no_pending_writes_low(bool declare) noexcept { const bool notify_wait= declare && write_slots->pending_io_count(); @@ -3533,14 +3451,14 @@ static void os_aio_wait_until_no_pending_writes_low(bool declare) /** Wait until there are no pending asynchronous writes. @param declare whether the wait will be declared in tpool */ -void os_aio_wait_until_no_pending_writes(bool declare) +void os_aio_wait_until_no_pending_writes(bool declare) noexcept { os_aio_wait_until_no_pending_writes_low(declare); buf_dblwr.wait_flush_buffered_writes(); } /** @return number of pending reads */ -size_t os_aio_pending_reads() +size_t os_aio_pending_reads() noexcept { mysql_mutex_lock(&read_slots->mutex()); size_t pending= read_slots->pending_io_count(); @@ -3549,13 +3467,13 @@ size_t os_aio_pending_reads() } /** @return approximate number of pending reads */ -size_t os_aio_pending_reads_approx() +size_t os_aio_pending_reads_approx() noexcept { return read_slots->pending_io_count(); } /** @return number of pending writes */ -size_t os_aio_pending_writes() +size_t os_aio_pending_writes() noexcept { mysql_mutex_lock(&write_slots->mutex()); size_t pending= write_slots->pending_io_count(); @@ -3565,7 +3483,7 @@ size_t os_aio_pending_writes() /** Wait until all pending asynchronous reads have completed. @param declare whether the wait will be declared in tpool */ -void os_aio_wait_until_no_pending_reads(bool declare) +void os_aio_wait_until_no_pending_reads(bool declare) noexcept { const bool notify_wait= declare && read_slots->pending_io_count(); @@ -3581,7 +3499,7 @@ void os_aio_wait_until_no_pending_reads(bool declare) /** Submit a fake read request during crash recovery. @param type fake read request @param offset additional context */ -void os_fake_read(const IORequest &type, os_offset_t offset) +void os_fake_read(const IORequest &type, os_offset_t offset) noexcept { tpool::aiocb *cb= read_slots->acquire(); @@ -3608,6 +3526,7 @@ void os_fake_read(const IORequest &type, os_offset_t offset) @retval DB_SUCCESS if request was queued successfully @retval DB_IO_ERROR on I/O error */ dberr_t os_aio(const IORequest &type, void *buf, os_offset_t offset, size_t n) + noexcept { ut_ad(n > 0); ut_ad((n % OS_FILE_LOG_BLOCK_SIZE) == 0); @@ -3688,10 +3607,7 @@ func_exit: goto func_exit; } -/** Prints info of the aio arrays. -@param[in,out] file file where to print */ -void -os_aio_print(FILE* file) +void os_aio_print(FILE *file) noexcept { time_t current_time; double time_elapsed; @@ -3742,9 +3658,7 @@ os_aio_print(FILE* file) os_last_printout = current_time; } -/** Refreshes the statistics used to print per-second averages. */ -void -os_aio_refresh_stats() +void os_aio_refresh_stats() noexcept { os_n_fsyncs_old = os_n_fsyncs; From 82fd202fa4c417a0be4f09028dfdc88f8d902130 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 8 Jan 2025 18:42:37 +0100 Subject: [PATCH 005/213] fix "enforce no trailing \n in Diagnostic_area messages" cannot have an assert in Warning_info::push_warning() because SQL command SIGNAL can set an absolutely arbitrary message, even an empty one or ending with '\n' move the assert into push_warning() and my_message_sql(). followup for 9508a44c3761 --- sql/mysqld.cc | 3 +++ sql/sql_error.cc | 2 +- sql/sql_repl.cc | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 31d9084f235..c48f94e6601 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3077,10 +3077,13 @@ void my_message_sql(uint error, const char *str, myf MyFlags) MyFlags)); DBUG_ASSERT(str != NULL); + DBUG_ASSERT(*str != '\0'); DBUG_ASSERT(error != 0); DBUG_ASSERT((MyFlags & ~(ME_BELL | ME_ERROR_LOG | ME_ERROR_LOG_ONLY | ME_NOTE | ME_WARNING | ME_FATAL)) == 0); + DBUG_ASSERT(str[strlen(str)-1] != '\n'); + if (MyFlags & ME_NOTE) { level= Sql_condition::WARN_LEVEL_NOTE; diff --git a/sql/sql_error.cc b/sql/sql_error.cc index e40a9a70f26..08810755d08 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -692,7 +692,6 @@ Sql_condition *Warning_info::push_warning(THD *thd, const char *msg) { Sql_condition *cond= NULL; - DBUG_ASSERT(msg[strlen(msg)-1] != '\n'); if (! m_read_only) { @@ -750,6 +749,7 @@ void push_warning(THD *thd, Sql_condition::enum_warning_level level, if (level == Sql_condition::WARN_LEVEL_ERROR) level= Sql_condition::WARN_LEVEL_WARN; + DBUG_ASSERT(msg[strlen(msg)-1] != '\n'); (void) thd->raise_condition(code, NULL, level, msg); /* Make sure we also count warnings pushed after calling set_ok_status(). */ diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 6ad5159737c..2b4b2667fc3 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -3086,6 +3086,8 @@ err: } else if (info->errmsg != NULL) safe_strcpy(info->error_text, sizeof(info->error_text), info->errmsg); + else if (info->error_text[0] == 0) + safe_strcpy(info->error_text, sizeof(info->error_text), ER(info->error)); my_message(info->error, info->error_text, MYF(0)); From 725b5e7794f1efc9e83ed054699fbb62197a947d Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 13 Nov 2024 20:35:03 +0100 Subject: [PATCH 006/213] MDEV-35335 implicit commit at START TRANSACTION doesn't reset characteristics --- mysql-test/main/commit.result | 20 ++++++++++++++++++++ mysql-test/main/commit.test | 20 ++++++++++++++++++++ sql/transaction.cc | 4 ++++ 3 files changed, 44 insertions(+) diff --git a/mysql-test/main/commit.result b/mysql-test/main/commit.result index 44d46900d38..dee53a4cdb4 100644 --- a/mysql-test/main/commit.result +++ b/mysql-test/main/commit.result @@ -579,3 +579,23 @@ a # This statement should work, since last statement committed. INSERT INTO t1 VALUES (1); DROP TABLE t1; +# +# MDEV-35335 implicit commit at START TRANSACTION doesn't reset characteristics +# +create table t1 (a int) engine=innodb; +insert t1 values (1); +start transaction; +set session transaction isolation level serializable; +start transaction; +select * from t1; +a +1 +connect con1,localhost,root; +set session innodb_lock_wait_timeout=0; +update t1 set a=2; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +disconnect con1; +connection default; +rollback; +drop table t1; +# End of 10.6 tests diff --git a/mysql-test/main/commit.test b/mysql-test/main/commit.test index a0d4ddee152..ed4847ecffb 100644 --- a/mysql-test/main/commit.test +++ b/mysql-test/main/commit.test @@ -677,3 +677,23 @@ SELECT * FROM t1; INSERT INTO t1 VALUES (1); DROP TABLE t1; + +--echo # +--echo # MDEV-35335 implicit commit at START TRANSACTION doesn't reset characteristics +--echo # +create table t1 (a int) engine=innodb; +insert t1 values (1); +start transaction; +set session transaction isolation level serializable; +start transaction; +select * from t1; +connect con1,localhost,root; +set session innodb_lock_wait_timeout=0; +--error ER_LOCK_WAIT_TIMEOUT +update t1 set a=2; +disconnect con1; +connection default; +rollback; +drop table t1; + +--echo # End of 10.6 tests diff --git a/sql/transaction.cc b/sql/transaction.cc index 6a5f767c85e..eab5d847077 100644 --- a/sql/transaction.cc +++ b/sql/transaction.cc @@ -120,11 +120,15 @@ bool trans_begin(THD *thd, uint flags) if (thd->in_multi_stmt_transaction_mode() || (thd->variables.option_bits & OPTION_TABLE_LOCK)) { + bool was_in_trans= thd->server_status & + (SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY); thd->variables.option_bits&= ~OPTION_TABLE_LOCK; thd->server_status&= ~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY); DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS")); res= MY_TEST(ha_commit_trans(thd, TRUE)); + if (was_in_trans) + trans_reset_one_shot_chistics(thd); #ifdef WITH_WSREP if (wsrep_thd_is_local(thd)) { From 0706c01b884bbebf8d54e753af72503541319d0e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 13 Nov 2024 23:47:38 +0100 Subject: [PATCH 007/213] cleanup: innodb.innodb_information_schema don't disable query/result log unless the output is unstable. and even then don't, but replace away unstable parts. --- .../innodb/r/innodb_information_schema.result | Bin 2255 -> 7516 bytes .../innodb/t/innodb_information_schema.test | 20 ------------------ 2 files changed, 20 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb_information_schema.result b/mysql-test/suite/innodb/r/innodb_information_schema.result index 921b062eae32f68a3f280370cb5c6aab53269dbb..608db358802fe3e3809e00ec06a91db7d66547ec 100644 GIT binary patch literal 7516 zcmd^EUvr|$63^@KDW<#+>M72a{1MEtQng0OF13nT)N?nttU{tBp;loJ;BGvh{&vp* z0-A(9wfE_!im|8Znd#~2{texk8FRYv9^CylapEM5+(*yxf=55_uFN0^N7sE}Xd8pM zLFa?(u|X4O=LfVUtUD5&o7SCa%|+uyCj2jM-+ZnWL-`SI1BP+N!8V! zqN!>BQkE4(mph8q>#Dlm?J>djshQp9|8p~g0Wvd7G8~ND?TP}L8ECEBRiMW$4Sh+| zbzPQ#mD?M*s(h(lYPx(0{8PK*u%4=Fx~g_`Mekg8yOJh#t4Fa~t&--l0nrhy@I)lg z${v0k*eykFgO|&dzEbI{m43I<*D8Iz+%I`AIxqSzx-NPyIxhOHj(%El(~{Pi8Jkj5 zq)qpJjX%wdz2fkwIz{4^N5k1v<~2jwWfc24?O&bE?zfG`z|AoG!oVz#mv@9R`87 zPACP!*@o+{A~f#yDU1^_3d2McD>8tpP7)nziMr2qMZsqsKZv~uzrmhg8k@*fVc(;(d3GwtJ-hxlQTpGset!Tsm%lW-mGc7Afz zLC)A1&gpOT#-2`6xWAd&ba6X^YY>jDBN4bk;8EaF;pxJo!K1^|gXfaK%^~2`Kstn9 z3`nHc0+KmMF^N-X0`{pMfQSD?55P_W&`B6_5(bgqqhTBHHAJr{+#qEqJXJme54rZ7a_u>l+H)$k z=TvLYslGbr84${6W;WS{8&9N+Ob*|2(!Jkiv>$A|=Ts!})+x1d6IWnhWLgkSlfm4a zTFz|v(U=V0nU*yjT|49H@Y9S=?U7;A>pQ*(j_V8g(j;FwrEp2`iAQYAMEMkHh0|wXGndQ(IlHq$UHIKi(F)& zQb$JNyPd#&9D50UAG_Z@C;n^eU@!uny?>u|FjnVu_Id0~rX%C3Iekx56uL0pBZc&m#56p57K~93p=D zxq!w+%YzSYXgb_FJbZA{?Zq2d~drUbHI6G?YCR<$vcn{ud@*2If+~$iJl#Q zL+*Vjwj?cCYSVoX`;URQA=Z=-YcU=ZCKM-b;*sxew0?4#-$x0I0>t(be+LVe zhDY9Cd+;f5!$0d`$!w~g)FyYvthm+>*T*`LTb{5gd5Meis3geauaZ5)U#k1?NpRSY7BXSvyZ(R`lj*-Vqnj=Plll#c=3Ln#C64Y z-Y$#|&iw%by~Y^G!eVxCwG?8~0B!z*UrQdse!Y((FIXR(#D`ti+J_&9TYdst@4L4p zUa;S_nouPiLDg+IolMO6+!!@Q&MGr*p_a%Bi6{;tP*^huWAi`AYgRpbANb%9&ict) ze~k%-33zPTyC1>`yfJXTdWTo#wr-p_MPVGHIKTKYadd(- z&-a7JQ`rKxm^ak;V$S9>nn=}}pOhB-(n6=qE1rb{5XJf>lzOOPLA}#}`zx!_mMWB3 zq2lF9NrVzrOBPjV6;Xp$6?>2hluNpDy>&$a5YK?(E>=?M!&guj^58bLjT^`htf7H> zs;MFt%`z1wrXnh;h{`cf;k6S$$(K`kE>ec`R|jOd4+!!5{&<3z`k%ETZFNN`1n1uX zSz$mbCqld`0NJbz`Kk&TsRlV`Pw3*^oZhn8>L&{4bK{-BPz`P$Ab&8R<#Y+lN-Pdn zBD*UJaKU9th`?EAf}Rhq#5I>L#UN)D!-&V`Tj>eA67$WG3DoS7=Gej zmd1?(apOSRhN;>WWu+$kM~3-%VVtn%Hhh2%hM4M6b2c5bq>qk`KaDXhVrE~sHUJA= z^j%Gq$ ztU$H*4?1+A@R(3{v!P)`_uueCjJkCFbD`46JK oGCMo(7befbt{Q5;%tl2My_5?vH+nT~U=oFkJ%Jph*ac7eFWvv&e*gdg delta 38 ucmca(bzX4uL+*5@$#eO9C)e=%ZjKP-Wtp5UabvQ9h{)u2DXYnmGP40B`3?*K diff --git a/mysql-test/suite/innodb/t/innodb_information_schema.test b/mysql-test/suite/innodb/t/innodb_information_schema.test index 88e2d3601a6..1fbf9f7eb57 100644 --- a/mysql-test/suite/innodb/t/innodb_information_schema.test +++ b/mysql-test/suite/innodb/t/innodb_information_schema.test @@ -12,15 +12,8 @@ # get NULL -- source include/not_encrypted.inc --- disable_query_log --- disable_result_log - SET default_storage_engine=InnoDB; --- disable_warnings -DROP TABLE IF EXISTS t_min, t_max; --- enable_warnings - let $table_def = ( c01 TINYINT, @@ -118,7 +111,6 @@ SELECT * FROM ```t'\"_str` WHERE c1 = '3' FOR UPDATE; -- send SELECT * FROM ```t'\"_str` WHERE c1 = '4' FOR UPDATE; --- enable_result_log -- connection con_verify_innodb_locks # Wait for the above queries to execute before continuing. # Without this, it sometimes happens that the SELECT from innodb_locks @@ -161,7 +153,6 @@ SET SQL_MODE='ANSI_QUOTES'; SELECT lock_table,COUNT(*) FROM INFORMATION_SCHEMA.INNODB_LOCKS GROUP BY lock_table; SET @@sql_mode=@save_sql_mode; --- disable_result_log -- connection default @@ -184,9 +175,7 @@ DROP TABLE t_min, t_max, ```t'\"_str`; # INFORMATION_SCHEMA.INNODB_TRX # --- enable_result_log DESCRIBE INFORMATION_SCHEMA.INNODB_TRX; --- disable_result_log -- disable_warnings DROP TABLE IF EXISTS t1; @@ -222,17 +211,14 @@ SELECT * FROM t1 FOR UPDATE; let $wait_condition= SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_TRX; --source include/wait_condition.inc --- disable_query_log -- connection con_verify_innodb_trx --- enable_result_log SELECT trx_state, trx_weight, trx_tables_in_use, trx_tables_locked, trx_rows_locked, trx_rows_modified, trx_concurrency_tickets, trx_isolation_level, trx_unique_checks, trx_foreign_key_checks FROM INFORMATION_SCHEMA.INNODB_TRX; -- connection con_trx --- disable_result_log ROLLBACK; SET FOREIGN_KEY_CHECKS = 0; SET UNIQUE_CHECKS = 0; @@ -243,14 +229,11 @@ INSERT INTO t1 VALUES (6,12); let $wait_condition= SELECT trx_unique_checks = 0 FROM INFORMATION_SCHEMA.INNODB_TRX; --source include/wait_condition.inc --- disable_query_log -- connection con_verify_innodb_trx --- enable_result_log SELECT trx_isolation_level, trx_unique_checks, trx_foreign_key_checks FROM INFORMATION_SCHEMA.INNODB_TRX; --- disable_result_log -- connection con_trx ROLLBACK; SET FOREIGN_KEY_CHECKS = 1; @@ -262,13 +245,10 @@ INSERT INTO t2 VALUES (4,10); let $wait_condition= SELECT trx_unique_checks = 1 FROM INFORMATION_SCHEMA.INNODB_TRX; --source include/wait_condition.inc --- disable_query_log --- enable_result_log -- connection con_verify_innodb_trx SELECT trx_state, trx_isolation_level, trx_last_foreign_key_error FROM INFORMATION_SCHEMA.INNODB_TRX; --- disable_result_log -- connection default From b79723ffe30f3905bf1db8e00a7452bc981c6171 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 14 Nov 2024 18:56:09 +0100 Subject: [PATCH 008/213] MDEV-35384 Table performance_schema.session_status and other two tables are not shown in information_schema.tables for normal users get_all_tables() skipped tables if the user has no privileges on the schema itself and no granted privilege on any tables in the schema. that is, it was skipping performance_schema tables (privileges on them aren't explicitly granted, but internally hard-coded) To fix: * extend ACL_internal_table_access::check() method with `bool any_combination_will_do` * fix all perfschema privilege checks to take it into account. * don't reuse table_acl_check object for all tables, initialize it for every table otherwise GRANT_INTERNAL_INFO will leak * remove incorrect privilege check from get_all_tables() --- mysql-test/suite/perfschema/r/grant.result | 16 ++++ mysql-test/suite/perfschema/t/grant.test | 13 +++ sql/sql_acl.cc | 3 +- sql/sql_acl.h | 2 +- sql/sql_show.cc | 9 +-- storage/perfschema/pfs_engine_table.cc | 94 ++++++++++++++-------- storage/perfschema/pfs_engine_table.h | 20 ++--- 7 files changed, 105 insertions(+), 52 deletions(-) diff --git a/mysql-test/suite/perfschema/r/grant.result b/mysql-test/suite/perfschema/r/grant.result index 4679499279f..985473c80f0 100644 --- a/mysql-test/suite/perfschema/r/grant.result +++ b/mysql-test/suite/perfschema/r/grant.result @@ -5,3 +5,19 @@ VARIABLE_NAME VARIABLE_VALUE connection default; disconnect a; drop user a@localhost; +# +# MDEV-35384 Table performance_schema.session_status and other two tables are not shown in information_schema.tables for normal users +# +create user foo@localhost; +connect foo,localhost,foo; +select table_schema,engine from information_schema.tables where table_name='session_status'; +table_schema engine +information_schema MEMORY +performance_schema PERFORMANCE_SCHEMA +select count(*) > 0 as 'table is readable' from performance_schema.session_status; +table is readable +1 +connection default; +disconnect foo; +drop user foo@localhost; +# End of 10.6 tests diff --git a/mysql-test/suite/perfschema/t/grant.test b/mysql-test/suite/perfschema/t/grant.test index 446965dfe9d..7c9bc31104e 100644 --- a/mysql-test/suite/perfschema/t/grant.test +++ b/mysql-test/suite/perfschema/t/grant.test @@ -10,3 +10,16 @@ connection default; disconnect a; drop user a@localhost; +--echo # +--echo # MDEV-35384 Table performance_schema.session_status and other two tables are not shown in information_schema.tables for normal users +--echo # +create user foo@localhost; +connect foo,localhost,foo; +sorted_result; +select table_schema,engine from information_schema.tables where table_name='session_status'; +select count(*) > 0 as 'table is readable' from performance_schema.session_status; +connection default; +disconnect foo; +drop user foo@localhost; + +--echo # End of 10.6 tests diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index d8053f7e49a..86e4d6415c7 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -8349,7 +8349,8 @@ bool check_grant(THD *thd, privilege_t want_access, TABLE_LIST *tables, if (access) { - switch(access->check(orig_want_access, &t_ref->grant.privilege)) + switch(access->check(orig_want_access, &t_ref->grant.privilege, + any_combination_will_do)) { case ACL_INTERNAL_ACCESS_GRANTED: t_ref->grant.privilege|= orig_want_access; diff --git a/sql/sql_acl.h b/sql/sql_acl.h index 44f3fa64b88..9506b911fa5 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -205,7 +205,7 @@ public: in save_priv. */ virtual ACL_internal_access_result check(privilege_t want_access, - privilege_t *save_priv) const= 0; + privilege_t *save_priv, bool any_combination_will_do) const= 0; }; /** diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 108346c275e..b654bd8c3d9 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -5174,7 +5174,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) DBUG_ENTER("get_all_tables"); LEX *lex= thd->lex; TABLE *table= tables->table; - TABLE_LIST table_acl_check; SELECT_LEX *lsel= tables->schema_select_lex; ST_SCHEMA_TABLE *schema_table= tables->schema_table; IS_table_read_plan *plan= tables->is_table_read_plan; @@ -5264,8 +5263,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) goto err; } - bzero((char*) &table_acl_check, sizeof(table_acl_check)); - if (make_db_list(thd, &db_names, &plan->lookup_field_vals)) goto err; @@ -5278,9 +5275,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) LEX_CSTRING *db_name= db_names.at(i); DBUG_ASSERT(db_name->length <= NAME_LEN); #ifndef NO_EMBEDDED_ACCESS_CHECKS - if (!(check_access(thd, SELECT_ACL, db_name->str, - &thd->col_access, NULL, 0, 1) || - (!thd->col_access && check_grant_db(thd, db_name->str))) || + if (!check_access(thd, SELECT_ACL, db_name->str, &thd->col_access, 0,0,1) || sctx->master_access & (DB_ACLS | SHOW_DB_ACL) || acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0)) #endif @@ -5301,6 +5296,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) #ifndef NO_EMBEDDED_ACCESS_CHECKS if (!(thd->col_access & TABLE_ACLS)) { + TABLE_LIST table_acl_check; + table_acl_check.reset(); table_acl_check.db= *db_name; table_acl_check.table_name= *table_name; table_acl_check.grant.privilege= thd->col_access; diff --git a/storage/perfschema/pfs_engine_table.cc b/storage/perfschema/pfs_engine_table.cc index b46eed0b531..f25c28ff441 100644 --- a/storage/perfschema/pfs_engine_table.cc +++ b/storage/perfschema/pfs_engine_table.cc @@ -760,28 +760,34 @@ static bool allow_drop_table_privilege() { PFS_readonly_acl pfs_readonly_acl; ACL_internal_access_result -PFS_readonly_acl::check(privilege_t want_access, privilege_t *save_priv) const +PFS_readonly_acl::check(privilege_t want_access, + privilege_t *save_priv, bool any_combination_will_do) const { const privilege_t always_forbidden= INSERT_ACL | UPDATE_ACL | DELETE_ACL | /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL | LOCK_TABLES_ACL; - if (unlikely((want_access & always_forbidden) != NO_ACL)) - return ACL_INTERNAL_ACCESS_DENIED; - - return ACL_INTERNAL_ACCESS_CHECK_GRANT; + if (any_combination_will_do) + return want_access & ~always_forbidden + ? ACL_INTERNAL_ACCESS_CHECK_GRANT: ACL_INTERNAL_ACCESS_DENIED; + else + return want_access & always_forbidden + ? ACL_INTERNAL_ACCESS_DENIED : ACL_INTERNAL_ACCESS_CHECK_GRANT; } PFS_readonly_world_acl pfs_readonly_world_acl; ACL_internal_access_result -PFS_readonly_world_acl::check(privilege_t want_access, privilege_t *save_priv) const +PFS_readonly_world_acl::check(privilege_t want_access, + privilege_t *save_priv, bool any_combination_will_do) const { - ACL_internal_access_result res= PFS_readonly_acl::check(want_access, save_priv); + ACL_internal_access_result res= + PFS_readonly_acl::check(want_access, save_priv, any_combination_will_do); if (res == ACL_INTERNAL_ACCESS_CHECK_GRANT) { - if (want_access == SELECT_ACL) + if (any_combination_will_do ? + ((want_access & SELECT_ACL) != NO_ACL) : (want_access == SELECT_ACL)) res= ACL_INTERNAL_ACCESS_GRANTED; } return res; @@ -790,9 +796,11 @@ PFS_readonly_world_acl::check(privilege_t want_access, privilege_t *save_priv) c PFS_readonly_processlist_acl pfs_readonly_processlist_acl; ACL_internal_access_result PFS_readonly_processlist_acl::check( - privilege_t want_access, privilege_t *save_priv) const { + privilege_t want_access, + privilege_t *save_priv, bool any_combination_will_do) const +{ ACL_internal_access_result res = - PFS_readonly_acl::check(want_access, save_priv); + PFS_readonly_acl::check(want_access, save_priv, any_combination_will_do); if ((res == ACL_INTERNAL_ACCESS_CHECK_GRANT) && (want_access == SELECT_ACL)) { THD *thd = current_thd; @@ -818,34 +826,41 @@ ACL_internal_access_result PFS_readonly_processlist_acl::check( PFS_truncatable_acl pfs_truncatable_acl; ACL_internal_access_result -PFS_truncatable_acl::check(privilege_t want_access, privilege_t *save_priv) const +PFS_truncatable_acl::check(privilege_t want_access, + privilege_t *save_priv, bool any_combination_will_do) const { const privilege_t always_forbidden= INSERT_ACL | UPDATE_ACL | DELETE_ACL | /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL | LOCK_TABLES_ACL; - if (unlikely((want_access & always_forbidden) != NO_ACL)) - return ACL_INTERNAL_ACCESS_DENIED; - - return ACL_INTERNAL_ACCESS_CHECK_GRANT; + if (any_combination_will_do) + return want_access & ~always_forbidden + ? ACL_INTERNAL_ACCESS_CHECK_GRANT: ACL_INTERNAL_ACCESS_DENIED; + else + return want_access & always_forbidden + ? ACL_INTERNAL_ACCESS_DENIED : ACL_INTERNAL_ACCESS_CHECK_GRANT; } PFS_truncatable_world_acl pfs_truncatable_world_acl; ACL_internal_access_result -PFS_truncatable_world_acl::check(privilege_t want_access, privilege_t *save_priv) const +PFS_truncatable_world_acl::check(privilege_t want_access, + privilege_t *save_priv, bool any_combination_will_do) const { - ACL_internal_access_result res= PFS_truncatable_acl::check(want_access, save_priv); + ACL_internal_access_result res= + PFS_truncatable_acl::check(want_access, save_priv, any_combination_will_do); if (res == ACL_INTERNAL_ACCESS_CHECK_GRANT) { - if (want_access == DROP_ACL) + if (any_combination_will_do ? + ((want_access & SELECT_ACL) != NO_ACL) : (want_access == SELECT_ACL)) + res= ACL_INTERNAL_ACCESS_GRANTED; + else if (any_combination_will_do ? + ((want_access & DROP_ACL) != NO_ACL) : (want_access == DROP_ACL)) { if (allow_drop_table_privilege()) res= ACL_INTERNAL_ACCESS_GRANTED; } - else if (want_access == SELECT_ACL) - res= ACL_INTERNAL_ACCESS_GRANTED; } return res; } @@ -854,44 +869,48 @@ PFS_truncatable_world_acl::check(privilege_t want_access, privilege_t *save_priv PFS_updatable_acl pfs_updatable_acl; ACL_internal_access_result -PFS_updatable_acl::check(privilege_t want_access, privilege_t *save_priv) const +PFS_updatable_acl::check(privilege_t want_access, + privilege_t *save_priv, bool any_combination_will_do) const { const privilege_t always_forbidden= INSERT_ACL | DELETE_ACL | /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL; - if (unlikely((want_access & always_forbidden) != NO_ACL)) - return ACL_INTERNAL_ACCESS_DENIED; - - return ACL_INTERNAL_ACCESS_CHECK_GRANT; + if (any_combination_will_do) + return want_access & ~always_forbidden + ? ACL_INTERNAL_ACCESS_CHECK_GRANT: ACL_INTERNAL_ACCESS_DENIED; + else + return want_access & always_forbidden + ? ACL_INTERNAL_ACCESS_DENIED : ACL_INTERNAL_ACCESS_CHECK_GRANT; } PFS_editable_acl pfs_editable_acl; ACL_internal_access_result -PFS_editable_acl::check(privilege_t want_access, privilege_t *save_priv) const +PFS_editable_acl::check(privilege_t want_access, + privilege_t *save_priv, bool any_combination_will_do) const { const privilege_t always_forbidden= /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL; - if (unlikely((want_access & always_forbidden) != NO_ACL)) - return ACL_INTERNAL_ACCESS_DENIED; - - return ACL_INTERNAL_ACCESS_CHECK_GRANT; + if (any_combination_will_do) + return want_access & ~always_forbidden + ? ACL_INTERNAL_ACCESS_CHECK_GRANT: ACL_INTERNAL_ACCESS_DENIED; + else + return want_access & always_forbidden + ? ACL_INTERNAL_ACCESS_DENIED : ACL_INTERNAL_ACCESS_CHECK_GRANT; } PFS_unknown_acl pfs_unknown_acl; ACL_internal_access_result -PFS_unknown_acl::check(privilege_t want_access, privilege_t *save_priv) const +PFS_unknown_acl::check(privilege_t want_access, + privilege_t *save_priv, bool any_combination_will_do) const { const privilege_t always_forbidden= CREATE_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | TRIGGER_ACL; - if (unlikely((want_access & always_forbidden) != NO_ACL)) - return ACL_INTERNAL_ACCESS_DENIED; - /* There is no point in hiding (by enforcing ACCESS_DENIED for SELECT_ACL on performance_schema.*) tables that do not exist anyway. @@ -902,7 +921,12 @@ PFS_unknown_acl::check(privilege_t want_access, privilege_t *save_priv) const The same goes for other DML (INSERT_ACL | UPDATE_ACL | DELETE_ACL), for ease of use: error messages will be less surprising. */ - return ACL_INTERNAL_ACCESS_CHECK_GRANT; + if (any_combination_will_do) + return want_access & ~always_forbidden + ? ACL_INTERNAL_ACCESS_CHECK_GRANT: ACL_INTERNAL_ACCESS_DENIED; + else + return want_access & always_forbidden + ? ACL_INTERNAL_ACCESS_DENIED : ACL_INTERNAL_ACCESS_CHECK_GRANT; } /** diff --git a/storage/perfschema/pfs_engine_table.h b/storage/perfschema/pfs_engine_table.h index 0bf8e58c081..45fded27d24 100644 --- a/storage/perfschema/pfs_engine_table.h +++ b/storage/perfschema/pfs_engine_table.h @@ -340,8 +340,8 @@ public: ~PFS_readonly_acl() = default; - ACL_internal_access_result check(privilege_t want_access, - privilege_t *save_priv) const override; + ACL_internal_access_result check(privilege_t want_access, + privilege_t *save_priv, bool any_combination_will_do) const override; }; /** Singleton instance of PFS_readonly_acl. */ @@ -359,7 +359,7 @@ public: ~PFS_truncatable_acl() = default; ACL_internal_access_result check(privilege_t want_access, - privilege_t *save_priv) const override; + privilege_t *save_priv, bool any_combination_will_do) const override; }; /** Singleton instance of PFS_truncatable_acl. */ @@ -377,7 +377,7 @@ public: ~PFS_updatable_acl() = default; ACL_internal_access_result check(privilege_t want_access, - privilege_t *save_priv) const override; + privilege_t *save_priv, bool any_combination_will_do) const override; }; /** Singleton instance of PFS_updatable_acl. */ @@ -395,7 +395,7 @@ public: ~PFS_editable_acl() = default; ACL_internal_access_result check(privilege_t want_access, - privilege_t *save_priv) const override; + privilege_t *save_priv, bool any_combination_will_do) const override; }; /** Singleton instance of PFS_editable_acl. */ @@ -412,7 +412,7 @@ public: ~PFS_unknown_acl() = default; ACL_internal_access_result check(privilege_t want_access, - privilege_t *save_priv) const override; + privilege_t *save_priv, bool any_combination_will_do) const override; }; /** Singleton instance of PFS_unknown_acl. */ @@ -430,7 +430,8 @@ public: ~PFS_readonly_world_acl() {} - ACL_internal_access_result check(privilege_t want_access, privilege_t *save_priv) const override; + ACL_internal_access_result check(privilege_t want_access, + privilege_t *save_priv, bool any_combination_will_do) const override; }; @@ -449,7 +450,8 @@ public: ~PFS_truncatable_world_acl() {} - ACL_internal_access_result check(privilege_t want_access, privilege_t *save_priv) const override; + ACL_internal_access_result check(privilege_t want_access, + privilege_t *save_priv, bool any_combination_will_do) const override; }; @@ -469,7 +471,7 @@ class PFS_readonly_processlist_acl : public PFS_readonly_acl { {} ACL_internal_access_result check(privilege_t want_access, - privilege_t *save_priv) const override; + privilege_t *save_priv, bool any_combination_will_do) const override; }; /** Singleton instance of PFS_readonly_processlist_acl */ From 74532f2355087a531512a95f843d53912f5435c1 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 15 Nov 2024 10:45:12 +0100 Subject: [PATCH 009/213] MCOL-5819 disable lto for ColumnStore --- debian/rules | 3 +++ storage/columnstore/CMakeLists.txt | 1 + 2 files changed, 4 insertions(+) diff --git a/debian/rules b/debian/rules index 554e5947d49..df831f8f150 100755 --- a/debian/rules +++ b/debian/rules @@ -4,6 +4,9 @@ # https://wiki.debian.org/Hardening export DEB_BUILD_MAINT_OPTIONS = hardening=+all +# LTO is generally enabled. Only ColumnStore doesn't support it (MCOL-5819) +# and disables it in storage/columnstore/CMakeLists.txt + DPKG_EXPORT_BUILDFLAGS = 1 # Include all defaults, including buildflags.mk include /usr/share/dpkg/default.mk diff --git a/storage/columnstore/CMakeLists.txt b/storage/columnstore/CMakeLists.txt index 87809f6c97b..2eb146a848a 100644 --- a/storage/columnstore/CMakeLists.txt +++ b/storage/columnstore/CMakeLists.txt @@ -20,6 +20,7 @@ endmacro() IF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "amd64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") + MY_CHECK_AND_SET_COMPILER_FLAG("-fno-lto") SET(PCRE_INCLUDES "${PCRE_INCLUDE_DIRS}") add_subdirectory(columnstore) From 9b941dc51f3fd58e1daa80cd49506a787f8406be Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 15 Nov 2024 15:33:42 +0100 Subject: [PATCH 010/213] MDEV-34494 restore broken feedback plugin it must report feedback_server_uid otherwise report stats won't work. --- plugin/feedback/feedback.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugin/feedback/feedback.cc b/plugin/feedback/feedback.cc index ca396573bc9..dd80a82aaf7 100644 --- a/plugin/feedback/feedback.cc +++ b/plugin/feedback/feedback.cc @@ -28,7 +28,7 @@ ulong debug_startup_interval, debug_first_interval, debug_interval; /* backing store for system variables */ static char *url, *http_proxy; -char *user_info; +char *user_info, *server_uid_ptr= server_uid; ulong send_timeout, send_retry_wait; /** @@ -356,6 +356,9 @@ static int free(void *p) #define DEFAULT_PROTO "http://" #endif +static MYSQL_SYSVAR_STR(server_uid, server_uid_ptr, + PLUGIN_VAR_READONLY | PLUGIN_VAR_NOCMDOPT, + "Automatically calculated server unique id hash.", NULL, NULL, 0); static MYSQL_SYSVAR_STR(user_info, user_info, PLUGIN_VAR_READONLY | PLUGIN_VAR_RQCMDARG, "User specified string that will be included in the feedback report.", @@ -386,6 +389,7 @@ static MYSQL_SYSVAR_ULONG(debug_interval, debug_interval, #endif static struct st_mysql_sys_var* settings[] = { + MYSQL_SYSVAR(server_uid), MYSQL_SYSVAR(user_info), MYSQL_SYSVAR(url), MYSQL_SYSVAR(send_timeout), From a0e5dd543333c64934dfdc43dc93bacc0d477e20 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 7 Jan 2025 21:38:11 +0100 Subject: [PATCH 011/213] mysqltest: fix --sorted_results only sort actual results not warnings or metadata also work for vertical results warnings are sorted separately --- client/mysqltest.cc | 147 +++++------------- mysql-test/main/metadata.result | 14 +- mysql-test/main/mysqlbinlog_row_big.result | 4 +- .../r/gcol_supported_sql_funcs_innodb.result | 14 +- .../r/gcol_supported_sql_funcs_myisam.result | 14 +- .../rocksdb/r/col_opt_not_null.result | 12 +- .../mysql-test/rocksdb/r/col_opt_null.result | 12 +- .../rocksdb/r/col_opt_unsigned.result | 12 +- .../rocksdb/mysql-test/rocksdb/r/misc.result | 8 +- .../mysql-test/rocksdb/r/type_float.result | 12 +- 10 files changed, 90 insertions(+), 159 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index f71c140d3b6..6262a46ad95 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -871,8 +871,7 @@ LogFile progress_file; void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, size_t len); void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val); void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val); -void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING* ds_input, - bool keep_header); +void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING* ds_input); static int match_expected_error(struct st_command *command, unsigned int err_errno, @@ -3433,7 +3432,7 @@ void do_exec(struct st_command *command) if (display_result_sorted) { - dynstr_append_sorted(&ds_res, &ds_sorted, 0); + dynstr_append_sorted(&ds_res, &ds_sorted); dynstr_free(&ds_sorted); } @@ -7719,16 +7718,29 @@ void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res) uint num_fields= mysql_num_fields(res); MYSQL_FIELD *fields= mysql_fetch_fields(res); ulong *lengths; + DYNAMIC_STRING rs_unsorted, *rs= ds; + + if (display_result_sorted) + { + init_dynamic_string(&rs_unsorted, "", 1024, 1024); + rs= &rs_unsorted; + } while ((row = mysql_fetch_row(res))) { uint i; lengths = mysql_fetch_lengths(res); for (i = 0; i < num_fields; i++) - append_field(ds, i, &fields[i], + append_field(rs, i, &fields[i], row[i], lengths[i], !row[i]); if (!display_result_vertically) - dynstr_append_mem(ds, "\n", 1); + dynstr_append_mem(rs, "\n", 1); + } + + if (display_result_sorted) + { + dynstr_append_sorted(ds, &rs_unsorted); + dynstr_free(&rs_unsorted); } } @@ -7746,6 +7758,13 @@ void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt, ulong *length; uint i; int error; + DYNAMIC_STRING rs_unsorted, *rs= ds; + + if (display_result_sorted) + { + init_dynamic_string(&rs_unsorted, "", 1024, 1024); + rs= &rs_unsorted; + } /* Allocate array with bind structs, lengths and NULL flags */ my_bind= (MYSQL_BIND*) my_malloc(PSI_NOT_INSTRUMENTED, num_fields * sizeof(MYSQL_BIND), @@ -7777,10 +7796,10 @@ void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt, while ((error=mysql_stmt_fetch(stmt)) == 0) { for (i= 0; i < num_fields; i++) - append_field(ds, i, &fields[i], (char*)my_bind[i].buffer, + append_field(rs, i, &fields[i], (char*)my_bind[i].buffer, *my_bind[i].length, *my_bind[i].is_null); if (!display_result_vertically) - dynstr_append_mem(ds, "\n", 1); + dynstr_append_mem(rs, "\n", 1); } if (error != MYSQL_NO_DATA) @@ -7799,6 +7818,12 @@ void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt, my_free(my_bind); my_free(length); my_free(is_null); + + if (display_result_sorted) + { + dynstr_append_sorted(ds, &rs_unsorted); + dynstr_free(&rs_unsorted); + } } @@ -7999,7 +8024,7 @@ static void append_session_track_info(DYNAMIC_STRING *ds, MYSQL *mysql) if (type == SESSION_TRACK_SYSTEM_VARIABLES) { dynstr_append_mem(ds_type, STRING_WITH_LEN("\n")); - dynstr_append_sorted(ds, ds_type, false); + dynstr_append_sorted(ds, ds_type); dynstr_append_mem(ds, STRING_WITH_LEN("\n")); dynstr_free(&ds_sort); } @@ -8041,7 +8066,6 @@ int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql) { uint count; MYSQL_RES *warn_res; - DYNAMIC_STRING res; DBUG_ENTER("append_warnings"); if (!(count= mysql_warning_count(mysql))) @@ -8062,18 +8086,8 @@ int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql) die("Warning count is %u but didn't get any warnings", count); - init_dynamic_string(&res, "", 1024, 1024); - - append_result(&res, warn_res); + append_result(ds, warn_res); mysql_free_result(warn_res); - - DBUG_PRINT("warnings", ("%s", res.str)); - - if (display_result_sorted) - dynstr_append_sorted(ds, &res, 0); - else - dynstr_append_mem(ds, res.str, res.length); - dynstr_free(&res); DBUG_RETURN(count); } @@ -8588,8 +8602,6 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, DYNAMIC_STRING ds_prepare_warnings; DYNAMIC_STRING ds_execute_warnings; DYNAMIC_STRING ds_res_1st_execution; - DYNAMIC_STRING ds_res_2_execution_unsorted; - DYNAMIC_STRING *ds_res_2_output; my_bool ds_res_1st_execution_init = FALSE; my_bool compare_2nd_execution = TRUE; int query_match_ps2_re; @@ -8651,7 +8663,6 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, parameter markers. */ -#if MYSQL_VERSION_ID >= 50000 if (cursor_protocol_enabled) { ps2_protocol_enabled = 0; @@ -8671,7 +8682,6 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); } } -#endif query_match_ps2_re = match_re(&ps2_re, query); @@ -8738,29 +8748,8 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, !disable_warnings) append_warnings(&ds_execute_warnings, mysql); - if (!disable_result_log && - compare_2nd_execution && - ps2_protocol_enabled && - query_match_ps2_re && - display_result_sorted) - { - init_dynamic_string(&ds_res_2_execution_unsorted, "", - RESULT_STRING_INIT_MEM, - RESULT_STRING_INCREMENT_MEM); - ds_res_2_output= &ds_res_2_execution_unsorted; - } - else - ds_res_2_output= ds; - - if (read_stmt_results(stmt, ds_res_2_output, command)) - { - if (ds_res_2_output != ds) - { - dynstr_append_mem(ds, ds_res_2_output->str, ds_res_2_output->length); - dynstr_free(ds_res_2_output); - } + if (read_stmt_results(stmt, ds, command)) goto end; - } if (!disable_result_log) { @@ -8770,35 +8759,12 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, */ if (compare_2nd_execution && ps2_protocol_enabled && query_match_ps2_re) { - DYNAMIC_STRING *ds_res_1_execution_compare; - DYNAMIC_STRING ds_res_1_execution_sorted; - if (display_result_sorted) - { - init_dynamic_string(&ds_res_1_execution_sorted, "", - RESULT_STRING_INIT_MEM, - RESULT_STRING_INCREMENT_MEM); - dynstr_append_sorted(&ds_res_1_execution_sorted, - &ds_res_1st_execution, 1); - dynstr_append_sorted(ds, &ds_res_2_execution_unsorted, 1); - ds_res_1_execution_compare= &ds_res_1_execution_sorted; - } - else - { - ds_res_1_execution_compare= &ds_res_1st_execution; - } - if (ds->length != ds_res_1_execution_compare->length || - !(memcmp(ds_res_1_execution_compare->str, ds->str, ds->length) == 0)) + if (ds->length != ds_res_1st_execution.length || + !(memcmp(ds_res_1st_execution.str, ds->str, ds->length) == 0)) { die("The result of the 1st execution does not match with \n" "the result of the 2nd execution of ps-protocol:\n 1st:\n" - "%s\n 2nd:\n %s", - ds_res_1_execution_compare->str, - ds->str); - } - if (display_result_sorted) - { - dynstr_free(&ds_res_1_execution_sorted); - dynstr_free(&ds_res_2_execution_unsorted); + "%s\n 2nd:\n %s", ds_res_1st_execution.str, ds->str); } } @@ -9391,10 +9357,6 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) DYNAMIC_STRING *rs_output; /* where to put results */ DYNAMIC_STRING rs_cmp_result; /* here we put results to compare with pre-recrded file */ - DYNAMIC_STRING rs_unsorted; /* if we need sorted results, here we store - results before sorting them */ - DYNAMIC_STRING *rs_sorted_save= NULL; /* here we store where to put sorted - result if needed */ DYNAMIC_STRING rs_warnings; char *query; size_t query_len; @@ -9565,18 +9527,6 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) dynstr_free(&query_str); } - if (display_result_sorted) - { - /* - Collect the query output in a separate string - that can be sorted before it's added to the - global result string - */ - init_dynamic_string(&rs_unsorted, "", 1024, 1024); - rs_sorted_save= rs_output; /* Remember original ds */ - rs_output= &rs_unsorted; - } - /* Find out how to run this query @@ -9603,14 +9553,6 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) dynstr_free(&rs_warnings); ds_warn= 0; - if (display_result_sorted) - { - /* Sort the result set and append it to result */ - dynstr_append_sorted(rs_sorted_save, &rs_unsorted, 1); - rs_output= rs_sorted_save; - dynstr_free(&rs_unsorted); - } - if (sp_created) { if (util_query(mysql, "DROP PROCEDURE mysqltest_tmp_sp ")) @@ -12169,7 +12111,6 @@ void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val) dynstr_append_sorted() ds string where the sorted output will be appended ds_input string to be sorted - keep_header If header should not be sorted */ static int comp_lines(const void *a_, const void *b_) @@ -12179,8 +12120,7 @@ static int comp_lines(const void *a_, const void *b_) return (strcmp(*a,*b)); } -void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input, - bool keep_header) +void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input) { unsigned i; char *start= ds_input->str; @@ -12192,15 +12132,6 @@ void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input, my_init_dynamic_array(PSI_NOT_INSTRUMENTED, &lines, sizeof(const char*), 32, 32, MYF(0)); - if (keep_header) - { - /* First line is result header, skip past it */ - while (*start && *start != '\n') - start++; - start++; /* Skip past \n */ - dynstr_append_mem(ds, ds_input->str, start - ds_input->str); - } - /* Insert line(s) in array */ while (*start) { diff --git a/mysql-test/main/metadata.result b/mysql-test/main/metadata.result index 16556a030cf..c8aca94aaa4 100644 --- a/mysql-test/main/metadata.result +++ b/mysql-test/main/metadata.result @@ -281,16 +281,16 @@ SELECT COALESCE(d, d), IFNULL(d, d), IF(i, d, d), CASE i WHEN i THEN d ELSE d END, GREATEST(d, d), LEAST(d, d) FROM t1 ORDER BY RAND(); Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def COALESCE(d, d) COALESCE(d, d) 10 10 10 Y 128 0 63 +def IFNULL(d, d) IFNULL(d, d) 10 10 10 Y 128 0 63 +def IF(i, d, d) IF(i, d, d) 10 10 10 Y 128 0 63 +def CASE i WHEN i THEN d ELSE d END CASE i WHEN i THEN d ELSE d END 10 10 10 Y 128 0 63 +def GREATEST(d, d) GREATEST(d, d) 10 10 10 Y 128 0 63 +def LEAST(d, d) LEAST(d, d) 10 10 10 Y 128 0 63 +COALESCE(d, d) IFNULL(d, d) IF(i, d, d) CASE i WHEN i THEN d ELSE d END GREATEST(d, d) LEAST(d, d) 2008-01-01 2008-01-01 2008-01-01 2008-01-01 2008-01-01 2008-01-01 2008-01-02 2008-01-02 2008-01-02 2008-01-02 2008-01-02 2008-01-02 2008-01-03 2008-01-03 2008-01-03 2008-01-03 2008-01-03 2008-01-03 -COALESCE(d, d) IFNULL(d, d) IF(i, d, d) CASE i WHEN i THEN d ELSE d END GREATEST(d, d) LEAST(d, d) -def CASE i WHEN i THEN d ELSE d END CASE i WHEN i THEN d ELSE d END 10 10 10 Y 128 0 63 -def COALESCE(d, d) COALESCE(d, d) 10 10 10 Y 128 0 63 -def GREATEST(d, d) GREATEST(d, d) 10 10 10 Y 128 0 63 -def IF(i, d, d) IF(i, d, d) 10 10 10 Y 128 0 63 -def IFNULL(d, d) IFNULL(d, d) 10 10 10 Y 128 0 63 -def LEAST(d, d) LEAST(d, d) 10 10 10 Y 128 0 63 DROP TABLE t1; # # Bug#41788 mysql_fetch_field returns org_table == table by a view diff --git a/mysql-test/main/mysqlbinlog_row_big.result b/mysql-test/main/mysqlbinlog_row_big.result index ecbb9df2be1..1f2a5bfa21e 100644 --- a/mysql-test/main/mysqlbinlog_row_big.result +++ b/mysql-test/main/mysqlbinlog_row_big.result @@ -52,10 +52,10 @@ affected rows: 1 # Do not display the column value itself, just its length. # SELECT LENGTH(c1) FROM t1; -LENGTH(c1) 67108864 LENGTH(c1) 33554432 LENGTH(c1) 4194304 LENGTH(c1) 524288 +LENGTH(c1) 67108864 affected rows: 4 # # Grow the rows by updating. @@ -68,8 +68,8 @@ info: Rows matched: 4 Changed: 4 Warnings: 0 # Do not display the column value itself, just its length. # SELECT LENGTH(c1) FROM t1; -LENGTH(c1) 134217728 LENGTH(c1) 1048576 +LENGTH(c1) 134217728 LENGTH(c1) 67108864 LENGTH(c1) 8388608 affected rows: 4 diff --git a/mysql-test/suite/gcol/r/gcol_supported_sql_funcs_innodb.result b/mysql-test/suite/gcol/r/gcol_supported_sql_funcs_innodb.result index 4fc4801482b..01d45a92657 100644 --- a/mysql-test/suite/gcol/r/gcol_supported_sql_funcs_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_supported_sql_funcs_innodb.result @@ -279,8 +279,8 @@ select * from t1; a b -2 NULL 2 0.693147 -Warning 1365 Division by 0 Warnings: +Warning 1365 Division by 0 drop table t1; set sql_warnings = 0; # LOG() @@ -303,8 +303,8 @@ a b c 1 100 NULL 10 100 2 2 65536 16 -Warning 1365 Division by 0 Warnings: +Warning 1365 Division by 0 drop table t1; set sql_warnings = 0; set sql_warnings = 1; @@ -323,8 +323,8 @@ select * from t1; a b -2 NULL 2 0.693147 -Warning 1365 Division by 0 Warnings: +Warning 1365 Division by 0 drop table t1; set sql_warnings = 0; # LOG2() @@ -344,8 +344,8 @@ select * from t1; a b -100 NULL 65536 16 -Warning 1365 Division by 0 Warnings: +Warning 1365 Division by 0 drop table t1; set sql_warnings = 0; # LOG10() @@ -367,8 +367,8 @@ a b -100 NULL 100 2 2 0.30103 -Warning 1365 Division by 0 Warnings: +Warning 1365 Division by 0 drop table t1; set sql_warnings = 0; # - @@ -2722,8 +2722,8 @@ select * from t1; a b -1 18446744073709551615 1 1 -Note 1105 Cast to unsigned converted negative integer to it's positive complement Warnings: +Note 1105 Cast to unsigned converted negative integer to it's positive complement drop table t1; set sql_warnings = 0; # Convert() @@ -2743,8 +2743,8 @@ select * from t1; a b -1 18446744073709551615 1 1 -Note 1105 Cast to unsigned converted negative integer to it's positive complement Warnings: +Note 1105 Cast to unsigned converted negative integer to it's positive complement drop table t1; set sql_warnings = 0; # diff --git a/mysql-test/suite/gcol/r/gcol_supported_sql_funcs_myisam.result b/mysql-test/suite/gcol/r/gcol_supported_sql_funcs_myisam.result index 7ddcd4f36ff..a46cbd5f0f4 100644 --- a/mysql-test/suite/gcol/r/gcol_supported_sql_funcs_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_supported_sql_funcs_myisam.result @@ -279,8 +279,8 @@ select * from t1; a b -2 NULL 2 0.693147 -Warning 1365 Division by 0 Warnings: +Warning 1365 Division by 0 drop table t1; set sql_warnings = 0; # LOG() @@ -303,8 +303,8 @@ a b c 1 100 NULL 10 100 2 2 65536 16 -Warning 1365 Division by 0 Warnings: +Warning 1365 Division by 0 drop table t1; set sql_warnings = 0; set sql_warnings = 1; @@ -323,8 +323,8 @@ select * from t1; a b -2 NULL 2 0.693147 -Warning 1365 Division by 0 Warnings: +Warning 1365 Division by 0 drop table t1; set sql_warnings = 0; # LOG2() @@ -344,8 +344,8 @@ select * from t1; a b -100 NULL 65536 16 -Warning 1365 Division by 0 Warnings: +Warning 1365 Division by 0 drop table t1; set sql_warnings = 0; # LOG10() @@ -367,8 +367,8 @@ a b -100 NULL 100 2 2 0.30103 -Warning 1365 Division by 0 Warnings: +Warning 1365 Division by 0 drop table t1; set sql_warnings = 0; # - @@ -2722,8 +2722,8 @@ select * from t1; a b -1 18446744073709551615 1 1 -Note 1105 Cast to unsigned converted negative integer to it's positive complement Warnings: +Note 1105 Cast to unsigned converted negative integer to it's positive complement drop table t1; set sql_warnings = 0; # Convert() @@ -2743,8 +2743,8 @@ select * from t1; a b -1 18446744073709551615 1 1 -Note 1105 Cast to unsigned converted negative integer to it's positive complement Warnings: +Note 1105 Cast to unsigned converted negative integer to it's positive complement drop table t1; set sql_warnings = 0; # diff --git a/storage/rocksdb/mysql-test/rocksdb/r/col_opt_not_null.result b/storage/rocksdb/mysql-test/rocksdb/r/col_opt_not_null.result index b3df869a0a7..687063e61a3 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/col_opt_not_null.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/col_opt_not_null.result @@ -1543,12 +1543,12 @@ d53_10 double(53,10) NO NULL pk double NO PRI NULL INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (12345.12345,12345.12345,0.9,123456789.123,56789.987,11111111.111,8.0,0.0123456789,1234566789123456789,99999999999999999.99999999,1); SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d 11111111.111 d10_10 0.0123456789 d1_0 8 d53 1234566789123456800 d53_10 100000000000000000.0000000000 +f 12345.1 f0 12345.1 f20_3 56789.988 f23_0 123457000 @@ -1571,7 +1571,6 @@ Warnings: Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d 0 d 11111111.111 d 1e81 @@ -1588,6 +1587,7 @@ d53_10 0.0000000000 d53_10 100000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f 0 +f 12345.1 f 1e38 f0 0 f0 12345.1 @@ -1603,7 +1603,6 @@ r1_1 0.9 r1_1 0.9 INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (-999999999999999999999999,-99999999999.999999999999,-0.9,-999.99999999999999999999,-99999999999999999.999,-999999999999999999999999999999999999999999999999999999999999-0.999,-9,-.9999999999,-999999999999999999999999999999.99999999999999999999999,-9999999999999999999999999999999999999999999.9999999999,4); SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d -1e60 d 0 d 11111111.111 @@ -1626,6 +1625,7 @@ d53_10 100000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f -1e24 f 0 +f 12345.1 f 1e38 f0 -100000000000 f0 0 @@ -1654,12 +1654,12 @@ CONCAT('', MAX(d1_0)), CONCAT('', MAX(d10_10)), CONCAT('', MAX(d53)), CONCAT('', MAX(d53_10)) FROM t1; -CONCAT('', MAX(f)) 1e38 CONCAT('', MAX(d)) 1e81 CONCAT('', MAX(d10_10)) 0.9999999999 CONCAT('', MAX(d1_0)) 9 CONCAT('', MAX(d53)) 100000000000000000000000000000000000000000000000000000 CONCAT('', MAX(d53_10)) 10000000000000000000000000000000000000000000.0000000000 +CONCAT('', MAX(f)) 1e38 CONCAT('', MAX(f0)) 1e38 CONCAT('', MAX(f20_3)) 99999998430674940.000 CONCAT('', MAX(f23_0)) 1e38 @@ -1688,7 +1688,6 @@ Warning 1264 Out of range value for column 'd10_10' at row 1 Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d -1e60 d 0 d 11111111.111 @@ -1716,6 +1715,7 @@ d53_10 10000000000000000000000000000000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f -1e24 f 0 +f 12345.1 f 1e38 f 3.40282e38 f0 -100000000000 @@ -1763,7 +1763,6 @@ Warning 1264 Out of range value for column 'd10_10' at row 1 Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d -1e60 d 0 d 11111111.111 @@ -1796,6 +1795,7 @@ d53_10 10000000000000000000000000000000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f -1e24 f 0 +f 12345.1 f 1e38 f 3.40282e38 f 3.40282e38 diff --git a/storage/rocksdb/mysql-test/rocksdb/r/col_opt_null.result b/storage/rocksdb/mysql-test/rocksdb/r/col_opt_null.result index f0cd1a7e8b3..dc8b8a47ae1 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/col_opt_null.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/col_opt_null.result @@ -1330,12 +1330,12 @@ d53_10 double(53,10) YES NULL pk double NO PRI NULL INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (12345.12345,12345.12345,0.9,123456789.123,56789.987,11111111.111,8.0,0.0123456789,1234566789123456789,99999999999999999.99999999,1); SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d 11111111.111 d10_10 0.0123456789 d1_0 8 d53 1234566789123456800 d53_10 100000000000000000.0000000000 +f 12345.1 f0 12345.1 f20_3 56789.988 f23_0 123457000 @@ -1358,7 +1358,6 @@ Warnings: Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d 0 d 11111111.111 d 1e81 @@ -1375,6 +1374,7 @@ d53_10 0.0000000000 d53_10 100000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f 0 +f 12345.1 f 1e38 f0 0 f0 12345.1 @@ -1390,7 +1390,6 @@ r1_1 0.9 r1_1 0.9 INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (-999999999999999999999999,-99999999999.999999999999,-0.9,-999.99999999999999999999,-99999999999999999.999,-999999999999999999999999999999999999999999999999999999999999-0.999,-9,-.9999999999,-999999999999999999999999999999.99999999999999999999999,-9999999999999999999999999999999999999999999.9999999999,4); SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d -1e60 d 0 d 11111111.111 @@ -1413,6 +1412,7 @@ d53_10 100000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f -1e24 f 0 +f 12345.1 f 1e38 f0 -100000000000 f0 0 @@ -1441,12 +1441,12 @@ CONCAT('', MAX(d1_0)), CONCAT('', MAX(d10_10)), CONCAT('', MAX(d53)), CONCAT('', MAX(d53_10)) FROM t1; -CONCAT('', MAX(f)) 1e38 CONCAT('', MAX(d)) 1e81 CONCAT('', MAX(d10_10)) 0.9999999999 CONCAT('', MAX(d1_0)) 9 CONCAT('', MAX(d53)) 100000000000000000000000000000000000000000000000000000 CONCAT('', MAX(d53_10)) 10000000000000000000000000000000000000000000.0000000000 +CONCAT('', MAX(f)) 1e38 CONCAT('', MAX(f0)) 1e38 CONCAT('', MAX(f20_3)) 99999998430674940.000 CONCAT('', MAX(f23_0)) 1e38 @@ -1475,7 +1475,6 @@ Warning 1264 Out of range value for column 'd10_10' at row 1 Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d -1e60 d 0 d 11111111.111 @@ -1503,6 +1502,7 @@ d53_10 10000000000000000000000000000000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f -1e24 f 0 +f 12345.1 f 1e38 f 3.40282e38 f0 -100000000000 @@ -1550,7 +1550,6 @@ Warning 1264 Out of range value for column 'd10_10' at row 1 Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d -1e60 d 0 d 11111111.111 @@ -1583,6 +1582,7 @@ d53_10 10000000000000000000000000000000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f -1e24 f 0 +f 12345.1 f 1e38 f 3.40282e38 f 3.40282e38 diff --git a/storage/rocksdb/mysql-test/rocksdb/r/col_opt_unsigned.result b/storage/rocksdb/mysql-test/rocksdb/r/col_opt_unsigned.result index 13445fc9326..0101245ae9b 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/col_opt_unsigned.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/col_opt_unsigned.result @@ -206,12 +206,12 @@ d53_10 double(53,10) unsigned YES NULL pk double unsigned NO PRI NULL INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (12345.12345,12345.12345,0.9,123456789.123,56789.987,11111111.111,8.0,0.0123456789,1234566789123456789,99999999999999999.99999999,1); SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d 11111111.111 d10_10 0.0123456789 d1_0 8 d53 1234566789123456800 d53_10 100000000000000000.0000000000 +f 12345.1 f0 12345.1 f20_3 56789.988 f23_0 123457000 @@ -234,7 +234,6 @@ Warnings: Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d 0 d 11111111.111 d 1e81 @@ -251,6 +250,7 @@ d53_10 0.0000000000 d53_10 100000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f 0 +f 12345.1 f 1e38 f0 0 f0 12345.1 @@ -277,7 +277,6 @@ Warning 1264 Out of range value for column 'd10_10' at row 1 Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d 0 d 0 d 11111111.111 @@ -300,6 +299,7 @@ d53_10 100000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f 0 f 0 +f 12345.1 f 1e38 f0 0 f0 0 @@ -328,12 +328,12 @@ CONCAT('', MAX(d1_0)), CONCAT('', MAX(d10_10)), CONCAT('', MAX(d53)), CONCAT('', MAX(d53_10)) FROM t1; -CONCAT('', MAX(f)) 1e38 CONCAT('', MAX(d)) 1e81 CONCAT('', MAX(d10_10)) 0.9999999999 CONCAT('', MAX(d1_0)) 9 CONCAT('', MAX(d53)) 100000000000000000000000000000000000000000000000000000 CONCAT('', MAX(d53_10)) 10000000000000000000000000000000000000000000.0000000000 +CONCAT('', MAX(f)) 1e38 CONCAT('', MAX(f0)) 1e38 CONCAT('', MAX(f20_3)) 99999998430674940.000 CONCAT('', MAX(f23_0)) 1e38 @@ -362,7 +362,6 @@ Warning 1264 Out of range value for column 'd10_10' at row 1 Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d 0 d 0 d 11111111.111 @@ -390,6 +389,7 @@ d53_10 10000000000000000000000000000000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f 0 f 0 +f 12345.1 f 1e38 f 3.40282e38 f0 0 @@ -437,7 +437,6 @@ Warning 1264 Out of range value for column 'd10_10' at row 1 Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d 0 d 0 d 11111111.111 @@ -470,6 +469,7 @@ d53_10 10000000000000000000000000000000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f 0 f 0 +f 12345.1 f 1e38 f 3.40282e38 f 3.40282e38 diff --git a/storage/rocksdb/mysql-test/rocksdb/r/misc.result b/storage/rocksdb/mysql-test/rocksdb/r/misc.result index f8734da6e6b..14afc71665a 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/misc.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/misc.result @@ -28,10 +28,6 @@ DROP EVENT ev1; SELECT TABLE_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE ORDER BY TABLE_NAME; TABLE_NAME COLUMN_NAME REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME -Warning 1286 Unknown storage engine 'InnoDB' -Warning 1286 Unknown storage engine 'InnoDB' -Warning 1286 Unknown storage engine 'InnoDB' -Warnings: column_stats column_name NULL NULL column_stats db_name NULL NULL column_stats table_name NULL NULL @@ -93,3 +89,7 @@ time_zone_transition Time_zone_id NULL NULL time_zone_transition Transition_time NULL NULL time_zone_transition_type Time_zone_id NULL NULL time_zone_transition_type Transition_type_id NULL NULL +Warnings: +Warning 1286 Unknown storage engine 'InnoDB' +Warning 1286 Unknown storage engine 'InnoDB' +Warning 1286 Unknown storage engine 'InnoDB' diff --git a/storage/rocksdb/mysql-test/rocksdb/r/type_float.result b/storage/rocksdb/mysql-test/rocksdb/r/type_float.result index 371b550d4ab..e4b0906ce17 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/type_float.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/type_float.result @@ -27,12 +27,12 @@ d53_10 double(53,10) YES NULL pk double NO PRI NULL INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (12345.12345,12345.12345,0.9,123456789.123,56789.987,11111111.111,8.0,0.0123456789,1234566789123456789,99999999999999999.99999999,1); SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d 11111111.111 d10_10 0.0123456789 d1_0 8 d53 1234566789123456800 d53_10 100000000000000000.0000000000 +f 12345.1 f0 12345.1 f20_3 56789.988 f23_0 123457000 @@ -55,7 +55,6 @@ Warnings: Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d 0 d 11111111.111 d 1e81 @@ -72,6 +71,7 @@ d53_10 0.0000000000 d53_10 100000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f 0 +f 12345.1 f 1e38 f0 0 f0 12345.1 @@ -87,7 +87,6 @@ r1_1 0.9 r1_1 0.9 INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (-999999999999999999999999,-99999999999.999999999999,-0.9,-999.99999999999999999999,-99999999999999999.999,-999999999999999999999999999999999999999999999999999999999999-0.999,-9,-.9999999999,-999999999999999999999999999999.99999999999999999999999,-9999999999999999999999999999999999999999999.9999999999,4); SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d -1e60 d 0 d 11111111.111 @@ -110,6 +109,7 @@ d53_10 100000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f -1e24 f 0 +f 12345.1 f 1e38 f0 -100000000000 f0 0 @@ -138,12 +138,12 @@ CONCAT('', MAX(d1_0)), CONCAT('', MAX(d10_10)), CONCAT('', MAX(d53)), CONCAT('', MAX(d53_10)) FROM t1; -CONCAT('', MAX(f)) 1e38 CONCAT('', MAX(d)) 1e81 CONCAT('', MAX(d10_10)) 0.9999999999 CONCAT('', MAX(d1_0)) 9 CONCAT('', MAX(d53)) 100000000000000000000000000000000000000000000000000000 CONCAT('', MAX(d53_10)) 10000000000000000000000000000000000000000000.0000000000 +CONCAT('', MAX(f)) 1e38 CONCAT('', MAX(f0)) 1e38 CONCAT('', MAX(f20_3)) 99999998430674940.000 CONCAT('', MAX(f23_0)) 1e38 @@ -172,7 +172,6 @@ Warning 1264 Out of range value for column 'd10_10' at row 1 Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d -1e60 d 0 d 11111111.111 @@ -200,6 +199,7 @@ d53_10 10000000000000000000000000000000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f -1e24 f 0 +f 12345.1 f 1e38 f 3.40282e38 f0 -100000000000 @@ -247,7 +247,6 @@ Warning 1264 Out of range value for column 'd10_10' at row 1 Warning 1264 Out of range value for column 'd53' at row 1 Warning 1264 Out of range value for column 'd53_10' at row 1 SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1; -f 12345.1 d -1e60 d 0 d 11111111.111 @@ -280,6 +279,7 @@ d53_10 10000000000000000000000000000000000000000000.0000000000 d53_10 10000000000000000000000000000000000000000000.0000000000 f -1e24 f 0 +f 12345.1 f 1e38 f 3.40282e38 f 3.40282e38 From cc99a41502323b0c5591fcffa2753fe3a8613ab7 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 16 Nov 2024 18:08:14 +0100 Subject: [PATCH 012/213] cleanup: extract common condition into a function --- sql/sql_show.cc | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index b654bd8c3d9..1653e7d5973 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4563,6 +4563,19 @@ static void get_table_engine_for_i_s(THD *thd, char *buf, TABLE_LIST *tl, } +/* + Hide error for a non-existing table. + For example, this error can occur when we use a where condition + with a db name and table, but the table does not exist or + there is a view with the same name. +*/ +static bool hide_object_error(uint err) +{ + return err == ER_NO_SUCH_TABLE || err == ER_WRONG_OBJECT || + err == ER_NOT_SEQUENCE; +} + + /** Fill I_S table with data obtained by performing full-blown table open. @@ -4691,16 +4704,8 @@ fill_schema_table_by_open(THD *thd, MEM_ROOT *mem_root, of backward compatibility. */ if (!is_show_fields_or_keys && result && thd->is_error() && - (thd->get_stmt_da()->sql_errno() == ER_NO_SUCH_TABLE || - thd->get_stmt_da()->sql_errno() == ER_WRONG_OBJECT || - thd->get_stmt_da()->sql_errno() == ER_NOT_SEQUENCE)) + hide_object_error(thd->get_stmt_da()->sql_errno())) { - /* - Hide error for a non-existing table. - For example, this error can occur when we use a where condition - with a db name and table, but the table does not exist or - there is a view with the same name. - */ result= false; thd->clear_error(); } @@ -4791,8 +4796,8 @@ static int fill_schema_table_names(THD *thd, TABLE_LIST *tables, else table->field[3]->store(STRING_WITH_LEN("ERROR"), cs); - if (unlikely(thd->is_error() && - thd->get_stmt_da()->sql_errno() == ER_NO_SUCH_TABLE)) + if (unlikely(thd->is_error()) && + hide_object_error(thd->get_stmt_da()->sql_errno())) { thd->clear_error(); return 0; @@ -5032,9 +5037,7 @@ static int fill_schema_table_from_frm(THD *thd, MEM_ROOT *mem_root, share= tdc_acquire_share(thd, &table_list, GTS_TABLE | GTS_VIEW); if (!share) { - if (thd->get_stmt_da()->sql_errno() == ER_NO_SUCH_TABLE || - thd->get_stmt_da()->sql_errno() == ER_WRONG_OBJECT || - thd->get_stmt_da()->sql_errno() == ER_NOT_SEQUENCE) + if (hide_object_error(thd->get_stmt_da()->sql_errno())) { res= 0; } From deb20fb751f663f1f4b95656535e7368fe5cfa8e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 16 Nov 2024 18:17:08 +0100 Subject: [PATCH 013/213] MDEV-32919 Cannot select particular field from IS.tables in case table needs upgrade from MySQL 5.7 use the same condition in fill_schema_table_from_frm() when open_table_from_share() fails, as in fill_schema_table_from_frm() when tdc_aquire_share() fails and as in fill_schema_table_from_open() when open_table_from_share() fails --- mysql-test/main/mysql_json_table_recreate.result | 9 +++++++++ mysql-test/main/mysql_json_table_recreate.test | 3 +++ sql/sql_show.cc | 13 ++++++++++--- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/mysql-test/main/mysql_json_table_recreate.result b/mysql-test/main/mysql_json_table_recreate.result index a61377fe21d..c8c53c9036a 100644 --- a/mysql-test/main/mysql_json_table_recreate.result +++ b/mysql-test/main/mysql_json_table_recreate.result @@ -20,6 +20,15 @@ show create table tempty; ERROR HY000: Table rebuild required. Please do "ALTER TABLE `test.tempty` FORCE" or dump/reload to fix it! select * from tempty; ERROR HY000: Table rebuild required. Please do "ALTER TABLE `test.tempty` FORCE" or dump/reload to fix it! +select table_name, table_comment from information_schema.tables where table_schema='test' and table_comment!='VIEW'; +table_name table_comment +mysql_json_test Table rebuild required. Please do "ALTER TABLE `test.mysql_json_test` FORCE" or dump/reload to fix it! +mysql_json_test_big Table rebuild required. Please do "ALTER TABLE `test.mysql_json_test_big` FORCE" or dump/reload to fix it! +tempty Table rebuild required. Please do "ALTER TABLE `test.tempty` FORCE" or dump/reload to fix it! +Warnings: +Warning 1707 Table rebuild required. Please do "ALTER TABLE `test.mysql_json_test_big` FORCE" or dump/reload to fix it! +Warning 1707 Table rebuild required. Please do "ALTER TABLE `test.mysql_json_test` FORCE" or dump/reload to fix it! +Warning 1707 Table rebuild required. Please do "ALTER TABLE `test.tempty` FORCE" or dump/reload to fix it! alter table tempty force; show create table tempty; Table Create Table diff --git a/mysql-test/main/mysql_json_table_recreate.test b/mysql-test/main/mysql_json_table_recreate.test index a6f1d3194ae..94477d4f328 100644 --- a/mysql-test/main/mysql_json_table_recreate.test +++ b/mysql-test/main/mysql_json_table_recreate.test @@ -43,6 +43,9 @@ show create table tempty; --error ER_TABLE_NEEDS_REBUILD select * from tempty; +--sorted_result +select table_name, table_comment from information_schema.tables where table_schema='test' and table_comment!='VIEW'; + alter table tempty force; show create table tempty; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 1653e7d5973..0a3a3209d26 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -5078,10 +5078,17 @@ static int fill_schema_table_from_frm(THD *thd, MEM_ROOT *mem_root, goto end_share; } - if (!open_table_from_share(thd, share, table_name, 0, - (EXTRA_RECORD | OPEN_FRM_FILE_ONLY), - thd->open_options, &tbl, FALSE)) + res= open_table_from_share(thd, share, table_name, 0, + EXTRA_RECORD | OPEN_FRM_FILE_ONLY, + thd->open_options, &tbl, FALSE); + if (res && hide_object_error(thd->get_stmt_da()->sql_errno())) + res= 0; + else { + char buf[NAME_CHAR_LEN + 1]; + if (unlikely(res)) + get_table_engine_for_i_s(thd, buf, &table_list, db_name, table_name); + tbl.s= share; table_list.table= &tbl; table_list.view= (LEX*) share->is_view; From d26b47dfd4f9b0478d5fe89a0b96d69438350ed9 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 9 Dec 2024 22:15:37 +0100 Subject: [PATCH 014/213] MDEV-35550 main.log_slow test failure: expects count(*) 5 got 4 when testing MDEV-34539 create a table specifically for the test, don't use a system table as a shortcut to save a couple of lines. followup for 8d813f080b51 --- mysql-test/main/log_slow.result | 6 ++++-- mysql-test/main/log_slow.test | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/mysql-test/main/log_slow.result b/mysql-test/main/log_slow.result index 946ddf1ca2e..caa0ae078ae 100644 --- a/mysql-test/main/log_slow.result +++ b/mysql-test/main/log_slow.result @@ -194,7 +194,9 @@ create database `a b`; use `a b`; -select count(*) from mysql.global_priv where length(priv)>2; +create table t1 (a int); +insert t1 values (1),(2),(3),(4),(5),(6),(7); +select count(*) from t1 where a>2; count(*) 5 drop database `a @@ -207,7 +209,7 @@ set timestamp=default; use `a b`; SET timestamp=1234567890; -select count(*) from mysql.global_priv where length(priv)>2 +select count(*) from t1 where a>2 # # MDEV-31366 Assertion `thd->start_time' failed in bool LOGGER::slow_log_print(THD*, const char*, size_t, ulonglong) # diff --git a/mysql-test/main/log_slow.test b/mysql-test/main/log_slow.test index 46f86b5f168..31f0858e805 100644 --- a/mysql-test/main/log_slow.test +++ b/mysql-test/main/log_slow.test @@ -206,9 +206,11 @@ create database `a b`; use `a b`; +create table t1 (a int); +insert t1 values (1),(2),(3),(4),(5),(6),(7); --disable_ps_protocol --disable_view_protocol -select count(*) from mysql.global_priv where length(priv)>2; +select count(*) from t1 where a>2; --enable_view_protocol --enable_ps_protocol drop database `a From c478b1ba0843d9efeb38e40e4ef83d8df1afb68e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 10 Dec 2024 00:11:41 +0100 Subject: [PATCH 015/213] MDEV-35598 foreign key error is unnecessary truncated truncate it at 512 bytes (max allowed by the protocol), not 192 --- mysql-test/suite/innodb/r/foreign-keys.result | 22 +++++++++++++++ mysql-test/suite/innodb/t/foreign-keys.test | 27 +++++++++++++++++++ sql/share/errmsg-utf8.txt | 16 +++++------ storage/innobase/trx/trx0trx.cc | 2 +- 4 files changed, 58 insertions(+), 9 deletions(-) diff --git a/mysql-test/suite/innodb/r/foreign-keys.result b/mysql-test/suite/innodb/r/foreign-keys.result index f7f87bd7898..8ed32cae3e7 100644 --- a/mysql-test/suite/innodb/r/foreign-keys.result +++ b/mysql-test/suite/innodb/r/foreign-keys.result @@ -243,3 +243,25 @@ Level Code Message Warning 140 InnoDB: PAGE_COMPRESSED table can't have ROW_TYPE=COMPRESSED Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") Warning 1030 Got error 140 "Wrong create options" from storage engine InnoDB +# End of 10.5 tests +# +# MDEV-35598 foreign key error is unnecessary truncated +# +set names utf8; +create table t1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш +(f1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш int not null primary key, +f2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш int not null +) engine=innodb; +create table t2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш +(f1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш varchar(100), +f2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш int not null, +index i2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш +(f2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш) +) engine=innodb; +insert t1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш values(99, 2); +alter table t2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш add foreign key(f2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш) references t1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш(f1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш); +insert t2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш values('g', 3); +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш`, CONSTRAINT `t2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш_ibfk_1` FOREIGN KEY (`f2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш`) REFERENCES `t1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш` (`f1яяяяяяяяяяььььььььььззззз +drop table t2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш, +t1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш; +# End of 10.6 tests diff --git a/mysql-test/suite/innodb/t/foreign-keys.test b/mysql-test/suite/innodb/t/foreign-keys.test index aeff7009402..6010ff0e3fc 100644 --- a/mysql-test/suite/innodb/t/foreign-keys.test +++ b/mysql-test/suite/innodb/t/foreign-keys.test @@ -272,3 +272,30 @@ SET FOREIGN_KEY_CHECKS=DEFAULT; --error ER_CANT_CREATE_TABLE CREATE TABLE t1(a SERIAL) ENGINE=InnoDB ROW_FORMAT=COMPRESSED PAGE_COMPRESSED=1; SHOW WARNINGS; + +--echo # End of 10.5 tests + +--echo # +--echo # MDEV-35598 foreign key error is unnecessary truncated +--echo # +set names utf8; +create table t1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш +(f1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш int not null primary key, + f2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш int not null +) engine=innodb; +create table t2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш +(f1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш varchar(100), + f2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш int not null, + index i2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш + (f2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш) +) engine=innodb; + +insert t1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш values(99, 2); +alter table t2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш add foreign key(f2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш) references t1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш(f1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш); + +--error ER_NO_REFERENCED_ROW_2 +insert t2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш values('g', 3); +drop table t2яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш, + t1яяяяяяяяяяььььььььььззззззззззшшшшшшшшшш; + +--echo # End of 10.6 tests diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index fd1c2bc47ec..f0273c6cb7a 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6318,15 +6318,15 @@ ER_FORBID_SCHEMA_CHANGE ger "Wechsel des Schemas von '%-.192s' auf '%-.192s' ist nicht erlaubt" spa "Vd no está autorizado a cambiar el esquema de '%-.192s' a '%-.192s'" ER_ROW_IS_REFERENCED_2 23000 - chi "无法删除或更新父行:外键约束失败(%.192s)" - eng "Cannot delete or update a parent row: a foreign key constraint fails (%.192s)" - ger "Kann Eltern-Zeile nicht löschen oder aktualisieren: eine Fremdschlüsselbedingung schlägt fehl (%.192s)" - spa "No puedo borrar o actualizar una fila padre: falla una restricción de clave foránea (%.192s)" + chi "无法删除或更新父行:外键约束失败(%s)" + eng "Cannot delete or update a parent row: a foreign key constraint fails (%s)" + ger "Kann Eltern-Zeile nicht löschen oder aktualisieren: eine Fremdschlüsselbedingung schlägt fehl (%s)" + spa "No puedo borrar o actualizar una fila padre: falla una restricción de clave foránea (%s)" ER_NO_REFERENCED_ROW_2 23000 - chi "无法添加或更新子行:外键约束失败(%.192s)" - eng "Cannot add or update a child row: a foreign key constraint fails (%.192s)" - ger "Kann Kind-Zeile nicht hinzufügen oder aktualisieren: eine Fremdschlüsselbedingung schlägt fehl (%.192s)" - spa "No puedo añadir o actualizar una fila hija: falla una restricción de clave foránea (%.192s)" + chi "无法添加或更新子行:外键约束失败(%s)" + eng "Cannot add or update a child row: a foreign key constraint fails (%s)" + ger "Kann Kind-Zeile nicht hinzufügen oder aktualisieren: eine Fremdschlüsselbedingung schlägt fehl (%s)" + spa "No puedo añadir o actualizar una fila hija: falla una restricción de clave foránea (%s)" ER_SP_BAD_VAR_SHADOW 42000 chi "变量'%-.64s'必须用`...`,或重命名" eng "Variable '%-.64s' must be quoted with `...`, or renamed" diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 94ed416eb60..133fbe32aad 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -63,7 +63,7 @@ const byte timestamp_max_bytes[7] = { }; -static const ulint MAX_DETAILED_ERROR_LEN = 256; +static const ulint MAX_DETAILED_ERROR_LEN = 512; /*************************************************************//** Set detailed error message for the transaction. */ From 9929a0a76ef67c5290a7fa1efd87c514a84dc227 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 2 Jan 2025 20:23:08 +0100 Subject: [PATCH 016/213] MDEV-32576 increase query length in the InnoDB deadlock output * increase target buffer size to 3072 * remove the parameter, just use the buffer size as a limit --- storage/innobase/handler/ha_innodb.cc | 8 +++----- storage/innobase/include/ha_prototypes.h | 4 +--- storage/innobase/include/trx0trx.h | 11 ++--------- storage/innobase/lock/lock0lock.cc | 6 +++--- storage/innobase/row/row0ins.cc | 2 +- storage/innobase/trx/trx0trx.cc | 17 +++++------------ 6 files changed, 15 insertions(+), 33 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 214144b86ac..4fedd79790b 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2361,14 +2361,12 @@ void innobase_mysql_print_thd( /*=====================*/ FILE* f, /*!< in: output stream */ - THD* thd, /*!< in: MySQL THD object */ - uint max_query_len) /*!< in: max query length to print, or 0 to - use the default max length */ + THD* thd) /*!< in: MySQL THD object */ { - char buffer[1024]; + char buffer[3072]; fputs(thd_get_error_context_description(thd, buffer, sizeof buffer, - max_query_len), f); + 0), f); putc('\n', f); } diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h index 48ab763a2ac..96ce0cfe783 100644 --- a/storage/innobase/include/ha_prototypes.h +++ b/storage/innobase/include/ha_prototypes.h @@ -128,9 +128,7 @@ void innobase_mysql_print_thd( /*=====================*/ FILE* f, /*!< in: output stream */ - THD* thd, /*!< in: pointer to a MySQL THD object */ - uint max_query_len); /*!< in: max query length to print, or 0 to - use the default max length */ + THD* thd); /*!< in: pointer to a MySQL THD object */ /** Converts a MySQL type to an InnoDB type. Note that this function returns the 'mtype' of InnoDB. InnoDB differentiates between MySQL's old <= 4.1 diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index e55c6f506ce..beb5a284876 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -210,9 +210,6 @@ trx_print_low( /*!< in: output stream */ const trx_t* trx, /*!< in: transaction */ - ulint max_query_len, - /*!< in: max query length to print, - or 0 to use the default max length */ ulint n_rec_locks, /*!< in: trx->lock.n_rec_locks */ ulint n_trx_locks, @@ -227,9 +224,7 @@ void trx_print_latched( /*==============*/ FILE* f, /*!< in: output stream */ - const trx_t* trx, /*!< in: transaction */ - ulint max_query_len); /*!< in: max query length to print, - or 0 to use the default max length */ + const trx_t* trx); /*!< in: transaction */ /**********************************************************************//** Prints info about a transaction. @@ -238,9 +233,7 @@ void trx_print( /*======*/ FILE* f, /*!< in: output stream */ - const trx_t* trx, /*!< in: transaction */ - ulint max_query_len); /*!< in: max query length to print, - or 0 to use the default max length */ + const trx_t* trx); /*!< in: transaction */ /**********************************************************************//** Determines if a transaction is in the given state. diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 1795852ec94..5a6857678fc 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -5212,7 +5212,7 @@ void lock_trx_print_wait_and_mvcc_state(FILE *file, const trx_t *trx, { fprintf(file, "---"); - trx_print_latched(file, trx, 600); + trx_print_latched(file, trx); trx->read_view.print_limits(file); if (const lock_t* wait_lock = trx->lock.wait_lock) { @@ -6944,11 +6944,11 @@ namespace Deadlock ulint n_trx_locks= UT_LIST_GET_LEN(trx.lock.trx_locks); ulint heap_size= mem_heap_get_size(trx.lock.lock_heap); - trx_print_low(lock_latest_err_file, &trx, 3000, + trx_print_low(lock_latest_err_file, &trx, n_rec_locks, n_trx_locks, heap_size); if (srv_print_all_deadlocks) - trx_print_low(stderr, &trx, 3000, n_rec_locks, n_trx_locks, heap_size); + trx_print_low(stderr, &trx, n_rec_locks, n_trx_locks, heap_size); } /** Print lock data to the deadlock file and possibly to stderr. diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 4f6c1b77046..0502568b312 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -723,7 +723,7 @@ row_ins_foreign_trx_print( ut_print_timestamp(dict_foreign_err_file); fputs(" Transaction:\n", dict_foreign_err_file); - trx_print_low(dict_foreign_err_file, trx, 600, + trx_print_low(dict_foreign_err_file, trx, n_rec_locks, n_trx_locks, heap_size); mysql_mutex_assert_owner(&dict_foreign_err_mutex); diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 133fbe32aad..7935cdb6bc6 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -1752,9 +1752,6 @@ trx_print_low( /*!< in: output stream */ const trx_t* trx, /*!< in: transaction */ - ulint max_query_len, - /*!< in: max query length to print, - or 0 to use the default max length */ ulint n_rec_locks, /*!< in: trx->lock.n_rec_locks */ ulint n_trx_locks, @@ -1844,7 +1841,7 @@ state_ok: } if (thd) { - innobase_mysql_print_thd(f, thd, uint(max_query_len)); + innobase_mysql_print_thd(f, thd); } } @@ -1856,13 +1853,11 @@ void trx_print_latched( /*==============*/ FILE* f, /*!< in: output stream */ - const trx_t* trx, /*!< in: transaction */ - ulint max_query_len) /*!< in: max query length to print, - or 0 to use the default max length */ + const trx_t* trx) /*!< in: transaction */ { lock_sys.assert_locked(); - trx_print_low(f, trx, max_query_len, + trx_print_low(f, trx, trx->lock.n_rec_locks, UT_LIST_GET_LEN(trx->lock.trx_locks), mem_heap_get_size(trx->lock.lock_heap)); @@ -1876,9 +1871,7 @@ void trx_print( /*======*/ FILE* f, /*!< in: output stream */ - const trx_t* trx, /*!< in: transaction */ - ulint max_query_len) /*!< in: max query length to print, - or 0 to use the default max length */ + const trx_t* trx) /*!< in: transaction */ { ulint n_rec_locks, n_trx_locks, heap_size; { @@ -1888,7 +1881,7 @@ trx_print( heap_size= mem_heap_get_size(trx->lock.lock_heap); } - trx_print_low(f, trx, max_query_len, n_rec_locks, n_trx_locks, heap_size); + trx_print_low(f, trx, n_rec_locks, n_trx_locks, heap_size); } /** Prepare a transaction. From 90bd638159f106a561ae1c03ceb118ffda372eac Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 8 Jan 2025 13:11:45 +0100 Subject: [PATCH 017/213] 32-bit rdiff fixes --- .../suite/sys_vars/r/sysvars_aria,32bit.rdiff | 18 +- .../r/sysvars_server_embedded,32bit.rdiff | 167 ++++++++-------- .../r/sysvars_server_notembedded,32bit.rdiff | 183 +++++++++--------- 3 files changed, 175 insertions(+), 193 deletions(-) diff --git a/mysql-test/suite/sys_vars/r/sysvars_aria,32bit.rdiff b/mysql-test/suite/sys_vars/r/sysvars_aria,32bit.rdiff index 1469397e83b..1a47adcbdc0 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_aria,32bit.rdiff +++ b/mysql-test/suite/sys_vars/r/sysvars_aria,32bit.rdiff @@ -1,5 +1,5 @@ ---- suite/sys_vars/r/sysvars_aria.result -+++ suite/sys_vars/r/sysvars_aria,32bit.reject +--- a/mysql-test/suite/sys_vars/r/sysvars_aria.result ++++ b/mysql-test/suite/sys_vars/r/sysvars_aria.result @@ -5,7 +5,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 8192 @@ -45,7 +45,7 @@ VARIABLE_COMMENT Interval between commits in microseconds (1/1000000 sec). 0 stands for no waiting for other threads to come and do a commit in "hard" mode and no sync()/commit at all in "soft" mode. Option has only an effect if aria_group_commit is used NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -89,7 +89,7 @@ +@@ -101,7 +101,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 1073741824 VARIABLE_SCOPE GLOBAL @@ -54,7 +54,7 @@ VARIABLE_COMMENT Limit for transaction log size NUMERIC_MIN_VALUE 8388608 NUMERIC_MAX_VALUE 4294967295 -@@ -125,10 +125,10 @@ +@@ -137,10 +137,10 @@ SESSION_VALUE NULL DEFAULT_VALUE 300 VARIABLE_SCOPE GLOBAL @@ -67,7 +67,7 @@ NUMERIC_BLOCK_SIZE 100 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -149,7 +149,7 @@ +@@ -161,7 +161,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 100 VARIABLE_SCOPE GLOBAL @@ -76,7 +76,7 @@ VARIABLE_COMMENT The minimum percentage of warm blocks in key cache NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 100 -@@ -161,7 +161,7 @@ +@@ -173,7 +173,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 512 VARIABLE_SCOPE GLOBAL @@ -85,7 +85,7 @@ VARIABLE_COMMENT Number of hash buckets for open and changed files. If you have a lot of Aria files open you should increase this for faster flush of changes. A good value is probably 1/10 of number of possible open Aria files. NUMERIC_MIN_VALUE 128 NUMERIC_MAX_VALUE 16384 -@@ -197,7 +197,7 @@ +@@ -209,7 +209,7 @@ SESSION_VALUE 1 DEFAULT_VALUE 1 VARIABLE_SCOPE SESSION @@ -94,10 +94,10 @@ VARIABLE_COMMENT Number of threads to use when repairing Aria tables. The value of 1 disables parallel repair. NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 128 -@@ -212,7 +212,7 @@ +@@ -224,7 +224,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE. - NUMERIC_MIN_VALUE 16376 + NUMERIC_MIN_VALUE 16352 -NUMERIC_MAX_VALUE 1152921504606846975 +NUMERIC_MAX_VALUE 268435455 NUMERIC_BLOCK_SIZE 1 diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff b/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff index a8aa785fcd9..0fa13800aec 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff @@ -1,5 +1,5 @@ ---- suite/sys_vars/r/sysvars_server_embedded.result -+++ suite/sys_vars/r/sysvars_server_embedded,32bit.reject +--- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result ++++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result @@ -34,7 +34,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME ARIA_BLOCK_SIZE @@ -97,7 +97,7 @@ @@ -217,7 +217,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE. - NUMERIC_MIN_VALUE 16376 + NUMERIC_MIN_VALUE 16352 -NUMERIC_MAX_VALUE 1152921504606846975 +NUMERIC_MAX_VALUE 268435455 NUMERIC_BLOCK_SIZE 1 @@ -713,16 +713,7 @@ VARIABLE_COMMENT If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 or autoset then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of file descriptors NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -2274,7 +2274,7 @@ - COMMAND_LINE_ARGUMENT REQUIRED - VARIABLE_NAME OPTIMIZER_ADJUST_SECONDARY_KEY_COSTS - VARIABLE_SCOPE SESSION --VARIABLE_TYPE BIGINT UNSIGNED -+VARIABLE_TYPE INT UNSIGNED - VARIABLE_COMMENT 0 = No changes. 1 = Update secondary key costs for ranges to be at least 5x of clustered primary key costs. 2 = Remove 'max_seek optimization' for secondary keys and slight adjustment of filter cost. This option will be deleted in MariaDB 11.0 as it is not needed with the new 11.0 optimizer. - NUMERIC_MIN_VALUE 0 - NUMERIC_MAX_VALUE 2 -@@ -2284,7 +2284,7 @@ +@@ -2294,7 +2294,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_MAX_SEL_ARGS VARIABLE_SCOPE SESSION @@ -731,7 +722,7 @@ VARIABLE_COMMENT The maximum number of SEL_ARG objects created when optimizing a range. If more objects would be needed, the range will not be used by the optimizer. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -2294,7 +2294,7 @@ +@@ -2304,7 +2304,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_MAX_SEL_ARG_WEIGHT VARIABLE_SCOPE SESSION @@ -740,7 +731,7 @@ VARIABLE_COMMENT The maximum weight of the SEL_ARG graph. Set to 0 for no limit NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -2304,7 +2304,7 @@ +@@ -2314,7 +2314,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_PRUNE_LEVEL VARIABLE_SCOPE SESSION @@ -749,7 +740,7 @@ VARIABLE_COMMENT Controls the heuristic(s) applied during query optimization to prune less-promising partial plans from the optimizer search space. Meaning: 0 - do not apply any heuristic, thus perform exhaustive search; 1 - prune plans based on number of retrieved rows NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1 -@@ -2314,7 +2314,7 @@ +@@ -2324,7 +2324,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_SEARCH_DEPTH VARIABLE_SCOPE SESSION @@ -758,7 +749,7 @@ VARIABLE_COMMENT Maximum depth of search performed by the query optimizer. Values larger than the number of relations in a query result in better query plans, but take longer to compile a query. Values smaller than the number of tables in a relation result in faster optimization, but may produce very bad query plans. If set to 0, the system will automatically pick a reasonable value. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 62 -@@ -2324,7 +2324,7 @@ +@@ -2334,7 +2334,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_SELECTIVITY_SAMPLING_LIMIT VARIABLE_SCOPE SESSION @@ -767,7 +758,7 @@ VARIABLE_COMMENT Controls number of record samples to check condition selectivity NUMERIC_MIN_VALUE 10 NUMERIC_MAX_VALUE 4294967295 -@@ -2354,17 +2354,17 @@ +@@ -2364,17 +2364,17 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_TRACE_MAX_MEM_SIZE VARIABLE_SCOPE SESSION @@ -788,7 +779,7 @@ VARIABLE_COMMENT Controls selectivity of which conditions the optimizer takes into account to calculate cardinality of a partial join when it searches for the best execution plan Meaning: 1 - use selectivity of index backed range conditions to calculate the cardinality of a partial join if the last joined table is accessed by full table scan or an index scan, 2 - use selectivity of index backed range conditions to calculate the cardinality of a partial join in any case, 3 - additionally always use selectivity of range conditions that are not backed by any index to calculate the cardinality of a partial join, 4 - use histograms to calculate selectivity of range conditions that are not backed by any index to calculate the cardinality of a partial join.5 - additionally use selectivity of certain non-range predicates calculated on record samples NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 5 -@@ -2384,7 +2384,7 @@ +@@ -2394,7 +2394,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME PERFORMANCE_SCHEMA_ACCOUNTS_SIZE VARIABLE_SCOPE GLOBAL @@ -797,7 +788,7 @@ VARIABLE_COMMENT Maximum number of instrumented user@host accounts. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2394,7 +2394,7 @@ +@@ -2404,7 +2404,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_DIGESTS_SIZE VARIABLE_SCOPE GLOBAL @@ -806,7 +797,7 @@ VARIABLE_COMMENT Size of the statement digest. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2404,7 +2404,7 @@ +@@ -2414,7 +2414,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_STAGES_HISTORY_LONG_SIZE VARIABLE_SCOPE GLOBAL @@ -815,7 +806,7 @@ VARIABLE_COMMENT Number of rows in EVENTS_STAGES_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2414,7 +2414,7 @@ +@@ -2424,7 +2424,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_STAGES_HISTORY_SIZE VARIABLE_SCOPE GLOBAL @@ -824,7 +815,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_STAGES_HISTORY. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2424,7 +2424,7 @@ +@@ -2434,7 +2434,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_STATEMENTS_HISTORY_LONG_SIZE VARIABLE_SCOPE GLOBAL @@ -833,7 +824,7 @@ VARIABLE_COMMENT Number of rows in EVENTS_STATEMENTS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2434,7 +2434,7 @@ +@@ -2444,7 +2444,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_STATEMENTS_HISTORY_SIZE VARIABLE_SCOPE GLOBAL @@ -842,7 +833,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_STATEMENTS_HISTORY. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2444,7 +2444,7 @@ +@@ -2454,7 +2454,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_TRANSACTIONS_HISTORY_LONG_SIZE VARIABLE_SCOPE GLOBAL @@ -851,7 +842,7 @@ VARIABLE_COMMENT Number of rows in EVENTS_TRANSACTIONS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2454,7 +2454,7 @@ +@@ -2464,7 +2464,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_TRANSACTIONS_HISTORY_SIZE VARIABLE_SCOPE GLOBAL @@ -860,7 +851,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_TRANSACTIONS_HISTORY. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2464,7 +2464,7 @@ +@@ -2474,7 +2474,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_WAITS_HISTORY_LONG_SIZE VARIABLE_SCOPE GLOBAL @@ -869,7 +860,7 @@ VARIABLE_COMMENT Number of rows in EVENTS_WAITS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2474,7 +2474,7 @@ +@@ -2484,7 +2484,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_WAITS_HISTORY_SIZE VARIABLE_SCOPE GLOBAL @@ -878,7 +869,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_WAITS_HISTORY. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2484,7 +2484,7 @@ +@@ -2494,7 +2494,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_HOSTS_SIZE VARIABLE_SCOPE GLOBAL @@ -887,7 +878,7 @@ VARIABLE_COMMENT Maximum number of instrumented hosts. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2494,7 +2494,7 @@ +@@ -2504,7 +2504,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_COND_CLASSES VARIABLE_SCOPE GLOBAL @@ -896,7 +887,7 @@ VARIABLE_COMMENT Maximum number of condition instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2504,7 +2504,7 @@ +@@ -2514,7 +2514,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_COND_INSTANCES VARIABLE_SCOPE GLOBAL @@ -905,7 +896,7 @@ VARIABLE_COMMENT Maximum number of instrumented condition objects. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2514,7 +2514,7 @@ +@@ -2524,7 +2524,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_DIGEST_LENGTH VARIABLE_SCOPE GLOBAL @@ -914,7 +905,7 @@ VARIABLE_COMMENT Maximum length considered for digest text, when stored in performance_schema tables. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1048576 -@@ -2524,7 +2524,7 @@ +@@ -2534,7 +2534,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_FILE_CLASSES VARIABLE_SCOPE GLOBAL @@ -923,7 +914,7 @@ VARIABLE_COMMENT Maximum number of file instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2534,7 +2534,7 @@ +@@ -2544,7 +2544,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_FILE_HANDLES VARIABLE_SCOPE GLOBAL @@ -932,7 +923,7 @@ VARIABLE_COMMENT Maximum number of opened instrumented files. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1048576 -@@ -2544,7 +2544,7 @@ +@@ -2554,7 +2554,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_FILE_INSTANCES VARIABLE_SCOPE GLOBAL @@ -941,7 +932,7 @@ VARIABLE_COMMENT Maximum number of instrumented files. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2554,7 +2554,7 @@ +@@ -2564,7 +2564,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_INDEX_STAT VARIABLE_SCOPE GLOBAL @@ -950,7 +941,7 @@ VARIABLE_COMMENT Maximum number of index statistics for instrumented tables. Use 0 to disable, -1 for automated scaling. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2564,7 +2564,7 @@ +@@ -2574,7 +2574,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_MEMORY_CLASSES VARIABLE_SCOPE GLOBAL @@ -959,7 +950,7 @@ VARIABLE_COMMENT Maximum number of memory pool instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1024 -@@ -2574,7 +2574,7 @@ +@@ -2584,7 +2584,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_METADATA_LOCKS VARIABLE_SCOPE GLOBAL @@ -968,7 +959,7 @@ VARIABLE_COMMENT Maximum number of metadata locks. Use 0 to disable, -1 for automated scaling. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 104857600 -@@ -2584,7 +2584,7 @@ +@@ -2594,7 +2594,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_MUTEX_CLASSES VARIABLE_SCOPE GLOBAL @@ -977,7 +968,7 @@ VARIABLE_COMMENT Maximum number of mutex instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2594,7 +2594,7 @@ +@@ -2604,7 +2604,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_MUTEX_INSTANCES VARIABLE_SCOPE GLOBAL @@ -986,7 +977,7 @@ VARIABLE_COMMENT Maximum number of instrumented MUTEX objects. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 104857600 -@@ -2604,7 +2604,7 @@ +@@ -2614,7 +2614,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_PREPARED_STATEMENTS_INSTANCES VARIABLE_SCOPE GLOBAL @@ -995,7 +986,7 @@ VARIABLE_COMMENT Maximum number of instrumented prepared statements. Use 0 to disable, -1 for automated scaling. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2614,7 +2614,7 @@ +@@ -2624,7 +2624,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_PROGRAM_INSTANCES VARIABLE_SCOPE GLOBAL @@ -1004,7 +995,7 @@ VARIABLE_COMMENT Maximum number of instrumented programs. Use 0 to disable, -1 for automated scaling. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2624,7 +2624,7 @@ +@@ -2634,7 +2634,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_RWLOCK_CLASSES VARIABLE_SCOPE GLOBAL @@ -1013,7 +1004,7 @@ VARIABLE_COMMENT Maximum number of rwlock instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2634,7 +2634,7 @@ +@@ -2644,7 +2644,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_RWLOCK_INSTANCES VARIABLE_SCOPE GLOBAL @@ -1022,7 +1013,7 @@ VARIABLE_COMMENT Maximum number of instrumented RWLOCK objects. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 104857600 -@@ -2644,7 +2644,7 @@ +@@ -2654,7 +2654,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_SOCKET_CLASSES VARIABLE_SCOPE GLOBAL @@ -1031,7 +1022,7 @@ VARIABLE_COMMENT Maximum number of socket instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2654,7 +2654,7 @@ +@@ -2664,7 +2664,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_SOCKET_INSTANCES VARIABLE_SCOPE GLOBAL @@ -1040,7 +1031,7 @@ VARIABLE_COMMENT Maximum number of opened instrumented sockets. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2664,7 +2664,7 @@ +@@ -2674,7 +2674,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_SQL_TEXT_LENGTH VARIABLE_SCOPE GLOBAL @@ -1049,7 +1040,7 @@ VARIABLE_COMMENT Maximum length of displayed sql text. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1048576 -@@ -2674,7 +2674,7 @@ +@@ -2684,7 +2684,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_STAGE_CLASSES VARIABLE_SCOPE GLOBAL @@ -1058,7 +1049,7 @@ VARIABLE_COMMENT Maximum number of stage instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2684,7 +2684,7 @@ +@@ -2694,7 +2694,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_STATEMENT_CLASSES VARIABLE_SCOPE GLOBAL @@ -1067,7 +1058,7 @@ VARIABLE_COMMENT Maximum number of statement instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2694,7 +2694,7 @@ +@@ -2704,7 +2704,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_STATEMENT_STACK VARIABLE_SCOPE GLOBAL @@ -1076,7 +1067,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_STATEMENTS_CURRENT. NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 256 -@@ -2704,7 +2704,7 @@ +@@ -2714,7 +2714,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_TABLE_HANDLES VARIABLE_SCOPE GLOBAL @@ -1085,7 +1076,7 @@ VARIABLE_COMMENT Maximum number of opened instrumented tables. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2714,7 +2714,7 @@ +@@ -2724,7 +2724,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_TABLE_INSTANCES VARIABLE_SCOPE GLOBAL @@ -1094,7 +1085,7 @@ VARIABLE_COMMENT Maximum number of instrumented tables. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2724,7 +2724,7 @@ +@@ -2734,7 +2734,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_TABLE_LOCK_STAT VARIABLE_SCOPE GLOBAL @@ -1103,7 +1094,7 @@ VARIABLE_COMMENT Maximum number of lock statistics for instrumented tables. Use 0 to disable, -1 for automated scaling. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2734,7 +2734,7 @@ +@@ -2744,7 +2744,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_THREAD_CLASSES VARIABLE_SCOPE GLOBAL @@ -1112,7 +1103,7 @@ VARIABLE_COMMENT Maximum number of thread instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2744,7 +2744,7 @@ +@@ -2754,7 +2754,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_THREAD_INSTANCES VARIABLE_SCOPE GLOBAL @@ -1121,7 +1112,7 @@ VARIABLE_COMMENT Maximum number of instrumented threads. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2754,7 +2754,7 @@ +@@ -2764,7 +2764,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_SESSION_CONNECT_ATTRS_SIZE VARIABLE_SCOPE GLOBAL @@ -1130,7 +1121,7 @@ VARIABLE_COMMENT Size of session attribute string buffer per thread. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2764,7 +2764,7 @@ +@@ -2774,7 +2774,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_SETUP_ACTORS_SIZE VARIABLE_SCOPE GLOBAL @@ -1139,7 +1130,7 @@ VARIABLE_COMMENT Maximum number of rows in SETUP_ACTORS. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2774,7 +2774,7 @@ +@@ -2784,7 +2784,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_SETUP_OBJECTS_SIZE VARIABLE_SCOPE GLOBAL @@ -1148,7 +1139,7 @@ VARIABLE_COMMENT Maximum number of rows in SETUP_OBJECTS. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2784,7 +2784,7 @@ +@@ -2794,7 +2794,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_USERS_SIZE VARIABLE_SCOPE GLOBAL @@ -1157,7 +1148,7 @@ VARIABLE_COMMENT Maximum number of instrumented users. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2834,7 +2834,7 @@ +@@ -2844,7 +2844,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PRELOAD_BUFFER_SIZE VARIABLE_SCOPE SESSION @@ -1166,7 +1157,7 @@ VARIABLE_COMMENT The size of the buffer that is allocated when preloading indexes NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 1073741824 -@@ -2854,7 +2854,7 @@ +@@ -2864,7 +2864,7 @@ COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME PROFILING_HISTORY_SIZE VARIABLE_SCOPE SESSION @@ -1175,7 +1166,7 @@ VARIABLE_COMMENT Number of statements about which profiling information is maintained. If set to 0, no profiles are stored. See SHOW PROFILES. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 100 -@@ -2864,7 +2864,7 @@ +@@ -2874,7 +2874,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PROGRESS_REPORT_TIME VARIABLE_SCOPE SESSION @@ -1184,7 +1175,7 @@ VARIABLE_COMMENT Seconds between sending progress reports to the client for time-consuming statements. Set to 0 to disable progress reporting. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -2924,7 +2924,7 @@ +@@ -2934,7 +2934,7 @@ COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME QUERY_ALLOC_BLOCK_SIZE VARIABLE_SCOPE SESSION @@ -1193,7 +1184,7 @@ VARIABLE_COMMENT Allocation block size for query parsing and execution NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 4294967295 -@@ -2934,7 +2934,7 @@ +@@ -2944,7 +2944,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME QUERY_CACHE_LIMIT VARIABLE_SCOPE GLOBAL @@ -1202,7 +1193,7 @@ VARIABLE_COMMENT Don't cache results that are bigger than this NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -2944,7 +2944,7 @@ +@@ -2954,7 +2954,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME QUERY_CACHE_MIN_RES_UNIT VARIABLE_SCOPE GLOBAL @@ -1211,7 +1202,7 @@ VARIABLE_COMMENT The minimum size for blocks allocated by the query cache NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -2957,7 +2957,7 @@ +@@ -2967,7 +2967,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT The memory allocated to store results from old queries NUMERIC_MIN_VALUE 0 @@ -1220,7 +1211,7 @@ NUMERIC_BLOCK_SIZE 1024 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -2994,7 +2994,7 @@ +@@ -3004,7 +3004,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME QUERY_PREALLOC_SIZE VARIABLE_SCOPE SESSION @@ -1229,7 +1220,7 @@ VARIABLE_COMMENT Persistent buffer for query parsing and execution NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 4294967295 -@@ -3007,7 +3007,7 @@ +@@ -3017,7 +3017,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes NUMERIC_MIN_VALUE 0 @@ -1238,7 +1229,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3017,14 +3017,14 @@ +@@ -3027,14 +3027,14 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes NUMERIC_MIN_VALUE 0 @@ -1255,7 +1246,7 @@ VARIABLE_COMMENT Allocation block size for storing ranges during optimization NUMERIC_MIN_VALUE 4096 NUMERIC_MAX_VALUE 4294967295 -@@ -3034,7 +3034,7 @@ +@@ -3044,7 +3044,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME READ_BUFFER_SIZE VARIABLE_SCOPE SESSION @@ -1264,7 +1255,7 @@ VARIABLE_COMMENT Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value NUMERIC_MIN_VALUE 8192 NUMERIC_MAX_VALUE 2147483647 -@@ -3054,7 +3054,7 @@ +@@ -3064,7 +3064,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME READ_RND_BUFFER_SIZE VARIABLE_SCOPE SESSION @@ -1273,7 +1264,7 @@ VARIABLE_COMMENT When reading rows in sorted order after a sort, the rows are read through this buffer to avoid a disk seeks NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 2147483647 -@@ -3074,10 +3074,10 @@ +@@ -3084,10 +3084,10 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME ROWID_MERGE_BUFF_SIZE VARIABLE_SCOPE SESSION @@ -1286,7 +1277,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3114,7 +3114,7 @@ +@@ -3124,7 +3124,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME SERVER_ID VARIABLE_SCOPE SESSION @@ -1295,7 +1286,7 @@ VARIABLE_COMMENT Uniquely identifies the server instance in the community of replication partners NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 4294967295 -@@ -3184,7 +3184,7 @@ +@@ -3204,7 +3204,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME SLAVE_MAX_ALLOWED_PACKET VARIABLE_SCOPE GLOBAL @@ -1304,7 +1295,7 @@ VARIABLE_COMMENT The maximum packet length to sent successfully from the master to slave. NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 1073741824 -@@ -3194,7 +3194,7 @@ +@@ -3214,7 +3214,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME SLOW_LAUNCH_TIME VARIABLE_SCOPE GLOBAL @@ -1313,7 +1304,7 @@ VARIABLE_COMMENT If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be incremented NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 31536000 -@@ -3237,7 +3237,7 @@ +@@ -3257,7 +3257,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Each thread that needs to do a sort allocates a buffer of this size NUMERIC_MIN_VALUE 1024 @@ -1322,7 +1313,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3454,7 +3454,7 @@ +@@ -3474,7 +3474,7 @@ COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME STORED_PROGRAM_CACHE VARIABLE_SCOPE GLOBAL @@ -1331,7 +1322,7 @@ VARIABLE_COMMENT The soft upper limit for number of cached stored routines for one connection. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 524288 -@@ -3534,7 +3534,7 @@ +@@ -3554,7 +3554,7 @@ COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME TABLE_DEFINITION_CACHE VARIABLE_SCOPE GLOBAL @@ -1340,7 +1331,7 @@ VARIABLE_COMMENT The number of cached table definitions NUMERIC_MIN_VALUE 400 NUMERIC_MAX_VALUE 2097152 -@@ -3544,7 +3544,7 @@ +@@ -3564,7 +3564,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME TABLE_OPEN_CACHE VARIABLE_SCOPE GLOBAL @@ -1349,7 +1340,7 @@ VARIABLE_COMMENT The number of cached open tables NUMERIC_MIN_VALUE 10 NUMERIC_MAX_VALUE 1048576 -@@ -3604,7 +3604,7 @@ +@@ -3624,7 +3624,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME THREAD_CACHE_SIZE VARIABLE_SCOPE GLOBAL @@ -1358,7 +1349,7 @@ VARIABLE_COMMENT How many threads we should keep in a cache for reuse. These are freed after 5 minutes of idle time NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 16384 -@@ -3687,7 +3687,7 @@ +@@ -3707,7 +3707,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Max size for data for an internal temporary on-disk MyISAM or Aria table. NUMERIC_MIN_VALUE 1024 @@ -1367,22 +1358,22 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3697,7 +3697,7 @@ +@@ -3717,7 +3717,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT If an internal in-memory temporary table exceeds this size, MariaDB will automatically convert it to an on-disk MyISAM or Aria table. Same as tmp_table_size. NUMERIC_MIN_VALUE 0 -NUMERIC_MAX_VALUE 18446744073709551615 +NUMERIC_MAX_VALUE 4294967295 - NUMERIC_BLOCK_SIZE 1 + NUMERIC_BLOCK_SIZE 16384 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3707,14 +3707,14 @@ +@@ -3727,14 +3727,14 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Alias for tmp_memory_table_size. If an internal in-memory temporary table exceeds this size, MariaDB will automatically convert it to an on-disk MyISAM or Aria table. NUMERIC_MIN_VALUE 0 -NUMERIC_MAX_VALUE 18446744073709551615 +NUMERIC_MAX_VALUE 4294967295 - NUMERIC_BLOCK_SIZE 1 + NUMERIC_BLOCK_SIZE 16384 ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED @@ -1393,7 +1384,7 @@ VARIABLE_COMMENT Allocation block size for transactions to be stored in binary log NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 134217728 -@@ -3724,7 +3724,7 @@ +@@ -3744,7 +3744,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME TRANSACTION_PREALLOC_SIZE VARIABLE_SCOPE SESSION @@ -1402,7 +1393,7 @@ VARIABLE_COMMENT Persistent buffer for transactions to be stored in binary log NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 134217728 -@@ -3864,7 +3864,7 @@ +@@ -3884,7 +3884,7 @@ COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME WAIT_TIMEOUT VARIABLE_SCOPE SESSION @@ -1411,7 +1402,7 @@ VARIABLE_COMMENT The number of seconds the server waits for activity on a connection before closing it NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 31536000 -@@ -3891,7 +3891,7 @@ +@@ -3911,7 +3911,7 @@ VARIABLE_NAME LOG_TC_SIZE GLOBAL_VALUE_ORIGIN AUTO VARIABLE_SCOPE GLOBAL diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff index 0fad61d69a7..74b40f3756e 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff @@ -1,5 +1,5 @@ ---- suite/sys_vars/r/sysvars_server_notembedded.result -+++ suite/sys_vars/r/sysvars_server_notembedded,32bit.reject +--- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result ++++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -34,7 +34,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME ARIA_BLOCK_SIZE @@ -97,7 +97,7 @@ @@ -217,7 +217,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE. - NUMERIC_MIN_VALUE 16376 + NUMERIC_MIN_VALUE 16352 -NUMERIC_MAX_VALUE 1152921504606846975 +NUMERIC_MAX_VALUE 268435455 NUMERIC_BLOCK_SIZE 1 @@ -713,16 +713,7 @@ VARIABLE_COMMENT If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 or autoset then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of file descriptors NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -2434,7 +2434,7 @@ - COMMAND_LINE_ARGUMENT REQUIRED - VARIABLE_NAME OPTIMIZER_ADJUST_SECONDARY_KEY_COSTS - VARIABLE_SCOPE SESSION --VARIABLE_TYPE BIGINT UNSIGNED -+VARIABLE_TYPE INT UNSIGNED - VARIABLE_COMMENT 0 = No changes. 1 = Update secondary key costs for ranges to be at least 5x of clustered primary key costs. 2 = Remove 'max_seek optimization' for secondary keys and slight adjustment of filter cost. This option will be deleted in MariaDB 11.0 as it is not needed with the new 11.0 optimizer. - NUMERIC_MIN_VALUE 0 - NUMERIC_MAX_VALUE 2 -@@ -2444,7 +2444,7 @@ +@@ -2454,7 +2454,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_MAX_SEL_ARGS VARIABLE_SCOPE SESSION @@ -731,7 +722,7 @@ VARIABLE_COMMENT The maximum number of SEL_ARG objects created when optimizing a range. If more objects would be needed, the range will not be used by the optimizer. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -2454,7 +2454,7 @@ +@@ -2464,7 +2464,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_MAX_SEL_ARG_WEIGHT VARIABLE_SCOPE SESSION @@ -740,7 +731,7 @@ VARIABLE_COMMENT The maximum weight of the SEL_ARG graph. Set to 0 for no limit NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -2464,7 +2464,7 @@ +@@ -2474,7 +2474,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_PRUNE_LEVEL VARIABLE_SCOPE SESSION @@ -749,7 +740,7 @@ VARIABLE_COMMENT Controls the heuristic(s) applied during query optimization to prune less-promising partial plans from the optimizer search space. Meaning: 0 - do not apply any heuristic, thus perform exhaustive search; 1 - prune plans based on number of retrieved rows NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1 -@@ -2474,7 +2474,7 @@ +@@ -2484,7 +2484,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_SEARCH_DEPTH VARIABLE_SCOPE SESSION @@ -758,7 +749,7 @@ VARIABLE_COMMENT Maximum depth of search performed by the query optimizer. Values larger than the number of relations in a query result in better query plans, but take longer to compile a query. Values smaller than the number of tables in a relation result in faster optimization, but may produce very bad query plans. If set to 0, the system will automatically pick a reasonable value. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 62 -@@ -2484,7 +2484,7 @@ +@@ -2494,7 +2494,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_SELECTIVITY_SAMPLING_LIMIT VARIABLE_SCOPE SESSION @@ -767,7 +758,7 @@ VARIABLE_COMMENT Controls number of record samples to check condition selectivity NUMERIC_MIN_VALUE 10 NUMERIC_MAX_VALUE 4294967295 -@@ -2514,17 +2514,17 @@ +@@ -2524,17 +2524,17 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_TRACE_MAX_MEM_SIZE VARIABLE_SCOPE SESSION @@ -788,7 +779,7 @@ VARIABLE_COMMENT Controls selectivity of which conditions the optimizer takes into account to calculate cardinality of a partial join when it searches for the best execution plan Meaning: 1 - use selectivity of index backed range conditions to calculate the cardinality of a partial join if the last joined table is accessed by full table scan or an index scan, 2 - use selectivity of index backed range conditions to calculate the cardinality of a partial join in any case, 3 - additionally always use selectivity of range conditions that are not backed by any index to calculate the cardinality of a partial join, 4 - use histograms to calculate selectivity of range conditions that are not backed by any index to calculate the cardinality of a partial join.5 - additionally use selectivity of certain non-range predicates calculated on record samples NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 5 -@@ -2544,7 +2544,7 @@ +@@ -2554,7 +2554,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME PERFORMANCE_SCHEMA_ACCOUNTS_SIZE VARIABLE_SCOPE GLOBAL @@ -797,7 +788,7 @@ VARIABLE_COMMENT Maximum number of instrumented user@host accounts. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2554,7 +2554,7 @@ +@@ -2564,7 +2564,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_DIGESTS_SIZE VARIABLE_SCOPE GLOBAL @@ -806,7 +797,7 @@ VARIABLE_COMMENT Size of the statement digest. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2564,7 +2564,7 @@ +@@ -2574,7 +2574,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_STAGES_HISTORY_LONG_SIZE VARIABLE_SCOPE GLOBAL @@ -815,7 +806,7 @@ VARIABLE_COMMENT Number of rows in EVENTS_STAGES_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2574,7 +2574,7 @@ +@@ -2584,7 +2584,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_STAGES_HISTORY_SIZE VARIABLE_SCOPE GLOBAL @@ -824,7 +815,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_STAGES_HISTORY. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2584,7 +2584,7 @@ +@@ -2594,7 +2594,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_STATEMENTS_HISTORY_LONG_SIZE VARIABLE_SCOPE GLOBAL @@ -833,7 +824,7 @@ VARIABLE_COMMENT Number of rows in EVENTS_STATEMENTS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2594,7 +2594,7 @@ +@@ -2604,7 +2604,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_STATEMENTS_HISTORY_SIZE VARIABLE_SCOPE GLOBAL @@ -842,7 +833,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_STATEMENTS_HISTORY. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2604,7 +2604,7 @@ +@@ -2614,7 +2614,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_TRANSACTIONS_HISTORY_LONG_SIZE VARIABLE_SCOPE GLOBAL @@ -851,7 +842,7 @@ VARIABLE_COMMENT Number of rows in EVENTS_TRANSACTIONS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2614,7 +2614,7 @@ +@@ -2624,7 +2624,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_TRANSACTIONS_HISTORY_SIZE VARIABLE_SCOPE GLOBAL @@ -860,7 +851,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_TRANSACTIONS_HISTORY. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2624,7 +2624,7 @@ +@@ -2634,7 +2634,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_WAITS_HISTORY_LONG_SIZE VARIABLE_SCOPE GLOBAL @@ -869,7 +860,7 @@ VARIABLE_COMMENT Number of rows in EVENTS_WAITS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2634,7 +2634,7 @@ +@@ -2644,7 +2644,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_WAITS_HISTORY_SIZE VARIABLE_SCOPE GLOBAL @@ -878,7 +869,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_WAITS_HISTORY. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2644,7 +2644,7 @@ +@@ -2654,7 +2654,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_HOSTS_SIZE VARIABLE_SCOPE GLOBAL @@ -887,7 +878,7 @@ VARIABLE_COMMENT Maximum number of instrumented hosts. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2654,7 +2654,7 @@ +@@ -2664,7 +2664,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_COND_CLASSES VARIABLE_SCOPE GLOBAL @@ -896,7 +887,7 @@ VARIABLE_COMMENT Maximum number of condition instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2664,7 +2664,7 @@ +@@ -2674,7 +2674,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_COND_INSTANCES VARIABLE_SCOPE GLOBAL @@ -905,7 +896,7 @@ VARIABLE_COMMENT Maximum number of instrumented condition objects. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2674,7 +2674,7 @@ +@@ -2684,7 +2684,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_DIGEST_LENGTH VARIABLE_SCOPE GLOBAL @@ -914,7 +905,7 @@ VARIABLE_COMMENT Maximum length considered for digest text, when stored in performance_schema tables. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1048576 -@@ -2684,7 +2684,7 @@ +@@ -2694,7 +2694,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_FILE_CLASSES VARIABLE_SCOPE GLOBAL @@ -923,7 +914,7 @@ VARIABLE_COMMENT Maximum number of file instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2694,7 +2694,7 @@ +@@ -2704,7 +2704,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_FILE_HANDLES VARIABLE_SCOPE GLOBAL @@ -932,7 +923,7 @@ VARIABLE_COMMENT Maximum number of opened instrumented files. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1048576 -@@ -2704,7 +2704,7 @@ +@@ -2714,7 +2714,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_FILE_INSTANCES VARIABLE_SCOPE GLOBAL @@ -941,7 +932,7 @@ VARIABLE_COMMENT Maximum number of instrumented files. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2714,7 +2714,7 @@ +@@ -2724,7 +2724,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_INDEX_STAT VARIABLE_SCOPE GLOBAL @@ -950,7 +941,7 @@ VARIABLE_COMMENT Maximum number of index statistics for instrumented tables. Use 0 to disable, -1 for automated scaling. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2724,7 +2724,7 @@ +@@ -2734,7 +2734,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_MEMORY_CLASSES VARIABLE_SCOPE GLOBAL @@ -959,7 +950,7 @@ VARIABLE_COMMENT Maximum number of memory pool instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1024 -@@ -2734,7 +2734,7 @@ +@@ -2744,7 +2744,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_METADATA_LOCKS VARIABLE_SCOPE GLOBAL @@ -968,7 +959,7 @@ VARIABLE_COMMENT Maximum number of metadata locks. Use 0 to disable, -1 for automated scaling. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 104857600 -@@ -2744,7 +2744,7 @@ +@@ -2754,7 +2754,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_MUTEX_CLASSES VARIABLE_SCOPE GLOBAL @@ -977,7 +968,7 @@ VARIABLE_COMMENT Maximum number of mutex instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2754,7 +2754,7 @@ +@@ -2764,7 +2764,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_MUTEX_INSTANCES VARIABLE_SCOPE GLOBAL @@ -986,7 +977,7 @@ VARIABLE_COMMENT Maximum number of instrumented MUTEX objects. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 104857600 -@@ -2764,7 +2764,7 @@ +@@ -2774,7 +2774,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_PREPARED_STATEMENTS_INSTANCES VARIABLE_SCOPE GLOBAL @@ -995,7 +986,7 @@ VARIABLE_COMMENT Maximum number of instrumented prepared statements. Use 0 to disable, -1 for automated scaling. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2774,7 +2774,7 @@ +@@ -2784,7 +2784,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_PROGRAM_INSTANCES VARIABLE_SCOPE GLOBAL @@ -1004,7 +995,7 @@ VARIABLE_COMMENT Maximum number of instrumented programs. Use 0 to disable, -1 for automated scaling. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2784,7 +2784,7 @@ +@@ -2794,7 +2794,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_RWLOCK_CLASSES VARIABLE_SCOPE GLOBAL @@ -1013,7 +1004,7 @@ VARIABLE_COMMENT Maximum number of rwlock instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2794,7 +2794,7 @@ +@@ -2804,7 +2804,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_RWLOCK_INSTANCES VARIABLE_SCOPE GLOBAL @@ -1022,7 +1013,7 @@ VARIABLE_COMMENT Maximum number of instrumented RWLOCK objects. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 104857600 -@@ -2804,7 +2804,7 @@ +@@ -2814,7 +2814,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_SOCKET_CLASSES VARIABLE_SCOPE GLOBAL @@ -1031,7 +1022,7 @@ VARIABLE_COMMENT Maximum number of socket instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2814,7 +2814,7 @@ +@@ -2824,7 +2824,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_SOCKET_INSTANCES VARIABLE_SCOPE GLOBAL @@ -1040,7 +1031,7 @@ VARIABLE_COMMENT Maximum number of opened instrumented sockets. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2824,7 +2824,7 @@ +@@ -2834,7 +2834,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_SQL_TEXT_LENGTH VARIABLE_SCOPE GLOBAL @@ -1049,7 +1040,7 @@ VARIABLE_COMMENT Maximum length of displayed sql text. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1048576 -@@ -2834,7 +2834,7 @@ +@@ -2844,7 +2844,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_STAGE_CLASSES VARIABLE_SCOPE GLOBAL @@ -1058,7 +1049,7 @@ VARIABLE_COMMENT Maximum number of stage instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2844,7 +2844,7 @@ +@@ -2854,7 +2854,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_STATEMENT_CLASSES VARIABLE_SCOPE GLOBAL @@ -1067,7 +1058,7 @@ VARIABLE_COMMENT Maximum number of statement instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2854,7 +2854,7 @@ +@@ -2864,7 +2864,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_STATEMENT_STACK VARIABLE_SCOPE GLOBAL @@ -1076,7 +1067,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_STATEMENTS_CURRENT. NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 256 -@@ -2864,7 +2864,7 @@ +@@ -2874,7 +2874,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_TABLE_HANDLES VARIABLE_SCOPE GLOBAL @@ -1085,7 +1076,7 @@ VARIABLE_COMMENT Maximum number of opened instrumented tables. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2874,7 +2874,7 @@ +@@ -2884,7 +2884,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_TABLE_INSTANCES VARIABLE_SCOPE GLOBAL @@ -1094,7 +1085,7 @@ VARIABLE_COMMENT Maximum number of instrumented tables. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2884,7 +2884,7 @@ +@@ -2894,7 +2894,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_TABLE_LOCK_STAT VARIABLE_SCOPE GLOBAL @@ -1103,7 +1094,7 @@ VARIABLE_COMMENT Maximum number of lock statistics for instrumented tables. Use 0 to disable, -1 for automated scaling. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2894,7 +2894,7 @@ +@@ -2904,7 +2904,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_THREAD_CLASSES VARIABLE_SCOPE GLOBAL @@ -1112,7 +1103,7 @@ VARIABLE_COMMENT Maximum number of thread instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2904,7 +2904,7 @@ +@@ -2914,7 +2914,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_THREAD_INSTANCES VARIABLE_SCOPE GLOBAL @@ -1121,7 +1112,7 @@ VARIABLE_COMMENT Maximum number of instrumented threads. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2914,7 +2914,7 @@ +@@ -2924,7 +2924,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_SESSION_CONNECT_ATTRS_SIZE VARIABLE_SCOPE GLOBAL @@ -1130,7 +1121,7 @@ VARIABLE_COMMENT Size of session attribute string buffer per thread. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2924,7 +2924,7 @@ +@@ -2934,7 +2934,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_SETUP_ACTORS_SIZE VARIABLE_SCOPE GLOBAL @@ -1139,7 +1130,7 @@ VARIABLE_COMMENT Maximum number of rows in SETUP_ACTORS. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2934,7 +2934,7 @@ +@@ -2944,7 +2944,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_SETUP_OBJECTS_SIZE VARIABLE_SCOPE GLOBAL @@ -1148,7 +1139,7 @@ VARIABLE_COMMENT Maximum number of rows in SETUP_OBJECTS. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2944,7 +2944,7 @@ +@@ -2954,7 +2954,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_USERS_SIZE VARIABLE_SCOPE GLOBAL @@ -1157,7 +1148,7 @@ VARIABLE_COMMENT Maximum number of instrumented users. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2994,7 +2994,7 @@ +@@ -3004,7 +3004,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PRELOAD_BUFFER_SIZE VARIABLE_SCOPE SESSION @@ -1166,7 +1157,7 @@ VARIABLE_COMMENT The size of the buffer that is allocated when preloading indexes NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 1073741824 -@@ -3014,7 +3014,7 @@ +@@ -3024,7 +3024,7 @@ COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME PROFILING_HISTORY_SIZE VARIABLE_SCOPE SESSION @@ -1175,7 +1166,7 @@ VARIABLE_COMMENT Number of statements about which profiling information is maintained. If set to 0, no profiles are stored. See SHOW PROFILES. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 100 -@@ -3024,7 +3024,7 @@ +@@ -3034,7 +3034,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PROGRESS_REPORT_TIME VARIABLE_SCOPE SESSION @@ -1184,7 +1175,7 @@ VARIABLE_COMMENT Seconds between sending progress reports to the client for time-consuming statements. Set to 0 to disable progress reporting. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -3084,7 +3084,7 @@ +@@ -3094,7 +3094,7 @@ COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME QUERY_ALLOC_BLOCK_SIZE VARIABLE_SCOPE SESSION @@ -1193,7 +1184,7 @@ VARIABLE_COMMENT Allocation block size for query parsing and execution NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 4294967295 -@@ -3094,7 +3094,7 @@ +@@ -3104,7 +3104,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME QUERY_CACHE_LIMIT VARIABLE_SCOPE GLOBAL @@ -1202,7 +1193,7 @@ VARIABLE_COMMENT Don't cache results that are bigger than this NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -3104,7 +3104,7 @@ +@@ -3114,7 +3114,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME QUERY_CACHE_MIN_RES_UNIT VARIABLE_SCOPE GLOBAL @@ -1211,7 +1202,7 @@ VARIABLE_COMMENT The minimum size for blocks allocated by the query cache NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -3117,7 +3117,7 @@ +@@ -3127,7 +3127,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT The memory allocated to store results from old queries NUMERIC_MIN_VALUE 0 @@ -1220,7 +1211,7 @@ NUMERIC_BLOCK_SIZE 1024 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3154,7 +3154,7 @@ +@@ -3164,7 +3164,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME QUERY_PREALLOC_SIZE VARIABLE_SCOPE SESSION @@ -1229,7 +1220,7 @@ VARIABLE_COMMENT Persistent buffer for query parsing and execution NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 4294967295 -@@ -3167,7 +3167,7 @@ +@@ -3177,7 +3177,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes NUMERIC_MIN_VALUE 0 @@ -1238,7 +1229,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3177,14 +3177,14 @@ +@@ -3187,14 +3187,14 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes NUMERIC_MIN_VALUE 0 @@ -1255,7 +1246,7 @@ VARIABLE_COMMENT Allocation block size for storing ranges during optimization NUMERIC_MIN_VALUE 4096 NUMERIC_MAX_VALUE 4294967295 -@@ -3197,14 +3197,14 @@ +@@ -3207,14 +3207,14 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Maximum speed(KB/s) to read binlog from master (0 = no limit) NUMERIC_MIN_VALUE 0 @@ -1272,7 +1263,7 @@ VARIABLE_COMMENT Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value NUMERIC_MIN_VALUE 8192 NUMERIC_MAX_VALUE 2147483647 -@@ -3224,7 +3224,7 @@ +@@ -3234,7 +3234,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME READ_RND_BUFFER_SIZE VARIABLE_SCOPE SESSION @@ -1281,7 +1272,7 @@ VARIABLE_COMMENT When reading rows in sorted order after a sort, the rows are read through this buffer to avoid a disk seeks NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 2147483647 -@@ -3434,10 +3434,10 @@ +@@ -3444,10 +3444,10 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME ROWID_MERGE_BUFF_SIZE VARIABLE_SCOPE SESSION @@ -1294,7 +1285,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3454,20 +3454,20 @@ +@@ -3464,20 +3464,20 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME RPL_SEMI_SYNC_MASTER_TIMEOUT VARIABLE_SCOPE GLOBAL @@ -1319,7 +1310,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3524,10 +3524,10 @@ +@@ -3534,10 +3534,10 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME RPL_SEMI_SYNC_SLAVE_TRACE_LEVEL VARIABLE_SCOPE GLOBAL @@ -1332,7 +1323,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3564,7 +3564,7 @@ +@@ -3574,7 +3574,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME SERVER_ID VARIABLE_SCOPE SESSION @@ -1341,7 +1332,7 @@ VARIABLE_COMMENT Uniquely identifies the server instance in the community of replication partners NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 4294967295 -@@ -3694,7 +3694,7 @@ +@@ -3714,7 +3714,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME SLAVE_DOMAIN_PARALLEL_THREADS VARIABLE_SCOPE GLOBAL @@ -1350,7 +1341,7 @@ VARIABLE_COMMENT Maximum number of parallel threads to use on slave for events in a single replication domain. When using multiple domains, this can be used to limit a single domain from grabbing all threads and thus stalling other domains. The default of 0 means to allow a domain to grab as many threads as it wants, up to the value of slave_parallel_threads. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 16383 -@@ -3724,7 +3724,7 @@ +@@ -3744,7 +3744,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME SLAVE_MAX_ALLOWED_PACKET VARIABLE_SCOPE GLOBAL @@ -1359,7 +1350,7 @@ VARIABLE_COMMENT The maximum packet length to sent successfully from the master to slave. NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 1073741824 -@@ -3744,7 +3744,7 @@ +@@ -3764,7 +3764,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME SLAVE_PARALLEL_MAX_QUEUED VARIABLE_SCOPE GLOBAL @@ -1368,7 +1359,7 @@ VARIABLE_COMMENT Limit on how much memory SQL threads should use per parallel replication thread when reading ahead in the relay log looking for opportunities for parallel replication. Only used when --slave-parallel-threads > 0. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 2147483647 -@@ -3764,7 +3764,7 @@ +@@ -3784,7 +3784,7 @@ COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME SLAVE_PARALLEL_THREADS VARIABLE_SCOPE GLOBAL @@ -1377,7 +1368,7 @@ VARIABLE_COMMENT If non-zero, number of threads to spawn to apply in parallel events on the slave that were group-committed on the master or were logged with GTID in different replication domains. Note that these threads are in addition to the IO and SQL threads, which are always created by a replication slave NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 16383 -@@ -3774,7 +3774,7 @@ +@@ -3794,7 +3794,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME SLAVE_PARALLEL_WORKERS VARIABLE_SCOPE GLOBAL @@ -1386,7 +1377,7 @@ VARIABLE_COMMENT Alias for slave_parallel_threads NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 16383 -@@ -3814,7 +3814,7 @@ +@@ -3834,7 +3834,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME SLAVE_TRANSACTION_RETRIES VARIABLE_SCOPE GLOBAL @@ -1395,7 +1386,7 @@ VARIABLE_COMMENT Number of times the slave SQL thread will retry a transaction in case it failed with a deadlock, elapsed lock wait timeout or listed in slave_transaction_retry_errors, before giving up and stopping NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -3834,7 +3834,7 @@ +@@ -3854,7 +3854,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME SLAVE_TRANSACTION_RETRY_INTERVAL VARIABLE_SCOPE GLOBAL @@ -1404,7 +1395,7 @@ VARIABLE_COMMENT Interval of the slave SQL thread will retry a transaction in case it failed with a deadlock or elapsed lock wait timeout or listed in slave_transaction_retry_errors NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 3600 -@@ -3854,7 +3854,7 @@ +@@ -3874,7 +3874,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME SLOW_LAUNCH_TIME VARIABLE_SCOPE GLOBAL @@ -1413,7 +1404,7 @@ VARIABLE_COMMENT If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be incremented NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 31536000 -@@ -3897,7 +3897,7 @@ +@@ -3917,7 +3917,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Each thread that needs to do a sort allocates a buffer of this size NUMERIC_MIN_VALUE 1024 @@ -1422,7 +1413,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -4124,7 +4124,7 @@ +@@ -4144,7 +4144,7 @@ COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME STORED_PROGRAM_CACHE VARIABLE_SCOPE GLOBAL @@ -1431,7 +1422,7 @@ VARIABLE_COMMENT The soft upper limit for number of cached stored routines for one connection. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 524288 -@@ -4224,7 +4224,7 @@ +@@ -4244,7 +4244,7 @@ COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME TABLE_DEFINITION_CACHE VARIABLE_SCOPE GLOBAL @@ -1440,7 +1431,7 @@ VARIABLE_COMMENT The number of cached table definitions NUMERIC_MIN_VALUE 400 NUMERIC_MAX_VALUE 2097152 -@@ -4234,7 +4234,7 @@ +@@ -4254,7 +4254,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME TABLE_OPEN_CACHE VARIABLE_SCOPE GLOBAL @@ -1449,7 +1440,7 @@ VARIABLE_COMMENT The number of cached open tables NUMERIC_MIN_VALUE 10 NUMERIC_MAX_VALUE 1048576 -@@ -4294,7 +4294,7 @@ +@@ -4314,7 +4314,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME THREAD_CACHE_SIZE VARIABLE_SCOPE GLOBAL @@ -1458,7 +1449,7 @@ VARIABLE_COMMENT How many threads we should keep in a cache for reuse. These are freed after 5 minutes of idle time NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 16384 -@@ -4467,7 +4467,7 @@ +@@ -4487,7 +4487,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Max size for data for an internal temporary on-disk MyISAM or Aria table. NUMERIC_MIN_VALUE 1024 @@ -1467,22 +1458,22 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -4477,7 +4477,7 @@ +@@ -4497,7 +4497,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT If an internal in-memory temporary table exceeds this size, MariaDB will automatically convert it to an on-disk MyISAM or Aria table. Same as tmp_table_size. NUMERIC_MIN_VALUE 0 -NUMERIC_MAX_VALUE 18446744073709551615 +NUMERIC_MAX_VALUE 4294967295 - NUMERIC_BLOCK_SIZE 1 + NUMERIC_BLOCK_SIZE 16384 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -4487,14 +4487,14 @@ +@@ -4507,14 +4507,14 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Alias for tmp_memory_table_size. If an internal in-memory temporary table exceeds this size, MariaDB will automatically convert it to an on-disk MyISAM or Aria table. NUMERIC_MIN_VALUE 0 -NUMERIC_MAX_VALUE 18446744073709551615 +NUMERIC_MAX_VALUE 4294967295 - NUMERIC_BLOCK_SIZE 1 + NUMERIC_BLOCK_SIZE 16384 ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED @@ -1493,7 +1484,7 @@ VARIABLE_COMMENT Allocation block size for transactions to be stored in binary log NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 134217728 -@@ -4504,7 +4504,7 @@ +@@ -4524,7 +4524,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME TRANSACTION_PREALLOC_SIZE VARIABLE_SCOPE SESSION @@ -1502,7 +1493,7 @@ VARIABLE_COMMENT Persistent buffer for transactions to be stored in binary log NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 134217728 -@@ -4644,7 +4644,7 @@ +@@ -4664,7 +4664,7 @@ COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME WAIT_TIMEOUT VARIABLE_SCOPE SESSION @@ -1511,7 +1502,7 @@ VARIABLE_COMMENT The number of seconds the server waits for activity on a connection before closing it NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 31536000 -@@ -4671,7 +4671,7 @@ +@@ -4691,7 +4691,7 @@ VARIABLE_NAME LOG_TC_SIZE GLOBAL_VALUE_ORIGIN AUTO VARIABLE_SCOPE GLOBAL From 9ddecc2164347edde5c727057e4aef43c2d7d2b7 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 8 Jan 2025 15:25:25 +0100 Subject: [PATCH 018/213] heap-buffer-overflow in mariadb-backup write of NULL ptr after the end of the allocated buffer --- extra/mariabackup/encryption_plugin.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extra/mariabackup/encryption_plugin.cc b/extra/mariabackup/encryption_plugin.cc index 04e8ae83957..765e1488248 100644 --- a/extra/mariabackup/encryption_plugin.cc +++ b/extra/mariabackup/encryption_plugin.cc @@ -218,9 +218,10 @@ void encryption_plugin_prepare_init(int argc, char **argv) opt_plugin_dir[FN_REFLEN - 1] = '\0'; } - char **new_argv = new char *[argc + 1]; + char **new_argv = new char *[argc + 2]; new_argv[0] = XTRABACKUP_EXE; memcpy(&new_argv[1], argv, argc*sizeof(char *)); + new_argv[argc+1]= 0; encryption_plugin_init(argc+1, new_argv); From ea19a6b38cdab17b6b435f42c3bb722ee8fcc1e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 9 Jan 2025 13:18:30 +0200 Subject: [PATCH 019/213] MDEV-35699 Multi-batch recovery occasionally fails recv_sys_t::parse(): Do invoke fil_space_set_recv_size_and_flags() and do parse enough of page 0 to facilitate that. This fixes a regression that had been introduced in commit b249a059da2ef03eda35872a763e5453dbc39339 (MDEV-34850). In a multi-batch crash recovery, we would fail to invoke fil_space_set_recv_size_and_flags() while parsing the remaining log, before starting the first recovery batch. Reviewed by: Debarun Banerjee Tested by: Matthias Leich --- .../suite/encryption/r/recovery_memory.result | 15 +++++++ .../suite/encryption/t/recovery_memory.opt | 8 ++++ .../suite/encryption/t/recovery_memory.test | 45 +++++++++++++++++++ storage/innobase/log/log0recv.cc | 33 ++++++++------ 4 files changed, 88 insertions(+), 13 deletions(-) create mode 100644 mysql-test/suite/encryption/r/recovery_memory.result create mode 100644 mysql-test/suite/encryption/t/recovery_memory.opt create mode 100644 mysql-test/suite/encryption/t/recovery_memory.test diff --git a/mysql-test/suite/encryption/r/recovery_memory.result b/mysql-test/suite/encryption/r/recovery_memory.result new file mode 100644 index 00000000000..1b02fb6d31d --- /dev/null +++ b/mysql-test/suite/encryption/r/recovery_memory.result @@ -0,0 +1,15 @@ +CREATE TABLE t1(f1 text, index idx(f1(20))) ENGINE INNODB; +set global innodb_fast_shutdown=0; +# restart: --debug_dbug=+d,ib_log_checkpoint_avoid_hard --innodb_flush_sync=0 +set global debug_dbug="+d,ib_log_checkpoint_avoid_hard"; +INSERT INTO t1 SELECT repeat('a', 8000) FROM seq_1_to_1280; +DELETE FROM t1; +SET GLOBAL innodb_max_purge_lag_wait=0; +INSERT INTO t1 VALUES('a'); +# XTRABACKUP PREPARE +# restart +SELECT COUNT(*) FROM t1; +COUNT(*) +1 +ALTER TABLE t1 FORCE; +DROP TABLE t1; diff --git a/mysql-test/suite/encryption/t/recovery_memory.opt b/mysql-test/suite/encryption/t/recovery_memory.opt new file mode 100644 index 00000000000..125f90920df --- /dev/null +++ b/mysql-test/suite/encryption/t/recovery_memory.opt @@ -0,0 +1,8 @@ +--innodb_doublewrite=0 +--innodb_log_file_size=24m +--innodb_immediate_scrub_data_uncompressed=1 +--plugin-load-add=$FILE_KEY_MANAGEMENT_SO +--loose-file-key-management +--loose-file-key-management-filename=$MYSQL_TEST_DIR/std_data/logkey.txt +--file-key-management-encryption-algorithm=aes_cbc +--innodb-encrypt-log=1 diff --git a/mysql-test/suite/encryption/t/recovery_memory.test b/mysql-test/suite/encryption/t/recovery_memory.test new file mode 100644 index 00000000000..6187a29dba9 --- /dev/null +++ b/mysql-test/suite/encryption/t/recovery_memory.test @@ -0,0 +1,45 @@ +--source include/have_debug.inc +--source include/have_innodb.inc +--source include/have_sequence.inc +--source filekeys_plugin.inc + +let $basedir=$MYSQLTEST_VARDIR/tmp/backup; +let MYSQLD_DATADIR=`select @@datadir`; + +CREATE TABLE t1(f1 text, index idx(f1(20))) ENGINE INNODB; + +# No checkpoint happens during this restart + +let $shutdown_timeout=; +set global innodb_fast_shutdown=0; +let $restart_parameters=--debug_dbug=+d,ib_log_checkpoint_avoid_hard --innodb_flush_sync=0; +--source include/restart_mysqld.inc +set global debug_dbug="+d,ib_log_checkpoint_avoid_hard"; + +--disable_result_log +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir; +--enable_result_log + +INSERT INTO t1 SELECT repeat('a', 8000) FROM seq_1_to_1280; +DELETE FROM t1; +SET GLOBAL innodb_max_purge_lag_wait=0; +INSERT INTO t1 VALUES('a'); + +--echo # XTRABACKUP PREPARE +exec $XTRABACKUP --prepare --target-dir=$basedir; + +let $shutdown_timeout=0; +--source include/shutdown_mysqld.inc + +# Since there is no checkpoint during previous run, we can +# Copy the datafile from t1.ibd and start the server + +remove_file $MYSQLD_DATADIR/test/t1.ibd; +copy_file $basedir/test/t1.ibd $MYSQLD_DATADIR/test/t1.ibd; +--enable_result_log +let $restart_parameters=; +--source include/start_mysqld.inc + +SELECT COUNT(*) FROM t1; +ALTER TABLE t1 FORCE; +DROP TABLE t1; diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index d0f68996001..1e692f92447 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -2509,7 +2509,7 @@ restart: ut_ad(log_sys.is_latest()); alignas(8) byte iv[MY_AES_BLOCK_SIZE]; - byte *decrypt_buf= storing == YES + byte *decrypt_buf= storing != BACKUP ? static_cast(alloca(srv_page_size)) : nullptr; const lsn_t start_lsn{lsn}; @@ -2654,7 +2654,7 @@ restart: sql_print_warning("InnoDB: Ignoring malformed log record at LSN " LSN_PF, lsn); /* the next record must not be same_page */ - if (storing == YES) last_offset= 1; + if (storing != BACKUP) last_offset= 1; continue; } if (srv_operation == SRV_OPERATION_BACKUP) @@ -2664,7 +2664,7 @@ restart: lsn, b, l - recs + rlen, space_id, page_no)); goto same_page; } - if (storing == YES) last_offset= 0; + if (storing != BACKUP) last_offset= 0; idlen= mlog_decode_varint_length(*l); if (UNIV_UNLIKELY(idlen > 5 || idlen >= rlen)) { @@ -2695,7 +2695,7 @@ restart: goto page_id_corrupted; l+= idlen; rlen-= idlen; - if (storing == YES) + if (storing != BACKUP) { mach_write_to_4(iv + 8, space_id); mach_write_to_4(iv + 12, page_no); @@ -2745,15 +2745,15 @@ restart: ut_d(if ((b & 0x70) == INIT_PAGE || (b & 0x70) == OPTION) freed.erase(id)); ut_ad(freed.find(id) == freed.end()); - const byte *cl= storing == NO ? nullptr : l.ptr; + const byte *cl= nullptr; /* avoid bogus -Wmaybe-uninitialized */ switch (b & 0x70) { case FREE_PAGE: ut_ad(freed.emplace(id).second); /* the next record must not be same_page */ - if (storing == YES) last_offset= 1; + if (storing != BACKUP) last_offset= 1; goto free_or_init_page; case INIT_PAGE: - if (storing == YES) last_offset= FIL_PAGE_TYPE; + if (storing != BACKUP) last_offset= FIL_PAGE_TYPE; free_or_init_page: if (storing == BACKUP) continue; @@ -2808,13 +2808,14 @@ restart: trim({space_id, 0}, start_lsn); truncated_undo_spaces[space_id - srv_undo_space_id_start]= { start_lsn, page_no }; - if (storing == BACKUP && undo_space_trunc) + if (storing != BACKUP) + /* the next record must not be same_page */ + last_offset= 1; + else if (undo_space_trunc) undo_space_trunc(space_id); - /* the next record must not be same_page */ - if (storing == YES) last_offset= 1; continue; } - if (storing == YES) last_offset= FIL_PAGE_TYPE; + if (storing != BACKUP) last_offset= FIL_PAGE_TYPE; break; case OPTION: if (storing == YES && rlen == 5 && *l == OPT_PAGE_CHECKSUM) @@ -2825,7 +2826,13 @@ restart: case WRITE: case MEMMOVE: case MEMSET: - if (storing != YES) + if (storing == BACKUP) + continue; + if (storing == NO && UNIV_LIKELY(page_no != 0)) + /* fil_space_set_recv_size_and_flags() is mandatory for storing==NO. + It is only applicable to page_no == 0. Other than that, we can just + ignore the payload and only compute the mini-transaction checksum; + there will be a subsequent call with storing==YES. */ continue; if (UNIV_UNLIKELY(rlen == 0 || last_offset == 1)) goto record_corrupted; @@ -2867,7 +2874,7 @@ restart: last_offset) : file_name_t::initial_flags; if (it == recv_spaces.end()) - ut_ad(space_id == TRX_SYS_SPACE || + ut_ad(storing == NO || space_id == TRX_SYS_SPACE || srv_is_undo_tablespace(space_id)); else if (!it->second.space) { From ed13d93a256eed0c48ffda7b8fb0f6969e886574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 9 Jan 2025 13:18:42 +0200 Subject: [PATCH 020/213] Fix mariadb-backup --backup with innodb_undo_log_truncate=ON MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes another regression that had been introduced in commit b249a059da2ef03eda35872a763e5453dbc39339 (MDEV-34850). This should prevent failures of mariadb-backup --backup of the following type: mariabackup: Failed to read undo log tablespace space id … and there is no undo tablespace truncation redo record. This error has not been hit by our internal testing, and we currently have no regression test to cover this. --- storage/innobase/log/log0recv.cc | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 1e692f92447..d4bdfbad391 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -2791,10 +2791,28 @@ restart: cl= l.copy_if_needed(iv, decrypt_buf, recs, rlen); break; case EXTENDED: - if (storing != YES) + if (storing == NO) + /* We really only care about WRITE records to page 0, to + invoke fil_space_set_recv_size_and_flags(). As of now, the + EXTENDED records refer to index or undo log pages (which + page 0 never can be), or we have the TRIM_PAGES subtype for + shrinking a tablespace, to a larger number of pages than 0. + Either way, we can ignore this record during the preparation + for multi-batch recovery. */ continue; if (UNIV_UNLIKELY(!rlen)) goto record_corrupted; + if (storing == BACKUP) + { + if (rlen == 1 && undo_space_trunc) + { + cl= l.copy_if_needed(iv, decrypt_buf, recs, rlen); + if (*cl == TRIM_PAGES) + undo_space_trunc(space_id); + } + continue; + } + cl= l.copy_if_needed(iv, decrypt_buf, recs, rlen); if (rlen == 1 && *cl == TRIM_PAGES) { @@ -2815,7 +2833,10 @@ restart: undo_space_trunc(space_id); continue; } - if (storing != BACKUP) last_offset= FIL_PAGE_TYPE; + /* This record applies to an undo log or index page, and it + may be followed by subsequent WRITE or similar records for the + same page in the same mini-transaction. */ + last_offset= FIL_PAGE_TYPE; break; case OPTION: if (storing == YES && rlen == 5 && *l == OPT_PAGE_CHECKSUM) From 81633f47c3febe056cd4c1e704dbe9a70c7b6357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 9 Jan 2025 13:21:38 +0200 Subject: [PATCH 021/213] MDEV-35796 OPT_PAGE_CHECKSUM is ignored if innodb_encrypt_log=ON recv_sys_t::parse(): When parsing an OPTION record, invoke l.copy_if_needed() before checking if the payload is OPT_PAGE_CHECKSUM followed by a 32-bit page checksum. This fixes up the merge 57d4a242dac0238dd63ac05cd9d65a38d75a5d5f of commit 4179f93d28035ea2798cb1c16feeaaef87ab4775 (MDEV-18976). The impact of this can be observed by running a debug instrumented build on the test encryption.recovery_memory. There should be over 5,000 invocations of log_phys_t::page_checksum(). Without this fix, there should be less than 100 of them (when the OPT_PAGE_CHECKSUM byte happens to encrypt to itself). Reviewed by: Debarun Banerjee Tested by: Matthias Leich --- storage/innobase/log/log0recv.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index d4bdfbad391..1e5ea6f5a6d 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -2787,7 +2787,6 @@ restart: erase(r); continue; } - copy_if_needed: cl= l.copy_if_needed(iv, decrypt_buf, recs, rlen); break; case EXTENDED: @@ -2839,8 +2838,14 @@ restart: last_offset= FIL_PAGE_TYPE; break; case OPTION: - if (storing == YES && rlen == 5 && *l == OPT_PAGE_CHECKSUM) - goto copy_if_needed; + /* OPTION records can be safely ignored in recovery */ + if (storing == YES && + rlen == 5/* OPT_PAGE_CHECKSUM and CRC-32C; see page_checksum() */) + { + cl= l.copy_if_needed(iv, decrypt_buf, recs, rlen); + if (*cl == OPT_PAGE_CHECKSUM) + break; + } /* fall through */ case RESERVED: continue; From 1b8358d9438c01c083fe4c66bcd43d755c3e2d7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 9 Jan 2025 14:27:13 +0200 Subject: [PATCH 022/213] Use assert() on RMW arguments The macros ut_ad() and DBUG_ASSERT() can evaluate their argument twice. That is wrong for any read-modify-write arguments. Thanks to Nikita Malyavin for pointing this out. --- storage/innobase/include/buf0buf.h | 2 +- storage/innobase/include/sux_lock.h | 6 ++---- storage/innobase/include/trx0trx.h | 8 ++++---- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index 0dc50638315..eed41113659 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -799,7 +799,7 @@ public: /** Prepare to release a file page to buf_pool.free. */ void free_file_page() noexcept { - ut_ad((zip.fix.fetch_sub(REMOVE_HASH - MEMORY)) == REMOVE_HASH); + assert((zip.fix.fetch_sub(REMOVE_HASH - MEMORY)) == REMOVE_HASH); /* buf_LRU_block_free_non_file_page() asserts !oldest_modification() */ ut_d(oldest_modification_= 0;) id_= page_id_t(~0ULL); diff --git a/storage/innobase/include/sux_lock.h b/storage/innobase/include/sux_lock.h index ea9487b943c..83fa552aafc 100644 --- a/storage/innobase/include/sux_lock.h +++ b/storage/innobase/include/sux_lock.h @@ -121,15 +121,13 @@ private: @param id the new owner of the U or X lock */ void set_new_owner(pthread_t id) { - IF_DBUG(DBUG_ASSERT(writer.exchange(id, std::memory_order_relaxed)), - writer.store(id, std::memory_order_relaxed)); + writer.store(id, std::memory_order_relaxed); } /** Assign the ownership of a write lock to a thread @param id the owner of the U or X lock */ void set_first_owner(pthread_t id) { - IF_DBUG(DBUG_ASSERT(!writer.exchange(id, std::memory_order_relaxed)), - writer.store(id, std::memory_order_relaxed)); + writer.store(id, std::memory_order_relaxed); } #ifdef UNIV_DEBUG /** Register the current thread as a holder of a shared lock */ diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index beb5a284876..9a1c5edd43f 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -618,14 +618,14 @@ public: { ut_ad(!mutex_is_owner()); mutex.wr_lock(); - ut_ad(!mutex_owner.exchange(pthread_self(), - std::memory_order_relaxed)); + assert(!mutex_owner.exchange(pthread_self(), + std::memory_order_relaxed)); } /** Release the mutex */ void mutex_unlock() { - ut_ad(mutex_owner.exchange(0, std::memory_order_relaxed) - == pthread_self()); + assert(mutex_owner.exchange(0, std::memory_order_relaxed) == + pthread_self()); mutex.wr_unlock(); } #ifndef SUX_LOCK_GENERIC From ff1f611a0d84b84a06b100a3b6901fc6d8957ff5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 10 Jan 2025 06:50:50 +0200 Subject: [PATCH 023/213] Avoid assert() By default, CMAKE_BUILD_TYPE RelWithDebInfo or Release implies -DNDEBUG, which disables the assert() macro. MariaDB is deviating from that. Let us be explicit to use assert() only in debug builds. This fixes up 1b8358d9438c01c083fe4c66bcd43d755c3e2d7d --- storage/innobase/include/trx0trx.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 9a1c5edd43f..7a3df5cf125 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -618,14 +618,14 @@ public: { ut_ad(!mutex_is_owner()); mutex.wr_lock(); - assert(!mutex_owner.exchange(pthread_self(), - std::memory_order_relaxed)); + ut_d(assert(!mutex_owner.exchange(pthread_self(), + std::memory_order_relaxed))); } /** Release the mutex */ void mutex_unlock() { - assert(mutex_owner.exchange(0, std::memory_order_relaxed) == - pthread_self()); + ut_d(assert(mutex_owner.exchange(0, std::memory_order_relaxed) == + pthread_self())); mutex.wr_unlock(); } #ifndef SUX_LOCK_GENERIC From 47044350687db857a2d9335c0fcd1f4962279636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 10 Jan 2025 08:15:09 +0200 Subject: [PATCH 024/213] MDEV-35802 Race condition in log_t::persist() log_t::persist(): Remove the parameter holding_latch, and assert latch_holding_any(). We used to avoid acquiring a latch when log resizing was not in progress. That allowed a race condition to occur where log_t::write_checkpoint() has just completed log resizing. In that case, we could wrongly invoke pmem_persist() on the old log_sys.buf instead of the new one, which was shortly before known as log_sys.resize_buf. log_write_persist(): A non-inline wrapper function that will invoke log_sys.persist() while holding a shared log_sys.latch. --- storage/innobase/include/log0log.h | 5 ++--- storage/innobase/log/log0log.cc | 20 +++++++++++--------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h index cfde0472e78..6d035fc97d1 100644 --- a/storage/innobase/include/log0log.h +++ b/storage/innobase/include/log0log.h @@ -462,9 +462,8 @@ public: #ifdef HAVE_PMEM /** Persist the log. - @param lsn desired new value of flushed_to_disk_lsn - @param holding_latch whether the caller is holding exclusive latch */ - void persist(lsn_t lsn, bool holding_latch) noexcept; + @param lsn desired new value of flushed_to_disk_lsn */ + void persist(lsn_t lsn) noexcept; #endif bool check_for_checkpoint() const diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index 10928c66b20..378528e78c3 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -885,13 +885,13 @@ static size_t log_pad(lsn_t lsn, size_t pad, byte *begin, byte *extra) #endif #ifdef HAVE_PMEM -void log_t::persist(lsn_t lsn, bool holding_latch) noexcept +void log_t::persist(lsn_t lsn) noexcept { ut_ad(!is_opened()); ut_ad(!write_lock.is_owner()); ut_ad(!flush_lock.is_owner()); #ifdef LOG_LATCH_DEBUG - ut_ad(holding_latch == latch_have_wr()); + ut_ad(latch_have_any()); #endif lsn_t old= flushed_to_disk_lsn.load(std::memory_order_relaxed); @@ -899,9 +899,6 @@ void log_t::persist(lsn_t lsn, bool holding_latch) noexcept if (old >= lsn) return; - const bool latching{!holding_latch && resize_in_progress()}; - if (UNIV_UNLIKELY(latching)) - latch.rd_lock(SRW_LOCK_CALL); const size_t start(calc_lsn_offset(old)); const size_t end(calc_lsn_offset(lsn)); @@ -925,9 +922,14 @@ void log_t::persist(lsn_t lsn, bool holding_latch) noexcept log_flush_notify(lsn); DBUG_EXECUTE_IF("crash_after_log_write_upto", DBUG_SUICIDE();); } +} - if (UNIV_UNLIKELY(latching)) - latch.rd_unlock(); +ATTRIBUTE_NOINLINE +static void log_write_persist(lsn_t lsn) noexcept +{ + log_sys.latch.rd_lock(SRW_LOCK_CALL); + log_sys.persist(lsn); + log_sys.latch.rd_unlock(); } #endif @@ -1145,7 +1147,7 @@ void log_write_up_to(lsn_t lsn, bool durable, if (log_sys.is_mmap()) { if (durable) - log_sys.persist(lsn, false); + log_write_persist(lsn); return; } #endif @@ -1266,7 +1268,7 @@ ATTRIBUTE_COLD void log_write_and_flush() ut_ad(!srv_read_only_mode); #ifdef HAVE_PMEM if (log_sys.is_mmap()) - log_sys.persist(log_sys.get_lsn(), true); + log_sys.persist(log_sys.get_lsn()); else #endif { From 542edc774373c03ea5854dac5bf0c5f4cabe0448 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 9 Jan 2025 19:34:01 +0100 Subject: [PATCH 025/213] MDEV-35720 fix the test case * cleanup after itself * disable cursor protocol for SELECT ... INTO --- mysql-test/main/log_state.result | 2 +- mysql-test/main/log_state.test | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/log_state.result b/mysql-test/main/log_state.result index af8d7d98455..e63114fafa7 100644 --- a/mysql-test/main/log_state.result +++ b/mysql-test/main/log_state.result @@ -310,9 +310,9 @@ select @s1 > 2.00 and @s1 < 10.00 as "should be true"; should be true 1 disconnect con2; -connection default; disconnect con1; connection default; +drop procedure p1; SET GLOBAL long_query_time = @save_long_query_time; SET GLOBAL log_output = @old_log_output; SET global general_log = @old_general_log; diff --git a/mysql-test/main/log_state.test b/mysql-test/main/log_state.test index 93e35854355..9686ace3f4b 100644 --- a/mysql-test/main/log_state.test +++ b/mysql-test/main/log_state.test @@ -328,7 +328,9 @@ SET GLOBAL general_log_file = @old_general_log_file; connect (con2,localhost,root,,); set @s1=(select variable_value from information_schema.session_status where variable_name='query_time'); +--disable_cursor_protocol select sleep(3) into @a; +--enable_cursor_protocol set @s2=(select variable_value from information_schema.session_status where variable_name='query_time'); set @s3=(select variable_value from information_schema.global_status where @@ -358,7 +360,6 @@ select @s1 > 2.00 and @s1 < 10.00 as "should be true"; # select @s1; disconnect con2; -connection default; # # Cleanup @@ -367,6 +368,7 @@ connection default; disconnect con1; # set back the saved default values connection default; +drop procedure p1; # Reset global system variables to initial values if forgotten somewhere above. SET GLOBAL long_query_time = @save_long_query_time; From 311e88c67a8ddf8319a6b65d0f770efa09821921 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 10 Jan 2025 13:11:09 +0100 Subject: [PATCH 026/213] fix rocksdb tests for buildbot --- storage/rocksdb/mysql-test/rocksdb/suite.pm | 1 + storage/rocksdb/mysql-test/rocksdb/t/type_float.inc | 2 ++ 2 files changed, 3 insertions(+) diff --git a/storage/rocksdb/mysql-test/rocksdb/suite.pm b/storage/rocksdb/mysql-test/rocksdb/suite.pm index b4feb20a451..40e424a75f9 100644 --- a/storage/rocksdb/mysql-test/rocksdb/suite.pm +++ b/storage/rocksdb/mysql-test/rocksdb/suite.pm @@ -18,6 +18,7 @@ my $sst_dump= "$::bindir/storage/rocksdb$::multiconfig/sst_dump", "$::path_client_bindir/sst_dump"); return "RocksDB is not compiled, no sst_dump" unless $sst_dump; +return "doesn't work in embedded" if $::opt_embedded_server; $ENV{MARIAROCKS_SST_DUMP}="$sst_dump"; ## Temporarily disable testing under valgrind, due to MDEV-12439 diff --git a/storage/rocksdb/mysql-test/rocksdb/t/type_float.inc b/storage/rocksdb/mysql-test/rocksdb/t/type_float.inc index 27adda9ba35..601d61feb1f 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/type_float.inc +++ b/storage/rocksdb/mysql-test/rocksdb/t/type_float.inc @@ -91,6 +91,7 @@ INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES ( --sorted_result --query_vertical SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1 +--enable_prepare_warnings INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES ( 999999999999999999999999999999999999999, 999999999999999999999999999999999999999.9999999999999999, @@ -104,6 +105,7 @@ INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES ( 19999999999999999999999999999999999999999999.9999999999, 6 ); +--disable_prepare_warnings --sorted_result --query_vertical SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1 From 43233fe469fd85d7c64978f01ed68de3288d43cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Fri, 10 Jan 2025 10:08:24 +0200 Subject: [PATCH 027/213] Fix -DBUILD_CONFIG=mysql_release to keep standard cmake flags -DCMAKE_BUILD_TYPE=xxx sets some C compiler flags according to the build type. -DBUILD_CONFIG was completely overwriting them in some compiler / arch combinations and not in others. Make it consistently "append-only", not overwrite. Also, enforce the same set of flags for Release and RelWithDebInfo. This reverts ff1f611a0d84b84a06b100a3b6901fc6d8957ff5 as it is no longer necessary. Avoid assert() By default, CMAKE_BUILD_TYPE RelWithDebInfo or Release implies -DNDEBUG, which disables the assert() macro. MariaDB is deviating from that. Let us be explicit to use assert() only in debug builds. --- .../build_configurations/mysql_release.cmake | 104 ++++++++++++------ storage/innobase/include/trx0trx.h | 8 +- 2 files changed, 73 insertions(+), 39 deletions(-) diff --git a/cmake/build_configurations/mysql_release.cmake b/cmake/build_configurations/mysql_release.cmake index 096b0afd6aa..8a34b0a6071 100644 --- a/cmake/build_configurations/mysql_release.cmake +++ b/cmake/build_configurations/mysql_release.cmake @@ -187,30 +187,40 @@ IF(UNIX) # Default GCC flags IF(CMAKE_COMPILER_IS_GNUCC) SET(COMMON_C_FLAGS "-g -fno-omit-frame-pointer -fno-strict-aliasing -Wno-uninitialized") - SET(CMAKE_C_FLAGS_DEBUG "-O ${COMMON_C_FLAGS}") - SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 ${COMMON_C_FLAGS}") + STRING(APPEND CMAKE_C_FLAGS_DEBUG " ${COMMON_C_FLAGS}") + STRING(APPEND CMAKE_C_FLAGS_RELEASE " ${COMMON_C_FLAGS}") + STRING(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO " ${COMMON_C_FLAGS}") + # MariaDB uses -O3 for release builds + STRING(REGEX REPLACE "-O2" "-O3" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") + STRING(REGEX REPLACE "-O2" "-O3" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}") ENDIF() IF(CMAKE_COMPILER_IS_GNUCXX) SET(COMMON_CXX_FLAGS "-g -fno-omit-frame-pointer -fno-strict-aliasing -Wno-uninitialized") - SET(CMAKE_CXX_FLAGS_DEBUG "-O ${COMMON_CXX_FLAGS}") - SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 ${COMMON_CXX_FLAGS}") + STRING(APPEND CMAKE_CXX_FLAGS_DEBUG " ${COMMON_CXX_FLAGS}") + STRING(APPEND CMAKE_CXX_FLAGS_RELEASE " ${COMMON_CXX_FLAGS}") + STRING(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " ${COMMON_CXX_FLAGS}") + # MariaDB uses -O3 for release builds + STRING(REGEX REPLACE "-O2" "-O3" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") + STRING(REGEX REPLACE "-O2" "-O3" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") ENDIF() # IBM Z flags IF(CMAKE_SYSTEM_PROCESSOR MATCHES "s390x") IF(RPM MATCHES "(rhel|centos)6" OR RPM MATCHES "(suse|sles)11") - SET(z_flags "-funroll-loops -march=z9-109 -mtune=z10 ") + SET(z_flags "-funroll-loops -march=z9-109 -mtune=z10") ELSEIF(RPM MATCHES "(rhel|centos)7" OR RPM MATCHES "(suse|sles)12") - SET(z_flags "-funroll-loops -march=z196 -mtune=zEC12 ") + SET(z_flags "-funroll-loops -march=z196 -mtune=zEC12") ELSE() SET(z_flags "") ENDIF() IF(CMAKE_COMPILER_IS_GNUCC) - SET(CMAKE_C_FLAGS_RELWITHDEBINFO "${z_flags}${CMAKE_C_FLAGS_RELWITHDEBINFO}") + STRING(APPEND CMAKE_C_FLAGS_RELEASE " ${z_flags}") + STRING(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO " ${z_flags}") ENDIF() IF(CMAKE_COMPILER_IS_GNUCXX) - SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${z_flags}${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + STRING(APPEND CMAKE_CXX_FLAGS_RELEASE " ${z_flags}") + STRING(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " ${z_flags}") ENDIF() UNSET(z_flags) ENDIF() @@ -221,11 +231,13 @@ IF(UNIX) IF(CMAKE_SYSTEM_PROCESSOR MATCHES "ia64") SET(COMMON_C_FLAGS "+DSitanium2 -mt -AC99") SET(COMMON_CXX_FLAGS "+DSitanium2 -mt -Aa") - SET(CMAKE_C_FLAGS_DEBUG "+O0 -g ${COMMON_C_FLAGS}") - SET(CMAKE_CXX_FLAGS_DEBUG "+O0 -g ${COMMON_CXX_FLAGS}") - # We have seen compiler bugs with optimisation and -g, so disabled for now - SET(CMAKE_C_FLAGS_RELWITHDEBINFO "+O2 ${COMMON_C_FLAGS}") - SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "+O2 ${COMMON_CXX_FLAGS}") + STRING(APPEND CMAKE_C_FLAGS_DEBUG " +O0 -g ${COMMON_C_FLAGS}") + STRING(APPEND CMAKE_CXX_FLAGS_DEBUG " +O0 -g ${COMMON_CXX_FLAGS}") + STRING(APPEND CMAKE_C_FLAGS_RELEASE " +O0 -g ${COMMON_C_FLAGS}") + STRING(APPEND CMAKE_CXX_FLAGS_RELEASE " +O0 -g ${COMMON_CXX_FLAGS}") + # We have seen compiler bugs with optimisation and -g, so disabled for now + STRING(APPEND CMAKE_C_FLAGS_RELEASE " +O2 ${COMMON_C_FLAGS}") + STRING(APPEND CMAKE_CXX_FLAGS_RELEASE " +O2 ${COMMON_CXX_FLAGS}") ENDIF() ENDIF() SET(WITH_SSL no) @@ -240,10 +252,18 @@ IF(UNIX) SET(COMMON_C_FLAGS "${COMMON_C_FLAGS} -no-ftz -no-prefetch") SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} -no-ftz -no-prefetch") ENDIF() - SET(CMAKE_C_FLAGS_DEBUG "${COMMON_C_FLAGS}") - SET(CMAKE_CXX_FLAGS_DEBUG "${COMMON_CXX_FLAGS}") - SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 -unroll2 -ip ${COMMON_C_FLAGS}") - SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -unroll2 -ip ${COMMON_CXX_FLAGS}") + STRING(APPEND CMAKE_C_FLAGS_DEBUG " ${COMMON_C_FLAGS}") + STRING(APPEND CMAKE_CXX_FLAGS_DEBUG " ${COMMON_CXX_FLAGS}") + STRING(APPEND CMAKE_C_FLAGS_RELEASE " -unroll2 -ip ${COMMON_C_FLAGS}") + STRING(APPEND CMAKE_CXX_FLAGS_RELEASE " -unroll2 -ip ${COMMON_CXX_FLAGS}") + STRING(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO " -unroll2 -ip ${COMMON_C_FLAGS}") + STRING(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " -unroll2 -ip ${COMMON_CXX_FLAGS}") + + # MariaDB uses -O3 for release builds. + STRING(REGEX REPLACE "-O2" "-O3" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") + STRING(REGEX REPLACE "-O2" "-O3" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") + STRING(REGEX REPLACE "-O2" "-O3" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}") + STRING(REGEX REPLACE "-O2" "-O3" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") SET(WITH_SSL no) ENDIF() ENDIF() @@ -251,13 +271,21 @@ IF(UNIX) # Default Clang flags IF(CMAKE_C_COMPILER_ID MATCHES "Clang") SET(COMMON_C_FLAGS "-g -fno-omit-frame-pointer -fno-strict-aliasing -Wno-parentheses-equality -Wno-string-plus-int") - SET(CMAKE_C_FLAGS_DEBUG "${COMMON_C_FLAGS}") - SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 ${COMMON_C_FLAGS}") + STRING(APPEND CMAKE_C_FLAGS_DEBUG " ${COMMON_C_FLAGS}") + STRING(APPEND CMAKE_C_FLAGS_RELEASE " ${COMMON_C_FLAGS}") + STRING(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO " ${COMMON_C_FLAGS}") + # MariaDB uses -O3 for release builds. + STRING(REGEX REPLACE "-O2" "-O3" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") + STRING(REGEX REPLACE "-O2" "-O3" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}") ENDIF() IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang") SET(COMMON_CXX_FLAGS "-g -fno-omit-frame-pointer -fno-strict-aliasing -Wno-parentheses-equality -Wno-string-plus-int") - SET(CMAKE_CXX_FLAGS_DEBUG "${COMMON_CXX_FLAGS}") - SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 ${COMMON_CXX_FLAGS}") + STRING(APPEND CMAKE_CXX_FLAGS_DEBUG " ${COMMON_CXX_FLAGS}") + STRING(APPEND CMAKE_CXX_FLAGS_RELEASE " ${COMMON_CXX_FLAGS}") + STRING(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " ${COMMON_CXX_FLAGS}") + # MariaDB uses -O3 for release builds. + STRING(REGEX REPLACE "-O2" "-O3" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") + STRING(REGEX REPLACE "-O2" "-O3" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") ENDIF() # Solaris flags @@ -270,27 +298,33 @@ IF(UNIX) IF(CMAKE_SYSTEM_PROCESSOR MATCHES "i386") SET(COMMON_C_FLAGS "-g -mt -fsimple=1 -ftrap=%none -nofstore -xbuiltin=%all -xlibmil -xlibmopt -xtarget=generic") SET(COMMON_CXX_FLAGS "-g0 -mt -fsimple=1 -ftrap=%none -nofstore -xbuiltin=%all -features=no%except -xlibmil -xlibmopt -xtarget=generic") - SET(CMAKE_C_FLAGS_DEBUG "-xO1 ${COMMON_C_FLAGS}") - SET(CMAKE_CXX_FLAGS_DEBUG "-xO1 ${COMMON_CXX_FLAGS}") + STRING(APPEND CMAKE_C_FLAGS_DEBUG " -xO1 ${COMMON_C_FLAGS}") + STRING(APPEND CMAKE_CXX_FLAGS_DEBUG " -xO1 ${COMMON_CXX_FLAGS}") IF(32BIT) - SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-xO2 ${COMMON_C_FLAGS}") - SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-xO2 ${COMMON_CXX_FLAGS}") + STRING(APPEND CMAKE_C_FLAGS_RELEASE " -xO2 ${COMMON_C_FLAGS}") + STRING(APPEND CMAKE_CXX_FLAGS_RELEASE " -xO2 ${COMMON_CXX_FLAGS}") + STRING(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO " -xO2 ${COMMON_C_FLAGS}") + STRING(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " -xO2 ${COMMON_CXX_FLAGS}") ELSEIF(64BIT) - SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-xO3 ${COMMON_C_FLAGS}") - SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-xO3 ${COMMON_CXX_FLAGS}") + STRING(APPEND CMAKE_C_FLAGS_RELEASE " -xO3 ${COMMON_C_FLAGS}") + STRING(APPEND CMAKE_CXX_FLAGS_RELEASE " -xO3 ${COMMON_CXX_FLAGS}") + STRING(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO " -xO3 ${COMMON_C_FLAGS}") + STRING(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " -xO3 ${COMMON_CXX_FLAGS}") ENDIF() - ELSE() + ELSE() # Assume !x86 is SPARC SET(COMMON_C_FLAGS "-g -Xa -xstrconst -mt") SET(COMMON_CXX_FLAGS "-g0 -noex -mt") IF(32BIT) - SET(COMMON_C_FLAGS "${COMMON_C_FLAGS} -xarch=sparc") - SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} -xarch=sparc") - ENDIF() - SET(CMAKE_C_FLAGS_DEBUG "${COMMON_C_FLAGS}") - SET(CMAKE_CXX_FLAGS_DEBUG "${COMMON_CXX_FLAGS}") - SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-xO3 ${COMMON_C_FLAGS}") - SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-xO3 ${COMMON_CXX_FLAGS}") + STRING(APPEND COMMON_C_FLAGS " -xarch=sparc") + STRING(APPEND COMMON_CXX_FLAGS " -xarch=sparc") + ENDIF() + STRING(APPEND CMAKE_C_FLAGS_DEBUG " ${COMMON_C_FLAGS}") + STRING(APPEND CMAKE_CXX_FLAGS_DEBUG " ${COMMON_CXX_FLAGS}") + STRING(APPEND CMAKE_C_FLAGS_RELEASE " -xO3 ${COMMON_C_FLAGS}") + STRING(APPEND CMAKE_CXX_FLAGS_RELEASE " -xO3 ${COMMON_CXX_FLAGS}") + STRING(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO " -xO3 ${COMMON_C_FLAGS}") + STRING(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " -xO3 ${COMMON_CXX_FLAGS}") ENDIF() ENDIF() ENDIF() diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 7a3df5cf125..9a1c5edd43f 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -618,14 +618,14 @@ public: { ut_ad(!mutex_is_owner()); mutex.wr_lock(); - ut_d(assert(!mutex_owner.exchange(pthread_self(), - std::memory_order_relaxed))); + assert(!mutex_owner.exchange(pthread_self(), + std::memory_order_relaxed)); } /** Release the mutex */ void mutex_unlock() { - ut_d(assert(mutex_owner.exchange(0, std::memory_order_relaxed) == - pthread_self())); + assert(mutex_owner.exchange(0, std::memory_order_relaxed) == + pthread_self()); mutex.wr_unlock(); } #ifndef SUX_LOCK_GENERIC From f014d5872b0a6876d9bfa2f9080bb7ed0c635cd3 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 9 Jan 2025 17:32:44 +1100 Subject: [PATCH 028/213] MDEV-35554 call to function show_binlog_space_total() through pointer to incorrect function type. The argument is void* rather than char*. This shows up with UBSAN testing under clang. --- sql/mysqld.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d575ed1aaa8..980eaedfd5b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -7372,7 +7372,7 @@ static int show_max_memory_used(THD *thd, SHOW_VAR *var, void *buff, } -static int show_binlog_space_total(THD *thd, SHOW_VAR *var, char *buff, +static int show_binlog_space_total(THD *thd, SHOW_VAR *var, void *buff, struct system_status_var *status_var, enum enum_var_type scope) { From f60a8a680e717a53d78e873f29f7d70f8e60635e Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 9 Jan 2025 17:27:29 +1100 Subject: [PATCH 029/213] MDEV-35554 runtime error: call to function show_cached_thread_count() through pointer to incorrect function type. The argument is void* rather than char* and was missing system_status_var * as an argument. This shows up with UBSAN testing under clang. Reviewer: Brandon Nesterenko --- sql/mysqld.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c48f94e6601..c798956910f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -7363,8 +7363,8 @@ static int show_threadpool_threads(THD *, SHOW_VAR *var, void *buff, #endif -static int show_cached_thread_count(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +static int show_cached_thread_count(THD *thd, SHOW_VAR *var, void *buff, + system_status_var *, enum enum_var_type scope) { var->type= SHOW_LONG; var->value= buff; From d7f27d717287a385bc73a5d5950cc22f957fc152 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 9 Jan 2025 18:15:41 +1100 Subject: [PATCH 030/213] MDEV-33158: UBSAN via MYSQL_THDVAR_U{INT,LONG{,LONG}} In plugins, use the correct resolver for ULONG and ULONGLONG types. InnoDB has a UINT type as evidenced by "Unknown variable type code 0x182 in plugin 'InnoDB'." so the implementation for UNSIGNED INT was added. Any InnoDB mtr test that changes lock_wait_timeout, spider_param_force_commit and some MyRocks unsigned thread server variables can verify this change is correct. Reviewer: Brandon Nesterenko --- sql/sql_plugin.cc | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 56c7b3332a2..360dc650334 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -3227,6 +3227,11 @@ static int *mysql_sys_var_int(THD* thd, int offset) return (int *) intern_sys_var_ptr(thd, offset, true); } +static unsigned int *mysql_sys_var_uint(THD* thd, int offset) +{ + return (unsigned int *) intern_sys_var_ptr(thd, offset, true); +} + static long *mysql_sys_var_long(THD* thd, int offset) { return (long *) intern_sys_var_ptr(thd, offset, true); @@ -3897,19 +3902,28 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp, continue; if (!(register_var(plugin_name_ptr, opt->name, opt->flags))) continue; - switch (opt->flags & PLUGIN_VAR_TYPEMASK) { + switch (opt->flags & (PLUGIN_VAR_TYPEMASK | PLUGIN_VAR_UNSIGNED)) { case PLUGIN_VAR_BOOL: ((thdvar_bool_t *) opt)->resolve= mysql_sys_var_char; break; case PLUGIN_VAR_INT: ((thdvar_int_t *) opt)->resolve= mysql_sys_var_int; break; + case PLUGIN_VAR_INT | PLUGIN_VAR_UNSIGNED: + ((thdvar_uint_t *) opt)->resolve= mysql_sys_var_uint; + break; case PLUGIN_VAR_LONG: ((thdvar_long_t *) opt)->resolve= mysql_sys_var_long; break; + case PLUGIN_VAR_LONG | PLUGIN_VAR_UNSIGNED: + ((thdvar_ulong_t *) opt)->resolve= mysql_sys_var_ulong; + break; case PLUGIN_VAR_LONGLONG: ((thdvar_longlong_t *) opt)->resolve= mysql_sys_var_longlong; break; + case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED: + ((thdvar_ulonglong_t *) opt)->resolve= mysql_sys_var_ulonglong; + break; case PLUGIN_VAR_STR: ((thdvar_str_t *) opt)->resolve= mysql_sys_var_str; break; From c3fd0f189a512b8775b72f2b3622bf7bea3a90aa Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sun, 12 Jan 2025 12:33:34 +1100 Subject: [PATCH 031/213] MDEV-33158: UBSAN - plugin.cc partial move to C++ casts There were too many C casts rather than C++ casts here. Started a partial conversion covering within-file scoped changes. Suggested by Brandon Nesterenko --- sql/sql_plugin.cc | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 360dc650334..b773c8ec954 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -3186,14 +3186,14 @@ void sync_dynamic_session_variables(THD* thd, bool global_lock) If required, will sync with global variables if the requested variable has not yet been allocated in the current thread. */ -static uchar *intern_sys_var_ptr(THD* thd, int offset, bool global_lock) +static void *intern_sys_var_ptr(THD* thd, int offset, bool global_lock) { DBUG_ENTER("intern_sys_var_ptr"); DBUG_ASSERT(offset >= 0); DBUG_ASSERT((uint)offset <= global_system_variables.dynamic_variables_head); if (!thd) - DBUG_RETURN((uchar*) global_system_variables.dynamic_variables_ptr + offset); + DBUG_RETURN(global_system_variables.dynamic_variables_ptr + offset); /* dynamic_variables_head points to the largest valid offset @@ -3205,7 +3205,7 @@ static uchar *intern_sys_var_ptr(THD* thd, int offset, bool global_lock) sync_dynamic_session_variables(thd, global_lock); mysql_prlock_unlock(&LOCK_system_variables_hash); } - DBUG_RETURN((uchar*)thd->variables.dynamic_variables_ptr + offset); + DBUG_RETURN(thd->variables.dynamic_variables_ptr + offset); } @@ -3219,47 +3219,47 @@ static uchar *intern_sys_var_ptr(THD* thd, int offset, bool global_lock) static char *mysql_sys_var_char(THD* thd, int offset) { - return (char *) intern_sys_var_ptr(thd, offset, true); + return static_cast(intern_sys_var_ptr(thd, offset, true)); } static int *mysql_sys_var_int(THD* thd, int offset) { - return (int *) intern_sys_var_ptr(thd, offset, true); + return static_cast(intern_sys_var_ptr(thd, offset, true)); } static unsigned int *mysql_sys_var_uint(THD* thd, int offset) { - return (unsigned int *) intern_sys_var_ptr(thd, offset, true); + return static_cast(intern_sys_var_ptr(thd, offset, true)); } static long *mysql_sys_var_long(THD* thd, int offset) { - return (long *) intern_sys_var_ptr(thd, offset, true); + return static_cast(intern_sys_var_ptr(thd, offset, true)); } static unsigned long *mysql_sys_var_ulong(THD* thd, int offset) { - return (unsigned long *) intern_sys_var_ptr(thd, offset, true); + return static_cast(intern_sys_var_ptr(thd, offset, true)); } static long long *mysql_sys_var_longlong(THD* thd, int offset) { - return (long long *) intern_sys_var_ptr(thd, offset, true); + return static_cast(intern_sys_var_ptr(thd, offset, true)); } static unsigned long long *mysql_sys_var_ulonglong(THD* thd, int offset) { - return (unsigned long long *) intern_sys_var_ptr(thd, offset, true); + return static_cast(intern_sys_var_ptr(thd, offset, true)); } static char **mysql_sys_var_str(THD* thd, int offset) { - return (char **) intern_sys_var_ptr(thd, offset, true); + return static_cast(intern_sys_var_ptr(thd, offset, true)); } static double *mysql_sys_var_double(THD* thd, int offset) { - return (double *) intern_sys_var_ptr(thd, offset, true); + return static_cast(intern_sys_var_ptr(thd, offset, true)); } void plugin_thdvar_init(THD *thd) @@ -3520,7 +3520,7 @@ uchar* sys_var_pluginvar::real_value_ptr(THD *thd, enum_var_type type) const if (type == OPT_GLOBAL) thd= NULL; - return intern_sys_var_ptr(thd, *(int*) (plugin_var+1), false); + return (uchar*) intern_sys_var_ptr(thd, *(int*) (plugin_var+1), false); } return *(uchar**) (plugin_var+1); } @@ -3529,8 +3529,8 @@ uchar* sys_var_pluginvar::real_value_ptr(THD *thd, enum_var_type type) const bool sys_var_pluginvar::session_is_default(THD *thd) { uchar *value= plugin_var->flags & PLUGIN_VAR_THDLOCAL - ? intern_sys_var_ptr(thd, *(int*) (plugin_var+1), true) - : *(uchar**) (plugin_var+1); + ? static_cast(intern_sys_var_ptr(thd, *(int*) (plugin_var+1), true)) + : *reinterpret_cast(plugin_var+1); real_value_ptr(thd, OPT_SESSION); @@ -3772,27 +3772,27 @@ void plugin_opt_set_limits(struct my_option *options, break; case PLUGIN_VAR_ENUM | PLUGIN_VAR_THDLOCAL: options->var_type= GET_ENUM; - options->typelib= ((thdvar_enum_t*) opt)->typelib; - options->def_value= ((thdvar_enum_t*) opt)->def_val; + options->typelib= reinterpret_cast(opt)->typelib; + options->def_value= reinterpret_cast(opt)->def_val; options->min_value= options->block_size= 0; options->max_value= options->typelib->count - 1; break; case PLUGIN_VAR_SET | PLUGIN_VAR_THDLOCAL: options->var_type= GET_SET; - options->typelib= ((thdvar_set_t*) opt)->typelib; - options->def_value= ((thdvar_set_t*) opt)->def_val; + options->typelib= reinterpret_cast(opt)->typelib; + options->def_value= reinterpret_cast(opt)->def_val; options->min_value= options->block_size= 0; options->max_value= (1ULL << options->typelib->count) - 1; break; case PLUGIN_VAR_BOOL | PLUGIN_VAR_THDLOCAL: options->var_type= GET_BOOL; - options->def_value= ((thdvar_bool_t*) opt)->def_val; + options->def_value= reinterpret_cast(opt)->def_val; options->typelib= &bool_typelib; break; case PLUGIN_VAR_STR | PLUGIN_VAR_THDLOCAL: options->var_type= ((opt->flags & PLUGIN_VAR_MEMALLOC) ? GET_STR_ALLOC : GET_STR); - options->def_value= (intptr) ((thdvar_str_t*) opt)->def_val; + options->def_value= reinterpret_cast(reinterpret_cast(opt)->def_val); break; default: DBUG_ASSERT(0); @@ -3831,7 +3831,7 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp, size_t plugin_name_len= strlen(plugin_name); size_t optnamelen; const int max_comment_len= 255; - char *comment= (char *) alloc_root(mem_root, max_comment_len + 1); + char *comment= static_cast(alloc_root(mem_root, max_comment_len + 1)); char *optname; int index= 0, UNINIT_VAR(offset); @@ -3843,7 +3843,7 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp, DBUG_ENTER("construct_options"); - plugin_name_ptr= (char*) alloc_root(mem_root, plugin_name_len + 1); + plugin_name_ptr= static_cast(alloc_root(mem_root, plugin_name_len + 1)); safe_strcpy(plugin_name_ptr, plugin_name_len + 1, plugin_name); my_casedn_str(&my_charset_latin1, plugin_name_ptr); convert_underscore_to_dash(plugin_name_ptr, plugin_name_len); From cb26d41d8129b156e5ad4b0344790bd802a722c9 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 10 Jan 2025 12:59:01 +1100 Subject: [PATCH 032/213] MDEV-35735: UBSAN: spider udf functions mismatch with UDF defination The mismatch occurs on the function calls as in the sql/sql_udf.h the types of "error" and "is_null" are unsigned char rather than char. This is corrected for the udf functions: * spider_direct_sql * spider_direct_bg_sql * spider_flush_table_mon_cache * spider_copy_tables * spider_ping_table Reviewer: Yuchen Pei --- storage/spider/spd_copy_tables.cc | 4 ++-- storage/spider/spd_direct_sql.cc | 4 ++-- storage/spider/spd_ping_table.cc | 4 ++-- storage/spider/spd_udf.cc | 28 ++++++++++++++-------------- storage/spider/spd_udf.h | 12 ++++++------ 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/storage/spider/spd_copy_tables.cc b/storage/spider/spd_copy_tables.cc index 4c361df0562..d9cf32b3923 100644 --- a/storage/spider/spd_copy_tables.cc +++ b/storage/spider/spd_copy_tables.cc @@ -714,8 +714,8 @@ int spider_udf_bg_copy_exec_sql( long long spider_copy_tables_body( UDF_INIT *initid, UDF_ARGS *args, - char *is_null, - char *error + unsigned char *is_null, + unsigned char *error ) { int error_num, roop_count, all_link_cnt = 0, use_table_charset; SPIDER_COPY_TABLES *copy_tables = NULL; diff --git a/storage/spider/spd_direct_sql.cc b/storage/spider/spd_direct_sql.cc index 7c7f9aa7558..5aabb5c07fc 100644 --- a/storage/spider/spd_direct_sql.cc +++ b/storage/spider/spd_direct_sql.cc @@ -1225,8 +1225,8 @@ void spider_udf_free_direct_sql_alloc( long long spider_direct_sql_body( UDF_INIT *initid, UDF_ARGS *args, - char *is_null, - char *error, + unsigned char *is_null, + unsigned char *error, my_bool bg ) { int error_num, roop_count; diff --git a/storage/spider/spd_ping_table.cc b/storage/spider/spd_ping_table.cc index 2795f8a3bb6..8e4f8a2214b 100644 --- a/storage/spider/spd_ping_table.cc +++ b/storage/spider/spd_ping_table.cc @@ -1071,8 +1071,8 @@ int spider_ping_table_cache_compare( long long spider_ping_table_body( UDF_INIT *initid, UDF_ARGS *args, - char *is_null, - char *error + unsigned char *is_null, + unsigned char *error ) { int error_num = 0, link_idx, flags, full_mon_count, current_mon_count, success_count, fault_count, tmp_error_num = 0; diff --git a/storage/spider/spd_udf.cc b/storage/spider/spd_udf.cc index 023285cb4f1..fc7ca93c85b 100644 --- a/storage/spider/spd_udf.cc +++ b/storage/spider/spd_udf.cc @@ -22,8 +22,8 @@ extern "C" { long long spider_direct_sql( UDF_INIT *initid, UDF_ARGS *args, - char *is_null, - char *error + unsigned char *is_null, + unsigned char *error ) { return spider_direct_sql_body(initid, args, is_null, error, FALSE); } @@ -46,8 +46,8 @@ void spider_direct_sql_deinit( long long spider_bg_direct_sql( UDF_INIT *initid, UDF_ARGS *args, - char *is_null, - char *error + unsigned char *is_null, + unsigned char *error ) { return spider_direct_sql_bg_end(initid); } @@ -68,8 +68,8 @@ void spider_bg_direct_sql_deinit( void spider_bg_direct_sql_clear( UDF_INIT *initid, - char *is_null, - char *error + unsigned char *is_null, + unsigned char *error ) { spider_direct_sql_bg_start(initid); } @@ -77,8 +77,8 @@ void spider_bg_direct_sql_clear( void spider_bg_direct_sql_add( UDF_INIT *initid, UDF_ARGS *args, - char *is_null, - char *error + unsigned char *is_null, + unsigned char *error ) { spider_direct_sql_body(initid, args, is_null, error, TRUE); } @@ -87,8 +87,8 @@ void spider_bg_direct_sql_add( long long spider_ping_table( UDF_INIT *initid, UDF_ARGS *args, - char *is_null, - char *error + unsigned char *is_null, + unsigned char *error ) { return spider_ping_table_body(initid, args, is_null, error); } @@ -110,8 +110,8 @@ void spider_ping_table_deinit( long long spider_flush_table_mon_cache( UDF_INIT *initid, UDF_ARGS *args, - char *is_null, - char *error + unsigned char *is_null, + unsigned char *error ) { return spider_flush_table_mon_cache_body(); } @@ -132,8 +132,8 @@ void spider_flush_table_mon_cache_deinit( long long spider_copy_tables( UDF_INIT *initid, UDF_ARGS *args, - char *is_null, - char *error + unsigned char *is_null, + unsigned char *error ) { return spider_copy_tables_body(initid, args, is_null, error); } diff --git a/storage/spider/spd_udf.h b/storage/spider/spd_udf.h index d00a6151894..a297640d945 100644 --- a/storage/spider/spd_udf.h +++ b/storage/spider/spd_udf.h @@ -16,8 +16,8 @@ long long spider_direct_sql_body( UDF_INIT *initid, UDF_ARGS *args, - char *is_null, - char *error, + unsigned char *is_null, + unsigned char *error, my_bool bg ); @@ -45,8 +45,8 @@ long long spider_direct_sql_bg_end( long long spider_ping_table_body( UDF_INIT *initid, UDF_ARGS *args, - char *is_null, - char *error + unsigned char *is_null, + unsigned char *error ); my_bool spider_ping_table_init_body( @@ -64,8 +64,8 @@ long long spider_flush_table_mon_cache_body(); long long spider_copy_tables_body( UDF_INIT *initid, UDF_ARGS *args, - char *is_null, - char *error + unsigned char *is_null, + unsigned char *error ); my_bool spider_copy_tables_init_body( From f361ad75b33ca44773483e212cfd7bf5144df31d Mon Sep 17 00:00:00 2001 From: ParadoxV5 Date: Thu, 9 Jan 2025 17:33:47 -0700 Subject: [PATCH 033/213] MDEV-35431: fix InnoDB flags error size specifier This came after I prepared #3518. --- storage/innobase/fsp/fsp0file.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/fsp/fsp0file.cc b/storage/innobase/fsp/fsp0file.cc index bae862f1ce2..63cbc2babd7 100644 --- a/storage/innobase/fsp/fsp0file.cc +++ b/storage/innobase/fsp/fsp0file.cc @@ -253,7 +253,7 @@ dberr_t Datafile::read_first_page_flags(const page_t *page) noexcept if (cflags == UINT32_MAX) switch (fsp_flags_is_incompatible_mysql(m_flags)) { case 0: - sql_print_error("InnoDB: Invalid flags 0x%zx in %s", + sql_print_error("InnoDB: Invalid flags 0x%" PRIx32 " in %s", m_flags, m_filepath); return DB_CORRUPTION; case 3: From 6e86fe006399ca7f0a67cc5d4e0b9cfcf3cf63bb Mon Sep 17 00:00:00 2001 From: Xiaochuan Cui Date: Fri, 29 Nov 2024 13:52:19 -0800 Subject: [PATCH 034/213] MDEV-35528: mariadb-binlog cannot process more than 1 logfiles when --stop-datetime is specified Fix regression introduced by commits 9588526 which attempted to address MDEV-27037. With the regression, mariadb-binlog cannot process multiple log files when --stop-datetime is specified. The change is to keep recording timestamp of last processed event, and after all log files are processed, if the last recorded timestamp has not reached specified --stop-datetime, it will emit a warning. This applies when processing local log files, or log files from remote servers. All new code of the whole pull request, including one or several files that are either new files or modified ones, are contributed under the BSD-new license. I am contributing on behalf of my employer Amazon Web Services, Inc. Co-authored-by: Brandon Nesterenko Reviewed-by: Brandon Nesterenko --- client/mysqlbinlog.cc | 23 ++- ...nlog_mysqlbinlog_warn_stop_datetime.result | 136 +++++++++++++++--- ...nlog_mysqlbinlog_warn_stop_position.result | 76 ++++++++-- .../binlog_mysqlbinlog_warn_stop_datetime.inc | 106 ++++++++++++++ ...binlog_mysqlbinlog_warn_stop_datetime.test | 108 +++++++++----- .../binlog_mysqlbinlog_warn_stop_position.inc | 115 +++++++++++++++ ...binlog_mysqlbinlog_warn_stop_position.test | 93 +++++++++--- 7 files changed, 559 insertions(+), 98 deletions(-) create mode 100644 mysql-test/suite/binlog/t/binlog_mysqlbinlog_warn_stop_datetime.inc create mode 100644 mysql-test/suite/binlog/t/binlog_mysqlbinlog_warn_stop_position.inc diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 5762e3965b5..8e3ce812993 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -148,6 +148,8 @@ static const longlong stop_position_default= (longlong)(~(my_off_t)0); static char *start_datetime_str, *stop_datetime_str; static my_time_t start_datetime= 0, stop_datetime= MY_TIME_T_MAX; +static my_time_t last_processed_datetime= MY_TIME_T_MAX; + static ulonglong rec_count= 0; static MYSQL* mysql = NULL; static const char* dirname_for_local_load= 0; @@ -1011,6 +1013,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, DBUG_ENTER("process_event"); Exit_status retval= OK_CONTINUE; IO_CACHE *const head= &print_event_info->head_cache; + my_time_t ev_when= ev->when; /* Bypass flashback settings to event */ ev->is_flashback= opt_flashback; @@ -1458,6 +1461,7 @@ err: retval= ERROR_STOP; end: rec_count++; + last_processed_datetime= ev_when; DBUG_PRINT("info", ("end event processing")); /* @@ -2847,7 +2851,6 @@ static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, IO_CACHE cache,*file= &cache; uchar tmp_buff[BIN_LOG_HEADER_SIZE]; Exit_status retval= OK_CONTINUE; - my_time_t last_ev_when= MY_TIME_T_MAX; if (logname && strcmp(logname, "-") != 0) { @@ -2953,21 +2956,8 @@ static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, "end of input", stop_position); } - /* - Emit a warning in the event that we finished processing input - before reaching the boundary indicated by --stop-datetime. - */ - if (stop_datetime != MY_TIME_T_MAX && - stop_datetime > last_ev_when) - { - retval = OK_STOP; - warning("Did not reach stop datetime '%s' " - "before end of input", stop_datetime_str); - } - goto end; } - last_ev_when= ev->when; if ((retval= process_event(print_event_info, ev, old_off, logname)) != OK_CONTINUE) goto end; @@ -3143,6 +3133,11 @@ int main(int argc, char** argv) start_position= BIN_LOG_HEADER_SIZE; } + if (stop_datetime != MY_TIME_T_MAX && + stop_datetime > last_processed_datetime) + warning("Did not reach stop datetime '%s' before end of input", + stop_datetime_str); + /* If enable flashback, need to print the events from the end to the beginning diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_warn_stop_datetime.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_warn_stop_datetime.result index 6ce0f2d63e5..88a3c6cc8ac 100644 --- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_warn_stop_datetime.result +++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_warn_stop_datetime.result @@ -1,23 +1,115 @@ - -# MDEV-27037 mysqlbinlog emits a warning when reaching EOF before stop-datetime - -set timestamp=1000000000; -CREATE TABLE t1(word VARCHAR(20)); -set timestamp=1000000010; -INSERT INTO t1 VALUES ("abirvalg"); -set timestamp=1000000020; -INSERT INTO t1 SELECT * FROM t1; -flush logs; -Case: Default, must not see warning. -# MYSQL_BINLOG --short-form MYSQLD_DATADIR/master-bin.000001 --result-file=ignored_output_file -Case: Stop datetime before EOF, must not see warning. -# MYSQL_BINLOG --short-form --stop-datetime='2001-09-08 21:46:50' MYSQLD_DATADIR/master-bin.000001 --result-file=ignored_output_file -Case: Stop datetime between records, must not see warning. -# MYSQL_BINLOG --short-form --stop-datetime='2001-09-08 21:46:55' MYSQLD_DATADIR/master-bin.000001 --result-file=ignored_output_file -Case: Stop datetime at EOF, must not see warning. -# MYSQL_BINLOG --short-form --stop-datetime='2001-09-08 21:46:55' MYSQLD_DATADIR/master-bin.000001 --result-file=ignored_output_file -Case: Stop datetime after EOF, must see warning. -# MYSQL_BINLOG --short-form --stop-datetime='2035-01-19 03:14:05' MYSQLD_DATADIR/master-bin.000001 --result-file=ignored_output_file -WARNING: Did not reach stop datetime '2035-01-19 03:14:05' before end of input -DROP TABLE t1; +SET TIMESTAMP= UNIX_TIMESTAMP('2024-12-01 10:20:30.123456'); +# +# Clear the existing binary log state, and start fresh using +# the timestamp variable set above +# +RESET MASTER; +create table t1 (a int); +insert into t1 values (1); +SET TIMESTAMP= UNIX_TIMESTAMP('2024-12-02 10:20:30.123456'); +insert into t1 values (2); +SET TIMESTAMP= UNIX_TIMESTAMP('2024-12-03 10:20:30.123456'); +flush binary logs; +SET TIMESTAMP= UNIX_TIMESTAMP('2024-12-04 10:20:30.123456'); +insert into t1 values (3); +insert into t1 values (4); +SET TIMESTAMP= UNIX_TIMESTAMP('2024-12-05 10:20:30.123456'); +insert into t1 values (5); +insert into t1 values (6); +insert into t1 values (7); +SET TIMESTAMP=UNIX_TIMESTAMP('2024-12-06 10:20:30.123456'); +flush binary logs; +drop table t1; +# Ensuring binary log order is correct +# +# +# Test using --read-from-remote-server +# +connection default; +# +# --stop-datetime tests +# Note: MDEV-35528 reported that mysqlbinlog would fail on tests cases +# 2.a, 2.b, and 2.c. +# +# Case 1.a) With one binlog file, a --stop-datetime before the end of +# the file should not result in a warning +# MYSQL_BINLOG --read-from-remote-server --stop-datetime='2024-12-02 10:20:30.123456' binlog_f1_full --result-file=tmp/warn_datetime_test_file.out 2>&1 +# +# Case 1.b) With one binlog file, a --stop-datetime at the end of the +# file should not result in a warning +# MYSQL_BINLOG --read-from-remote-server --stop-datetime='2024-12-03 10:20:30.123456' binlog_f1_full --result-file=tmp/warn_datetime_test_file.out 2>&1 +# +# Case 1.c) With one binlog file, a --stop-datetime beyond the end of +# the file should(!) result in a warning +# MYSQL_BINLOG --read-from-remote-server --stop-datetime='2024-12-04 10:20:30.123456' binlog_f1_full --result-file=tmp/warn_datetime_test_file.out 2>&1 +WARNING: Did not reach stop datetime '2024-12-04 10:20:30.123456' before end of input +# +# Case 2.a) With two binlog files, a --stop-datetime within the +# timespan of binlog 2 should: +# 1) not provide any warnings +# 2) not prevent binlog 1 or 2 from outputting the desired events +# MYSQL_BINLOG --read-from-remote-server --stop-datetime='2024-12-04 10:20:30.123456' binlog_f1_full binlog_f2_full --result-file=tmp/warn_datetime_test_file.out 2>&1 +include/assert_grep.inc [Ensure all intended GTIDs are present] +include/assert_grep.inc [Ensure the next GTID binlogged is _not_ present] +# +# Case 2.b) With two binlog files, a --stop-datetime at the end of +# binlog 2 should: +# 1) not provide any warnings +# 2) not prevent binlog 1 or 2 from outputting all events +# MYSQL_BINLOG --read-from-remote-server --stop-datetime='2024-12-06 10:20:30.123456' binlog_f1_full binlog_f2_full --result-file=tmp/warn_datetime_test_file.out 2>&1 +include/assert_grep.inc [Ensure a GTID exists for each transaction] +# +# Case 2.c) With two binlog files, a --stop-datetime beyond the end of +# binlog 2 should: +# 1) provide a warning that the stop datetime was not reached +# 2) not prevent binlog 1 or 2 from outputting all events +# MYSQL_BINLOG --read-from-remote-server --stop-datetime='2024-12-07 10:20:30.123456' binlog_f1_full binlog_f2_full --result-file=tmp/warn_datetime_test_file.out 2>&1 +WARNING: Did not reach stop datetime '2024-12-07 10:20:30.123456' before end of input +include/assert_grep.inc [Ensure a GTID exists for each transaction] +# +# +# Test using local binlog files +# +connection default; +# +# --stop-datetime tests +# Note: MDEV-35528 reported that mysqlbinlog would fail on tests cases +# 2.a, 2.b, and 2.c. +# +# Case 1.a) With one binlog file, a --stop-datetime before the end of +# the file should not result in a warning +# MYSQL_BINLOG --stop-datetime='2024-12-02 10:20:30.123456' binlog_f1_full --result-file=tmp/warn_datetime_test_file.out 2>&1 +# +# Case 1.b) With one binlog file, a --stop-datetime at the end of the +# file should not result in a warning +# MYSQL_BINLOG --stop-datetime='2024-12-03 10:20:30.123456' binlog_f1_full --result-file=tmp/warn_datetime_test_file.out 2>&1 +# +# Case 1.c) With one binlog file, a --stop-datetime beyond the end of +# the file should(!) result in a warning +# MYSQL_BINLOG --stop-datetime='2024-12-04 10:20:30.123456' binlog_f1_full --result-file=tmp/warn_datetime_test_file.out 2>&1 +WARNING: Did not reach stop datetime '2024-12-04 10:20:30.123456' before end of input +# +# Case 2.a) With two binlog files, a --stop-datetime within the +# timespan of binlog 2 should: +# 1) not provide any warnings +# 2) not prevent binlog 1 or 2 from outputting the desired events +# MYSQL_BINLOG --stop-datetime='2024-12-04 10:20:30.123456' binlog_f1_full binlog_f2_full --result-file=tmp/warn_datetime_test_file.out 2>&1 +include/assert_grep.inc [Ensure all intended GTIDs are present] +include/assert_grep.inc [Ensure the next GTID binlogged is _not_ present] +# +# Case 2.b) With two binlog files, a --stop-datetime at the end of +# binlog 2 should: +# 1) not provide any warnings +# 2) not prevent binlog 1 or 2 from outputting all events +# MYSQL_BINLOG --stop-datetime='2024-12-06 10:20:30.123456' binlog_f1_full binlog_f2_full --result-file=tmp/warn_datetime_test_file.out 2>&1 +include/assert_grep.inc [Ensure a GTID exists for each transaction] +# +# Case 2.c) With two binlog files, a --stop-datetime beyond the end of +# binlog 2 should: +# 1) provide a warning that the stop datetime was not reached +# 2) not prevent binlog 1 or 2 from outputting all events +# MYSQL_BINLOG --stop-datetime='2024-12-07 10:20:30.123456' binlog_f1_full binlog_f2_full --result-file=tmp/warn_datetime_test_file.out 2>&1 +WARNING: Did not reach stop datetime '2024-12-07 10:20:30.123456' before end of input +include/assert_grep.inc [Ensure a GTID exists for each transaction] +# # End of binlog_mysqlbinlog_warn_stop_datetime.test diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_warn_stop_position.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_warn_stop_position.result index 5b99d30bd84..1517fd765ac 100644 --- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_warn_stop_position.result +++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_warn_stop_position.result @@ -1,13 +1,65 @@ - -# MDEV-27037 mysqlbinlog emits a warning when reaching EOF before stop-condition - -Case: Default stop position, WARNING must not appear -# MYSQL_BINLOG --short-form --start-position=4 mysql-test/std_data/master-bin.000001 --result-file=warn_pos_test_file.out 2>&1 -Case: Stop position before EOF, WARNING must not appear -# MYSQL_BINLOG --short-form --start-position=4 --stop-position=97 mysql-test/std_data/master-bin.000001 --result-file=warn_pos_test_file.out 2>&1 -Case: Stop position at EOF, WARNING must not appear -# MYSQL_BINLOG --short-form --start-position=4 --stop-position=98 mysql-test/std_data/master-bin.000001 --result-file=warn_pos_test_file.out 2>&1 -Case: Stop position after EOF, WARNING must appear -# MYSQL_BINLOG --short-form --start-position=4 --stop-position=99 mysql-test/std_data/master-bin.000001 --result-file=warn_pos_test_file.out 2>&1 -WARNING: Did not reach stop position 99 before end of input +# +# Clear the existing binary log state. +# +RESET MASTER; +create table t1 (a int); +insert into t1 values (1); +insert into t1 values (2); +flush binary logs; +insert into t1 values (3); +# Tag binlog_f2_mid +insert into t1 values (4); +insert into t1 values (5); +insert into t1 values (6); +insert into t1 values (7); +flush binary logs; +drop table t1; +# Ensuring binary log order is correct +# Ensuring file offset of binlog_f2_mid < binlog_f1_end +# +# +# Test using local binlog files +# +connection default; +# +# --stop-position tests +# +# Case 1.a) With one binlog file, a --stop-position before the end of +# the file should not result in a warning +# MYSQL_BINLOG --stop-position=binlog_f1_pre_rotate binlog_f1_full --result-file=tmp/warn_position_test_file.out 2>&1 +# +# Case 1.b) With one binlog file, a --stop-position at the exact end of +# the file should not result in a warning +# MYSQL_BINLOG --stop-position=binlog_f1_end binlog_f1_full --result-file=tmp/warn_position_test_file.out 2>&1 +# +# Case 1.c) With one binlog file, a --stop-position past the end of the +# file should(!) result in a warning +# MYSQL_BINLOG --short-form --stop-position=binlog_f1_over_eof binlog_f1_full --result-file=tmp/warn_position_test_file.out 2>&1 +WARNING: Did not reach stop position before end of input +# +# Case 2.a) With two binlog files, a --stop-position targeting b2 which +# exists in the size of b1 should: +# 1) not provide any warnings +# 2) not prevent b2 from outputting its desired events before the +# stop position +# MYSQL_BINLOG --stop-position=binlog_f2_mid binlog_f1_full binlog_f2_full --result-file=tmp/warn_position_test_file.out 2>&1 +include/assert_grep.inc [Ensure all intended GTIDs are present] +include/assert_grep.inc [Ensure the next GTID binlogged is _not_ present] +# +# Case 2.b) With two binlog files, a --stop-position targeting the end +# of binlog 2 should: +# 1) not provide any warnings +# 2) not prevent b2 from outputting its entire binary log +# MYSQL_BINLOG --stop-position=binlog_f2_end binlog_f1_full binlog_f2_full --result-file=tmp/warn_position_test_file.out 2>&1 +include/assert_grep.inc [Ensure a GTID exists for each transaction] +include/assert_grep.inc [Ensure the last GTID binlogged is present] +# +# Case 2.c) With two binlog files, a --stop-position targeting beyond +# the eof of binlog 2 should: +# 1) provide a warning that the stop position was not reached +# 2) not prevent b2 from outputting its entire binary log +# MYSQL_BINLOG --stop-position=binlog_f2_over_eof binlog_f1_full binlog_f2_full --result-file=tmp/warn_position_test_file.out 2>&1 +WARNING: Did not reach stop position before end of input +include/assert_grep.inc [Ensure a GTID exists for each transaction] +# # End of binlog_mysqlbinlog_warn_stop_position.test diff --git a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_warn_stop_datetime.inc b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_warn_stop_datetime.inc new file mode 100644 index 00000000000..839e506551c --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_warn_stop_datetime.inc @@ -0,0 +1,106 @@ +# +# Helper file that ensures mysqlbinlog --stop-datetime behavior for local +# files or a remote server +# +# Parameters: +# read_from_remote_server (bool): A boolean that changes which source to use +# for mysqlbinlog. When true, reads remotely; when false, uses local files. +# + +--connection default +--let $MYSQLD_DATADIR= `select @@datadir` + +# PARAM_READ_FROM_REMOTE is used as a parameter to mysqlbinlog (_OUT suffix is +# output in echo commands). If using local files, they are blank; if reading +# from remote server, it is overridden to the correct values. +--let $PARAM_READ_FROM_REMOTE= +# Used in echo statements to remove potentially changing values +--let $PARAM_READ_FROM_REMOTE_OUT= + +if ($read_from_remote_server) +{ + --let $PARAM_READ_FROM_REMOTE= --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT + --let $PARAM_READ_FROM_REMOTE_OUT= --read-from-remote-server + # binlog files in --read-from-remote-server don't use file system path + --let $binlog_f1_full= $binlog_f1 + --let $binlog_f2_full= $binlog_f2 +} +if (!$read_from_remote_server) +{ + # If using local files, file system path to the binlog files is needed + --let $binlog_f1_full= $MYSQLD_DATADIR/$binlog_f1 + --let $binlog_f2_full= $MYSQLD_DATADIR/$binlog_f2 +} + +--echo # +--echo # --stop-datetime tests +--echo # Note: MDEV-35528 reported that mysqlbinlog would fail on tests cases +--echo # 2.a, 2.b, and 2.c. +--echo # + +--echo # Case 1.a) With one binlog file, a --stop-datetime before the end of +--echo # the file should not result in a warning +--echo # MYSQL_BINLOG $PARAM_READ_FROM_REMOTE_OUT --stop-datetime='$b1_timestamp2' binlog_f1_full --result-file=$binlog_out_relpath 2>&1 +--exec $MYSQL_BINLOG $PARAM_READ_FROM_REMOTE --stop-datetime='$b1_timestamp2' $binlog_f1_full --result-file=$binlog_out 2>&1 + +--echo # +--echo # Case 1.b) With one binlog file, a --stop-datetime at the end of the +--echo # file should not result in a warning +--echo # MYSQL_BINLOG $PARAM_READ_FROM_REMOTE_OUT --stop-datetime='$b1_timestamp3' binlog_f1_full --result-file=$binlog_out_relpath 2>&1 +--exec $MYSQL_BINLOG $PARAM_READ_FROM_REMOTE --stop-datetime='$b1_timestamp3' $binlog_f1_full --result-file=$binlog_out 2>&1 + +--echo # +--echo # Case 1.c) With one binlog file, a --stop-datetime beyond the end of +--echo # the file should(!) result in a warning +--let $future_timestamp= 2035-12-06 10:20:30.123456 +--echo # MYSQL_BINLOG $PARAM_READ_FROM_REMOTE_OUT --stop-datetime='$b2_timestamp1' binlog_f1_full --result-file=$binlog_out_relpath 2>&1 +--exec $MYSQL_BINLOG $PARAM_READ_FROM_REMOTE --stop-datetime='$b2_timestamp1' $binlog_f1_full --result-file=$binlog_out 2>&1 + +--echo # +--echo # Case 2.a) With two binlog files, a --stop-datetime within the +--echo # timespan of binlog 2 should: +--echo # 1) not provide any warnings +--echo # 2) not prevent binlog 1 or 2 from outputting the desired events + +--echo # MYSQL_BINLOG $PARAM_READ_FROM_REMOTE_OUT --stop-datetime='$b2_timestamp1' binlog_f1_full binlog_f2_full --result-file=$binlog_out_relpath 2>&1 +--exec $MYSQL_BINLOG $PARAM_READ_FROM_REMOTE --stop-datetime='$b2_timestamp1' $binlog_f1_full $binlog_f2_full --result-file=$binlog_out 2>&1 + +--let $server_id= `SELECT @@GLOBAL.server_id` +--let $domain_id= `SELECT @@GLOBAL.gtid_domain_id` +--let $assert_file= $binlog_out +--let $assert_text= Ensure all intended GTIDs are present +--let $assert_select= GTID $domain_id-$server_id- +--let $assert_count= 3 +--source include/assert_grep.inc + +--let $assert_text= Ensure the next GTID binlogged is _not_ present +--let $assert_select= GTID $binlog_f2_gtid_after_midpoint +--let $assert_count= 0 +--source include/assert_grep.inc + +--echo # +--echo # Case 2.b) With two binlog files, a --stop-datetime at the end of +--echo # binlog 2 should: +--echo # 1) not provide any warnings +--echo # 2) not prevent binlog 1 or 2 from outputting all events +--echo # MYSQL_BINLOG $PARAM_READ_FROM_REMOTE_OUT --stop-datetime='$b2_timestamp3' binlog_f1_full binlog_f2_full --result-file=$binlog_out_relpath 2>&1 +--exec $MYSQL_BINLOG $PARAM_READ_FROM_REMOTE --stop-datetime='$b2_timestamp3' $binlog_f1_full $binlog_f2_full --result-file=$binlog_out 2>&1 + +--let $assert_text= Ensure a GTID exists for each transaction +--let $assert_select= GTID $domain_id-$server_id- +--let $assert_count= 8 +--source include/assert_grep.inc + +--echo # +--echo # Case 2.c) With two binlog files, a --stop-datetime beyond the end of +--echo # binlog 2 should: +--echo # 1) provide a warning that the stop datetime was not reached +--echo # 2) not prevent binlog 1 or 2 from outputting all events +--echo # MYSQL_BINLOG $PARAM_READ_FROM_REMOTE_OUT --stop-datetime='$b2_timestamp_not_reached' binlog_f1_full binlog_f2_full --result-file=$binlog_out_relpath 2>&1 +--exec $MYSQL_BINLOG $PARAM_READ_FROM_REMOTE --stop-datetime='$b2_timestamp_not_reached' $binlog_f1_full $binlog_f2_full --result-file=$binlog_out 2>&1 + +--let $assert_text= Ensure a GTID exists for each transaction +--let $assert_select= GTID $domain_id-$server_id- +--let $assert_count= 8 +--source include/assert_grep.inc + diff --git a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_warn_stop_datetime.test b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_warn_stop_datetime.test index 9d30544c5f4..f862f0e7887 100644 --- a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_warn_stop_datetime.test +++ b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_warn_stop_datetime.test @@ -1,42 +1,86 @@ ---echo ---echo # MDEV-27037 mysqlbinlog emits a warning when reaching EOF before stop-datetime ---echo +# +# Test ensures that --stop-datetime work correctly for mysqlbinlog. This high +# level test sets up the binary log (and tags certain locations for comparison), +# and the helper file binlog_mysqlbinlog_warn_stop_datetime.inc performs the +# actual tests. +# +# References: +# MDEV-27037: mysqlbinlog emits a warning when reaching EOF before +# stop-condition +# MDEV-35528: mariadb-binlog cannot process more than 1 logfiles when +# --stop-datetime is specified +# +--source include/have_log_bin.inc ---source include/have_binlog_format_statement.inc +--let $binlog_out_relpath= tmp/warn_datetime_test_file.out +--let $binlog_out= $MYSQLTEST_VARDIR/$binlog_out_relpath ---let ignored_output_file= $MYSQLTEST_VARDIR/tmp/warn_pos_test_file.out +--let $b1_timestamp1= 2024-12-01 10:20:30.123456 +--let $b1_timestamp2= 2024-12-02 10:20:30.123456 +--let $b1_timestamp3= 2024-12-03 10:20:30.123456 +--let $b2_timestamp1= 2024-12-04 10:20:30.123456 +--let $b2_timestamp2= 2024-12-05 10:20:30.123456 +--let $b2_timestamp3= 2024-12-06 10:20:30.123456 +--let $b2_timestamp_not_reached= 2024-12-07 10:20:30.123456 -set timestamp=1000000000; -CREATE TABLE t1(word VARCHAR(20)); -set timestamp=1000000010; -INSERT INTO t1 VALUES ("abirvalg"); -set timestamp=1000000020; -INSERT INTO t1 SELECT * FROM t1; ---let MYSQLD_DATADIR= `select @@datadir;` -flush logs; +--eval SET TIMESTAMP= UNIX_TIMESTAMP('$b1_timestamp1') ---echo Case: Default, must not see warning. ---echo # MYSQL_BINLOG --short-form MYSQLD_DATADIR/master-bin.000001 --result-file=ignored_output_file ---exec $MYSQL_BINLOG --short-form $MYSQLD_DATADIR/master-bin.000001 --result-file=$ignored_output_file 2>&1 +--echo # +--echo # Clear the existing binary log state, and start fresh using +--echo # the timestamp variable set above +--echo # +RESET MASTER; ---echo Case: Stop datetime before EOF, must not see warning. ---echo # MYSQL_BINLOG --short-form --stop-datetime='2001-09-08 21:46:50' MYSQLD_DATADIR/master-bin.000001 --result-file=ignored_output_file ---exec $MYSQL_BINLOG --short-form --stop-datetime='2001-09-08 21:46:50' $MYSQLD_DATADIR/master-bin.000001 --result-file=$ignored_output_file 2>&1 +--let $binlog_f1= query_get_value(SHOW MASTER STATUS, File, 1) +create table t1 (a int); +insert into t1 values (1); +--eval SET TIMESTAMP= UNIX_TIMESTAMP('$b1_timestamp2') +insert into t1 values (2); +--eval SET TIMESTAMP= UNIX_TIMESTAMP('$b1_timestamp3') +flush binary logs; +--let $binlog_f2= query_get_value(SHOW MASTER STATUS, File, 1) +--eval SET TIMESTAMP= UNIX_TIMESTAMP('$b2_timestamp1') +insert into t1 values (3); +insert into t1 values (4); +--eval SET TIMESTAMP= UNIX_TIMESTAMP('$b2_timestamp2') +--let $binlog_f2_gtid_after_midpoint= `SELECT @@GLOBAL.gtid_binlog_pos` +insert into t1 values (5); +insert into t1 values (6); +insert into t1 values (7); +--let $binlog_f2_last_gtid= `SELECT @@GLOBAL.gtid_binlog_pos` +--eval SET TIMESTAMP=UNIX_TIMESTAMP('$b2_timestamp3') +flush binary logs; +drop table t1; ---echo Case: Stop datetime between records, must not see warning. ---echo # MYSQL_BINLOG --short-form --stop-datetime='2001-09-08 21:46:55' MYSQLD_DATADIR/master-bin.000001 --result-file=ignored_output_file ---exec $MYSQL_BINLOG --short-form --stop-datetime='2001-09-08 21:46:55' $MYSQLD_DATADIR/master-bin.000001 --result-file=$ignored_output_file 2>&1 +--echo # Ensuring binary log order is correct +--let $binlog_f1_show= query_get_value(SHOW BINARY LOGS, Log_name, 1) +if (`SELECT strcmp('$binlog_f1','$binlog_f1_show') != 0`) +{ + --echo # Real binlog_f1: $binlog_f1 + --echo # First binlog in SHOW BINLOG FILES: $binlog_f1_show + --die Wrong order of binary log files in SHOW BINARY LOGS +} +--let $binlog_f2_show= query_get_value(SHOW BINARY LOGS, Log_name, 2) +if (`SELECT strcmp('$binlog_f2','$binlog_f2_show') != 0`) +{ + --echo # Real binlog_f2: $binlog_f2 + --echo # First binlog in SHOW BINLOG FILES: $binlog_f2_show + --die Wrong order of binary log files in SHOW BINARY LOGS +} ---echo Case: Stop datetime at EOF, must not see warning. ---echo # MYSQL_BINLOG --short-form --stop-datetime='2001-09-08 21:46:55' MYSQLD_DATADIR/master-bin.000001 --result-file=ignored_output_file ---exec $MYSQL_BINLOG --short-form --stop-datetime='2001-09-08 21:46:55' $MYSQLD_DATADIR/master-bin.000001 --result-file=$ignored_output_file 2>&1 +--echo # +--echo # +--echo # Test using --read-from-remote-server +--echo # +--let $read_from_remote_server= 1 +--source binlog_mysqlbinlog_warn_stop_datetime.inc ---echo Case: Stop datetime after EOF, must see warning. ---echo # MYSQL_BINLOG --short-form --stop-datetime='2035-01-19 03:14:05' MYSQLD_DATADIR/master-bin.000001 --result-file=ignored_output_file ---exec $MYSQL_BINLOG --short-form --stop-datetime='2035-01-19 03:14:05' $MYSQLD_DATADIR/master-bin.000001 --result-file=$ignored_output_file 2>&1 - -DROP TABLE t1; - ---remove_file $ignored_output_file +--echo # +--echo # +--echo # Test using local binlog files +--echo # +--let $read_from_remote_server= 0 +--source binlog_mysqlbinlog_warn_stop_datetime.inc +--echo # --echo # End of binlog_mysqlbinlog_warn_stop_datetime.test diff --git a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_warn_stop_position.inc b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_warn_stop_position.inc new file mode 100644 index 00000000000..2c3c565d692 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_warn_stop_position.inc @@ -0,0 +1,115 @@ +# +# Helper file that ensures mysqlbinlog --stop-position behavior for local +# files or a remote server +# +# Parameters: +# read_from_remote_server (bool): A boolean that changes which source to use +# for mysqlbinlog. When true, reads remotely; when false, uses local files. +# + +--connection default +--let $MYSQLD_DATADIR= `select @@datadir` + +# PARAM_READ_FROM_REMOTE is used as a parameter to mysqlbinlog (_OUT suffix is +# output in echo commands). If using local files, they are blank; if reading +# from remote server, it is overridden to the correct values. +--let $PARAM_READ_FROM_REMOTE= +# Used in echo statements to remove potentially changing values +--let $PARAM_READ_FROM_REMOTE_OUT= + +if ($read_from_remote_server) +{ + --let $PARAM_READ_FROM_REMOTE= --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT + --let $PARAM_READ_FROM_REMOTE_OUT= --read-from-remote-server + # binlog files in --read-from-remote-server don't use file system path + --let $binlog_f1_full= $binlog_f1 + --let $binlog_f2_full= $binlog_f2 +} +if (!$read_from_remote_server) +{ + # If using local files, file system path to the binlog files is needed + --let $binlog_f1_full= $MYSQLD_DATADIR/$binlog_f1 + --let $binlog_f2_full= $MYSQLD_DATADIR/$binlog_f2 +} + +--echo # +--echo # --stop-position tests +--echo # + +--echo # Case 1.a) With one binlog file, a --stop-position before the end of +--echo # the file should not result in a warning +--echo # MYSQL_BINLOG $PARAM_READ_FROM_REMOTE_OUT --stop-position=binlog_f1_pre_rotate binlog_f1_full --result-file=$binlog_out_relpath 2>&1 +--exec $MYSQL_BINLOG $PARAM_READ_FROM_REMOTE --stop-position=$binlog_f1_pre_rotate $binlog_f1_full --result-file=$binlog_out 2>&1 + +--echo # +--echo # Case 1.b) With one binlog file, a --stop-position at the exact end of +--echo # the file should not result in a warning +--echo # MYSQL_BINLOG $PARAM_READ_FROM_REMOTE_OUT --stop-position=binlog_f1_end binlog_f1_full --result-file=$binlog_out_relpath 2>&1 +--exec $MYSQL_BINLOG $PARAM_READ_FROM_REMOTE --stop-position=$binlog_f1_end $binlog_f1_full --result-file=$binlog_out 2>&1 + +--echo # +--echo # Case 1.c) With one binlog file, a --stop-position past the end of the +--echo # file should(!) result in a warning +--let $binlog_f1_over_eof= `SELECT $binlog_f1_end + 1` +--echo # MYSQL_BINLOG $PARAM_READ_FROM_REMOTE_OUT --short-form --stop-position=binlog_f1_over_eof binlog_f1_full --result-file=$binlog_out_relpath 2>&1 +--replace_result $binlog_f1_over_eof +--exec $MYSQL_BINLOG $PARAM_READ_FROM_REMOTE --short-form --stop-position=$binlog_f1_over_eof $binlog_f1_full --result-file=$binlog_out 2>&1 + +--echo # +--echo # Case 2.a) With two binlog files, a --stop-position targeting b2 which +--echo # exists in the size of b1 should: +--echo # 1) not provide any warnings +--echo # 2) not prevent b2 from outputting its desired events before the +--echo # stop position +--echo # MYSQL_BINLOG $PARAM_READ_FROM_REMOTE_OUT --stop-position=binlog_f2_mid binlog_f1_full binlog_f2_full --result-file=$binlog_out_relpath 2>&1 +--exec $MYSQL_BINLOG $PARAM_READ_FROM_REMOTE --stop-position=$binlog_f2_mid $binlog_f1_full $binlog_f2_full --result-file=$binlog_out 2>&1 + +--let $server_id= `SELECT @@GLOBAL.server_id` +--let $domain_id= `SELECT @@GLOBAL.gtid_domain_id` +--let $assert_file= $binlog_out +--let $assert_text= Ensure all intended GTIDs are present +--let $assert_select= GTID $domain_id-$server_id- +--let $assert_count= 4 +--source include/assert_grep.inc + +--let $assert_text= Ensure the next GTID binlogged is _not_ present +--let $assert_select= GTID $binlog_f2_gtid_after_midpoint +--let $assert_count= 0 +--source include/assert_grep.inc + +--echo # +--echo # Case 2.b) With two binlog files, a --stop-position targeting the end +--echo # of binlog 2 should: +--echo # 1) not provide any warnings +--echo # 2) not prevent b2 from outputting its entire binary log +--echo # MYSQL_BINLOG $PARAM_READ_FROM_REMOTE_OUT --stop-position=binlog_f2_end binlog_f1_full binlog_f2_full --result-file=$binlog_out_relpath 2>&1 +--exec $MYSQL_BINLOG $PARAM_READ_FROM_REMOTE --stop-position=$binlog_f2_end $binlog_f1_full $binlog_f2_full --result-file=$binlog_out 2>&1 + +--let $server_id= `SELECT @@GLOBAL.server_id` +--let $domain_id= `SELECT @@GLOBAL.gtid_domain_id` +--let $assert_text= Ensure a GTID exists for each transaction +--let $assert_select= GTID $domain_id-$server_id- +--let $assert_count= 8 +--source include/assert_grep.inc + +--let $assert_text= Ensure the last GTID binlogged is present +--let $assert_select= GTID $binlog_f2_last_gtid +--let $assert_count= 1 +--source include/assert_grep.inc + +--echo # +--echo # Case 2.c) With two binlog files, a --stop-position targeting beyond +--echo # the eof of binlog 2 should: +--echo # 1) provide a warning that the stop position was not reached +--echo # 2) not prevent b2 from outputting its entire binary log +--let $binlog_f2_over_eof= `SELECT $binlog_f2_end + 1` +--echo # MYSQL_BINLOG $PARAM_READ_FROM_REMOTE_OUT --stop-position=binlog_f2_over_eof binlog_f1_full binlog_f2_full --result-file=$binlog_out_relpath 2>&1 +--replace_result $binlog_f2_over_eof +--exec $MYSQL_BINLOG $PARAM_READ_FROM_REMOTE --stop-position=$binlog_f2_over_eof $binlog_f1_full $binlog_f2_full --result-file=$binlog_out 2>&1 + +--let $server_id= `SELECT @@GLOBAL.server_id` +--let $domain_id= `SELECT @@GLOBAL.gtid_domain_id` +--let $assert_text= Ensure a GTID exists for each transaction +--let $assert_select= GTID $domain_id-$server_id- +--let $assert_count= 8 +--source include/assert_grep.inc diff --git a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_warn_stop_position.test b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_warn_stop_position.test index 97fabfc6513..a9179297220 100644 --- a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_warn_stop_position.test +++ b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_warn_stop_position.test @@ -1,26 +1,83 @@ ---echo ---echo # MDEV-27037 mysqlbinlog emits a warning when reaching EOF before stop-condition ---echo +# +# Test ensures that --stop-position work correctly for mysqlbinlog. This high +# level test sets up the binary log (and tags certain locations for comparison), +# and the helper file binlog_mysqlbinlog_warn_stop_position.inc performs the +# actual tests. +# +# References: +# MDEV-27037: mysqlbinlog emits a warning when reaching EOF before +# stop-condition +# +--source include/have_log_bin.inc ---let assert_file= $MYSQLTEST_VARDIR/tmp/warn_pos_test_file.out ---let data_file= $MYSQLTEST_VARDIR/std_data/master-bin.000001 +--let $binlog_out_relpath= tmp/warn_position_test_file.out +--let $binlog_out= $MYSQLTEST_VARDIR/$binlog_out_relpath ---echo Case: Default stop position, WARNING must not appear ---echo # MYSQL_BINLOG --short-form --start-position=4 mysql-test/std_data/master-bin.000001 --result-file=warn_pos_test_file.out 2>&1 ---exec $MYSQL_BINLOG --short-form --start-position=4 $data_file --result-file=$assert_file 2>&1 +--echo # +--echo # Clear the existing binary log state. +--echo # +RESET MASTER; ---echo Case: Stop position before EOF, WARNING must not appear ---echo # MYSQL_BINLOG --short-form --start-position=4 --stop-position=97 mysql-test/std_data/master-bin.000001 --result-file=warn_pos_test_file.out 2>&1 ---exec $MYSQL_BINLOG --short-form --start-position=4 --stop-position=97 $data_file --result-file=$assert_file 2>&1 +--let $binlog_f1= query_get_value(SHOW MASTER STATUS, File, 1) +create table t1 (a int); +insert into t1 values (1); +insert into t1 values (2); +--let $binlog_f1_pre_rotate= query_get_value(SHOW MASTER STATUS, Position, 1) +flush binary logs; +--let $binlog_f2= query_get_value(SHOW MASTER STATUS, File, 1) +insert into t1 values (3); +--echo # Tag binlog_f2_mid +--let $binlog_f2_mid= query_get_value(SHOW MASTER STATUS, Position, 1) +insert into t1 values (4); +--let $binlog_f2_gtid_after_midpoint= `SELECT @@GLOBAL.gtid_binlog_pos` +insert into t1 values (5); +insert into t1 values (6); +insert into t1 values (7); +--let $binlog_f2_last_gtid= `SELECT @@GLOBAL.gtid_binlog_pos` +--let $binlog_f2_pre_rot= query_get_value(SHOW MASTER STATUS, Position, 1) +flush binary logs; +drop table t1; ---echo Case: Stop position at EOF, WARNING must not appear ---echo # MYSQL_BINLOG --short-form --start-position=4 --stop-position=98 mysql-test/std_data/master-bin.000001 --result-file=warn_pos_test_file.out 2>&1 ---exec $MYSQL_BINLOG --short-form --start-position=4 --stop-position=98 $data_file --result-file=$assert_file 2>&1 +--echo # Ensuring binary log order is correct +--let $binlog_f1_show= query_get_value(SHOW BINARY LOGS, Log_name, 1) +--let $binlog_f1_end= query_get_value(SHOW BINARY LOGS, File_size, 1) +if (`SELECT strcmp('$binlog_f1','$binlog_f1_show') != 0`) +{ + --echo # Real binlog_f1: $binlog_f1 + --echo # First binlog in SHOW BINLOG FILES: $binlog_f1_show + --die Wrong order of binary log files in SHOW BINARY LOGS +} +--let $binlog_f2_show= query_get_value(SHOW BINARY LOGS, Log_name, 2) +--let $binlog_f2_end= query_get_value(SHOW BINARY LOGS, File_size, 2) +if (`SELECT strcmp('$binlog_f2','$binlog_f2_show') != 0`) +{ + --echo # Real binlog_f2: $binlog_f2 + --echo # First binlog in SHOW BINLOG FILES: $binlog_f2_show + --die Wrong order of binary log files in SHOW BINARY LOGS +} ---echo Case: Stop position after EOF, WARNING must appear ---echo # MYSQL_BINLOG --short-form --start-position=4 --stop-position=99 mysql-test/std_data/master-bin.000001 --result-file=warn_pos_test_file.out 2>&1 ---exec $MYSQL_BINLOG --short-form --start-position=4 --stop-position=99 $data_file --result-file=$assert_file 2>&1 +--echo # Ensuring file offset of binlog_f2_mid < binlog_f1_end +if ($binlog_f2_mid > $binlog_f1_end) +{ + --echo # Binlog 1 end: $binlog_f1:$binlog_f1_end + --echo # Binlog 2 stop point: $binlog_f2:$binlog_f2_mid + --die Mid point chosen to end in binlog 2 does not exist in earlier binlog +} ---remove_file $assert_file +#--echo # +#--echo # +#--echo # Test using --read-from-remote-server +#--echo # +#--let $read_from_remote_server= 1 +#--emit warning is not supported by --read-from-remote-server now +#--source binlog_mysqlbinlog_warn_stop_position.inc +--echo # +--echo # +--echo # Test using local binlog files +--echo # +--let $read_from_remote_server= 0 +--source binlog_mysqlbinlog_warn_stop_position.inc + +--echo # --echo # End of binlog_mysqlbinlog_warn_stop_position.test From 04408fff40447f9aab12aed1957356e65e1c8b15 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sun, 12 Jan 2025 13:20:56 +1100 Subject: [PATCH 035/213] MDEV-35687 Various UBSAN function-type-mismatch debug_sync and myisam MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit storage/maria/ma_open.c:352:7: runtime error: call to function debug_sync(THD*, char const*, unsigned long) through pointer to incorrect function type 'void (*)(void *, const char *, unsigned long)' The THD argument is a void *. Because of the way myisam is .c files the function prototype is mismatched. As Marko pointed out the MYSQL_THD is declared as void * in C. Thanks Jimmy Hú for noting that struct THD is the equalivalant in C to the class THD. The C NULL was also different to the C++ nullptr. Corrected the definations of MYSQL_THD and DEBUG_SYNC_C to be C and C++ compatible. --- include/mysql/plugin.h | 3 ++- include/mysql/service_debug_sync.h | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h index d9aef6ac11c..87efbefde68 100644 --- a/include/mysql/plugin.h +++ b/include/mysql/plugin.h @@ -44,7 +44,8 @@ class THD; class Item; #define MYSQL_THD THD* #else -#define MYSQL_THD void* +struct THD; +typedef struct THD* MYSQL_THD; #endif typedef char my_bool; diff --git a/include/mysql/service_debug_sync.h b/include/mysql/service_debug_sync.h index 0bd49a13458..f7fdbf04832 100644 --- a/include/mysql/service_debug_sync.h +++ b/include/mysql/service_debug_sync.h @@ -351,7 +351,11 @@ extern void (*debug_sync_C_callback_ptr)(MYSQL_THD, const char *, size_t); #endif /* defined(ENABLED_DEBUG_SYNC) */ /* compatibility macro */ +#ifdef __cplusplus +#define DEBUG_SYNC_C(name) DEBUG_SYNC(nullptr, name) +#else #define DEBUG_SYNC_C(name) DEBUG_SYNC(NULL, name) +#endif #ifdef __cplusplus } From f862fe8b2bb359e0bbeb48d0d38047a95dc0e43c Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Mon, 16 Dec 2024 10:26:21 +1100 Subject: [PATCH 036/213] MDEV-35641 bring call to use_all_columns() forward when reading from mysql.servers TABLE::use_all_columns turn on all bits of read_set, which is interpreted by innodb as a request to read all columns. Without doing so before calling init_read_record(), innodb will not retrieve any columns if mysql.servers table has been altered to use innodb as the engine, and any foreign servers stored in the table are "lost". --- mysql-test/main/servers.result | 7 +++++++ mysql-test/main/servers.test | 9 +++++++++ sql/sql_servers.cc | 6 +++--- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/mysql-test/main/servers.result b/mysql-test/main/servers.result index d660aff1bd2..a02c3d6ac74 100644 --- a/mysql-test/main/servers.result +++ b/mysql-test/main/servers.result @@ -43,3 +43,10 @@ ERROR HY000: Can't read record in system table drop table mysql.servers; rename table mysql.servers_save to mysql.servers; drop server s1; +# +# MDEV-35641 foreign server "disappears" after ALTERing the servers system table to use innodb and FLUSH PRIVILEGES +# +CREATE SERVER s1 FOREIGN DATA WRAPPER mysql OPTIONS (HOST '127.0.0.1'); +ALTER TABLE mysql.servers ENGINE=innodb; +FLUSH PRIVILEGES; +drop server s1; diff --git a/mysql-test/main/servers.test b/mysql-test/main/servers.test index 1a58d5849f8..f46041bb21c 100644 --- a/mysql-test/main/servers.test +++ b/mysql-test/main/servers.test @@ -41,3 +41,12 @@ create server s2 foreign data wrapper foo options(user 'a'); drop table mysql.servers; rename table mysql.servers_save to mysql.servers; drop server s1; + +--echo # +--echo # MDEV-35641 foreign server "disappears" after ALTERing the servers system table to use innodb and FLUSH PRIVILEGES +--echo # +--source include/have_innodb.inc +CREATE SERVER s1 FOREIGN DATA WRAPPER mysql OPTIONS (HOST '127.0.0.1'); +ALTER TABLE mysql.servers ENGINE=innodb; +FLUSH PRIVILEGES; +drop server s1; diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc index 59a4679847b..ecf411ab313 100644 --- a/sql/sql_servers.cc +++ b/sql/sql_servers.cc @@ -283,7 +283,7 @@ end: static bool servers_load(THD *thd, TABLE_LIST *tables) { - TABLE *table; + TABLE *table= tables[0].table; READ_RECORD read_record_info; bool return_val= TRUE; DBUG_ENTER("servers_load"); @@ -292,7 +292,8 @@ static bool servers_load(THD *thd, TABLE_LIST *tables) free_root(&mem, MYF(0)); init_sql_alloc(key_memory_servers, &mem, ACL_ALLOC_BLOCK_SIZE, 0, MYF(0)); - if (init_read_record(&read_record_info,thd,table=tables[0].table, NULL, NULL, + table->use_all_columns(); + if (init_read_record(&read_record_info,thd,table, NULL, NULL, 1,0, FALSE)) DBUG_RETURN(1); while (!(read_record_info.read_record())) @@ -405,7 +406,6 @@ get_server_from_table_to_cache(TABLE *table) FOREIGN_SERVER *server= (FOREIGN_SERVER *)alloc_root(&mem, sizeof(FOREIGN_SERVER)); DBUG_ENTER("get_server_from_table_to_cache"); - table->use_all_columns(); /* get each field into the server struct ptr */ ptr= get_field(&mem, table->field[0]); From 8b9c8631a413933f19b54c2b22e376f3e785624d Mon Sep 17 00:00:00 2001 From: ParadoxV5 Date: Sat, 11 Jan 2025 12:04:35 -0700 Subject: [PATCH 037/213] MDEV-35818: Fix `replace_binlog_file` info message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `ATTRIBUITE_FORMAT` from #3360 uncovers issues on `my_snprintf` uses. This commit fixes the one in `Binlog_commit_by_rotate::` `replace_binlog_file()` about “required size too big”. All I found is that it’s not present in 11.4 (after I prepared previous batches for all maintained branches), for GitHub blame can’t process a file with over 10K lines. --- sql/log.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index e3e944322f5..1995c164e08 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -13257,10 +13257,11 @@ bool Binlog_commit_by_rotate::replace_binlog_file() DBUG_EXECUTE_IF("simulate_required_size_too_big", required_size= 10000;); if (required_size > m_cache_data->file_reserved_bytes()) { - sql_print_information("Could not rename binlog cache to binlog(as " + sql_print_information("Could not rename binlog cache to binlog (as " "requested by --binlog-commit-by-rotate-threshold). " - "Required %llu bytes but only %llu bytes reserved.", - required_size, m_cache_data->file_reserved_bytes()); + "Required %zu bytes but only %lu bytes reserved.", + required_size, static_cast( + m_cache_data->file_reserved_bytes())); return false; } From faca9500fb3c1e5c56d9626f606df8de67513bc1 Mon Sep 17 00:00:00 2001 From: ParadoxV5 Date: Sat, 11 Jan 2025 12:09:47 -0700 Subject: [PATCH 038/213] MDEV-35430: Add cast to semi-sync wait skip msg This came after I prepared #3493. --- sql/semisync_master.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/semisync_master.cc b/sql/semisync_master.cc index 437b9bb99b4..3e33cff06f6 100644 --- a/sql/semisync_master.cc +++ b/sql/semisync_master.cc @@ -938,8 +938,8 @@ int Repl_semi_sync_master::commit_trx(const char *trx_wait_binlog_name, sql_print_information( "Skipping semi-sync wait for transaction at pos %s, %lu. This " "should be because semi-sync turned off and on during the " - "lifetime of this transaction.", - trx_wait_binlog_name, trx_wait_binlog_pos);); + "lifetime of this transaction.", trx_wait_binlog_name, + static_cast(trx_wait_binlog_pos));); /* The only known reason for a missing entry at this point is if * semi-sync was turned off then on, so on debug builds, we track From 42e60586295ec010511cf73f1becee60758c900e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 13 Jan 2025 07:27:17 +0200 Subject: [PATCH 039/213] MDEV-35785 innodb_log_file_mmap is not defined on 32-bit systems MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit innodb_log_file_mmap: Use a constant documentation string that refers to persistent memory also when it is not available in the build. HAVE_INNODB_MMAP: Remove, and unconditionally enable this code. log_mmap(): On 32-bit systems, ensure that the size fits in 32 bits. log_t::resize_start(), log_t::resize_abort(): Only handle memory-mapping if HAVE_PMEM is defined. The generic memory-mapped interface is only for reading the log in recovery. Writable memory mappings are only for persistent memory, that is, Linux file systems with mount -o dax. Reviewed by: Debarun Banerjee, Otto Kekäläinen --- extra/mariabackup/xtrabackup.cc | 9 +--- .../innodb_redo_log_overwrite.combinations | 4 ++ .../suite/sys_vars/r/sysvars_innodb.result | 13 +++++- .../suite/sys_vars/t/sysvars_innodb.test | 1 - storage/innobase/handler/ha_innodb.cc | 8 +--- storage/innobase/include/log0log.h | 11 ----- storage/innobase/include/log0recv.h | 7 +-- storage/innobase/include/univ.i | 3 -- storage/innobase/log/log0log.cc | 44 +++++++------------ storage/innobase/log/log0recv.cc | 4 -- storage/innobase/mtr/mtr0mtr.cc | 2 +- storage/innobase/srv/srv0start.cc | 4 -- 12 files changed, 36 insertions(+), 74 deletions(-) create mode 100644 mysql-test/suite/mariabackup/innodb_redo_log_overwrite.combinations diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 5367ea5148e..8385114f39b 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -1331,9 +1331,7 @@ enum options_xtrabackup OPT_INNODB_BUFFER_POOL_FILENAME, OPT_INNODB_LOCK_WAIT_TIMEOUT, OPT_INNODB_LOG_BUFFER_SIZE, -#ifdef HAVE_INNODB_MMAP OPT_INNODB_LOG_FILE_MMAP, -#endif #if defined __linux__ || defined _WIN32 OPT_INNODB_LOG_FILE_BUFFERING, #endif @@ -1895,13 +1893,11 @@ struct my_option xb_server_options[] = (G_PTR*) &log_sys.buf_size, (G_PTR*) &log_sys.buf_size, 0, GET_UINT, REQUIRED_ARG, 2U << 20, 2U << 20, log_sys.buf_size_max, 0, 4096, 0}, -#ifdef HAVE_INNODB_MMAP {"innodb_log_file_mmap", OPT_INNODB_LOG_FILE_SIZE, "Whether ib_logfile0 should be memory-mapped", (G_PTR*) &log_sys.log_mmap, (G_PTR*) &log_sys.log_mmap, 0, GET_BOOL, NO_ARG, log_sys.log_mmap_default, 0, 0, 0, 0, 0}, -#endif #if defined __linux__ || defined _WIN32 {"innodb_log_file_buffering", OPT_INNODB_LOG_FILE_BUFFERING, "Whether the file system cache for ib_logfile0 is enabled during --backup", @@ -3370,7 +3366,6 @@ skip: return(FALSE); } -#ifdef HAVE_INNODB_MMAP static int xtrabackup_copy_mmap_snippet(ds_file_t *ds, const byte *start, const byte *end) { @@ -3470,7 +3465,6 @@ static bool xtrabackup_copy_mmap_logfile() msg(">> log scanned up to (" LSN_PF ")", recv_sys.lsn); return false; } -#endif /** Copy redo log until the current end of the log is reached @return whether the operation failed */ @@ -3482,10 +3476,9 @@ static bool xtrabackup_copy_logfile() ut_a(dst_log_file); ut_ad(recv_sys.is_initialised()); -#ifdef HAVE_INNODB_MMAP if (log_sys.is_mmap()) return xtrabackup_copy_mmap_logfile(); -#endif + const size_t sequence_offset{log_sys.is_encrypted() ? 8U + 5U : 5U}; const size_t block_size_1{log_sys.write_size - 1}; diff --git a/mysql-test/suite/mariabackup/innodb_redo_log_overwrite.combinations b/mysql-test/suite/mariabackup/innodb_redo_log_overwrite.combinations new file mode 100644 index 00000000000..5221a9747be --- /dev/null +++ b/mysql-test/suite/mariabackup/innodb_redo_log_overwrite.combinations @@ -0,0 +1,4 @@ +[pread] +--innodb-log-file-mmap=OFF +[mmap] +--innodb-log-file-mmap=ON diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result index d24dfd5c374..2d8e1573db8 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result +++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result @@ -4,7 +4,6 @@ variable_name not in ( 'innodb_numa_interleave', # only available WITH_NUMA 'innodb_evict_tables_on_commit_debug', # one may want to override this 'innodb_use_native_aio', # default value depends on OS -'innodb_log_file_mmap', # only available on 64-bit 'innodb_log_file_buffering', # only available on Linux and Windows 'innodb_buffer_pool_load_pages_abort') # debug build only, and is only for testing order by variable_name; @@ -1028,6 +1027,18 @@ NUMERIC_BLOCK_SIZE NULL ENUM_VALUE_LIST OFF,ON READ_ONLY NO COMMAND_LINE_ARGUMENT OPTIONAL +VARIABLE_NAME INNODB_LOG_FILE_MMAP +SESSION_VALUE NULL +DEFAULT_VALUE ON +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE BOOLEAN +VARIABLE_COMMENT Whether ib_logfile0 resides in persistent memory (when supported) or should initially be memory-mapped +NUMERIC_MIN_VALUE NULL +NUMERIC_MAX_VALUE NULL +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST OFF,ON +READ_ONLY YES +COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME INNODB_LOG_FILE_SIZE SESSION_VALUE NULL DEFAULT_VALUE 100663296 diff --git a/mysql-test/suite/sys_vars/t/sysvars_innodb.test b/mysql-test/suite/sys_vars/t/sysvars_innodb.test index 86f5ffddf1c..2680e442da4 100644 --- a/mysql-test/suite/sys_vars/t/sysvars_innodb.test +++ b/mysql-test/suite/sys_vars/t/sysvars_innodb.test @@ -11,7 +11,6 @@ select VARIABLE_NAME, SESSION_VALUE, DEFAULT_VALUE, VARIABLE_SCOPE, VARIABLE_TYP 'innodb_numa_interleave', # only available WITH_NUMA 'innodb_evict_tables_on_commit_debug', # one may want to override this 'innodb_use_native_aio', # default value depends on OS - 'innodb_log_file_mmap', # only available on 64-bit 'innodb_log_file_buffering', # only available on Linux and Windows 'innodb_buffer_pool_load_pages_abort') # debug build only, and is only for testing order by variable_name; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 45caf8aaf03..a97dcba1b35 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -19475,18 +19475,14 @@ static MYSQL_SYSVAR_UINT(log_buffer_size, log_sys.buf_size, "Redo log buffer size in bytes.", NULL, NULL, 16U << 20, 2U << 20, log_sys.buf_size_max, 4096); -#ifdef HAVE_INNODB_MMAP static constexpr const char *innodb_log_file_mmap_description= "Whether ib_logfile0" -# ifdef HAVE_PMEM - " resides in persistent memory or" -# endif + " resides in persistent memory (when supported) or" " should initially be memory-mapped"; static MYSQL_SYSVAR_BOOL(log_file_mmap, log_sys.log_mmap, PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY, innodb_log_file_mmap_description, nullptr, nullptr, log_sys.log_mmap_default); -#endif #if defined __linux__ || defined _WIN32 static MYSQL_SYSVAR_BOOL(log_file_buffering, log_sys.log_buffered, @@ -19982,9 +19978,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(deadlock_report), MYSQL_SYSVAR(page_size), MYSQL_SYSVAR(log_buffer_size), -#ifdef HAVE_INNODB_MMAP MYSQL_SYSVAR(log_file_mmap), -#endif #if defined __linux__ || defined _WIN32 MYSQL_SYSVAR(log_file_buffering), #endif diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h index 6d035fc97d1..2ca34a93789 100644 --- a/storage/innobase/include/log0log.h +++ b/storage/innobase/include/log0log.h @@ -282,7 +282,6 @@ public: uint write_size; /** format of the redo log: e.g., FORMAT_10_8 */ uint32_t format; -#ifdef HAVE_INNODB_MMAP /** whether the memory-mapped interface is enabled for the log */ my_bool log_mmap; /** the default value of log_mmap */ @@ -294,7 +293,6 @@ public: # else /* an unnecessary read-ahead of a large ib_logfile0 is a risk */ # endif false; -#endif #if defined __linux__ || defined _WIN32 /** whether file system caching is enabled for the log */ my_bool log_buffered; @@ -347,11 +345,7 @@ public: void set_buf_free(size_t f) noexcept { ut_ad(f < buf_free_LOCK); buf_free.store(f, std::memory_order_relaxed); } -#ifdef HAVE_INNODB_MMAP bool is_mmap() const noexcept { return !flush_buf; } -#else - static constexpr bool is_mmap() { return false; } -#endif /** @return whether a handle to the log is open; is_mmap() && !is_opened() holds for PMEM */ @@ -412,14 +406,9 @@ public: @return whether the memory allocation succeeded */ bool attach(log_file_t file, os_offset_t size); -#ifdef HAVE_INNODB_MMAP /** Disable memory-mapped access (update log_mmap) */ void clear_mmap(); void close_file(bool really_close= true); -#else - static void clear_mmap() {} - void close_file(); -#endif #if defined __linux__ || defined _WIN32 /** Try to enable or disable file system caching (update log_buffered) */ void set_buffered(bool buffered); diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h index d9dd0945059..1a4459001a6 100644 --- a/storage/innobase/include/log0recv.h +++ b/storage/innobase/include/log0recv.h @@ -430,12 +430,7 @@ public: @tparam storing whether to store the records @param if_exists storing=YES: whether to check if the tablespace exists */ template - static parse_mtr_result parse_mmap(bool if_exists) noexcept -#ifdef HAVE_INNODB_MMAP - ; -#else - { return parse_mtr(if_exists); } -#endif + static parse_mtr_result parse_mmap(bool if_exists) noexcept; /** Erase log records for a page. */ void erase(map::iterator p); diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index 9c3f8fe1f65..c9b0bfca1e0 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -169,9 +169,6 @@ using the call command. */ #define UNIV_INLINE static inline #define UNIV_WORD_SIZE SIZEOF_SIZE_T -#if SIZEOF_SIZE_T == 8 -# define HAVE_INNODB_MMAP -#endif /** The following alignment is used in memory allocations in memory heap management to ensure correct alignment for doubles etc. */ diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index 378528e78c3..e2f26f0dcad 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -187,7 +187,6 @@ void log_file_t::write(os_offset_t offset, span buf) noexcept abort(); } -#ifdef HAVE_INNODB_MMAP # ifdef HAVE_PMEM # include "cache.h" # endif @@ -203,6 +202,10 @@ static void *log_mmap(os_file_t file, # endif os_offset_t size) { +#if SIZEOF_SIZE_T < 8 + if (size != os_offset_t(size_t(size))) + return MAP_FAILED; +#endif if (my_system_page_size > 4096) return MAP_FAILED; # ifndef HAVE_PMEM @@ -300,20 +303,17 @@ remap: # endif return ptr; } -#endif #if defined __linux__ || defined _WIN32 /** Display a message about opening the log */ ATTRIBUTE_COLD static void log_file_message() { sql_print_information("InnoDB: %s (block size=%u bytes)", -# ifdef HAVE_INNODB_MMAP log_sys.log_mmap ? (log_sys.log_buffered ? "Memory-mapped log" : "Memory-mapped unbuffered log") : -# endif log_sys.log_buffered ? "Buffered log writes" : "File system buffers for log disabled", @@ -332,7 +332,6 @@ bool log_t::attach(log_file_t file, os_offset_t size) ut_ad(!buf); ut_ad(!flush_buf); ut_ad(!writer); -#ifdef HAVE_INNODB_MMAP if (size) { # ifdef HAVE_PMEM @@ -363,7 +362,6 @@ bool log_t::attach(log_file_t file, os_offset_t size) } } log_mmap= false; -#endif buf= static_cast(ut_malloc_dontdump(buf_size, PSI_INSTRUMENT_ME)); if (!buf) { @@ -400,9 +398,7 @@ bool log_t::attach(log_file_t file, os_offset_t size) writer_update(); memset_aligned<512>(checkpoint_buf, 0, write_size); -#ifdef HAVE_INNODB_MMAP func_exit: -#endif log_file_message(); return true; } @@ -477,25 +473,19 @@ ATTRIBUTE_COLD static void log_close_failed(dberr_t err) ib::fatal() << "closing ib_logfile0 failed: " << err; } -#ifdef HAVE_INNODB_MMAP void log_t::close_file(bool really_close) -#else -void log_t::close_file() -#endif { -#ifdef HAVE_INNODB_MMAP if (is_mmap()) { ut_ad(!checkpoint_buf); ut_ad(!flush_buf); if (buf) { - my_munmap(buf, file_size); + my_munmap(buf, size_t(file_size)); buf= nullptr; } } else -#endif { ut_ad(!buf == !flush_buf); ut_ad(!buf == !checkpoint_buf); @@ -512,9 +502,7 @@ void log_t::close_file() writer= nullptr; -#ifdef HAVE_INNODB_MMAP if (really_close) -#endif if (is_opened()) if (const dberr_t err= log.close()) log_close_failed(err); @@ -621,14 +609,10 @@ log_t::resize_start_status log_t::resize_start(os_offset_t size) noexcept void *ptr= nullptr, *ptr2= nullptr; success= os_file_set_size(path.c_str(), resize_log.m_file, size); if (!success); -#ifdef HAVE_INNODB_MMAP +#ifdef HAVE_PMEM else if (is_mmap()) { - ptr= ::log_mmap(resize_log.m_file, -#ifdef HAVE_PMEM - is_pmem, -#endif - size); + ptr= ::log_mmap(resize_log.m_file, is_pmem, size); if (ptr == MAP_FAILED) goto alloc_fail; @@ -636,6 +620,7 @@ log_t::resize_start_status log_t::resize_start(os_offset_t size) noexcept #endif else { + ut_ad(!is_mmap()); ptr= ut_malloc_dontdump(buf_size, PSI_INSTRUMENT_ME); if (ptr) { @@ -705,21 +690,26 @@ void log_t::resize_abort() noexcept if (resize_in_progress() > 1) { - if (!is_mmap()) +#ifdef HAVE_PMEM + const bool is_mmap{this->is_mmap()}; +#else + constexpr bool is_mmap{false}; +#endif + if (!is_mmap) { ut_free_dodump(resize_buf, buf_size); ut_free_dodump(resize_flush_buf, buf_size); resize_flush_buf= nullptr; } -#ifdef HAVE_INNODB_MMAP else { ut_ad(!resize_log.is_opened()); ut_ad(!resize_flush_buf); +#ifdef HAVE_PMEM if (resize_buf) my_munmap(resize_buf, resize_target); +#endif /* HAVE_PMEM */ } -#endif if (resize_log.is_opened()) resize_log.close(); resize_buf= nullptr; @@ -1226,7 +1216,6 @@ ATTRIBUTE_COLD void log_write_and_flush_prepare() group_commit_lock::ACQUIRED); } -#ifdef HAVE_INNODB_MMAP void log_t::clear_mmap() { if (!is_mmap() || @@ -1260,7 +1249,6 @@ void log_t::clear_mmap() } log_resize_release(); } -#endif /** Durably write the log up to log_sys.get_lsn(). */ ATTRIBUTE_COLD void log_write_and_flush() diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 570a85d97dd..d7aef5292d7 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -2285,7 +2285,6 @@ struct recv_buf } }; -#ifdef HAVE_INNODB_MMAP /** Ring buffer wrapper for log_sys.buf[]; recv_sys.len == log_sys.file_size */ struct recv_ring : public recv_buf { @@ -2417,7 +2416,6 @@ struct recv_ring : public recv_buf return log_decrypt_buf(iv, tmp + s, b, static_cast(len)); } }; -#endif template void recv_sys_t::rewind(source &l, source &begin) noexcept @@ -3152,7 +3150,6 @@ template recv_sys_t::parse_mtr_result recv_sys_t::parse_mtr(bool) noexcept; -#ifdef HAVE_INNODB_MMAP template recv_sys_t::parse_mtr_result recv_sys_t::parse_mmap(bool if_exists) noexcept { @@ -3173,7 +3170,6 @@ recv_sys_t::parse_mtr_result recv_sys_t::parse_mmap(bool if_exists) noexcept template recv_sys_t::parse_mtr_result recv_sys_t::parse_mmap(bool) noexcept; -#endif /** Apply the hashed log records to the page, if the page lsn is less than the lsn of a log record. diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index 2cb0e57df27..310e509074d 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -1212,7 +1212,7 @@ inline void log_t::resize_write(lsn_t lsn, const byte *end, size_t len, end-= len; size_t s; -#ifdef HAVE_INNODB_MMAP +#ifdef HAVE_PMEM if (!resize_flush_buf) { ut_ad(is_mmap()); diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index f0500b1a744..e32ed6e4710 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -1879,15 +1879,11 @@ skip_monitors: if (srv_print_verbose_log) { sql_print_information("InnoDB: " "log sequence number " LSN_PF -#ifdef HAVE_INNODB_MMAP "%s" -#endif "; transaction id " TRX_ID_FMT, recv_sys.lsn, -#ifdef HAVE_INNODB_MMAP log_sys.is_mmap() ? " (memory-mapped)" : "", -#endif trx_sys.get_max_trx_id()); } From 4fc3a44bab04fcb0825486c6806cb3e94deb03da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 13 Jan 2025 07:28:40 +0200 Subject: [PATCH 040/213] MDEV-33447 fixup: pmem_persist() on RISC-V and LoongArch Let us enable pmem_persist() on RISC-V and LoongArch, because those are available in the Debian CI. In commit 3f9f5ca48e6be55613926964314f550c8ca8542d these were initially disabled by default. According to the available documentation, these instructions are available in all ISA versions. On LoongArch there would also be __builtin_loongarch_dbar() that generates the same code. --- storage/innobase/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index 2c0384575e8..7dde90286f5 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -49,7 +49,7 @@ IF(UNIX) LINK_LIBRARIES(numa) ENDIF() IF(CMAKE_SIZEOF_VOID_P EQUAL 8) - IF(CMAKE_SYSTEM_PROCESSOR MATCHES "(aarch|AARCH|p(ower)?pc|x86_|amd)64") + IF(CMAKE_SYSTEM_PROCESSOR MATCHES "(aarch|AARCH|p(ower)?pc|x86_|amd|loongarch|riscv)64") OPTION(WITH_INNODB_PMEM "Support memory-mapped InnoDB redo log" ON) ELSE() # Disable by default on ISA that are not covered by our CI OPTION(WITH_INNODB_PMEM "Support memory-mapped InnoDB redo log" OFF) From d5a417b9d55ac2744b600463a1abaf065772d678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 13 Jan 2025 09:14:30 +0200 Subject: [PATCH 041/213] MDEV-35827 The generic MY_RELAX_CPU is expensive MY_RELAX_CPU(): On GCC and compatible compilers (including clang and its derivatives), let us use a null inline assembler block as the fallback. This should benefit s390x and LoongArch, for example. Also, let us remove the generic fallback block that does exactly the opposite of what this function aims to achieve: avoid hogging the memory bus so that other threads will have a chance to let our spin loop to proceed. On RISC-V, we will use __builtin_riscv_pause() which is a valid instruction encoding in all ISA versions according to https://gcc.gnu.org/pipermail/gcc-patches/2021-January/562936.html --- include/my_cpu.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/include/my_cpu.h b/include/my_cpu.h index 003087dd94d..67da4f93946 100644 --- a/include/my_cpu.h +++ b/include/my_cpu.h @@ -101,13 +101,11 @@ static inline void MY_RELAX_CPU(void) /* Changed from __ppc_get_timebase for musl compatibility */ __builtin_ppc_get_timebase(); #endif -#elif defined __GNUC__ && (defined __arm__ || defined __aarch64__) +#elif defined __GNUC__ && defined __riscv + __builtin_riscv_pause(); +#elif defined __GNUC__ /* Mainly, prevent the compiler from optimizing away delay loops */ __asm__ __volatile__ ("":::"memory"); -#else - int32 var, oldval = 0; - my_atomic_cas32_strong_explicit(&var, &oldval, 1, MY_MEMORY_ORDER_RELAXED, - MY_MEMORY_ORDER_RELAXED); #endif } From aa35f62f1c9b7cba0720d250a86294d686f8eb99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 13 Jan 2025 10:41:40 +0200 Subject: [PATCH 042/213] MDEV-35810 Missing error handling in log resizing log_t::resize_start(): If the ib_logfile101 cannot be created, be sure to reset log_sys.resize_lsn. log_t::resize_abort(): In case SET GLOBAL innodb_log_file_size is aborted, delete the ib_logfile101. --- mysql-test/include/mtr_check.sql | 1 + .../suite/innodb/r/log_file_size_online.result | 8 +++++++- mysql-test/suite/innodb/t/log_file_size_online.test | 12 +++++++++++- storage/innobase/log/log0log.cc | 4 +++- 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/mysql-test/include/mtr_check.sql b/mysql-test/include/mtr_check.sql index 5d73d1f59f1..360f7b40bb8 100644 --- a/mysql-test/include/mtr_check.sql +++ b/mysql-test/include/mtr_check.sql @@ -31,6 +31,7 @@ BEGIN WHERE variable_name NOT IN ('timestamp') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' + AND variable_name != 'INNODB_LOG_FILE_BUFFERING' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' diff --git a/mysql-test/suite/innodb/r/log_file_size_online.result b/mysql-test/suite/innodb/r/log_file_size_online.result index 7b2b23bd776..8dcd9a47b2f 100644 --- a/mysql-test/suite/innodb/r/log_file_size_online.result +++ b/mysql-test/suite/innodb/r/log_file_size_online.result @@ -25,8 +25,14 @@ SET GLOBAL innodb_log_file_buffering=ON; SET GLOBAL innodb_log_file_buffering=@save; SET GLOBAL innodb_log_file_mmap=OFF; Got one of the listed errors -SET GLOBAL innodb_log_file_size=5242880; connect con1,localhost,root; +SET GLOBAL innodb_log_file_size=7340032; +connection default; +KILL QUERY @id; +connection con1; +connection default; +SET GLOBAL innodb_log_file_size=5242880; +connection con1; UPDATE t SET b='' WHERE a<10; connection default; SHOW VARIABLES LIKE 'innodb_log_file_size'; diff --git a/mysql-test/suite/innodb/t/log_file_size_online.test b/mysql-test/suite/innodb/t/log_file_size_online.test index bf9f3510592..fb6722ee8d7 100644 --- a/mysql-test/suite/innodb/t/log_file_size_online.test +++ b/mysql-test/suite/innodb/t/log_file_size_online.test @@ -36,9 +36,19 @@ SET GLOBAL innodb_log_file_buffering=@save; --error ER_INCORRECT_GLOBAL_LOCAL_VAR,ER_UNKNOWN_SYSTEM_VARIABLE SET GLOBAL innodb_log_file_mmap=OFF; +--connect con1,localhost,root +let $ID= `SELECT @id := CONNECTION_ID()`; +send SET GLOBAL innodb_log_file_size=7340032; +--connection default +let $ignore= `SELECT @id := $ID`; +KILL QUERY @id; +--connection con1 +reap; + +--connection default send SET GLOBAL innodb_log_file_size=5242880; ---connect con1,localhost,root +--connection con1 send UPDATE t SET b='' WHERE a<10; --connection default diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index e2f26f0dcad..0e9d4c9ad45 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -663,9 +663,9 @@ log_t::resize_start_status log_t::resize_start(os_offset_t size) noexcept writer_update(); } - resize_lsn.store(start_lsn, std::memory_order_relaxed); status= success ? RESIZE_STARTED : RESIZE_FAILED; } + resize_lsn.store(start_lsn, std::memory_order_relaxed); } log_resize_release(); @@ -715,6 +715,8 @@ void log_t::resize_abort() noexcept resize_buf= nullptr; resize_target= 0; resize_lsn.store(0, std::memory_order_relaxed); + std::string path{get_log_file_path("ib_logfile101")}; + IF_WIN(DeleteFile(path.c_str()), unlink(path.c_str())); } writer_update(); From 0d35fe6e5761cbee731ffcac55f2bf8eaf2a6a8f Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Mon, 23 Dec 2024 22:36:01 +0100 Subject: [PATCH 043/213] MDEV-35326: Memory Leak in init_io_cache_ext upon SHUTDOWN The problems were that: 1) resources was freed "asimetric" normal execution in send_eof, in case of error in destructor. 2) destructor was not called in case of SP for result objects. (so if the last SP execution ended with error resorces was not freeded on reinit before execution (cleanup() called before next execution) and destructor also was not called due to lack of delete call for the object) Result cleanup() renamed to reset_for_next_ps_execution() to better reflect function(). All result method revised and freeing resources made "symetric". Destructor of result object called for SP. Added skipped invalidation in case of error in insert. Removed misleading naming of reset(thd) (could be mixed with with reset()). --- sql/item_subselect.cc | 6 +- sql/sp_head.cc | 11 ++++ sql/sp_head.h | 11 +--- sql/sql_class.cc | 56 +++++++++++-------- sql/sql_class.h | 48 ++++++++-------- sql/sql_delete.cc | 14 +++++ sql/sql_insert.cc | 24 +++++++- sql/sql_prepare.cc | 2 +- sql/sql_union.cc | 10 ++-- sql/sql_update.cc | 14 +++++ .../spider/bugfix/r/mdev_35326.result | 14 +++++ .../spider/bugfix/t/mdev_35326.test | 21 +++++++ 12 files changed, 162 insertions(+), 69 deletions(-) create mode 100644 storage/spider/mysql-test/spider/bugfix/r/mdev_35326.result create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_35326.test diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index c0ac4022cd9..8da808ca3a0 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -3753,7 +3753,7 @@ void subselect_single_select_engine::cleanup() DBUG_ENTER("subselect_single_select_engine::cleanup"); prepared= executed= 0; join= 0; - result->cleanup(); + result->reset_for_next_ps_execution(); select_lex->uncacheable&= ~UNCACHEABLE_DEPENDENT_INJECTED; DBUG_VOID_RETURN; } @@ -3763,7 +3763,7 @@ void subselect_union_engine::cleanup() { DBUG_ENTER("subselect_union_engine::cleanup"); unit->reinit_exec_mechanism(); - result->cleanup(); + result->reset_for_next_ps_execution(); unit->uncacheable&= ~UNCACHEABLE_DEPENDENT_INJECTED; for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select()) sl->uncacheable&= ~UNCACHEABLE_DEPENDENT_INJECTED; @@ -5436,7 +5436,7 @@ void subselect_hash_sj_engine::cleanup() } DBUG_ASSERT(lookup_engine->engine_type() == UNIQUESUBQUERY_ENGINE); lookup_engine->cleanup(); - result->cleanup(); /* Resets the temp table as well. */ + result->reset_for_next_ps_execution(); /* Resets the temp table as well. */ DBUG_ASSERT(tmp_table); free_tmp_table(thd, tmp_table); tmp_table= NULL; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 506e755c2fd..c751636fbf7 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -3665,6 +3665,17 @@ int sp_lex_keeper::cursor_reset_lex_and_exec_core(THD *thd, uint *nextp, return res; } +sp_lex_keeper::~sp_lex_keeper() +{ + if (m_lex_resp) + { + /* Prevent endless recursion. */ + m_lex->sphead= NULL; + delete m_lex->result; + lex_end(m_lex); + delete m_lex; + } +} /* sp_instr class functions diff --git a/sql/sp_head.h b/sql/sp_head.h index 3de8e843753..ba677053e87 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -1273,16 +1273,7 @@ public: { lex->sp_lex_in_use= TRUE; } - virtual ~sp_lex_keeper() - { - if (m_lex_resp) - { - /* Prevent endless recursion. */ - m_lex->sphead= NULL; - lex_end(m_lex); - delete m_lex; - } - } + virtual ~sp_lex_keeper(); /** Prepare execution of instruction using LEX, if requested check whenever diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 73e182edd0f..8cb5b4954aa 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -3066,7 +3066,7 @@ void Item_change_list::rollback_item_tree_changes() ** Functions to provide a interface to select results *****************************************************************************/ -void select_result::cleanup() +void select_result::reset_for_next_ps_execution() { /* do nothing */ } @@ -3135,6 +3135,7 @@ void select_send::abort_result_set() */ thd->spcont->end_partial_result_set= TRUE; } + reset_for_next_ps_execution(); DBUG_VOID_RETURN; } @@ -3145,7 +3146,7 @@ void select_send::abort_result_set() stored procedure statement. */ -void select_send::cleanup() +void select_send::reset_for_next_ps_execution() { is_result_set_started= FALSE; } @@ -3183,7 +3184,7 @@ bool select_send::send_eof() if (unlikely(thd->is_error())) return TRUE; ::my_eof(thd); - is_result_set_started= 0; + reset_for_next_ps_execution(); return FALSE; } @@ -3192,10 +3193,22 @@ bool select_send::send_eof() Handling writing to file ************************************************************************/ +bool select_to_file::free_recources() +{ + if (file >= 0) + { + (void) end_io_cache(&cache); + bool error= mysql_file_close(file, MYF(MY_WME)); + file= -1; + return error; + } + return FALSE; +} + bool select_to_file::send_eof() { - int error= MY_TEST(end_io_cache(&cache)); - if (unlikely(mysql_file_close(file, MYF(MY_WME))) || + int error= false; + if (unlikely(free_recources()) || unlikely(thd->is_error())) error= true; @@ -3203,20 +3216,19 @@ bool select_to_file::send_eof() { ::my_ok(thd,row_count); } - file= -1; return error; } +void select_to_file::abort_result_set() +{ + select_result_interceptor::abort_result_set(); + free_recources(); +} -void select_to_file::cleanup() +void select_to_file::reset_for_next_ps_execution() { /* In case of error send_eof() may be not called: close the file here. */ - if (file >= 0) - { - (void) end_io_cache(&cache); - mysql_file_close(file, MYF(0)); - file= -1; - } + free_recources(); path[0]= '\0'; row_count= 0; } @@ -3224,12 +3236,8 @@ void select_to_file::cleanup() select_to_file::~select_to_file() { - if (file >= 0) - { // This only happens in case of error - (void) end_io_cache(&cache); - mysql_file_close(file, MYF(0)); - file= -1; - } + DBUG_ASSERT(file < 0); + free_recources(); // just in case } /*************************************************************************** @@ -3716,9 +3724,9 @@ int select_singlerow_subselect::send_data(List &items) } -void select_max_min_finder_subselect::cleanup() +void select_max_min_finder_subselect::reset_for_next_ps_execution() { - DBUG_ENTER("select_max_min_finder_subselect::cleanup"); + DBUG_ENTER("select_max_min_finder_subselect::reset_for_next_ps_execution"); cache= 0; DBUG_VOID_RETURN; } @@ -3943,7 +3951,7 @@ bool select_dumpvar::check_simple_select() const } -void select_dumpvar::cleanup() +void select_dumpvar::reset_for_next_ps_execution() { row_count= 0; } @@ -4372,10 +4380,10 @@ void select_materialize_with_stats::reset() } -void select_materialize_with_stats::cleanup() +void select_materialize_with_stats::reset_for_next_ps_execution() { reset(); - select_unit::cleanup(); + select_unit::reset_for_next_ps_execution(); } diff --git a/sql/sql_class.h b/sql/sql_class.h index 28aef92c31e..032d0bc2606 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -5585,7 +5585,8 @@ public: */ virtual int send_data(List &items)=0; virtual ~select_result_sink() = default; - void reset(THD *thd_arg) { thd= thd_arg; } + // Used in cursors to initialize and reset + void reinit(THD *thd_arg) { thd= thd_arg; } }; class select_result_interceptor; @@ -5659,15 +5660,11 @@ public: */ virtual bool check_simple_select() const; virtual void abort_result_set() {} - /* - Cleanup instance of this class for next execution of a prepared - statement/stored procedure. - */ - virtual void cleanup(); + virtual void reset_for_next_ps_execution(); void set_thd(THD *thd_arg) { thd= thd_arg; } - void reset(THD *thd_arg) + void reinit(THD *thd_arg) { - select_result_sink::reset(thd_arg); + select_result_sink::reinit(thd_arg); unit= NULL; } #ifdef EMBEDDED_LIBRARY @@ -5773,9 +5770,9 @@ public: elsewhere. (this is used by ANALYZE $stmt feature). */ void disable_my_ok_calls() { suppress_my_ok= true; } - void reset(THD *thd_arg) + void reinit(THD *thd_arg) { - select_result::reset(thd_arg); + select_result::reinit(thd_arg); suppress_my_ok= false; } protected: @@ -5827,7 +5824,7 @@ private: {} void reset(THD *thd_arg) { - select_result_interceptor::reset(thd_arg); + select_result_interceptor::reinit(thd_arg); spvar_list= NULL; field_count= 0; } @@ -5871,7 +5868,7 @@ public: void reset(THD *thd_arg, sp_lex_keeper *lex_keeper) { sp_cursor_statistics::reset(); - result.reset(thd_arg); + result.reinit(thd_arg); m_lex_keeper= lex_keeper; server_side_cursor= NULL; } @@ -5899,7 +5896,7 @@ public: bool send_eof() override; bool check_simple_select() const override { return FALSE; } void abort_result_set() override; - void cleanup() override; + void reset_for_next_ps_execution() override; select_result_interceptor *result_interceptor() override { return NULL; } }; @@ -5934,7 +5931,9 @@ public: { path[0]=0; } ~select_to_file(); bool send_eof() override; - void cleanup() override; + void abort_result_set() override; + void reset_for_next_ps_execution() override; + bool free_recources(); }; @@ -6011,7 +6010,7 @@ class select_insert :public select_result_interceptor { bool send_eof() override; void abort_result_set() override; /* not implemented: select_insert is never re-used in prepared statements */ - void cleanup() override; + void reset_for_next_ps_execution() override; }; @@ -6231,7 +6230,7 @@ public: int delete_record(); bool send_eof() override; virtual bool flush(); - void cleanup() override; + void reset_for_next_ps_execution() override; virtual bool create_result_table(THD *thd, List *column_types, bool is_distinct, ulonglong options, const LEX_CSTRING *alias, @@ -6406,9 +6405,10 @@ class select_union_recursive :public select_unit */ List rec_table_refs; /* - The count of how many times cleanup() was called with cleaned==false - for the unit specifying the recursive CTE for which this object was created - or for the unit specifying a CTE that mutually recursive with this CTE. + The count of how many times reset_for_next_ps_execution() was called with + cleaned==false for the unit specifying the recursive CTE for which this + object was created or for the unit specifying a CTE that mutually + recursive with this CTE. */ uint cleanup_count; long row_counter; @@ -6427,7 +6427,7 @@ class select_union_recursive :public select_unit bool create_table, bool keep_row_order, uint hidden) override; - void cleanup() override; + void reset_for_next_ps_execution() override; }; /** @@ -6497,7 +6497,7 @@ public: { result->abort_result_set(); /* purecov: inspected */ } - void cleanup() override + void reset_for_next_ps_execution() override { send_records= 0; } @@ -6600,7 +6600,7 @@ public: uint hidden) override; bool init_result_table(ulonglong select_options); int send_data(List &items) override; - void cleanup() override; + void reset_for_next_ps_execution() override; ha_rows get_null_count_of_col(uint idx) { DBUG_ASSERT(idx < table->s->fields); @@ -6633,7 +6633,7 @@ public: bool mx, bool all): select_subselect(thd_arg, item_arg), cache(0), fmax(mx), is_all(all) {} - void cleanup() override; + void reset_for_next_ps_execution() override; int send_data(List &items) override; bool cmp_real(); bool cmp_int(); @@ -7049,7 +7049,7 @@ public: int send_data(List &items) override; bool send_eof() override; bool check_simple_select() const override; - void cleanup() override; + void reset_for_next_ps_execution() override; }; /* Bits in sql_command_flags */ diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 25b3aef3ebe..fa677feb551 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -1422,6 +1422,13 @@ void multi_delete::abort_result_set() { DBUG_ENTER("multi_delete::abort_result_set"); + /**************************************************************************** + + NOTE: if you change here be aware that almost the same code is in + multi_delete::send_eof(). + + ***************************************************************************/ + /* the error was handled or nothing deleted and no side effects return */ if (error_handled || (!thd->transaction->stmt.modified_non_trans_table && !deleted)) @@ -1622,6 +1629,13 @@ bool multi_delete::send_eof() /* reset used flags */ THD_STAGE_INFO(thd, stage_end); + /**************************************************************************** + + NOTE: if you change here be aware that almost the same code is in + multi_delete::abort_result_set(). + + ***************************************************************************/ + if (thd->transaction->stmt.modified_non_trans_table) thd->transaction->all.modified_non_trans_table= TRUE; thd->transaction->all.m_unsafe_rollback_flags|= diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index e1d87e29869..000695c5399 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -4131,7 +4131,7 @@ int select_insert::prepare2(JOIN *) } -void select_insert::cleanup() +void select_insert::reset_for_next_ps_execution() { /* select_insert/select_create are never re-used in prepared statement */ DBUG_ASSERT(0); @@ -4245,6 +4245,13 @@ bool select_insert::prepare_eof() DBUG_PRINT("enter", ("trans_table: %d, table_type: '%s'", trans_table, table->file->table_type())); + /**************************************************************************** + + NOTE: if you change here be aware that almost the same code is in + select_insert::abort_result_set(). + + ****************************************************************************/ + #ifdef WITH_WSREP error= (thd->wsrep_cs().current_error()) ? -1 : (thd->locked_tables_mode <= LTM_LOCK_TABLES) ? @@ -4377,6 +4384,12 @@ void select_insert::abort_result_set() */ if (table && table->file->is_open()) { + /**************************************************************************** + + NOTE: if you change here be aware that almost the same code is in + select_insert::prepare_eof(). + + ****************************************************************************/ bool changed, transactional_table; /* If we are not in prelocked mode, we end the bulk insert started @@ -4404,7 +4417,14 @@ void select_insert::abort_result_set() If table creation failed, the number of rows modified will also be zero, so no check for that is made. */ - changed= (info.copied || info.deleted || info.updated); + if ((changed= (info.copied || info.deleted || info.updated))) + { + /* + We must invalidate the table in the query cache before binlog writing + and ha_autocommit_or_rollback. + */ + query_cache_invalidate3(thd, table, 1); + } transactional_table= table->file->has_transactions_and_rollback(); if (thd->transaction->stmt.modified_non_trans_table || thd->log_current_statement) diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 93e81b2025d..9d53d7cf543 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -3194,7 +3194,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) if (lex->result) { - lex->result->cleanup(); + lex->result->reset_for_next_ps_execution(); lex->result->set_thd(thd); } lex->allow_sum_func.clear_all(); diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 53e604bfa92..09dc045b543 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -547,7 +547,7 @@ int select_unit::delete_record() tables of JOIN - exec_tmp_table_[1 | 2]. */ -void select_unit::cleanup() +void select_unit::reset_for_next_ps_execution() { table->file->extra(HA_EXTRA_RESET_STATE); table->file->ha_delete_all_rows(); @@ -902,11 +902,11 @@ bool select_unit_ext::send_eof() return (MY_TEST(error)); } -void select_union_recursive::cleanup() +void select_union_recursive::reset_for_next_ps_execution() { if (table) { - select_unit::cleanup(); + select_unit::reset_for_next_ps_execution(); free_tmp_table(thd, table); } @@ -2194,7 +2194,7 @@ bool st_select_lex_unit::exec() if (uncacheable || !item || !item->assigned() || describe) { if (!fake_select_lex && !(with_element && with_element->is_recursive)) - union_result->cleanup(); + union_result->reset_for_next_ps_execution(); for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select()) { ha_rows records_at_start= 0; @@ -2636,7 +2636,7 @@ bool st_select_lex_unit::cleanup() { if (union_result) { - ((select_union_recursive *) union_result)->cleanup(); + ((select_union_recursive *) union_result)->reset_for_next_ps_execution(); delete union_result; union_result= 0; } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 4a13d83d52f..9dfb681b119 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -2743,6 +2743,13 @@ void multi_update::abort_result_set() (!thd->transaction->stmt.modified_non_trans_table && !updated))) return; + /**************************************************************************** + + NOTE: if you change here be aware that almost the same code is in + multi_update::send_eof(). + + ***************************************************************************/ + /* Something already updated so we have to invalidate cache */ if (updated) query_cache_invalidate3(thd, update_tables, 1); @@ -3072,6 +3079,13 @@ bool multi_update::send_eof() killed_status= (local_error == 0) ? NOT_KILLED : thd->killed; THD_STAGE_INFO(thd, stage_end); + /**************************************************************************** + + NOTE: if you change here be aware that almost the same code is in + multi_update::abort_result_set(). + + ***************************************************************************/ + /* We must invalidate the query cache before binlog writing and ha_autocommit_... */ diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_35326.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_35326.result new file mode 100644 index 00000000000..41481447a6c --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_35326.result @@ -0,0 +1,14 @@ +for master_1 +for child2 +for child3 +CREATE TABLE t (c INT) ENGINE=Spider; +CREATE PROCEDURE p() CONTAINS SQL READS SQL DATA SELECT * FROM t INTO OUTFILE 'foo.txt'; +Warnings: +Warning 1287 ' INTO FROM...' instead +CALL p(); +ERROR HY000: Unable to connect to foreign data source: localhost +drop procedure p; +drop table t; +for master_1 +for child2 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_35326.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_35326.test new file mode 100644 index 00000000000..1ce8e1aa780 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_35326.test @@ -0,0 +1,21 @@ +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log + +let $MYSQLD_DATADIR= `select @@datadir`; + +CREATE TABLE t (c INT) ENGINE=Spider; +CREATE PROCEDURE p() CONTAINS SQL READS SQL DATA SELECT * FROM t INTO OUTFILE 'foo.txt'; +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +CALL p(); +remove_file $MYSQLD_DATADIR/test/foo.txt; +drop procedure p; +drop table t; + +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log From 14f42e12a42e5c5e787b101b2c4600e44ac90cab Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 13 Jan 2025 16:29:11 +0400 Subject: [PATCH 044/213] MDEV-35596 Assertion `type_handler()->result_type() == value.type_handler()->result_type()' failed in virtual bool Item_param::get_date(THD*, MYSQL_TIME*, date_mode_t) This is a cleanup for MDEV-25593. When binding from NULL, IGNORE or DEFAULT, value.type_handler should be set to &type_handler_null, to satisfy the DBUG_ASSERT in Item_param::get_date(). --- sql/item.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sql/item.cc b/sql/item.cc index dd9a9063e55..44bd4bbfbba 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4168,6 +4168,7 @@ void Item_param::set_null() max_length= 0; decimals= 0; state= NULL_VALUE; + value.set_handler(&type_handler_null); DBUG_VOID_RETURN; } @@ -4981,7 +4982,10 @@ void Item_param::set_default(bool set_type_handler_null) */ null_value= true; if (set_type_handler_null) + { + value.set_handler(&type_handler_null); set_handler(&type_handler_null); + } } void Item_param::set_ignore(bool set_type_handler_null) @@ -4990,7 +4994,10 @@ void Item_param::set_ignore(bool set_type_handler_null) state= IGNORE_VALUE; null_value= true; if (set_type_handler_null) + { + value.set_handler(&type_handler_null); set_handler(&type_handler_null); + } } /** From 1327f40f9649f399fec14d1dff0f2bbc55da749a Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 13 Jan 2025 17:51:51 +0400 Subject: [PATCH 045/213] MDEV-35596 Assertion `type_handler()->result_type() == value.type_handler()->result_type()' failed in virtual bool Item_param::get_date(THD*, MYSQL_TIME*, date_mode_t) Adding mtr tests forgotten in the previous commit. --- mysql-test/main/ps_11bugs.result | 35 ++++++++++++++++++++++++++++++++ mysql-test/main/ps_11bugs.test | 34 +++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/mysql-test/main/ps_11bugs.result b/mysql-test/main/ps_11bugs.result index 87a3487141b..985654eb283 100644 --- a/mysql-test/main/ps_11bugs.result +++ b/mysql-test/main/ps_11bugs.result @@ -245,4 +245,39 @@ NULL DEALLOCATE PREPARE stmt; SET timestamp=DEFAULT; SET time_zone=DEFAULT; +# +# MDEV-35596 Assertion `type_handler()->result_type() == value.type_handler()->result_type()' failed in virtual bool Item_param::get_date(THD*, MYSQL_TIME*, date_mode_t) +# +CREATE TABLE t (c TIMESTAMP); +PREPARE s FROM 'DELETE FROM t WHERE c=?'; +EXECUTE s USING 1; +INSERT INTO t (c) VALUES (now()); +EXECUTE s USING NULL; +DROP TABLE t; +CREATE TABLE t (c TIMESTAMP); +INSERT INTO t (c) VALUES ('2001-01-01 10:20:30'); +PREPARE s FROM 'DELETE FROM t WHERE c=?'; +EXECUTE s USING 1; +Warnings: +Warning 1292 Truncated incorrect datetime value: '1' +EXECUTE s USING NULL; +DROP TABLE t; +CREATE TABLE t (c TIMESTAMP); +INSERT INTO t (c) VALUES ('2001-01-01 10:20:30'); +PREPARE s FROM 'DELETE FROM t WHERE c=?'; +EXECUTE s USING 1; +Warnings: +Warning 1292 Truncated incorrect datetime value: '1' +EXECUTE s USING DEFAULT; +ERROR HY000: Default/ignore value is not supported for such parameter usage +DROP TABLE t; +CREATE TABLE t (c TIMESTAMP); +INSERT INTO t (c) VALUES ('2001-01-01 10:20:30'); +PREPARE s FROM 'DELETE FROM t WHERE c=?'; +EXECUTE s USING 1; +Warnings: +Warning 1292 Truncated incorrect datetime value: '1' +EXECUTE s USING IGNORE; +ERROR HY000: Default/ignore value is not supported for such parameter usage +DROP TABLE t; # End of 10.5 tests diff --git a/mysql-test/main/ps_11bugs.test b/mysql-test/main/ps_11bugs.test index 7a0843e9352..7cb5708d062 100644 --- a/mysql-test/main/ps_11bugs.test +++ b/mysql-test/main/ps_11bugs.test @@ -254,4 +254,38 @@ DEALLOCATE PREPARE stmt; SET timestamp=DEFAULT; SET time_zone=DEFAULT; +--echo # +--echo # MDEV-35596 Assertion `type_handler()->result_type() == value.type_handler()->result_type()' failed in virtual bool Item_param::get_date(THD*, MYSQL_TIME*, date_mode_t) +--echo # + +CREATE TABLE t (c TIMESTAMP); +PREPARE s FROM 'DELETE FROM t WHERE c=?'; +EXECUTE s USING 1; +INSERT INTO t (c) VALUES (now()); +EXECUTE s USING NULL; +DROP TABLE t; + +CREATE TABLE t (c TIMESTAMP); +INSERT INTO t (c) VALUES ('2001-01-01 10:20:30'); +PREPARE s FROM 'DELETE FROM t WHERE c=?'; +EXECUTE s USING 1; +EXECUTE s USING NULL; +DROP TABLE t; + +CREATE TABLE t (c TIMESTAMP); +INSERT INTO t (c) VALUES ('2001-01-01 10:20:30'); +PREPARE s FROM 'DELETE FROM t WHERE c=?'; +EXECUTE s USING 1; +--error ER_INVALID_DEFAULT_PARAM +EXECUTE s USING DEFAULT; +DROP TABLE t; + +CREATE TABLE t (c TIMESTAMP); +INSERT INTO t (c) VALUES ('2001-01-01 10:20:30'); +PREPARE s FROM 'DELETE FROM t WHERE c=?'; +EXECUTE s USING 1; +--error ER_INVALID_DEFAULT_PARAM +EXECUTE s USING IGNORE; +DROP TABLE t; + --echo # End of 10.5 tests From 46aaf328ce424aededdb61e59a48db05630563d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 13 Jan 2025 16:57:11 +0200 Subject: [PATCH 046/213] MDEV-35830 Fix innodb_undo_log_truncate in backup recv_sys_t::parse(): Correctly handle the storing==BACKUP case, and simplify some logic around storing==YES as well. The added test mariabackup.undo_truncate is based on an idea of Thirunarayanan Balathandayuthapani. It nondeterministically (not on every run) covers this logic, including the function backup_undo_trunc(), for both innodb_encrypt_log=ON and innodb_encrypt_log=OFF. Reviewed by: Debarun Banerjee --- .../mariabackup/undo_truncate.combinations | 4 + .../suite/mariabackup/undo_truncate.opt | 6 + .../suite/mariabackup/undo_truncate.result | 39 +++++++ .../suite/mariabackup/undo_truncate.test | 59 ++++++++++ storage/innobase/log/log0recv.cc | 104 +++++++++--------- 5 files changed, 159 insertions(+), 53 deletions(-) create mode 100644 mysql-test/suite/mariabackup/undo_truncate.combinations create mode 100644 mysql-test/suite/mariabackup/undo_truncate.opt create mode 100644 mysql-test/suite/mariabackup/undo_truncate.result create mode 100644 mysql-test/suite/mariabackup/undo_truncate.test diff --git a/mysql-test/suite/mariabackup/undo_truncate.combinations b/mysql-test/suite/mariabackup/undo_truncate.combinations new file mode 100644 index 00000000000..fe6a3ba58fd --- /dev/null +++ b/mysql-test/suite/mariabackup/undo_truncate.combinations @@ -0,0 +1,4 @@ +[clear] +--innodb-encrypt-log=OFF +[crypt] +--innodb-encrypt-log=ON diff --git a/mysql-test/suite/mariabackup/undo_truncate.opt b/mysql-test/suite/mariabackup/undo_truncate.opt new file mode 100644 index 00000000000..9b4f76ab5de --- /dev/null +++ b/mysql-test/suite/mariabackup/undo_truncate.opt @@ -0,0 +1,6 @@ +--innodb-undo-tablespaces=2 +--plugin-load-add=$FILE_KEY_MANAGEMENT_SO +--loose-file-key-management +--loose-file-key-management-filekey=FILE:$MTR_SUITE_DIR/filekeys-data.key +--loose-file-key-management-filename=$MTR_SUITE_DIR/filekeys-data.enc +--loose-file-key-management-encryption-algorithm=aes_cbc diff --git a/mysql-test/suite/mariabackup/undo_truncate.result b/mysql-test/suite/mariabackup/undo_truncate.result new file mode 100644 index 00000000000..a3bfb182dd8 --- /dev/null +++ b/mysql-test/suite/mariabackup/undo_truncate.result @@ -0,0 +1,39 @@ +SET GLOBAL innodb_undo_log_truncate = 0; +create table t1 (keyc int primary key default 0, c char(6)) engine=innodb; +create table t2 (keyc int primary key default 0, c char(6)) engine=innodb; +CREATE PROCEDURE p(t VARCHAR(64)) +BEGIN +DECLARE i TEXT DEFAULT 'insert into t1 select seq,repeat(chr(48),6) + from seq_1_to_20000'; +DECLARE u1 TEXT DEFAULT 'update t1 set c=repeat(chr(32),6)'; +DECLARE u2 TEXT DEFAULT 'update t1 set c=repeat(chr(64),6)'; +EXECUTE IMMEDIATE REPLACE(i,'t1', t); +EXECUTE IMMEDIATE REPLACE(u1,'t1', t); +EXECUTE IMMEDIATE REPLACE(u2,'t1', t); +END; +$$ +connect con1,localhost,root,,; +begin; +call p('t1'); +connection default; +call p('t2'); +connection con1; +commit; +disconnect con1; +connection default; +DROP PROCEDURE p; +SET GLOBAL innodb_undo_log_truncate = 1; +SET GLOBAL innodb_max_undo_log_size=DEFAULT; +SET GLOBAL innodb_max_purge_lag_wait=0; +# Prepare full backup +# shutdown server +# remove datadir +# xtrabackup move back +# restart +select count(*) from t1; +count(*) +20000 +select count(*) from t2; +count(*) +20000 +DROP TABLE t1,t2; diff --git a/mysql-test/suite/mariabackup/undo_truncate.test b/mysql-test/suite/mariabackup/undo_truncate.test new file mode 100644 index 00000000000..a23c9cf64ff --- /dev/null +++ b/mysql-test/suite/mariabackup/undo_truncate.test @@ -0,0 +1,59 @@ +--source include/have_innodb.inc +--source include/not_embedded.inc +--source include/have_sequence.inc +--source include/have_file_key_management.inc + +SET GLOBAL innodb_undo_log_truncate = 0; + +# +# Perform DML action using multiple clients and multiple undo tablespace. +# + +create table t1 (keyc int primary key default 0, c char(6)) engine=innodb; +create table t2 (keyc int primary key default 0, c char(6)) engine=innodb; + +DELIMITER $$; +CREATE PROCEDURE p(t VARCHAR(64)) +BEGIN + DECLARE i TEXT DEFAULT 'insert into t1 select seq,repeat(chr(48),6) + from seq_1_to_20000'; + DECLARE u1 TEXT DEFAULT 'update t1 set c=repeat(chr(32),6)'; + DECLARE u2 TEXT DEFAULT 'update t1 set c=repeat(chr(64),6)'; + EXECUTE IMMEDIATE REPLACE(i,'t1', t); + EXECUTE IMMEDIATE REPLACE(u1,'t1', t); + EXECUTE IMMEDIATE REPLACE(u2,'t1', t); +END; +$$ +DELIMITER ;$$ + +connect (con1,localhost,root,,); +begin; +send call p('t1'); + +connection default; +call p('t2'); + +connection con1; +reap; +commit; +disconnect con1; +connection default; +DROP PROCEDURE p; + +SET GLOBAL innodb_undo_log_truncate = 1; +SET GLOBAL innodb_max_undo_log_size=DEFAULT; +SET GLOBAL innodb_max_purge_lag_wait=0; +let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; + +--disable_result_log +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir --throttle=1000; +--echo # Prepare full backup +exec $XTRABACKUP --prepare --target-dir=$targetdir; +--enable_result_log + +source include/restart_and_restore.inc; +select count(*) from t1; +select count(*) from t2; +# Cleanup +rmdir $targetdir; +DROP TABLE t1,t2; diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index d7aef5292d7..4b794bc7fee 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -2698,43 +2698,57 @@ restart: mach_write_to_4(iv + 8, space_id); mach_write_to_4(iv + 12, page_no); } - got_page_op= !(b & 0x80); - if (!got_page_op); - else if (storing == BACKUP && srv_operation == SRV_OPERATION_BACKUP) - { - if (page_no == 0 && (b & 0xf0) == INIT_PAGE && first_page_init) - first_page_init(space_id); - continue; - } - else if (storing == YES && file_checkpoint && - space_id != TRX_SYS_SPACE && !srv_is_undo_tablespace(space_id)) - { - recv_spaces_t::iterator i= recv_spaces.lower_bound(space_id); - if (i != recv_spaces.end() && i->first == space_id); - else if (lsn < file_checkpoint) - /* We have not seen all records between the checkpoint and - FILE_CHECKPOINT. There should be a FILE_DELETE for this - tablespace later. */ - recv_spaces.emplace_hint(i, space_id, file_name_t("", false)); - else - { - const page_id_t id(space_id, page_no); - if (!srv_force_recovery) - { - ib::error() << "Missing FILE_DELETE or FILE_MODIFY for " << id - << " at " << lsn - << "; set innodb_force_recovery=1 to ignore the record."; - goto corrupted; - } - ib::warn() << "Ignoring record for " << id << " at " << lsn; - continue; - } - } DBUG_PRINT("ib_log", ("scan " LSN_PF ": rec %x len %zu page %u:%u", lsn, b, l - recs + rlen, space_id, page_no)); + got_page_op= !(b & 0x80); if (got_page_op) { + if (storing == BACKUP) + { + if (page_no == 0 && (b & 0xf0) == INIT_PAGE && first_page_init) + first_page_init(space_id); + else if (rlen == 1 && undo_space_trunc) + { + mach_write_to_4(iv + 8, space_id); + mach_write_to_4(iv + 12, page_no); + byte eb[1/*type,length*/ + 5/*space_id*/ + 5/*page_no*/ + 1/*rlen*/]; + if (*l.copy_if_needed(iv, eb, recs, 1) == TRIM_PAGES) + undo_space_trunc(space_id); + } + continue; + } + if (storing == YES && UNIV_LIKELY(space_id != TRX_SYS_SPACE) && + !srv_is_undo_tablespace(space_id)) + { + ut_ad(file_checkpoint != 0); + recv_spaces_t::iterator i= recv_spaces.lower_bound(space_id); + if (i != recv_spaces.end() && i->first == space_id); + else if (lsn < file_checkpoint) + /* We have not seen all records between the checkpoint and + FILE_CHECKPOINT. There should be a FILE_DELETE for this + tablespace later. */ + recv_spaces.emplace_hint(i, space_id, file_name_t("", false)); + else + { + if (!srv_force_recovery) + { + sql_print_error("InnoDB: Missing FILE_DELETE or FILE_MODIFY for " + "[page id: space=" UINT32PF + ", page number=" UINT32PF "]" + " at " LSN_PF + "; set innodb_force_recovery=1 to" + " ignore the record.", + space_id, page_no, lsn); + goto corrupted; + } + sql_print_warning("InnoDB: Ignoring record for " + "[page id: space=" UINT32PF + ", page number=" UINT32PF "] at " LSN_PF, + space_id, page_no, lsn); + continue; + } + } same_page: if (!rlen); else if (UNIV_UNLIKELY(l - recs + rlen > srv_page_size)) @@ -2748,13 +2762,11 @@ restart: case FREE_PAGE: ut_ad(freed.emplace(id).second); /* the next record must not be same_page */ - if (storing != BACKUP) last_offset= 1; + last_offset= 1; goto free_or_init_page; case INIT_PAGE: - if (storing != BACKUP) last_offset= FIL_PAGE_TYPE; + last_offset= FIL_PAGE_TYPE; free_or_init_page: - if (storing == BACKUP) - continue; if (UNIV_UNLIKELY(rlen != 0)) goto record_corrupted; store_freed_or_init_rec(id, (b & 0x70) == FREE_PAGE); @@ -2799,17 +2811,6 @@ restart: continue; if (UNIV_UNLIKELY(!rlen)) goto record_corrupted; - if (storing == BACKUP) - { - if (rlen == 1 && undo_space_trunc) - { - cl= l.copy_if_needed(iv, decrypt_buf, recs, rlen); - if (*cl == TRIM_PAGES) - undo_space_trunc(space_id); - } - continue; - } - cl= l.copy_if_needed(iv, decrypt_buf, recs, rlen); if (rlen == 1 && *cl == TRIM_PAGES) { @@ -2823,10 +2824,9 @@ restart: trim({space_id, 0}, start_lsn); truncated_undo_spaces[space_id - srv_undo_space_id_start]= { start_lsn, page_no }; - if (storing != BACKUP) - /* the next record must not be same_page */ - last_offset= 1; - else if (undo_space_trunc) + /* the next record must not be same_page */ + last_offset= 1; + if (undo_space_trunc) undo_space_trunc(space_id); continue; } @@ -2850,8 +2850,6 @@ restart: case WRITE: case MEMMOVE: case MEMSET: - if (storing == BACKUP) - continue; if (storing == NO && UNIV_LIKELY(page_no != 0)) /* fil_space_set_recv_size_and_flags() is mandatory for storing==NO. It is only applicable to page_no == 0. Other than that, we can just From fe2f2377688cdf4862baff753f04f390aec17793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 13 Jan 2025 17:43:58 +0200 Subject: [PATCH 047/213] MDEV-35808 Test case to handle undo tablespace truncation in Mariabackup This is the test case from commit 46aaf328ce424aededdb61e59a48db05630563d5 (MDEV-35830) to cover backup_undo_trunc() in the regression tests of earlier major versions of mariadb-backup. --- .../mariabackup/undo_truncate.combinations | 4 ++ .../suite/mariabackup/undo_truncate.opt | 6 ++ .../suite/mariabackup/undo_truncate.result | 39 ++++++++++++ .../suite/mariabackup/undo_truncate.test | 59 +++++++++++++++++++ 4 files changed, 108 insertions(+) create mode 100644 mysql-test/suite/mariabackup/undo_truncate.combinations create mode 100644 mysql-test/suite/mariabackup/undo_truncate.opt create mode 100644 mysql-test/suite/mariabackup/undo_truncate.result create mode 100644 mysql-test/suite/mariabackup/undo_truncate.test diff --git a/mysql-test/suite/mariabackup/undo_truncate.combinations b/mysql-test/suite/mariabackup/undo_truncate.combinations new file mode 100644 index 00000000000..fe6a3ba58fd --- /dev/null +++ b/mysql-test/suite/mariabackup/undo_truncate.combinations @@ -0,0 +1,4 @@ +[clear] +--innodb-encrypt-log=OFF +[crypt] +--innodb-encrypt-log=ON diff --git a/mysql-test/suite/mariabackup/undo_truncate.opt b/mysql-test/suite/mariabackup/undo_truncate.opt new file mode 100644 index 00000000000..9b4f76ab5de --- /dev/null +++ b/mysql-test/suite/mariabackup/undo_truncate.opt @@ -0,0 +1,6 @@ +--innodb-undo-tablespaces=2 +--plugin-load-add=$FILE_KEY_MANAGEMENT_SO +--loose-file-key-management +--loose-file-key-management-filekey=FILE:$MTR_SUITE_DIR/filekeys-data.key +--loose-file-key-management-filename=$MTR_SUITE_DIR/filekeys-data.enc +--loose-file-key-management-encryption-algorithm=aes_cbc diff --git a/mysql-test/suite/mariabackup/undo_truncate.result b/mysql-test/suite/mariabackup/undo_truncate.result new file mode 100644 index 00000000000..a3bfb182dd8 --- /dev/null +++ b/mysql-test/suite/mariabackup/undo_truncate.result @@ -0,0 +1,39 @@ +SET GLOBAL innodb_undo_log_truncate = 0; +create table t1 (keyc int primary key default 0, c char(6)) engine=innodb; +create table t2 (keyc int primary key default 0, c char(6)) engine=innodb; +CREATE PROCEDURE p(t VARCHAR(64)) +BEGIN +DECLARE i TEXT DEFAULT 'insert into t1 select seq,repeat(chr(48),6) + from seq_1_to_20000'; +DECLARE u1 TEXT DEFAULT 'update t1 set c=repeat(chr(32),6)'; +DECLARE u2 TEXT DEFAULT 'update t1 set c=repeat(chr(64),6)'; +EXECUTE IMMEDIATE REPLACE(i,'t1', t); +EXECUTE IMMEDIATE REPLACE(u1,'t1', t); +EXECUTE IMMEDIATE REPLACE(u2,'t1', t); +END; +$$ +connect con1,localhost,root,,; +begin; +call p('t1'); +connection default; +call p('t2'); +connection con1; +commit; +disconnect con1; +connection default; +DROP PROCEDURE p; +SET GLOBAL innodb_undo_log_truncate = 1; +SET GLOBAL innodb_max_undo_log_size=DEFAULT; +SET GLOBAL innodb_max_purge_lag_wait=0; +# Prepare full backup +# shutdown server +# remove datadir +# xtrabackup move back +# restart +select count(*) from t1; +count(*) +20000 +select count(*) from t2; +count(*) +20000 +DROP TABLE t1,t2; diff --git a/mysql-test/suite/mariabackup/undo_truncate.test b/mysql-test/suite/mariabackup/undo_truncate.test new file mode 100644 index 00000000000..a23c9cf64ff --- /dev/null +++ b/mysql-test/suite/mariabackup/undo_truncate.test @@ -0,0 +1,59 @@ +--source include/have_innodb.inc +--source include/not_embedded.inc +--source include/have_sequence.inc +--source include/have_file_key_management.inc + +SET GLOBAL innodb_undo_log_truncate = 0; + +# +# Perform DML action using multiple clients and multiple undo tablespace. +# + +create table t1 (keyc int primary key default 0, c char(6)) engine=innodb; +create table t2 (keyc int primary key default 0, c char(6)) engine=innodb; + +DELIMITER $$; +CREATE PROCEDURE p(t VARCHAR(64)) +BEGIN + DECLARE i TEXT DEFAULT 'insert into t1 select seq,repeat(chr(48),6) + from seq_1_to_20000'; + DECLARE u1 TEXT DEFAULT 'update t1 set c=repeat(chr(32),6)'; + DECLARE u2 TEXT DEFAULT 'update t1 set c=repeat(chr(64),6)'; + EXECUTE IMMEDIATE REPLACE(i,'t1', t); + EXECUTE IMMEDIATE REPLACE(u1,'t1', t); + EXECUTE IMMEDIATE REPLACE(u2,'t1', t); +END; +$$ +DELIMITER ;$$ + +connect (con1,localhost,root,,); +begin; +send call p('t1'); + +connection default; +call p('t2'); + +connection con1; +reap; +commit; +disconnect con1; +connection default; +DROP PROCEDURE p; + +SET GLOBAL innodb_undo_log_truncate = 1; +SET GLOBAL innodb_max_undo_log_size=DEFAULT; +SET GLOBAL innodb_max_purge_lag_wait=0; +let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; + +--disable_result_log +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir --throttle=1000; +--echo # Prepare full backup +exec $XTRABACKUP --prepare --target-dir=$targetdir; +--enable_result_log + +source include/restart_and_restore.inc; +select count(*) from t1; +select count(*) from t2; +# Cleanup +rmdir $targetdir; +DROP TABLE t1,t2; From 133e26fd7dc454c5b154495ab876c76bbcfd1715 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 11 Dec 2024 09:34:18 +0200 Subject: [PATCH 048/213] MDEV-34924 : gtid_slave_pos table neven been deleted on non replica nodes (wsrep_gtid_mode = 1) Problem was caused by MDEV-31413 commit 277968aa where mysql.gtid_slave_pos table was replicated by Galera. However, as not all nodes in Galera cluster are replica nodes, rows were not deleted from table. In this fix this is corrected so that mysql.gtid_slave_pos table is not replicated by Galera. Instead when Galera node receives GTID event and wsrep_gtid_mode=1, this event is stored to mysql.gtid_slave_pos table. Added test case galera_2primary_replica for 2 async primaries replicating to galera cluster. Added test case galera_circular_replication where async primary replicates to galera cluster and one of the galera cluster nodes is master to async replica. Modified test case galera_restart_replica to monitor gtid positions and rows in mysql.gtid_pos_table. --- .../galera_2nodes_as_replica_2primary.cnf | 70 ++++++ .../galera/r/galera_2primary_replica.result | 95 +++++++ .../r/galera_circular_replication.result | 138 +++++++++++ .../galera/r/galera_restart_replica.result | 191 ++++++++------ .../galera/t/galera_2primary_replica.cnf | 22 ++ .../galera/t/galera_2primary_replica.test | 170 +++++++++++++ .../galera/t/galera_circular_replication.cnf | 25 ++ .../galera/t/galera_circular_replication.test | 234 ++++++++++++++++++ .../galera/t/galera_restart_replica.test | 197 ++++++++++----- sql/rpl_gtid.cc | 50 +--- sql/wsrep_applier.cc | 5 + sql/wsrep_schema.cc | 80 +++++- sql/wsrep_schema.h | 14 +- 13 files changed, 1110 insertions(+), 181 deletions(-) create mode 100644 mysql-test/suite/galera/galera_2nodes_as_replica_2primary.cnf create mode 100644 mysql-test/suite/galera/r/galera_2primary_replica.result create mode 100644 mysql-test/suite/galera/r/galera_circular_replication.result create mode 100644 mysql-test/suite/galera/t/galera_2primary_replica.cnf create mode 100644 mysql-test/suite/galera/t/galera_2primary_replica.test create mode 100644 mysql-test/suite/galera/t/galera_circular_replication.cnf create mode 100644 mysql-test/suite/galera/t/galera_circular_replication.test diff --git a/mysql-test/suite/galera/galera_2nodes_as_replica_2primary.cnf b/mysql-test/suite/galera/galera_2nodes_as_replica_2primary.cnf new file mode 100644 index 00000000000..714caf6ee67 --- /dev/null +++ b/mysql-test/suite/galera/galera_2nodes_as_replica_2primary.cnf @@ -0,0 +1,70 @@ +# +# This .cnf file creates a setup with 2 standard MariaDB servers, followed by a 2-node Galera cluster +# + +# Use default setting for mysqld processes +!include include/default_mysqld.cnf + +[mysqld] +loose-innodb +log-bin=mysqld-bin +log-slave-updates +binlog-format=row +innodb-autoinc-lock-mode=2 +default-storage-engine=innodb +# enforce read-committed characteristics across the cluster +# wsrep-causal-reads=ON +wsrep-sync-wait=15 + +[mysqld.1] +wsrep-on=1 +server-id=1 +#galera_port=@OPT.port +#ist_port=@OPT.port +#sst_port=@OPT.port +wsrep_provider=@ENV.WSREP_PROVIDER +wsrep_cluster_address=gcomm:// +wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.1.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;gcache.size=10M' +wsrep_node_address='127.0.0.1:@mysqld.1.#galera_port' +wsrep_node_incoming_address=127.0.0.1:@mysqld.1.port +wsrep_sst_receive_address='127.0.0.1:@mysqld.1.#sst_port' + +[mysqld.2] +wsrep-on=1 +server-id=2 +#galera_port=@OPT.port +#ist_port=@OPT.port +#sst_port=@OPT.port +wsrep_provider=@ENV.WSREP_PROVIDER +wsrep_cluster_address='gcomm://127.0.0.1:@mysqld.1.#galera_port' +wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.2.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;gcache.size=10M' +wsrep_node_address='127.0.0.1:@mysqld.2.#galera_port' +wsrep_node_incoming_address=127.0.0.1:@mysqld.2.port +wsrep_sst_receive_address='127.0.0.1:@mysqld.2.#sst_port' + +[mysqld.3] +wsrep-on=OFF +server-id=3 +gtid_domain_id=3 + +[mysqld.4] +wsrep-on=OFF +server-id=4 +gtid_domain_id=4 + + +[sst] +sst-log-archive-dir=@ENV.MYSQLTEST_VARDIR/log + +[ENV] +NODE_MYPORT_1= @mysqld.1.port +NODE_MYSOCK_1= @mysqld.1.socket + +NODE_MYPORT_2= @mysqld.2.port +NODE_MYSOCK_2= @mysqld.2.socket + +NODE_MYPORT_3= @mysqld.3.port +NODE_MYSOCK_3= @mysqld.3.socket + +NODE_MYPORT_4= @mysqld.4.port +NODE_MYSOCK_4= @mysqld.4.socket diff --git a/mysql-test/suite/galera/r/galera_2primary_replica.result b/mysql-test/suite/galera/r/galera_2primary_replica.result new file mode 100644 index 00000000000..8bdbf5be962 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_2primary_replica.result @@ -0,0 +1,95 @@ +connection node_2; +connection node_1; +connect primary1, 127.0.0.1, root, , test, $NODE_MYPORT_3; +connect primary2, 127.0.0.1, root, , test, $NODE_MYPORT_4; +connection primary1; +# Primary1 creating user for replication +create user repl@'%' identified by 'repl'; +grant all on *.* to repl@'%'; +connection primary2; +# Primary2 creating user for replication +create user repl2@'%' identified by 'repl2'; +grant all on *.* to repl2@'%'; +connect replica, 127.0.0.1, root, , test, $NODE_MYPORT_1; +connection replica; +connection node_2; +connection replica; +# Galera replica changing master to primary1 +SET @@default_master_connection='stream2'; +# Primary node changing master to primary2 +START ALL SLAVES; +Warnings: +Note 1937 SLAVE 'stream1' started +Note 1937 SLAVE 'stream2' started +connection primary1; +# Primary 1: Creating table and populating it with data +CREATE TABLE t1 (id bigint auto_increment primary key, msg varchar(100)) engine=innodb; +# Intentionally generate 1k GTID-events +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +EXPECT_1000 +1000 +connection primary2; +# Primary 2: Creating table and populating it with data +CREATE TABLE t2 (id bigint auto_increment primary key, msg varchar(100)) engine=innodb; +# Intentionally generate 1k GTID-events +SELECT COUNT(*) AS EXPECT_1000 FROM t2; +EXPECT_1000 +1000 +connection replica; +# Waiting for data to replicate to node_1 +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t2; +EXPECT_1000 +1000 +SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; +EXPECT_1 +1 +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +EXPECT_1 +1 +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; +@@gtid_slave_pos @@gtid_binlog_pos @@gtid_current_pos +3-3-1003,4-4-1003 3-3-1003,4-4-1003 3-3-1003,4-4-1003 +connection node_2; +# Waiting for data to replicate to node_2 +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t2; +EXPECT_1000 +1000 +SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; +EXPECT_1 +1 +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +EXPECT_1 +1 +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; +@@gtid_slave_pos @@gtid_binlog_pos @@gtid_current_pos +3-3-1003,4-4-1003 3-3-1003,4-4-1003 3-3-1003,4-4-1003 +connection primary1; +drop table t1; +connection primary2; +drop table t2; +# Wait until drop table is replicated on Galera +connection replica; +connection node_2; +connection replica; +STOP ALL SLAVES; +Warnings: +Note 1938 SLAVE 'stream1' stopped +Note 1938 SLAVE 'stream2' stopped +RESET SLAVE ALL; +connection primary1; +RESET MASTER; +connection primary2; +RESET MASTER; +connection node_1; +disconnect primary1; +disconnect primary2; +disconnect replica; +disconnect node_2; +disconnect node_1; +# End of test diff --git a/mysql-test/suite/galera/r/galera_circular_replication.result b/mysql-test/suite/galera/r/galera_circular_replication.result new file mode 100644 index 00000000000..72340977005 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_circular_replication.result @@ -0,0 +1,138 @@ +connection node_2; +connection node_1; +connect replica1, 127.0.0.1, root, , test, $NODE_MYPORT_1; +connect primary2, 127.0.0.1, root, , test, $NODE_MYPORT_3; +connect primary1, 127.0.0.1, root, , test, $NODE_MYPORT_4; +connect replica2, 127.0.0.1, root, , test, $NODE_MYPORT_4; +connection primary1; +# Primary1 node creating user for replication +create user repl@'%' identified by 'repl'; +grant all on *.* to repl@'%'; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +connection replica1; +connection node_2; +connection primary2; +connection replica1; +# Galera replica changing master to primary1 +START SLAVE; +connection primary2; +# Primary2 creating user for replication +create user repl2@'%' identified by 'repl2'; +grant all on *.* to repl2@'%'; +connection replica2; +# replica2 changing master to primary2 +START SLAVE; +connection primary1; +# Primary1: Creating table and populating it with data +CREATE TABLE t1 (id bigint auto_increment primary key, msg varchar(100)) engine=innodb; +# Intentionally generate 1k GTID-events +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +EXPECT_1000 +1000 +connection replica1; +# Waiting for data to replicate to replica +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +EXPECT_1000 +1000 +# Writing more data to table +# Intentionally generate 1k GTID-events +SELECT COUNT(*) AS EXPECT_2000 FROM t1; +EXPECT_2000 +2000 +connection node_2; +# Waiting for data to replicate to Galera node_2 +SELECT COUNT(*) AS EXPECT_2000 FROM t1; +EXPECT_2000 +2000 +# Writing more data to table +# Intentionally generate 1k GTID-events +SELECT COUNT(*) AS EXPECT_3000 FROM t1; +EXPECT_3000 +3000 +connection primary2; +# Waiting for data to replicate to primary2 +SELECT COUNT(*) AS EXPECT_3000 FROM t1; +EXPECT_3000 +3000 +# Writing more data to table +# Intentionally generate 1k GTID-events +SELECT COUNT(*) AS EXPECT_4000 FROM t1; +EXPECT_4000 +4000 +connection primary1; +# Waiting for data to replicate to primary1 +SELECT COUNT(*) AS EXPECT_4000 FROM t1; +EXPECT_4000 +4000 +SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; +EXPECT_1 +1 +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +EXPECT_1 +1 +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; +@@gtid_slave_pos @@gtid_binlog_pos @@gtid_current_pos +0-4-1004,16-15-3002 0-4-1004,16-15-3002 0-4-1004,16-15-3002 +connection replica1; +# Waiting for data to replicate to replica +SELECT COUNT(*) AS EXPECT_4000 FROM t1; +EXPECT_4000 +4000 +SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; +EXPECT_1 +1 +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +EXPECT_1 +1 +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; +@@gtid_slave_pos @@gtid_binlog_pos @@gtid_current_pos +0-4-1004,16-15-3002 0-4-1004,16-15-3002 0-4-1004,16-15-3002 +connection node_2; +# Waiting for data to replicate to node_2 +SELECT COUNT(*) AS EXPECT_4000 FROM t1; +EXPECT_4000 +4000 +SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; +EXPECT_1 +1 +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +EXPECT_1 +1 +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; +@@gtid_slave_pos @@gtid_binlog_pos @@gtid_current_pos +0-4-1004 0-4-1004,16-15-3002 0-4-1004,16-15-3002 +connection primary2; +# Waiting for data to replicate to node_3 +SELECT COUNT(*) AS EXPECT_4000 FROM t1; +EXPECT_4000 +4000 +SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; +EXPECT_1 +1 +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +EXPECT_1 +1 +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; +@@gtid_slave_pos @@gtid_binlog_pos @@gtid_current_pos +0-4-1004 0-4-1004,16-15-3002 0-4-1004,16-15-3002 +connection primary1; +drop table t1; +# Wait until drop table is replicated on Galera +connection replica1; +connection node_2; +connection primary2; +connection replica1; +STOP SLAVE; +RESET SLAVE ALL; +connection replica2; +STOP SLAVE; +RESET SLAVE ALL; +RESET MASTER; +connection node_1; +disconnect primary1; +disconnect replica1; +disconnect primary2; +disconnect replica2; +disconnect node_2; +disconnect node_1; +# End of test diff --git a/mysql-test/suite/galera/r/galera_restart_replica.result b/mysql-test/suite/galera/r/galera_restart_replica.result index 9b7e9fd259f..efc9a83a168 100644 --- a/mysql-test/suite/galera/r/galera_restart_replica.result +++ b/mysql-test/suite/galera/r/galera_restart_replica.result @@ -1,122 +1,169 @@ connection node_2; connection node_1; -connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3; +connect replica, 127.0.0.1, root, , test, $NODE_MYPORT_2; +connect primary, 127.0.0.1, root, , test, $NODE_MYPORT_3; create user repl@'%' identified by 'repl'; grant all on *.* to repl@'%'; ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; connection node_1; -connection node_2; -connection node_2; +connection replica; +connection replica; START SLAVE; -connection node_3; -CREATE TABLE t1 (id bigint primary key, msg varchar(100)) engine=innodb; -SELECT COUNT(*) AS EXPECT_10000 FROM t1; -EXPECT_10000 -10000 -connection node_2; +connection primary; +CREATE TABLE t1 (id bigint auto_increment primary key, msg varchar(100)) engine=innodb; +# Intentionally generate 1k GTID-events +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +EXPECT_1000 +1000 +connection replica; SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; EXPECT_1 1 -SELECT COUNT(*) AS EXPECT_10000 FROM t1; -EXPECT_10000 -10000 +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +EXPECT_1 +1 +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; +@@gtid_slave_pos @@gtid_binlog_pos @@gtid_current_pos +0-3-1004 0-3-1004 0-3-1004 +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +EXPECT_1000 +1000 connection node_1; SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; EXPECT_1 1 -SELECT COUNT(*) AS EXPECT_10000 FROM t1; -EXPECT_10000 -10000 -connection node_2; -# Verify that graceful shutdown succeeds. +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +EXPECT_1 +1 +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; +@@gtid_slave_pos @@gtid_binlog_pos @@gtid_current_pos +0-3-1004 0-3-1004 0-3-1004 +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +EXPECT_1000 +1000 +connection replica; +# Verify that graceful shutdown succeeds in replica. # Force SST connection node_1; -# Waiting until node_2 is not part of cluster anymore -connection node_2; -# Start node_2 again -¤ Wait until node_2 is back on cluster -connection node_2; +# Waiting until replica is not part of cluster anymore +connection replica; +# Start replica again +# Wait until replica is back on cluster SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; EXPECT_1 1 -SELECT COUNT(*) AS EXPECT_10000 FROM t1; -EXPECT_10000 -10000 +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +EXPECT_1 +1 +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; +@@gtid_slave_pos @@gtid_binlog_pos @@gtid_current_pos +0-3-1004 0-3-1004 0-3-1004 +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +EXPECT_1000 +1000 connection node_1; SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; EXPECT_1 1 -SELECT COUNT(*) AS EXPECT_10000 FROM t1; -EXPECT_10000 -10000 -connection node_3; -SELECT COUNT(*) AS EXPECT_10000 FROM t1; -EXPECT_10000 -10000 -connection node_3; +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +EXPECT_1 +1 +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; +@@gtid_slave_pos @@gtid_binlog_pos @@gtid_current_pos +0-3-1004 0-3-1004 0-3-1004 +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +EXPECT_1000 +1000 +connection primary; +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +EXPECT_1000 +1000 drop table t1; -connection node_2; +connection replica; connection node_1; -connection node_3; -CREATE TABLE t1 (id bigint primary key, msg varchar(100)) engine=innodb; -SELECT COUNT(*) AS EXPECT_10000 FROM t1; -EXPECT_10000 -10000 -connection node_2; +connection primary; +CREATE TABLE t1 (id bigint auto_increment primary key, msg varchar(100)) engine=innodb; +# Intentionally generate 1k GTID-events +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +EXPECT_1000 +1000 +connection replica; SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; EXPECT_1 1 -SELECT COUNT(*) AS EXPECT_10000 FROM t1; -EXPECT_10000 -10000 +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +EXPECT_1 +1 +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; +@@gtid_slave_pos @@gtid_binlog_pos @@gtid_current_pos +0-3-2006 0-3-2006 0-3-2006 +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +EXPECT_1000 +1000 connection node_1; SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; EXPECT_1 1 -SELECT COUNT(*) AS EXPECT_10000 FROM t1; -EXPECT_10000 -10000 -connection node_2; -# Verify that graceful shutdown succeeds. +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +EXPECT_1 +1 +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; +@@gtid_slave_pos @@gtid_binlog_pos @@gtid_current_pos +0-3-2006 0-3-2006 0-3-2006 +connection replica; +# Verify that graceful shutdown succeeds in replica. # Force SST connection node_1; -# Waiting until node_2 is not part of cluster anymore -connection node_3; -SELECT COUNT(*) AS EXPECT_20000 FROM t1; -EXPECT_20000 -20000 -connection node_2; -# Start node_2 again -¤ Wait until node_2 is back on cluster -connection node_2; +# Waiting until replica is not part of cluster anymore +# Add writes to primary +connection primary; +# Intentionally generate 1k GTID-events +SELECT COUNT(*) AS EXPECT_2000 FROM t1; +EXPECT_2000 +2000 +connection replica; +# Start replica again +# Wait until replica is back on cluster SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; EXPECT_1 1 -SELECT COUNT(*) AS EXPECT_20000 FROM t1; -EXPECT_20000 -20000 +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +EXPECT_1 +1 +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; +@@gtid_slave_pos @@gtid_binlog_pos @@gtid_current_pos +0-3-3006 0-3-3006 0-3-3006 +SELECT COUNT(*) AS EXPECT_2000 FROM t1; +EXPECT_2000 +2000 connection node_1; SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; EXPECT_1 1 -SELECT COUNT(*) AS EXPECT_20000 FROM t1; -EXPECT_20000 -20000 -connection node_3; -SELECT COUNT(*) AS EXPECT_20000 FROM t1; -EXPECT_20000 -20000 -connection node_3; +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +EXPECT_1 +1 +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; +@@gtid_slave_pos @@gtid_binlog_pos @@gtid_current_pos +0-3-3006 0-3-3006 0-3-3006 +SELECT COUNT(*) AS EXPECT_2000 FROM t1; +EXPECT_2000 +2000 +connection primary; +SELECT COUNT(*) AS EXPECT_2000 FROM t1; +EXPECT_2000 +2000 drop table t1; -connection node_2; +connection replica; connection node_1; -connection node_2; +connection replica; STOP SLAVE; RESET SLAVE ALL; -connection node_3; +connection primary; RESET MASTER; connection node_1; -disconnect node_3; +disconnect primary; +disconnect replica; disconnect node_2; disconnect node_1; # End of test diff --git a/mysql-test/suite/galera/t/galera_2primary_replica.cnf b/mysql-test/suite/galera/t/galera_2primary_replica.cnf new file mode 100644 index 00000000000..e066866de87 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_2primary_replica.cnf @@ -0,0 +1,22 @@ +!include ../galera_2nodes_as_replica_2primary.cnf + +[mysqld] +wsrep-debug=1 + +[mysqld.1] +server_id=15 +wsrep_gtid_mode=1 +wsrep_gtid_domain_id=16 +gtid_domain_id=11 +gtid_strict_mode=1 +wsrep-slave-threads=4 +slave-parallel-threads=2 + +[mysqld.2] +skip-slave-start=OFF +server_id=15 +wsrep_gtid_mode=1 +wsrep_gtid_domain_id=16 +gtid_domain_id=11 +gtid_strict_mode=1 +wsrep-slave-threads=4 diff --git a/mysql-test/suite/galera/t/galera_2primary_replica.test b/mysql-test/suite/galera/t/galera_2primary_replica.test new file mode 100644 index 00000000000..fb57c6637d0 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_2primary_replica.test @@ -0,0 +1,170 @@ +# +# Test two primary nodes async replication to Galera cluster +# +# primary1 primary2 +# #3 #4 +# | | +# | async replication v +# +-------------------+ +----------------+ +# | | +# v v +# galera replica <------galera replication-------->galera node_2 +# #1 #2 +# +# Test outline +# +# - Create user for async replication and table with rows in both primaries +# - Verify that tables and rows are replicated to all Galera nodes +# - Verify that gtid position is same in all Galera nodes +# +# The galera/galera_2nodes_as_replica_2primary.cnf describes the setup of the nodes +# +--source include/force_restart.inc +--source include/galera_cluster.inc +--source include/have_innodb.inc + +# As node #3 and #4 are not a Galera node, and galera_cluster.inc does not open connetion to it +# we open the connections here +--connect primary1, 127.0.0.1, root, , test, $NODE_MYPORT_3 +--connect primary2, 127.0.0.1, root, , test, $NODE_MYPORT_4 +--connection primary1 +--echo # Primary1 creating user for replication +create user repl@'%' identified by 'repl'; +grant all on *.* to repl@'%'; + +--connection primary2 +--echo # Primary2 creating user for replication +create user repl2@'%' identified by 'repl2'; +grant all on *.* to repl2@'%'; + +--connect replica, 127.0.0.1, root, , test, $NODE_MYPORT_1 + +--let $node_1 = replica +--let $node_2 = node_2 +--source include/auto_increment_offset_save.inc + +--connection replica +--echo # Galera replica changing master to primary1 +--disable_query_log +SET @@default_master_connection='stream1'; +--eval CHANGE MASTER 'stream1' TO master_host='127.0.0.1', master_user='repl', master_password='repl', master_port=$NODE_MYPORT_3, master_use_gtid=slave_pos; +--enable_query_log + +SET @@default_master_connection='stream2'; +--echo # Primary node changing master to primary2 +--disable_query_log +--eval CHANGE MASTER 'stream2' TO master_host='127.0.0.1', master_user='repl2', master_password='repl2', master_port=$NODE_MYPORT_4, master_use_gtid=slave_pos; +--enable_query_log + +START ALL SLAVES; + +--connection primary1 +--echo # Primary 1: Creating table and populating it with data +CREATE TABLE t1 (id bigint auto_increment primary key, msg varchar(100)) engine=innodb; +--disable_query_log +--echo # Intentionally generate 1k GTID-events +--let $inserts=1000 +--let $count=0 +--disable_query_log +while($count < $inserts) +{ + --eval insert into t1 values (NULL,'test1') + --inc $count +} +--enable_query_log + +SELECT COUNT(*) AS EXPECT_1000 FROM t1; + +--connection primary2 +--echo # Primary 2: Creating table and populating it with data +CREATE TABLE t2 (id bigint auto_increment primary key, msg varchar(100)) engine=innodb; +--echo # Intentionally generate 1k GTID-events +--let $inserts=1000 +--let $count=0 +--disable_query_log +while($count < $inserts) +{ + --eval insert into t2 values (NULL,'test1') + --inc $count +} +--enable_query_log + +SELECT COUNT(*) AS EXPECT_1000 FROM t2; + +--connection replica +--echo # Waiting for data to replicate to node_1 +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +--let $wait_condition_on_error_output = SHOW ALL SLAVES STATUS; +--source include/wait_condition_with_debug.inc +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'; +--let $wait_condition_on_error_output = SHOW ALL SLAVES STATUS; +--source include/wait_condition_with_debug.inc + +--let $wait_condition = SELECT COUNT(*) = 1000 FROM t1; +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) = 1000 FROM t2; +--source include/wait_condition.inc + +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +SELECT COUNT(*) AS EXPECT_1000 FROM t2; + +SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; + +--connection node_2 +--echo # Waiting for data to replicate to node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'; +--source include/wait_condition.inc + +--let $wait_condition = SELECT COUNT(*) = 1000 FROM t1; +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) = 1000 FROM t2; +--source include/wait_condition.inc + +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +SELECT COUNT(*) AS EXPECT_1000 FROM t2; +SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; +# +# Cleanup +# +--connection primary1 +drop table t1; +--connection primary2 +drop table t2; + +--echo # Wait until drop table is replicated on Galera +--connection replica +--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'; +--source include/wait_condition.inc + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'; +--source include/wait_condition.inc + +--connection replica +STOP ALL SLAVES; +RESET SLAVE ALL; + +--connection primary1 +RESET MASTER; +--connection primary2 +RESET MASTER; + +--source include/auto_increment_offset_restore.inc + +--connection node_1 +--disconnect primary1 +--disconnect primary2 +--disconnect replica + +--source include/galera_end.inc +--echo # End of test diff --git a/mysql-test/suite/galera/t/galera_circular_replication.cnf b/mysql-test/suite/galera/t/galera_circular_replication.cnf new file mode 100644 index 00000000000..b1c6320d4df --- /dev/null +++ b/mysql-test/suite/galera/t/galera_circular_replication.cnf @@ -0,0 +1,25 @@ +!include ../galera_3nodes_as_slave.cnf + +[mysqld] +wsrep-debug=1 + +[mysqld.1] +server_id=15 +wsrep_gtid_mode=1 +wsrep_gtid_domain_id=16 +gtid_domain_id=11 +gtid_strict_mode=1 + +[mysqld.2] +server_id=15 +wsrep_gtid_mode=1 +wsrep_gtid_domain_id=16 +gtid_domain_id=11 +gtid_strict_mode=1 + +[mysqld.3] +server_id=15 +wsrep_gtid_mode=1 +wsrep_gtid_domain_id=16 +gtid_domain_id=11 +gtid_strict_mode=1 diff --git a/mysql-test/suite/galera/t/galera_circular_replication.test b/mysql-test/suite/galera/t/galera_circular_replication.test new file mode 100644 index 00000000000..dbe85da4b23 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_circular_replication.test @@ -0,0 +1,234 @@ +# +# Test circular replication where galera cluster is async replica and master +# +# mariadb #4 galera galera +# primary1 +# replica2 +# ---async replication-->replica1 #1 <--galera replication--> node_2 #2 +# ^ ^ +# | | galera replication +# | v +# +<------------------async replication----------------------primary2 (galera) #3 +# +# Test outline: +# +# - Create user for async replication in primary1 +# - Create user for async replication in primary2 +# - Create table and some data in primary1 +# - Verify that table and data is replicated to galera nodes +# - Verify that mysql.gtid_slave_pos has some rows in all Galera nodes +# - Verify that gtid_slave_pos, gtid_binlog_pos and gtid_current_pos are +# same in all Galera nodes and primary1 +# - Verify that writes on Galera nodes are replicated to all nodes +# and to primary1 +# +# The galera/galera_3nodes_as_slave.cnf describes the setup of the nodes +# +--source include/force_restart.inc +--source include/galera_cluster.inc +--source include/have_innodb.inc + +--connect replica1, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connect primary2, 127.0.0.1, root, , test, $NODE_MYPORT_3 + +# As node #4 is not a Galera node, and galera_cluster.inc does not open connetion to it +# because it is both primary and replica we open both connections here +--connect primary1, 127.0.0.1, root, , test, $NODE_MYPORT_4 +--connect replica2, 127.0.0.1, root, , test, $NODE_MYPORT_4 + +--connection primary1 +--echo # Primary1 node creating user for replication +create user repl@'%' identified by 'repl'; +grant all on *.* to repl@'%'; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; + +--let $node_1 = replica1 +--let $node_2 = node_2 +--let $node_3 = primary2 +--source include/auto_increment_offset_save.inc + +--connection replica1 +--echo # Galera replica changing master to primary1 +--disable_query_log +--eval CHANGE MASTER TO master_host='127.0.0.1', master_user='repl', master_password='repl', master_port=$NODE_MYPORT_4, master_use_gtid=slave_pos; +--enable_query_log +START SLAVE; + +--connection primary2 +--echo # Primary2 creating user for replication +create user repl2@'%' identified by 'repl2'; +grant all on *.* to repl2@'%'; + +--connection replica2 +--echo # replica2 changing master to primary2 +--disable_query_log +--eval CHANGE MASTER TO master_host='127.0.0.1', master_user='repl2', master_password='repl2', master_port=$NODE_MYPORT_3, master_use_gtid=slave_pos; +--enable_query_log +START SLAVE; + +--connection primary1 +--echo # Primary1: Creating table and populating it with data +CREATE TABLE t1 (id bigint auto_increment primary key, msg varchar(100)) engine=innodb; +--echo # Intentionally generate 1k GTID-events +--let $inserts=1000 +--let $count=0 +--disable_query_log +while($count < $inserts) +{ + --eval insert into t1 values (NULL,'test1') + --inc $count +} +--enable_query_log + +SELECT COUNT(*) AS EXPECT_1000 FROM t1; + +--connection replica1 +--echo # Waiting for data to replicate to replica +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +--source include/wait_condition.inc + +--let $wait_condition = SELECT COUNT(*) = 1000 FROM t1; +--source include/wait_condition.inc + +SELECT COUNT(*) AS EXPECT_1000 FROM t1; + +--echo # Writing more data to table +--echo # Intentionally generate 1k GTID-events +--let $inserts=1000 +--let $count=0 +--disable_query_log +while($count < $inserts) +{ + --eval insert into t1 values (NULL,'test1') + --inc $count +} +--enable_query_log + +SELECT COUNT(*) AS EXPECT_2000 FROM t1; + +--connection node_2 +--echo # Waiting for data to replicate to Galera node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +--source include/wait_condition.inc + +--let $wait_condition = SELECT COUNT(*) = 2000 FROM t1; +--source include/wait_condition.inc + +SELECT COUNT(*) AS EXPECT_2000 FROM t1; + +--echo # Writing more data to table +--echo # Intentionally generate 1k GTID-events +--let $inserts=1000 +--let $count=0 +--disable_query_log +while($count < $inserts) +{ + --eval insert into t1 values (NULL,'test1') + --inc $count +} +--enable_query_log + +SELECT COUNT(*) AS EXPECT_3000 FROM t1; + +--connection primary2 +--echo # Waiting for data to replicate to primary2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +--source include/wait_condition.inc + +--let $wait_condition = SELECT COUNT(*) = 3000 FROM t1; +--source include/wait_condition.inc + +SELECT COUNT(*) AS EXPECT_3000 FROM t1; + +--echo # Writing more data to table +--echo # Intentionally generate 1k GTID-events +--let $inserts=1000 +--let $count=0 +--disable_query_log +while($count < $inserts) +{ + --eval insert into t1 values (NULL,'test1') + --inc $count +} +--enable_query_log + +SELECT COUNT(*) AS EXPECT_4000 FROM t1; + +--connection primary1 +--echo # Waiting for data to replicate to primary1 +--let $wait_condition = SELECT COUNT(*) = 4000 FROM t1; +--let $wait_condition_on_error_output = SHOW SLAVE STATUS; +--source include/wait_condition_with_debug.inc + +SELECT COUNT(*) AS EXPECT_4000 FROM t1; +SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; + +--connection replica1 +--echo # Waiting for data to replicate to replica +--let $wait_condition = SELECT COUNT(*) = 4000 FROM t1; +--source include/wait_condition.inc + +SELECT COUNT(*) AS EXPECT_4000 FROM t1; +SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; + +--connection node_2 +--echo # Waiting for data to replicate to node_2 +--let $wait_condition = SELECT COUNT(*) = 4000 FROM t1; +--source include/wait_condition.inc + +SELECT COUNT(*) AS EXPECT_4000 FROM t1; +SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; + +--connection primary2 +--echo # Waiting for data to replicate to node_3 +--let $wait_condition = SELECT COUNT(*) = 4000 FROM t1; +--source include/wait_condition.inc + +SELECT COUNT(*) AS EXPECT_4000 FROM t1; +SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; +# +# Cleanup +# +--connection primary1 +drop table t1; + +--echo # Wait until drop table is replicated on Galera +--connection replica1 +--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +--source include/wait_condition.inc + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +--source include/wait_condition.inc + +--connection primary2 +--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +--source include/wait_condition.inc + +--connection replica1 +STOP SLAVE; +RESET SLAVE ALL; + +--connection replica2 +STOP SLAVE; +RESET SLAVE ALL; +RESET MASTER; + +--source include/auto_increment_offset_restore.inc + +--connection node_1 +--disconnect primary1 +--disconnect replica1 +--disconnect primary2 +--disconnect replica2 + +--source include/galera_end.inc +--echo # End of test diff --git a/mysql-test/suite/galera/t/galera_restart_replica.test b/mysql-test/suite/galera/t/galera_restart_replica.test index 37cfd9bc0f9..05ab77f2519 100644 --- a/mysql-test/suite/galera/t/galera_restart_replica.test +++ b/mysql-test/suite/galera/t/galera_restart_replica.test @@ -1,77 +1,115 @@ # -# Test Galera as a replica to a MySQL async replication +# Test Galera as a replica to a MariaDB async replication +# +# MariaDB +# primary ---async replication--->galera node_2 (replica)<----galera replication---> galera node1 +# +# Test outline: +# +# - Create user for async replication +# - Create table and some data in primary +# - Verify that table and data is replicated to galera nodes +# - Verify that mysql.gtid_slave_pos has some rows in all Galera nodes +# - Verify that gtid_slave_pos, gtid_binlog_pos and gtid_current_pos are +# same in all Galera nodes +# - Verify that we can shutdown and restart Galera replica (node #2) +# - Verify that gtid_slave_pos, gtid_binlog_pos and gtid_current_pos are +# same in all Galera nodes +# - Verify that mysql.gtid_slave_pos table has limited amount of rows +# - Veruft that ddl works (drop table) +# +# Similar test is done so that new rows are added to table in +# primary while async replica (node #2) is down. # # The galera/galera_2node_slave.cnf describes the setup of the nodes # --source include/force_restart.inc --source include/galera_cluster.inc --source include/have_innodb.inc ---source include/have_sequence.inc + +# In this test we mark node #2 as replica +--connect replica, 127.0.0.1, root, , test, $NODE_MYPORT_2 # As node #3 is not a Galera node, and galera_cluster.inc does not open connetion to it -# we open the node_3 connection here ---connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 +# we open the primary connection her +--connect primary, 127.0.0.1, root, , test, $NODE_MYPORT_3 create user repl@'%' identified by 'repl'; grant all on *.* to repl@'%'; ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; --let $node_1 = node_1 ---let $node_2 = node_2 +--let $node_2 = replica --source include/auto_increment_offset_save.inc ---connection node_2 +--connection replica --disable_query_log --eval CHANGE MASTER TO master_host='127.0.0.1', master_user='repl', master_password='repl', master_port=$NODE_MYPORT_3, master_use_gtid=slave_pos; --enable_query_log START SLAVE; ---connection node_3 +--connection primary +CREATE TABLE t1 (id bigint auto_increment primary key, msg varchar(100)) engine=innodb; -CREATE TABLE t1 (id bigint primary key, msg varchar(100)) engine=innodb; +--echo # Intentionally generate 1k GTID-events +--let $inserts=1000 +--let $count=0 --disable_query_log -INSERT INTO t1 SELECT seq, 'test' from seq_1_to_10000; +while($count < $inserts) +{ + --eval insert into t1 values (NULL,'test1') + --inc $count +} --enable_query_log -SELECT COUNT(*) AS EXPECT_10000 FROM t1; ---connection node_2 +SELECT COUNT(*) AS EXPECT_1000 FROM t1; + +--connection replica --let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; --source include/wait_condition.inc ---let $wait_condition = SELECT COUNT(*) = 10000 FROM t1; +--let $wait_condition = SELECT COUNT(*) = 1000 FROM t1; --source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) < 1000 FROM mysql.gtid_slave_pos; +--source include/wait_condition.inc SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; -SELECT COUNT(*) AS EXPECT_10000 FROM t1; +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; +SELECT COUNT(*) AS EXPECT_1000 FROM t1; --connection node_1 --let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; --source include/wait_condition.inc ---let $wait_condition = SELECT COUNT(*) = 10000 FROM t1; +--let $wait_condition = SELECT COUNT(*) = 1000 FROM t1; --source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) < 1000 FROM mysql.gtid_slave_pos; +--source include/wait_condition.inc SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; -SELECT COUNT(*) AS EXPECT_10000 FROM t1; +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; +SELECT COUNT(*) AS EXPECT_1000 FROM t1; ---connection node_2 ---echo # Verify that graceful shutdown succeeds. +--connection replica +--echo # Verify that graceful shutdown succeeds in replica. --source include/shutdown_mysqld.inc --echo # Force SST --remove_file $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat --connection node_1 ---echo # Waiting until node_2 is not part of cluster anymore +--echo # Waiting until replica is not part of cluster anymore --let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; --source include/wait_condition.inc --let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; --source include/wait_condition.inc ---connection node_2 ---echo # Start node_2 again +--connection replica +--echo # Start replica again --source include/start_mysqld.inc ---echo ¤ Wait until node_2 is back on cluster +--echo # Wait until replica is back on cluster --let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; --source include/wait_condition.inc --let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; @@ -79,24 +117,30 @@ SELECT COUNT(*) AS EXPECT_10000 FROM t1; --let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; --source include/wait_condition.inc ---connection node_2 +--let $wait_condition = SELECT COUNT(*) < 1000 FROM mysql.gtid_slave_pos; +--source include/wait_condition.inc SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; -SELECT COUNT(*) AS EXPECT_10000 FROM t1; +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; +SELECT COUNT(*) AS EXPECT_1000 FROM t1; --connection node_1 +--let $wait_condition = SELECT COUNT(*) < 1000 FROM mysql.gtid_slave_pos; +--source include/wait_condition.inc SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; -SELECT COUNT(*) AS EXPECT_10000 FROM t1; +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; +SELECT COUNT(*) AS EXPECT_1000 FROM t1; ---connection node_3 -SELECT COUNT(*) AS EXPECT_10000 FROM t1; +--connection primary +SELECT COUNT(*) AS EXPECT_1000 FROM t1; # # Cleanup # ---connection node_3 drop table t1; ---connection node_2 +--connection replica --let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; --source include/wait_condition.inc @@ -108,59 +152,80 @@ drop table t1; # Case 2 : While slave is down add writes to master # ---connection node_3 - -CREATE TABLE t1 (id bigint primary key, msg varchar(100)) engine=innodb; +--connection primary +CREATE TABLE t1 (id bigint auto_increment primary key, msg varchar(100)) engine=innodb; +--echo # Intentionally generate 1k GTID-events +--let $inserts=1000 +--let $count=0 --disable_query_log -INSERT INTO t1 SELECT seq, 'test' from seq_1_to_10000; +while($count < $inserts) +{ + --eval insert into t1 values (NULL,'test1') + --inc $count +} --enable_query_log -SELECT COUNT(*) AS EXPECT_10000 FROM t1; +SELECT COUNT(*) AS EXPECT_1000 FROM t1; ---connection node_2 +--connection replica --let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; --source include/wait_condition.inc ---let $wait_condition = SELECT COUNT(*) = 10000 FROM t1; +--let $wait_condition = SELECT COUNT(*) = 1000 FROM t1; --source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) < 1000 FROM mysql.gtid_slave_pos; +--source include/wait_condition.inc SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; -SELECT COUNT(*) AS EXPECT_10000 FROM t1; +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; +SELECT COUNT(*) AS EXPECT_1000 FROM t1; --connection node_1 --let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; --source include/wait_condition.inc ---let $wait_condition = SELECT COUNT(*) = 10000 FROM t1; +--let $wait_condition = SELECT COUNT(*) = 1000 FROM t1; --source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) < 1000 FROM mysql.gtid_slave_pos; +--source include/wait_condition.inc SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; -SELECT COUNT(*) AS EXPECT_10000 FROM t1; +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; ---connection node_2 ---echo # Verify that graceful shutdown succeeds. +--connection replica +--echo # Verify that graceful shutdown succeeds in replica. --source include/shutdown_mysqld.inc --echo # Force SST --remove_file $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat --connection node_1 ---echo # Waiting until node_2 is not part of cluster anymore +--echo # Waiting until replica is not part of cluster anymore --let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; --source include/wait_condition.inc --let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; --source include/wait_condition.inc -# Add writes to master ---connection node_3 +--echo # Add writes to primary +--connection primary +--echo # Intentionally generate 1k GTID-events +--let $inserts=1000 +--let $count=0 --disable_query_log -INSERT INTO t1 SELECT seq, 'test' from seq_20001_to_30000; +while($count < $inserts) +{ + --eval insert into t1 values (NULL,'test1') + --inc $count +} --enable_query_log -SELECT COUNT(*) AS EXPECT_20000 FROM t1; ---connection node_2 ---echo # Start node_2 again +SELECT COUNT(*) AS EXPECT_2000 FROM t1; + +--connection replica +--echo # Start replica again --source include/start_mysqld.inc ---echo ¤ Wait until node_2 is back on cluster +--echo # Wait until replica is back on cluster --let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; --source include/wait_condition.inc --let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; @@ -168,28 +233,34 @@ SELECT COUNT(*) AS EXPECT_20000 FROM t1; --let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; --source include/wait_condition.inc ---connection node_2 ---let $wait_condition = SELECT COUNT(*) = 20000 FROM t1; +--let $wait_condition = SELECT COUNT(*) = 2000 FROM t1; +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) < 1000 FROM mysql.gtid_slave_pos; --source include/wait_condition.inc SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; -SELECT COUNT(*) AS EXPECT_20000 FROM t1; +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; +SELECT COUNT(*) AS EXPECT_2000 FROM t1; --connection node_1 ---let $wait_condition = SELECT COUNT(*) = 20000 FROM t1; +--let $wait_condition = SELECT COUNT(*) = 2000 FROM t1; +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) < 1000 FROM mysql.gtid_slave_pos; --source include/wait_condition.inc SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.gtid_slave_pos; -SELECT COUNT(*) AS EXPECT_20000 FROM t1; +SELECT COUNT(*) < 1000 AS EXPECT_1 FROM mysql.gtid_slave_pos; +SELECT @@gtid_slave_pos,@@gtid_binlog_pos,@@gtid_current_pos; +SELECT COUNT(*) AS EXPECT_2000 FROM t1; ---connection node_3 -SELECT COUNT(*) AS EXPECT_20000 FROM t1; +--connection primary +SELECT COUNT(*) AS EXPECT_2000 FROM t1; # # Cleanup # ---connection node_3 drop table t1; ---connection node_2 +--connection replica --let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; --source include/wait_condition.inc @@ -197,16 +268,18 @@ drop table t1; --let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; --source include/wait_condition.inc ---connection node_2 +--connection replica STOP SLAVE; RESET SLAVE ALL; ---connection node_3 +--connection primary RESET MASTER; ---connection node_1 ---disconnect node_3 - --source include/auto_increment_offset_restore.inc + +--connection node_1 +--disconnect primary +--disconnect replica + --source include/galera_end.inc --echo # End of test diff --git a/sql/rpl_gtid.cc b/sql/rpl_gtid.cc index 93a83426d37..8112a5b911d 100644 --- a/sql/rpl_gtid.cc +++ b/sql/rpl_gtid.cc @@ -28,10 +28,6 @@ #include "rpl_rli.h" #include "slave.h" #include "log_event.h" -#ifdef WITH_WSREP -#include "wsrep_mysqld.h" // wsrep_thd_is_local -#include "wsrep_trans_observer.h" // wsrep_start_trx_if_not_started -#endif const LEX_CSTRING rpl_gtid_slave_state_table_name= { STRING_WITH_LEN("gtid_slave_pos") }; @@ -696,23 +692,7 @@ rpl_slave_state::record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id, goto end; #ifdef WITH_WSREP - /* - We should replicate local gtid_slave_pos updates to other nodes if - wsrep gtid mode is set. - In applier we should not append them to galera writeset. - */ - if (WSREP_ON_ && wsrep_gtid_mode && wsrep_thd_is_local(thd)) - { - thd->wsrep_ignore_table= false; - table->file->row_logging= 1; // replication requires binary logging - if (thd->wsrep_next_trx_id() == WSREP_UNDEFINED_TRX_ID) - thd->set_query_id(next_query_id()); - wsrep_start_trx_if_not_started(thd); - } - else - { - thd->wsrep_ignore_table= true; - } + thd->wsrep_ignore_table= true; // Do not replicate mysql.gtid_slave_pos table #endif if (!in_transaction) @@ -749,10 +729,6 @@ rpl_slave_state::record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id, } end: -#ifdef WITH_WSREP - thd->wsrep_ignore_table= false; -#endif - if (table_opened) { if (err || (err= ha_commit_trans(thd, FALSE))) @@ -764,6 +740,10 @@ end: else thd->release_transactional_locks(); } + +#ifdef WITH_WSREP + thd->wsrep_ignore_table= false; +#endif thd->lex->restore_backup_query_tables_list(&lex_backup); thd->variables.option_bits= thd_saved_option; thd->resume_subsequent_commits(suspended_wfc); @@ -877,25 +857,7 @@ rpl_slave_state::gtid_delete_pending(THD *thd, return; #ifdef WITH_WSREP - /* - We should replicate local gtid_slave_pos updates to other nodes if - wsrep gtid mode is set. - In applier we should not append them to galera writeset. - */ - if (WSREP_ON_ && wsrep_gtid_mode && - wsrep_thd_is_local(thd) && - thd->wsrep_cs().state() != wsrep::client_state::s_none) - { - if (thd->wsrep_trx().active() == false) - { - if (thd->wsrep_next_trx_id() == WSREP_UNDEFINED_TRX_ID) - thd->set_query_id(next_query_id()); - wsrep_start_transaction(thd, thd->wsrep_next_trx_id()); - } - thd->wsrep_ignore_table= false; - } - else - thd->wsrep_ignore_table= true; + thd->wsrep_ignore_table= true; // No Galera replication for mysql.gtid_pos_table #endif thd_saved_option= thd->variables.option_bits; diff --git a/sql/wsrep_applier.cc b/sql/wsrep_applier.cc index feb78507bf9..39df306a0e2 100644 --- a/sql/wsrep_applier.cc +++ b/sql/wsrep_applier.cc @@ -22,6 +22,7 @@ #include "wsrep_xid.h" #include "wsrep_thd.h" #include "wsrep_trans_observer.h" +#include "wsrep_schema.h" // wsrep_schema #include "slave.h" // opt_log_slave_updates #include "debug_sync.h" @@ -180,6 +181,10 @@ int wsrep_apply_events(THD* thd, { thd->variables.gtid_seq_no= gtid_ev->seq_no; } + + if (wsrep_gtid_mode) + wsrep_schema->store_gtid_event(thd, gtid_ev); + delete ev; } continue; diff --git a/sql/wsrep_schema.cc b/sql/wsrep_schema.cc index 08e516b2a7a..f29442abac1 100644 --- a/sql/wsrep_schema.cc +++ b/sql/wsrep_schema.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2023 Codership Oy +/* Copyright (C) 2015-2025 Codership Oy 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 @@ -31,6 +31,8 @@ #include "wsrep_storage_service.h" #include "wsrep_thd.h" #include "wsrep_server_state.h" +#include "log_event.h" +#include "sql_class.h" #include #include @@ -165,6 +167,24 @@ private: my_bool m_wsrep_on; }; +class wsrep_ignore_table +{ +public: + wsrep_ignore_table(THD* thd) + : m_thd(thd) + , m_wsrep_ignore_table(thd->wsrep_ignore_table) + { + thd->wsrep_ignore_table= true; + } + ~wsrep_ignore_table() + { + m_thd->wsrep_ignore_table= m_wsrep_ignore_table; + } +private: + THD* m_thd; + my_bool m_wsrep_ignore_table; +}; + class thd_server_status { public: @@ -1535,3 +1555,61 @@ int Wsrep_schema::recover_sr_transactions(THD *orig_thd) out: DBUG_RETURN(ret); } + +int Wsrep_schema::store_gtid_event(THD* thd, + const Gtid_log_event *gtid) +{ + DBUG_ENTER("Wsrep_schema::store_gtid_event"); + int error=0; + void *hton= NULL; + const bool in_transaction= (gtid->flags2 & Gtid_log_event::FL_TRANSACTIONAL); + const bool in_ddl= (gtid->flags2 & Gtid_log_event::FL_DDL); + + DBUG_PRINT("info", ("thd: %p, in_transaction: %d, in_ddl: %d " + "in_active_multi_stmt_transaction: %d", + thd, in_transaction, in_ddl, + thd->in_active_multi_stmt_transaction())); + + Wsrep_schema_impl::wsrep_ignore_table ignore_table(thd); + Wsrep_schema_impl::binlog_off binlog_off(thd); + Wsrep_schema_impl::sql_safe_updates sql_safe_updates(thd); + + rpl_group_info *rgi= thd->wsrep_rgi; + const uint64 sub_id= rpl_global_gtid_slave_state->next_sub_id(gtid->domain_id); + rpl_gtid current_gtid; + current_gtid.domain_id= gtid->domain_id; + current_gtid.server_id= gtid->server_id; + current_gtid.seq_no= gtid->seq_no; + rgi->gtid_pending= false; + + DBUG_ASSERT(!in_transaction || thd->in_active_multi_stmt_transaction()); + + if ((error= rpl_global_gtid_slave_state->record_gtid(thd, ¤t_gtid, + sub_id, + in_transaction, false, &hton))) + goto out; + + rpl_global_gtid_slave_state->update_state_hash(sub_id, ¤t_gtid, hton, rgi); + + if (in_ddl) + { + // Commit transaction if this GTID is part of DDL-clause because + // DDL causes implicit commit assuming there is no multi statement + // transaction ongoing. + if((error= trans_commit_stmt(thd))) + goto out; + + (void)trans_commit(thd); + } + +out: + if (error) + { + WSREP_DEBUG("Wsrep_schema::store_gtid_event %llu-%llu-%llu failed error=%s (%d).", + gtid->domain_id, gtid->server_id, gtid->seq_no, strerror(error), error); + (void)trans_rollback_stmt(thd); + (void)trans_rollback(thd); + } + + DBUG_RETURN(error); +} diff --git a/sql/wsrep_schema.h b/sql/wsrep_schema.h index f0f79046768..46acba2961b 100644 --- a/sql/wsrep_schema.h +++ b/sql/wsrep_schema.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2023 Codership Oy +/* Copyright (C) 2015-2024 Codership Oy 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 @@ -22,7 +22,6 @@ #include "mysqld.h" #include "wsrep_mysqld.h" - /* Forward decls */ @@ -32,6 +31,7 @@ struct TABLE; struct TABLE_LIST; struct st_mysql_lex_string; typedef struct st_mysql_lex_string LEX_STRING; +class Gtid_log_event; /** Name of the table in `wsrep_schema_str` used for storing streaming replication data. In an InnoDB full format, e.g. "database/tablename". */ @@ -133,6 +133,16 @@ class Wsrep_schema */ int recover_sr_transactions(THD* orig_thd); + /** + Store GTID-event to mysql.gtid_slave_pos table. + + @param thd The THD object of the calling thread. + @param gtid GTID event from binlog. + + @return Zero on success, non-zero on failure. + */ + int store_gtid_event(THD* thd, const Gtid_log_event *gtid); + private: /* Non-copyable */ Wsrep_schema(const Wsrep_schema&); From c618c6612fbf467f63b7836a58062c876d9f4ed7 Mon Sep 17 00:00:00 2001 From: Dave Gosselin Date: Thu, 9 Jan 2025 08:27:57 -0500 Subject: [PATCH 049/213] MDEV-35805 Update main.lowercase_table4 for new default collation Update main.lowercase_table4 for new default collation at 11.6 as described in https://mariadb.com/kb/en/setting-character-sets-and-collations/ --- mysql-test/main/lowercase_table4.result | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mysql-test/main/lowercase_table4.result b/mysql-test/main/lowercase_table4.result index 11c5ff2bfcb..422c2744af8 100644 --- a/mysql-test/main/lowercase_table4.result +++ b/mysql-test/main/lowercase_table4.result @@ -30,7 +30,7 @@ Create Table CREATE TABLE `Table2` ( PRIMARY KEY (`c1`), KEY `fk1` (`c2`), CONSTRAINT `fk1` FOREIGN KEY (`c2`) REFERENCES `Table1` (`c1`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci SELECT * FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS WHERE CONSTRAINT_SCHEMA='test'; CONSTRAINT_CATALOG def CONSTRAINT_SCHEMA test @@ -75,7 +75,7 @@ Create Table CREATE TABLE `Product_Order` ( KEY `Customer_Id` (`Customer_Id`), CONSTRAINT `product_order_ibfk_1` FOREIGN KEY (`Product_Category`, `Product_Id`) REFERENCES `Product` (`Category`, `Id`) ON UPDATE CASCADE, CONSTRAINT `product_order_ibfk_2` FOREIGN KEY (`Customer_Id`) REFERENCES `Customer` (`Id`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci SHOW CREATE TABLE Product; Table Product Create Table CREATE TABLE `Product` ( @@ -83,13 +83,13 @@ Create Table CREATE TABLE `Product` ( `Id` int(11) NOT NULL, `Price` decimal(10,0) DEFAULT NULL, PRIMARY KEY (`Category`,`Id`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci SHOW CREATE TABLE Customer; Table Customer Create Table CREATE TABLE `Customer` ( `Id` int(11) NOT NULL, PRIMARY KEY (`Id`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci SELECT * FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS WHERE CONSTRAINT_SCHEMA='test'; CONSTRAINT_CATALOG def CONSTRAINT_SCHEMA test From 8de5b58627b42b90fdd9b1908257b58670556ec3 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 5 Jan 2025 13:14:58 +0100 Subject: [PATCH 050/213] Bump the VERSION --- VERSION | 4 ++-- mysql-test/suite/sys_vars/r/sysvars_star.result | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/VERSION b/VERSION index c96348cabee..56e3da97868 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=11 MYSQL_VERSION_MINOR=7 -MYSQL_VERSION_PATCH=1 -SERVER_MATURITY=gamma +MYSQL_VERSION_PATCH=2 +SERVER_MATURITY=stable diff --git a/mysql-test/suite/sys_vars/r/sysvars_star.result b/mysql-test/suite/sys_vars/r/sysvars_star.result index c005a6d2ad6..6dc840b7d15 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_star.result +++ b/mysql-test/suite/sys_vars/r/sysvars_star.result @@ -60,7 +60,7 @@ VARIABLE_NAME PLUGIN_MATURITY SESSION_VALUE NULL GLOBAL_VALUE alpha GLOBAL_VALUE_ORIGIN CONFIG -DEFAULT_VALUE beta +DEFAULT_VALUE gamma VARIABLE_SCOPE GLOBAL VARIABLE_TYPE ENUM VARIABLE_COMMENT The lowest desirable plugin maturity. Plugins less mature than that will not be installed or loaded From 61806af658fa7112c68298175d35ae4b946ccd19 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 29 Dec 2024 17:54:52 +0100 Subject: [PATCH 051/213] MDEV-35417 InnoDB crashes under ... AND DISABLE CHECKPOINT restore pre-11.7 behavior when InnoDB was ignoring the "AND DISABLE CHECKPOINT" clause of FTWGRL. InnoDB isn't ready for it yet --- mysql-test/main/flush_read_lock.result | 21 +++++++++++++++++ mysql-test/main/flush_read_lock.test | 32 ++++++++++++++++++++++++++ storage/innobase/handler/ha_innodb.cc | 6 +++++ 3 files changed, 59 insertions(+) diff --git a/mysql-test/main/flush_read_lock.result b/mysql-test/main/flush_read_lock.result index 948b4fb062b..72ae769c0e9 100644 --- a/mysql-test/main/flush_read_lock.result +++ b/mysql-test/main/flush_read_lock.result @@ -1854,3 +1854,24 @@ connection con2; disconnect con2; connection default; SET DEBUG_SYNC= 'RESET'; +# End of 10.4 tests +# +# MDEV-35417 InnoDB crashes under ... AND DISABLE CHECKPOINT +# +set global innodb_stats_persistent=0; +create table t (a int) engine=innodb; +set global innodb_stats_persistent=1; +alter table t add column b int; +flush tables with read lock and disable checkpoint; +insert into t values (1,2) ; +ERROR HY000: Can't execute the query because you have a conflicting read lock +unlock tables; +drop table t; +flush tables with read lock and disable checkpoint; +create temporary table t(a int) engine=innodb; +unlock tables; +drop table t; +# restart: --innodb-read-only +flush tables with read lock and disable checkpoint; +# restart +# End of 11.7 tests diff --git a/mysql-test/main/flush_read_lock.test b/mysql-test/main/flush_read_lock.test index f24f6e389f1..3f8bde09bef 100644 --- a/mysql-test/main/flush_read_lock.test +++ b/mysql-test/main/flush_read_lock.test @@ -2269,3 +2269,35 @@ reap; disconnect con2; connection default; SET DEBUG_SYNC= 'RESET'; + +--echo # End of 10.4 tests + +--echo # +--echo # MDEV-35417 InnoDB crashes under ... AND DISABLE CHECKPOINT +--echo # + +# case 1 +set global innodb_stats_persistent=0; +create table t (a int) engine=innodb; +set global innodb_stats_persistent=1; +alter table t add column b int; +flush tables with read lock and disable checkpoint; +--error ER_CANT_UPDATE_WITH_READLOCK +insert into t values (1,2) ; +unlock tables; +drop table t; + +# case 2 +flush tables with read lock and disable checkpoint; +create temporary table t(a int) engine=innodb; +unlock tables; +drop table t; + +# case 3 +--let $restart_parameters=--innodb-read-only +--source include/restart_mysqld.inc +flush tables with read lock and disable checkpoint; +--let $restart_parameters= +--source include/restart_mysqld.inc + +--echo # End of 11.7 tests diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index f8eef5a1965..0be423e28dc 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1889,6 +1889,12 @@ static void sst_enable_innodb_writes() static void innodb_disable_internal_writes(bool disable) { + /* + this works only in the SST donor thread and is not yet fixed + to work in a normal connection thread + */ + if (thd_get_thread_id(current_thd)) // if normal thread + return; if (disable) sst_disable_innodb_writes(); else From cca243bf02f200c6b9ed8117efc8c162c5a16af2 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 4 Jan 2025 14:42:01 +0100 Subject: [PATCH 052/213] MDEV-35768 Vector key is not used upon selecting from views / subqueries --- mysql-test/main/vector2.result | 18 ++++++++++++++++++ mysql-test/main/vector2.test | 15 +++++++++++++++ sql/item_vectorfunc.h | 8 ++++---- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/mysql-test/main/vector2.result b/mysql-test/main/vector2.result index be0f0e8315d..82bdc9e1996 100644 --- a/mysql-test/main/vector2.result +++ b/mysql-test/main/vector2.result @@ -369,3 +369,21 @@ vec_totext(v) [7] [6] drop table t; +# +# MDEV-35768 Vector key is not used upon selecting from views / subqueries +# +create table t (b vector(1) not null, vector(b)); +insert into t values (0x31313131),(0x32323232); +create view v as select * from t; +explain select * from t order by vec_distance_euclidean(b,0x30303030) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t index NULL b 6 NULL 1 +explain select * from v order by vec_distance_euclidean(b,0x30303030) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t index NULL b 6 NULL 1 +explain select * from (select * from t) sq order by vec_distance_euclidean(b,0x30303030) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t index NULL b 6 NULL 1 +drop view v; +drop table t; +# End of 11.7 tests diff --git a/mysql-test/main/vector2.test b/mysql-test/main/vector2.test index 58319b675f5..e7b5d794e65 100644 --- a/mysql-test/main/vector2.test +++ b/mysql-test/main/vector2.test @@ -265,3 +265,18 @@ create table t (v vector(1) not null, vector(v)); insert into t select vec_fromtext(concat('[',seq,']')) FROM seq_1_to_10; select vec_totext(v) from t order by vec_distance_euclidean(v,vec_fromtext('[0]')) desc limit 5; drop table t; + +--echo # +--echo # MDEV-35768 Vector key is not used upon selecting from views / subqueries +--echo # + +create table t (b vector(1) not null, vector(b)); +insert into t values (0x31313131),(0x32323232); +create view v as select * from t; +explain select * from t order by vec_distance_euclidean(b,0x30303030) limit 1; +explain select * from v order by vec_distance_euclidean(b,0x30303030) limit 1; +explain select * from (select * from t) sq order by vec_distance_euclidean(b,0x30303030) limit 1; +drop view v; +drop table t; + +--echo # End of 11.7 tests diff --git a/sql/item_vectorfunc.h b/sql/item_vectorfunc.h index 58dc300c451..e6da1b77441 100644 --- a/sql/item_vectorfunc.h +++ b/sql/item_vectorfunc.h @@ -26,10 +26,10 @@ class Item_func_vec_distance_common: public Item_real_func { Item_field *get_field_arg() const { - if (args[0]->type() == Item::FIELD_ITEM && args[1]->const_item()) - return (Item_field*)(args[0]); - if (args[1]->type() == Item::FIELD_ITEM && args[0]->const_item()) - return (Item_field*)(args[1]); + if (args[0]->real_item()->type() == Item::FIELD_ITEM && args[1]->const_item()) + return (Item_field*)(args[0]->real_item()); + if (args[1]->real_item()->type() == Item::FIELD_ITEM && args[0]->const_item()) + return (Item_field*)(args[1])->real_item(); return NULL; } bool check_arguments() const override From 0eaefafbafac39883a8852f1d3947bdb6b1bc71e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 4 Jan 2025 17:27:55 +0100 Subject: [PATCH 053/213] MDEV-35769 ER_SQL_DISCOVER_ERROR upon updating vector key column using incorrect value return as soon as the error status is known. also, init_from_sql_statement_string() cannot be run if thd->is_error(), assert it. --- mysql-test/main/vector2.result | 9 +++++++++ mysql-test/main/vector2.test | 10 ++++++++++ sql/sql_update.cc | 4 ++-- sql/table.cc | 1 + 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/vector2.result b/mysql-test/main/vector2.result index 82bdc9e1996..92678db9c14 100644 --- a/mysql-test/main/vector2.result +++ b/mysql-test/main/vector2.result @@ -386,4 +386,13 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t index NULL b 6 NULL 1 drop view v; drop table t; +# +# MDEV-35769 ER_SQL_DISCOVER_ERROR upon updating vector key column using incorrect value +# +create table t (v vector(1) not null, vector(v)); +insert into t values (0x31313131); +flush tables; +update t set v = 1; +ERROR HY000: Cannot cast 'int' as 'vector' in assignment of `test`.`t`.`v` +drop table t; # End of 11.7 tests diff --git a/mysql-test/main/vector2.test b/mysql-test/main/vector2.test index e7b5d794e65..916792277b1 100644 --- a/mysql-test/main/vector2.test +++ b/mysql-test/main/vector2.test @@ -279,4 +279,14 @@ explain select * from (select * from t) sq order by vec_distance_euclidean(b,0x3 drop view v; drop table t; +--echo # +--echo # MDEV-35769 ER_SQL_DISCOVER_ERROR upon updating vector key column using incorrect value +--echo # +create table t (v vector(1) not null, vector(v)); +insert into t values (0x31313131); +flush tables; +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +update t set v = 1; +drop table t; + --echo # End of 11.7 tests diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 01cfd3ef9c4..ba9d9eaa6f4 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1877,6 +1877,8 @@ int multi_update::prepare(List ¬_used_values, *values, MARK_COLUMNS_READ, 0, NULL, 0) || TABLE::check_assignability_explicit_fields(*fields, *values, ignore); + if (unlikely(error)) + DBUG_RETURN(1); ti.rewind(); while ((table_ref= ti++)) @@ -1893,8 +1895,6 @@ int multi_update::prepare(List ¬_used_values, table->file->prepare_for_modify(true, true); } } - if (unlikely(error)) - DBUG_RETURN(1); /* Save tables being updated in update_tables diff --git a/sql/table.cc b/sql/table.cc index 034e11427fe..8012e99c624 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -3647,6 +3647,7 @@ int TABLE_SHARE::init_from_sql_statement_string(THD *thd, bool write, LEX_CUSTRING frm= {0,0}; LEX_CSTRING db_backup= thd->db; DBUG_ENTER("TABLE_SHARE::init_from_sql_statement_string"); + DBUG_ASSERT(!thd->is_error()); /* Ouch. Parser may *change* the string it's working on. From 8ef37ade1778dd31b45f7c2305df4d61edd77ddf Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 6 Jan 2025 20:26:06 +0100 Subject: [PATCH 054/213] MDEV-35745 Assertion failure, ASAN errors, crash in mhnsw_read_first/mhnsw_read_next If the table has many deleted nodes, they can overflow `candidates` even when `best` isn't full yet --- sql/vector_mhnsw.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/vector_mhnsw.cc b/sql/vector_mhnsw.cc index 449a7daf344..9777ce19ccd 100644 --- a/sql/vector_mhnsw.cc +++ b/sql/vector_mhnsw.cc @@ -1092,7 +1092,7 @@ static int search_layer(MHNSW_Share *ctx, TABLE *graph, const FVector *target, if (!best.is_full()) { max_distance= std::max(max_distance, v->distance_to_target); - candidates.push(v); + candidates.safe_push(v); if (skip_deleted && v->node->deleted) continue; best.push(v); From d8c841d0d4fcd7a37e1e135052838d8fba565c92 Mon Sep 17 00:00:00 2001 From: Brandon Nesterenko Date: Mon, 13 Jan 2025 07:04:53 -0700 Subject: [PATCH 055/213] MDEV-35096: History is stored in different partitions on different nodes when using SYSTEM VERSION MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Row-injection updates don’t correctly set the historical partition for tables with system versioning and system_time partitions. This results in inconsistencies between the master and slave when replicating transactions that target such tables (i.e. the primary server would correctly distribute archived rows amongst its partitions, whereas the replica would have all archived rows in a single partition). The function partition_info::vers_set_hist_part(THD*) is used to set the partition; however, its initial check for vers_require_hist_part(THD*) returns false, bypassing the rest of the function (which sets up the partition to use). This is because the actual check uses the LEX sql_command (via LEX::vers_history_generating()) to determine if the command is valid to generate history. Row injections don’t have sql_commands though. This patch provides a fix which extends the check in vers_history_generating() to additionally allow row injections to be history generating (via the function LEX::is_stmt_row_injection()). Special thanks to Jan Lindstrom for his work in reproducing the bug, and providing an initial test case. Reviewed By ============ Kristian Nielsen Aleksey Midenkov --- .../r/rpl_system_versioning_partitions.result | 71 +++++ .../t/rpl_system_versioning_partitions.cnf | 4 + .../t/rpl_system_versioning_partitions.test | 248 ++++++++++++++++++ sql/sql_lex.h | 6 +- 4 files changed, 328 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/rpl/r/rpl_system_versioning_partitions.result create mode 100644 mysql-test/suite/rpl/t/rpl_system_versioning_partitions.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_system_versioning_partitions.test diff --git a/mysql-test/suite/rpl/r/rpl_system_versioning_partitions.result b/mysql-test/suite/rpl/r/rpl_system_versioning_partitions.result new file mode 100644 index 00000000000..8edc6996a05 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_system_versioning_partitions.result @@ -0,0 +1,71 @@ +include/master-slave.inc +[connection master] +# +# Initialize system-versioned and partitioned table and its data +connection master; +SET timestamp=UNIX_TIMESTAMP('2025-01-01 01:00:00.000000'); +RESET MASTER; +create table t1 (x int) engine=InnoDB with system versioning partition by system_time limit 3 partitions 5; +insert into t1 values(1); +insert into t1 values(2); +insert into t1 values(3); +insert into t1 values(4); +insert into t1 values(5); +# Verifying master partitions are correct after data insertion.. +# .. done +connection slave; +connection slave; +# Verifying partitions of master and slave match on data setup.. +# .. done +# +# "Delete" each row -- these are the BINLOG commands generated by +# mysqlbinlog from `delete from t1 where x=` statments. Because the +# table uses system versioning and system_time partition, the actual +# events are updates, with added fields for the `row_start` and `row_end` +# columns. +connection master; +# BINLOG for Format Description event +BINLOG ' +APZ0Zw8BAAAA/AAAAAABAAAAAAQAMTAuNi4yMS1NYXJpYURCLWRlYnVnLWxvZwAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAA9nRnEzgNAAgAEgAEBAQEEgAA5AAEGggAAAAICAgCAAAACgoKAAAAAAAA +CgoKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAEEwQADQgICAoKCgHgiCNP +'; +# BINLOG for delete from t1 where x=1; +BINLOG ' +APZ0ZxMBAAAAMQAAAAQHAAAAACEAAAAAAAEABHRlc3QAAnQxAAMDERECBgYBvaHPfA== +APZ0ZxgBAAAASAAAAEwHAAAAACEAAAAAAAEAAwcH+AEAAABndPYAAAAAf////w9CP/gBAAAAZ3T2 +AAAAAGd09gAAAADnhA23 +'; +# BINLOG for delete from t1 where x=2; +BINLOG ' +APZ0ZxMBAAAAMQAAAPUHAAAAACEAAAAAAAEABHRlc3QAAnQxAAMDERECBgYBwNtQNQ== +APZ0ZxgBAAAASAAAAD0IAAAAACEAAAAAAAEAAwcH+AIAAABndPYAAAAAf////w9CP/gCAAAAZ3T2 +AAAAAGd09gAAAABPYZUX +'; +# BINLOG for delete from t1 where x=3; +BINLOG ' +APZ0ZxMBAAAAMQAAAOYIAAAAACEAAAAAAAEABHRlc3QAAnQxAAMDERECBgYBKWGevg== +APZ0ZxgBAAAASAAAAC4JAAAAACEAAAAAAAEAAwcH+AMAAABndPYAAAAAf////w9CP/gDAAAAZ3T2 +AAAAAGd09gAAAAD0hz5S +'; +# BINLOG for delete from t1 where x=4; +BINLOG ' +APZ0ZxMBAAAAMQAAANcJAAAAACEAAAAAAAEABHRlc3QAAnQxAAMDERECBgYBaT9IZg== +APZ0ZxgBAAAASAAAAB8KAAAAACEAAAAAAAEAAwcH+AQAAABndPYAAAAAf////w9CP/gEAAAAZ3T2 +AAAAAGd09gAAAADA4Tdx +'; +# BINLOG for delete from t1 where x=5; +BINLOG ' +APZ0ZxMBAAAAMQAAAMgKAAAAACEAAAAAAAEABHRlc3QAAnQxAAMDERECBgYBMk64Mw== +APZ0ZxgBAAAASAAAABALAAAAACEAAAAAAAEAAwcH+AUAAABndPYAAAAAf////w9CP/gFAAAAZ3T2 +AAAAAGd09gAAAAA5blY6 +'; +# Verifying master partitions are correct after deletion BINLOG stmts.. +# .. done +connection slave; +connection slave; +connection master; +drop table t1; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_system_versioning_partitions.cnf b/mysql-test/suite/rpl/t/rpl_system_versioning_partitions.cnf new file mode 100644 index 00000000000..53153614f0a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_system_versioning_partitions.cnf @@ -0,0 +1,4 @@ +!include ../my.cnf + +[mysqld] +default_time_zone="-7:00" diff --git a/mysql-test/suite/rpl/t/rpl_system_versioning_partitions.test b/mysql-test/suite/rpl/t/rpl_system_versioning_partitions.test new file mode 100644 index 00000000000..70103acf862 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_system_versioning_partitions.test @@ -0,0 +1,248 @@ +# +# Ensure that executing row-injected events (i.e. via BINLOG statments and +# row-based binlog events) uses historical partitions. That is, for tables +# which use system versioning and system_time partitions, MDEV-35096 reported +# that row-injected events would not be stored into the correct historical +# partition. This test considers both use cases of row-injected events. +# +# The test setup creates a system-versioned table with system_time-based +# partitioning and fills the table up with enough records that bypass the size +# limit of each historical partition. +# +# To test BINLOG statements, a series of BINLOG statements are used to delete +# all the records in the test tables, and the resulting partitions are analyzed +# to ensure that they match the partition specification. The BINLOG events +# were collected by running an original set of delete statements on the table +# data, and taking their binlog data from mysqlbinlog. Note these binary log +# events are actually Update events, because system versioning just archives +# the rows, rather than deleting them. +# +# To test row-based event replication, a slave replicates the master's +# events, and the partitions are compared between the slave and master for +# consistency. +# +# Note that the TIMESTAMP of this test is fixed so the BINLOG statements can +# identify the correct rows to delete (system versioning adds implicit fields +# `row_start` and `row_end`, which are automatically populated using the current +# timestamp). +# +# +# References: +# MDEV-35096: History is stored in different partitions on different nodes +# when using SYSTEM VERSION +# +--source include/have_binlog_format_row.inc +--source include/master-slave.inc +--source include/have_innodb.inc +--source include/have_partition.inc + +--echo # +--echo # Initialize system-versioned and partitioned table and its data +--connection master + +# Fix the timestamp for the system versioned row_start and row_end fields, so +# the later hard-coded BINLOG base64 data can find the rows. +SET timestamp=UNIX_TIMESTAMP('2025-01-01 01:00:00.000000'); +RESET MASTER; + +create table t1 (x int) engine=InnoDB with system versioning partition by system_time limit 3 partitions 5; +insert into t1 values(1); +insert into t1 values(2); +insert into t1 values(3); +insert into t1 values(4); +insert into t1 values(5); +--let $master_total_size= `select count(*) from t1` +--let $master_p0_size= `select count(*) from t1 partition (p0)` +--let $master_p1_size= `select count(*) from t1 partition (p1)` +--let $master_p2_size= `select count(*) from t1 partition (p2)` + +--echo # Verifying master partitions are correct after data insertion.. +if ($master_total_size != 5) +{ + --echo # Master t1 count: $master_total_size + --die Master table t1 should have 5 entries +} +if ($master_p0_size) +{ + --echo # Master t1,p0 count: $master_p0_size + --die Master t1 partition p0 should be empty +} +if ($master_p1_size) +{ + --echo # Master t1,p1 count: $master_p1_size + --die Master t1 partition p1 should be empty +} +if ($master_p2_size) +{ + --echo # Master t1,p2 count: $master_p2_size + --die Master t1 partition p2 should be empty +} +--echo # .. done + +--sync_slave_with_master + +--connection slave +--let $slave_total_size= `select count(*) from t1` +--let $slave_p0_size= `select count(*) from t1 partition (p0)` +--let $slave_p1_size= `select count(*) from t1 partition (p1)` +--let $slave_p2_size= `select count(*) from t1 partition (p2)` + +--echo # Verifying partitions of master and slave match on data setup.. +if ($slave_total_size != $master_total_size) +{ + --connection master + select count(*) from t0; + --connection slave + select count(*) from t1; + --die Size of t1 differs between master and slave +} +if ($slave_p0_size != $master_p0_size) +{ + --connection master + select count(*) from t1 partition (p0); + --connection slave + select count(*) from t1 partition (p0); + --die Size of t1 partition p0 differs between master and slave +} +if ($slave_p1_size != $master_p1_size) +{ + --connection master + select count(*) from t1 partition (p1); + --connection slave + select count(*) from t1 partition (p1); + --die Size of t1 partition p1 differs between master and slave +} +if ($slave_p2_size != $master_p2_size) +{ + --connection master + select count(*) from t1 partition (p2); + --connection slave + select count(*) from t1 partition (p2); + --die Size of t1 partition p2 differs between master and slave +} +--echo # .. done + +--echo # +--echo # "Delete" each row -- these are the BINLOG commands generated by +--echo # mysqlbinlog from `delete from t1 where x=` statments. Because the +--echo # table uses system versioning and system_time partition, the actual +--echo # events are updates, with added fields for the `row_start` and `row_end` +--echo # columns. +--connection master + +--echo # BINLOG for Format Description event +BINLOG ' +APZ0Zw8BAAAA/AAAAAABAAAAAAQAMTAuNi4yMS1NYXJpYURCLWRlYnVnLWxvZwAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAA9nRnEzgNAAgAEgAEBAQEEgAA5AAEGggAAAAICAgCAAAACgoKAAAAAAAA +CgoKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAEEwQADQgICAoKCgHgiCNP +'; + +--echo # BINLOG for delete from t1 where x=1; +BINLOG ' +APZ0ZxMBAAAAMQAAAAQHAAAAACEAAAAAAAEABHRlc3QAAnQxAAMDERECBgYBvaHPfA== +APZ0ZxgBAAAASAAAAEwHAAAAACEAAAAAAAEAAwcH+AEAAABndPYAAAAAf////w9CP/gBAAAAZ3T2 +AAAAAGd09gAAAADnhA23 +'; + +--echo # BINLOG for delete from t1 where x=2; +BINLOG ' +APZ0ZxMBAAAAMQAAAPUHAAAAACEAAAAAAAEABHRlc3QAAnQxAAMDERECBgYBwNtQNQ== +APZ0ZxgBAAAASAAAAD0IAAAAACEAAAAAAAEAAwcH+AIAAABndPYAAAAAf////w9CP/gCAAAAZ3T2 +AAAAAGd09gAAAABPYZUX +'; + + +--echo # BINLOG for delete from t1 where x=3; +BINLOG ' +APZ0ZxMBAAAAMQAAAOYIAAAAACEAAAAAAAEABHRlc3QAAnQxAAMDERECBgYBKWGevg== +APZ0ZxgBAAAASAAAAC4JAAAAACEAAAAAAAEAAwcH+AMAAABndPYAAAAAf////w9CP/gDAAAAZ3T2 +AAAAAGd09gAAAAD0hz5S +'; + +--echo # BINLOG for delete from t1 where x=4; +BINLOG ' +APZ0ZxMBAAAAMQAAANcJAAAAACEAAAAAAAEABHRlc3QAAnQxAAMDERECBgYBaT9IZg== +APZ0ZxgBAAAASAAAAB8KAAAAACEAAAAAAAEAAwcH+AQAAABndPYAAAAAf////w9CP/gEAAAAZ3T2 +AAAAAGd09gAAAADA4Tdx +'; + +--echo # BINLOG for delete from t1 where x=5; +BINLOG ' +APZ0ZxMBAAAAMQAAAMgKAAAAACEAAAAAAAEABHRlc3QAAnQxAAMDERECBgYBMk64Mw== +APZ0ZxgBAAAASAAAABALAAAAACEAAAAAAAEAAwcH+AUAAABndPYAAAAAf////w9CP/gFAAAAZ3T2 +AAAAAGd09gAAAAA5blY6 +'; + +--let $master_total_size= `select count(*) from t1` +--let $master_p0_size= `select count(*) from t1 partition (p0)` +--let $master_p1_size= `select count(*) from t1 partition (p1)` +--let $master_p2_size= `select count(*) from t1 partition (p2)` +--echo # Verifying master partitions are correct after deletion BINLOG stmts.. +if ($master_total_size > 0) +{ + --echo # Master t1 count: $master_total_size + --die Master table t1 should have 0 count +} +if ($master_p0_size != 3) +{ + --echo # Master t1,p0 count: $master_p0_size + --die Master t1 partition p0 should have 3 entries +} +if ($master_p1_size != 2) +{ + --echo # Master t1,p1 count: $master_p1_size + --die Master t1 partition p1 should have 2 entries +} +if ($master_p2_size) +{ + --echo # Master t1,p2 count: $master_p2_size + --die Master t1 partition p2 should be empty +} +--echo # .. done +--sync_slave_with_master + +--connection slave +--let $slave_total_size= `select count(*) from t1` +--let $slave_p0_size= `select count(*) from t1 partition (p0)` +--let $slave_p1_size= `select count(*) from t1 partition (p1)` +--let $slave_p2_size= `select count(*) from t1 partition (p2)` + +if ($slave_total_size != $master_total_size) +{ + --connection master + select count(*) from t1; + --connection slave + select count(*) from t1; + --die Size of t1 differs between master and slave +} +if ($slave_p0_size != $master_p0_size) +{ + --connection master + select count(*) from t1 partition (p0); + --connection slave + select count(*) from t1 partition (p0); + --die Size of t1 partition p0 differs between master and slave +} +if ($slave_p1_size != $master_p1_size) +{ + --connection master + select count(*) from t1 partition (p1); + --connection slave + select count(*) from t1 partition (p1); + --die Size of t1 partition p1 differs between master and slave +} +if ($slave_p2_size != $master_p2_size) +{ + --connection master + select count(*) from t1 partition (p2); + --connection slave + select count(*) from t1 partition (p2); + --die Size of t1 partition p2 differs between master and slave +} + +--connection master +drop table t1; + +--source include/rpl_end.inc diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 1dbd839ac53..f1c3e041c7a 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -4617,7 +4617,11 @@ public: case SQLCOM_LOAD: return duplicates == DUP_REPLACE; default: - return false; + /* + Row injections (i.e. row binlog events and BINLOG statements) should + generate history. + */ + return is_stmt_row_injection(); } } From 4b0ac5a12b95afbb47a7c41b33b3e8785c9f21a4 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 14 Jan 2025 10:48:59 +1100 Subject: [PATCH 056/213] MDEV-35838 libressl support differences in CRYPTO_set_mem_functions Based on FreeBSD patch. The FreeBSD inclusion of check_openssl_compatibility prevented any use of the crypto callbacks and as such the later differences where ignored. The later differences in coc_malloc didn't propegate to the other callback functions of CRYPTO_set_mem_functions where a reduced argument list also applied. Looking where[2] libressl added the functions it was of the same prototype 10 years ago so omitting any version check. [1] https://github.com/freebsd/freebsd-ports/blob/a34cf9c2dbf503c8248371ba3bab24f34d2d045d/databases/mariadb106-server/files/patch-mysys__ssl_openssl.c [2] https://github.com/libressl/openbsd/commit/5ebad8aceae77c6da6a1e47c3f7e70e8ffae3dae#diff-7f393e5489e6c5780773408f11ca27d9b3bb8f55b174631a1e9467a1dd3010b9R22 --- mysys_ssl/openssl.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/mysys_ssl/openssl.c b/mysys_ssl/openssl.c index e0271817309..3890e3524be 100644 --- a/mysys_ssl/openssl.c +++ b/mysys_ssl/openssl.c @@ -36,8 +36,12 @@ int check_openssl_compatibility() static uint testing; static size_t alloc_size, alloc_count; -static void *coc_malloc(size_t size, const char *f __attribute__((unused)), - int l __attribute__((unused))) +static void *coc_malloc(size_t size +#ifndef LIBRESSL_VERSION_NUMBER + , const char *f __attribute__((unused)), + int l __attribute__((unused)) +#endif +) { if (unlikely(testing)) { @@ -47,15 +51,22 @@ static void *coc_malloc(size_t size, const char *f __attribute__((unused)), return malloc(size); } -static void *coc_realloc(void *addr, size_t num, - const char *file __attribute__((unused)), - int line __attribute__((unused))) +static void *coc_realloc(void *addr, size_t num +#ifndef LIBRESSL_VERSION_NUMBER + , const char *file __attribute__((unused)), + int line __attribute__((unused)) +#endif +) { return realloc(addr, num); } -static void coc_free(void *addr, const char *file __attribute__((unused)), - int line __attribute__((unused))) +static void coc_free(void *addr +#ifndef LIBRESSL_VERSION_NUMBER + , const char *file __attribute__((unused)), + int line __attribute__((unused)) +#endif +) { free(addr); } From 901c6c7ab63f9c9473b90d3f62be656321bcf871 Mon Sep 17 00:00:00 2001 From: Denis Protivensky Date: Mon, 25 Dec 2023 13:59:07 +0300 Subject: [PATCH 057/213] MDEV-33064: Sync trx->wsrep state from THD on trx start InnoDB transactions may be reused after committed: - when taken from the transaction pool - during a DDL operation execution In this case wsrep flag on trx object is cleared, which may cause wrong execution logic afterwards (wsrep-related hooks are not run). Make trx->wsrep flag initialize from THD object only once on InnoDB transaction start and don't change it throughout the transaction's lifetime. The flag is reset at commit time as before. Unconditionally set wsrep=OFF for THD objects that represent InnoDB background threads. Make Wsrep_schema::store_view() operate in its own transaction. Fix streaming replication transactions' fragments rollback to not switch THD->wsrep value during transaction's execution (use THD->wsrep_ignore_table as a workaround). Signed-off-by: Julius Goryavsky --- mysql-test/suite/galera/r/MDEV-33064.result | 26 ++++++++++ mysql-test/suite/galera/t/MDEV-33064.test | 57 +++++++++++++++++++++ sql/handler.cc | 4 +- sql/sql_class.cc | 6 ++- sql/wsrep_schema.cc | 23 ++++++++- sql/wsrep_server_service.cc | 24 +-------- storage/innobase/handler/ha_innodb.cc | 11 ++-- storage/innobase/trx/trx0trx.cc | 3 ++ 8 files changed, 122 insertions(+), 32 deletions(-) create mode 100644 mysql-test/suite/galera/r/MDEV-33064.result create mode 100644 mysql-test/suite/galera/t/MDEV-33064.test diff --git a/mysql-test/suite/galera/r/MDEV-33064.result b/mysql-test/suite/galera/r/MDEV-33064.result new file mode 100644 index 00000000000..22e1ce7a77a --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-33064.result @@ -0,0 +1,26 @@ +connection node_2; +connection node_1; +connect con1,127.0.0.1,root,,test,$NODE_MYPORT_1; +CREATE TABLE t1(c1 INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t1_fk(c1 INT PRIMARY KEY, c2 INT, INDEX (c2), FOREIGN KEY (c2) REFERENCES t1(c1)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +connection con1; +SET SESSION wsrep_retry_autocommit = 0; +SET DEBUG_SYNC = 'ib_after_row_insert SIGNAL may_alter WAIT_FOR bf_abort'; +INSERT INTO t1_fk VALUES (1, 1); +connection node_1; +SET DEBUG_SYNC = 'now WAIT_FOR may_alter'; +SET DEBUG_SYNC = 'lock_wait_end WAIT_FOR alter_continue'; +ALTER TABLE t1 ADD COLUMN c2 INT, ALGORITHM=INPLACE; +connection con1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SET DEBUG_SYNC = 'now SIGNAL alter_continue'; +connection node_1; +connection node_2; +INSERT INTO t1 (c1, c2) VALUES (2, 2); +connection node_1; +SET DEBUG_SYNC = 'RESET'; +DROP TABLE t1_fk, t1; +disconnect con1; +disconnect node_2; +disconnect node_1; diff --git a/mysql-test/suite/galera/t/MDEV-33064.test b/mysql-test/suite/galera/t/MDEV-33064.test new file mode 100644 index 00000000000..704ed70ab56 --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-33064.test @@ -0,0 +1,57 @@ +# +# MDEV-33064: ALTER INPLACE running TOI should abort a conflicting DML operation +# +# DDL operations may commit InnoDB transactions more than once during the execution. +# In this case wsrep flag on trx object is cleared, which may cause wrong logic of +# such operations afterwards (wsrep-related hooks are not run). +# One of the consequences was that DDL operation couldn't abort a DML operation +# holding conflicting locks. +# +# The fix: re-enable wsrep flag on trx restart if it's a part of a DDL operation. +# + +--source include/galera_cluster.inc +--source include/have_debug_sync.inc +--source include/have_debug.inc + +--connect con1,127.0.0.1,root,,test,$NODE_MYPORT_1 + +CREATE TABLE t1(c1 INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t1_fk(c1 INT PRIMARY KEY, c2 INT, INDEX (c2), FOREIGN KEY (c2) REFERENCES t1(c1)) ENGINE=InnoDB; + +INSERT INTO t1 VALUES (1); + +--connection con1 +SET SESSION wsrep_retry_autocommit = 0; +SET DEBUG_SYNC = 'ib_after_row_insert SIGNAL may_alter WAIT_FOR bf_abort'; +# INSERT also grabs FK-referenced table lock. +--send + INSERT INTO t1_fk VALUES (1, 1); + +--connection node_1 +SET DEBUG_SYNC = 'now WAIT_FOR may_alter'; +SET DEBUG_SYNC = 'lock_wait_end WAIT_FOR alter_continue'; +# ALTER BF-aborts INSERT. +--send + ALTER TABLE t1 ADD COLUMN c2 INT, ALGORITHM=INPLACE; + +--connection con1 +# INSERT gets BF-aborted. +--error ER_LOCK_DEADLOCK +--reap +SET DEBUG_SYNC = 'now SIGNAL alter_continue'; + +--connection node_1 +# ALTER succeeds. +--reap + +--connection node_2 +# Sanity check that ALTER has been replicated. +INSERT INTO t1 (c1, c2) VALUES (2, 2); + +# Cleanup. +--connection node_1 +SET DEBUG_SYNC = 'RESET'; +DROP TABLE t1_fk, t1; +--disconnect con1 +--source include/galera_end.inc diff --git a/sql/handler.cc b/sql/handler.cc index 4ecd1ea2048..38453b5e2a7 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -7500,7 +7500,9 @@ int handler::ha_delete_row(const uchar *buf) } #ifdef WITH_WSREP THD *thd= ha_thd(); - if (WSREP_NNULL(thd)) + /* For streaming replication, when removing fragments, don't call + wsrep_after_row() as that would initiate new streaming transaction */ + if (WSREP_NNULL(thd) && !thd->wsrep_ignore_table) { /* for streaming replication, the following wsrep_after_row() may replicate a fragment, so we have to declare potential PA diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 8cb5b4954aa..66f689c5312 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -5083,6 +5083,9 @@ MYSQL_THD create_background_thd() thd->real_id= 0; thd->thread_id= 0; thd->query_id= 0; +#ifdef WITH_WSREP + thd->variables.wsrep_on= FALSE; +#endif /* WITH_WSREP */ return thd; } @@ -6347,7 +6350,8 @@ int THD::decide_logging_format(TABLE_LIST *tables) wsrep_is_active(this) && variables.wsrep_trx_fragment_size > 0) { - if (!is_current_stmt_binlog_format_row()) + if (!is_current_stmt_binlog_disabled() && + !is_current_stmt_binlog_format_row()) { my_message(ER_NOT_SUPPORTED_YET, "Streaming replication not supported with " diff --git a/sql/wsrep_schema.cc b/sql/wsrep_schema.cc index f29442abac1..8e271565b13 100644 --- a/sql/wsrep_schema.cc +++ b/sql/wsrep_schema.cc @@ -768,6 +768,12 @@ int Wsrep_schema::store_view(THD* thd, const Wsrep_view& view) Wsrep_schema_impl::binlog_off binlog_off(thd); Wsrep_schema_impl::sql_safe_updates sql_safe_updates(thd); + if (trans_begin(thd, MYSQL_START_TRANS_OPT_READ_WRITE)) + { + WSREP_ERROR("Failed to start transaction for store view"); + goto out_not_started; + } + /* Clean up cluster table and members table. */ @@ -861,7 +867,22 @@ int Wsrep_schema::store_view(THD* thd, const Wsrep_view& view) #endif /* WSREP_SCHEMA_MEMBERS_HISTORY */ ret= 0; out: + if (ret) + { + trans_rollback_stmt(thd); + if (!trans_rollback(thd)) + { + close_thread_tables(thd); + } + } + else if (trans_commit(thd)) + { + ret= 1; + WSREP_ERROR("Failed to commit transaction for store view"); + } + thd->release_transactional_locks(); +out_not_started: DBUG_RETURN(ret); } @@ -1213,7 +1234,7 @@ int Wsrep_schema::remove_fragments(THD* thd, int ret= 0; WSREP_DEBUG("Removing %zu fragments", fragments.size()); - Wsrep_schema_impl::wsrep_off wsrep_off(thd); + Wsrep_schema_impl::wsrep_ignore_table wsrep_ignore_table(thd); Wsrep_schema_impl::binlog_off binlog_off(thd); Wsrep_schema_impl::sql_safe_updates sql_safe_updates(thd); diff --git a/sql/wsrep_server_service.cc b/sql/wsrep_server_service.cc index a2879b59789..b50a3081660 100644 --- a/sql/wsrep_server_service.cc +++ b/sql/wsrep_server_service.cc @@ -241,29 +241,9 @@ void Wsrep_server_service::log_view( view.state_id().seqno().get() >= prev_view.state_id().seqno().get()); } - if (trans_begin(applier->m_thd, MYSQL_START_TRANS_OPT_READ_WRITE)) + if (wsrep_schema->store_view(applier->m_thd, view)) { - WSREP_WARN("Failed to start transaction for store view"); - } - else - { - if (wsrep_schema->store_view(applier->m_thd, view)) - { - WSREP_WARN("Failed to store view"); - trans_rollback_stmt(applier->m_thd); - if (!trans_rollback(applier->m_thd)) - { - close_thread_tables(applier->m_thd); - } - } - else - { - if (trans_commit(applier->m_thd)) - { - WSREP_WARN("Failed to commit transaction for store view"); - } - } - applier->m_thd->release_transactional_locks(); + WSREP_WARN("Failed to store view"); } /* diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index c2341aa667a..68e3f6c7b56 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2381,9 +2381,6 @@ innobase_trx_init( trx->check_unique_secondary = !thd_test_options( thd, OPTION_RELAXED_UNIQUE_CHECKS); -#ifdef WITH_WSREP - trx->wsrep = wsrep_on(thd); -#endif DBUG_VOID_RETURN; } @@ -4173,9 +4170,6 @@ innobase_commit_low( trx_commit_for_mysql(trx); } else { trx->will_lock = false; -#ifdef WITH_WSREP - trx->wsrep = false; -#endif /* WITH_WSREP */ } #ifdef WITH_WSREP @@ -8571,7 +8565,10 @@ func_exit: } #ifdef WITH_WSREP - if (error == DB_SUCCESS && trx->is_wsrep() + if (error == DB_SUCCESS && + /* For sequences, InnoDB transaction may not have been started yet. + Check THD-level wsrep state in that case. */ + (trx->is_wsrep() || (!trx_is_started(trx) && wsrep_on(m_user_thd))) && wsrep_thd_is_local(m_user_thd) && !wsrep_thd_ignore_table(m_user_thd) && (thd_sql_command(m_user_thd) != SQLCOM_CREATE_TABLE) diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 284437497b5..38393444932 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -953,6 +953,7 @@ trx_start_low( #ifdef WITH_WSREP trx->xid->null(); + trx->wsrep = wsrep_on(trx->mysql_thd); #endif /* WITH_WSREP */ ut_a(ib_vector_is_empty(trx->autoinc_locks)); @@ -1402,6 +1403,8 @@ inline void trx_t::commit_in_memory(const mtr_t *mtr) trx_finalize_for_fts(this, undo_no != 0); #ifdef WITH_WSREP + ut_ad(is_wsrep() == wsrep_on(mysql_thd)); + /* Serialization history has been written and the transaction is committed in memory, which makes this commit ordered. Release commit order critical section. */ From d1f2ceee1bb1d33e181b5f35b12ed8536a8a0d24 Mon Sep 17 00:00:00 2001 From: Denis Protivensky Date: Thu, 20 Jun 2024 12:34:55 +0300 Subject: [PATCH 058/213] MDEV-33064: Sync trx->wsrep state from THD on trx start Replace trx->wsrep= 0 with an assert in trx_rollback_for_mysql() Signed-off-by: Julius Goryavsky --- storage/innobase/trx/trx0roll.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc index fbe5a7e9b0a..626dd7378f6 100644 --- a/storage/innobase/trx/trx0roll.cc +++ b/storage/innobase/trx/trx0roll.cc @@ -211,7 +211,7 @@ dberr_t trx_rollback_for_mysql(trx_t* trx) trx->will_lock = false; ut_ad(trx->mysql_thd); #ifdef WITH_WSREP - trx->wsrep= false; + ut_ad(!trx->is_wsrep()); trx->lock.was_chosen_as_wsrep_victim= false; #endif return(DB_SUCCESS); From 5335681f67571345970e7d0f8913c9eb477848ac Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 12 Dec 2024 08:51:11 +1100 Subject: [PATCH 059/213] MDEV-32686: Debian: include ELF package notes Providing build information compiled into the executable provides the ability of core file handlers to access information on the distro and source package version. This information can sometime be lost between the source and an upstream bug report. The Debian dh-package-notes includes the makefile included in debian/rules that sets linking flags to the right values. The jammy version of dh-package-notes does not include the same makefile implementation as the others. ref: https://systemd.io/ELF_PACKAGE_METADATA/ fix --- debian/autobake-deb.sh | 8 ++++++++ debian/control | 1 + debian/rules | 3 +++ 3 files changed, 12 insertions(+) diff --git a/debian/autobake-deb.sh b/debian/autobake-deb.sh index 0a4a14624b5..04a8c2f5e48 100755 --- a/debian/autobake-deb.sh +++ b/debian/autobake-deb.sh @@ -77,6 +77,12 @@ disable_libfmt() sed '/libfmt-dev/d' -i debian/control } +remove_package_notes() +{ + # binutils >=2.39 + disto makefile /usr/share/debhelper/dh_package_notes/package-notes.mk + sed -e '/package.notes/d' -i debian/rules debian/control +} + architecture=$(dpkg-architecture -q DEB_BUILD_ARCH) uname_machine=$(uname -m) @@ -114,6 +120,7 @@ in ;& "bullseye") add_lsb_base_depends + remove_package_notes ;& "bookworm") # mariadb-plugin-rocksdb in control is 4 arches covered by the distro rocksdb-tools @@ -134,6 +141,7 @@ in ;& "jammy"|"kinetic") add_lsb_base_depends + remove_package_notes ;& "lunar"|"mantic") if [[ ! "$architecture" =~ amd64|arm64|armhf|ppc64el|s390x ]] diff --git a/debian/control b/debian/control index 2a64b824f36..9b2f8a0dbbb 100644 --- a/debian/control +++ b/debian/control @@ -7,6 +7,7 @@ Build-Depends: bison, cracklib-runtime , debhelper (>= 11), dh-exec, + dh-package-notes, flex [amd64], gdb , libaio-dev [linux-any], diff --git a/debian/rules b/debian/rules index 34425886604..07d922f705c 100644 --- a/debian/rules +++ b/debian/rules @@ -10,6 +10,9 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=+all DPKG_EXPORT_BUILDFLAGS = 1 # Include all defaults, including buildflags.mk include /usr/share/dpkg/default.mk +# Include package notes in built executables +include /usr/share/debhelper/dh_package_notes/package-notes.mk + # CPPFLAGS are nor read by CMake, so copy them to CXXFLAGS # See why at https://cmake.org/Bug/view.php?id=12928 # This is needed for e.g. all automatic Debian hardening flags to apply on all cmake builds. From e55fe2c2e3679af80516c4d7eedaed4953068ece Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 18 Dec 2024 15:25:10 +1100 Subject: [PATCH 060/213] MDEV-32686 Use Red Hat package notes in compilation This tests the compile using a spec file. This spec file is defined by environment variables. If the spec file doesn't exist (SLES/OpenSUSE), isn't supported (e.g. clang), or has incorrect environment variables the linker flag won't be used. Stripping output avoid gcc ICE bug https://bugzilla.redhat.com/show_bug.cgi?id=2336272 Launcher used to make env variables show up in the build step rather than just the configure step. --- cmake/cpack_rpm.cmake | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/cmake/cpack_rpm.cmake b/cmake/cpack_rpm.cmake index 5e8966ec7bb..3ffd83078be 100644 --- a/cmake/cpack_rpm.cmake +++ b/cmake/cpack_rpm.cmake @@ -2,6 +2,8 @@ IF(RPM) MESSAGE(STATUS "CPackRPM building with RPM configuration: ${RPM}") +INCLUDE(check_linker_flag) + SET(CPACK_GENERATOR "RPM") SET(CPACK_RPM_PACKAGE_DEBUG 1) SET(CPACK_PACKAGING_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}) @@ -52,6 +54,19 @@ SET(CPACK_PACKAGE_RELOCATABLE FALSE) SET(CPACK_RPM_PACKAGE_GROUP "Applications/Databases") SET(CPACK_RPM_PACKAGE_URL ${CPACK_PACKAGE_URL}) +# The spec file depends on environment variables +SET(ENV{RPM_PACKAGE_NAME} ${CPACK_RPM_PACKAGE_NAME}) +EXECUTE_PROCESS(COMMAND rpm --eval ${CPACK_RPM_PACKAGE_RELEASE} OUTPUT_VARIABLE RPM_PACKAGE_RELEASE_EXPANDED) +STRING(STRIP "${RPM_PACKAGE_RELEASE_EXPANDED}" RPM_PACKAGE_RELEASE_EXPANDED) +SET(ENV{RPM_PACKAGE_RELEASE} ${RPM_PACKAGE_RELEASE_EXPANDED}) +SET(ENV{RPM_ARCH} ${CMAKE_SYSTEM_PROCESSOR}) +SET(ENV{RPM_PACKAGE_VERSION} ${SERVER_VERSION}) +MY_CHECK_AND_SET_LINKER_FLAG("-specs=/usr/lib/rpm/redhat/redhat-package-notes") +IF(HAVE_LINK_FLAG__specs_/usr/lib/rpm/redhat/redhat_package_notes) + SET(CMAKE_CXX_LINKER_LAUNCHER "env;RPM_PACKAGE_NAME=$ENV{RPM_PACKAGE_NAME};RPM_ARCH=$ENV{RPM_ARCH};RPM_PACKAGE_VERSION=$ENV{RPM_PACKAGE_VERSION};RPM_PACKAGE_RELEASE=$ENV{RPM_PACKAGE_RELEASE}") + SET(CMAKE_C_LINKER_LAUNCHER ${CMAKE_CXX_LINKER_LAUNCHER}) +ENDIF() + SET(CPACK_RPM_shared_PACKAGE_VENDOR "MariaDB Corporation Ab") SET(CPACK_RPM_shared_PACKAGE_LICENSE "LGPLv2.1") From 6868d965db1e14f2441c3bff05f0156079524c35 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 14 Jan 2025 08:54:14 +1100 Subject: [PATCH 061/213] MDEV-34825 FreeBSD fails to build under clang natively (postfix) The fix in MDEV-34825/#3484/dff354e7df2f originally just took the FreeBSD carried patch of inline ASM as it didn't have the __ppc_get_timebase function. What clang does have is the __builtin_ppc_get_timebase, which was replaced in the same commit, which was the fix taken from Alpine. To reduce complexity - we only need one working function rather than an equivalent asm implementation. Noted by Marko, thanks! --- include/my_cpu.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/include/my_cpu.h b/include/my_cpu.h index 1f562dc700c..f9b0c5f0c6d 100644 --- a/include/my_cpu.h +++ b/include/my_cpu.h @@ -94,13 +94,8 @@ static inline void MY_RELAX_CPU(void) __asm__ __volatile__ ("pause"); #endif #elif defined(_ARCH_PWR8) -#ifdef __FreeBSD__ - uint64_t __tb; - __asm__ volatile ("mfspr %0, 268" : "=r" (__tb)); -#else - /* Changed from __ppc_get_timebase for musl compatibility */ + /* Changed from __ppc_get_timebase for musl and clang compatibility */ __builtin_ppc_get_timebase(); -#endif #elif defined __GNUC__ && (defined __arm__ || defined __aarch64__) /* Mainly, prevent the compiler from optimizing away delay loops */ #ifdef _aarch64_ From 200c235244bd06d12fc4d01c79830f2e8b2512cf Mon Sep 17 00:00:00 2001 From: ParadoxV5 Date: Thu, 9 Jan 2025 17:54:57 -0700 Subject: [PATCH 062/213] MDEV-35429 my_snprintf fixes for 10.5+ * Innobase `os0file.cc`: use `PRIu64` over `llu` * These came after I prepared #3485. * MyISAM `mi_check.c`: in impossible block length warning * I missed this one in #3485 (and #3360 too?). --- storage/innobase/os/os0file.cc | 6 +++--- storage/myisam/mi_check.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 012f23b3b8d..c6106d47557 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -1641,8 +1641,8 @@ bool os_file_set_size(const char *name, os_file_t file, os_offset_t size, if (is_sparse) { bool success = !ftruncate(file, size); if (!success) { - sql_print_error("InnoDB: ftruncate of file %s" - " to %llu bytes failed with error %d", + sql_print_error("InnoDB: ftruncate of file %s to %" + PRIu64 " bytes failed with error %d", name, size, errno); } return success; @@ -1680,7 +1680,7 @@ bool os_file_set_size(const char *name, os_file_t file, os_offset_t size, case 0: return true; default: - sql_print_error("InnoDB: preallocating %llu" + sql_print_error("InnoDB: preallocating %" PRIu64 " bytes for file %s failed with error %d", size, name, err); /* fall through */ diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index e46dc35f861..dff5fcdbcb6 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -3429,9 +3429,9 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) { if (!searching) mi_check_print_info(param, - "Found block with impossible length %u at %s; Skipped", - block_info.block_len+ (uint) (block_info.filepos-pos), - llstr(pos,llbuff)); + "Found block with impossible length %lu at %s; Skipped", + block_info.block_len + (unsigned long) (block_info.filepos-pos), + llstr(pos, llbuff)); if (found_record) goto try_next; searching=1; From 9d80422f79ec7324a6897c4219e984f138566e7c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 14 Jan 2025 13:49:24 +0100 Subject: [PATCH 063/213] MDEV-26266 disable the test on 10.11 for now --- mysql-test/suite/galera/disabled.def | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 5b92b282ece..e77af6477df 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -12,3 +12,4 @@ galera_as_slave_replay : MDEV-32780 galera_as_slave_replay: assertion in the wsrep::transaction::before_rollback() galera_slave_replay : MDEV-32780 galera_as_slave_replay: assertion in the wsrep::transaction::before_rollback() +MDEV-26266 : MDEV-26266 From b04fb9fb43fd39f612c14813c14e0ad3e398eaa3 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 14 Jan 2025 13:56:19 +0100 Subject: [PATCH 064/213] MDEV-34062 compilation failure on 32bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit extra/mariabackup/xtrabackup.cc:3407:15: error: conversion from ‘lsn_t’ {aka ‘long long unsigned int’} to ‘size_t’ {aka ‘unsigned int’} may change value [-Werror=conversion] followup for 6acada713a95 --- extra/mariabackup/xtrabackup.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 8385114f39b..5ad77e3d682 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -3404,7 +3404,7 @@ static bool xtrabackup_copy_mmap_logfile() /* Set the sequence bit (the backed-up log will not wrap around) */ size_t seqo= recv_sys.offset - seq_offset; if (seqo < log_sys.START_OFFSET) - seqo+= log_sys.file_size - log_sys.START_OFFSET; + seqo+= static_cast(log_sys.file_size - log_sys.START_OFFSET); const byte *seq= &log_sys.buf[seqo]; ut_ad(*seq == log_sys.get_sequence_bit(recv_sys.lsn - seq_offset)); if (!*seq) From 4469540d399391749f2413759482babc08daa229 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 14 Jan 2025 14:01:28 +0100 Subject: [PATCH 065/213] MDEV-35810 fix test results followup for aa35f62f1c9b --- mysql-test/suite/funcs_1/r/is_routines_embedded.result | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/funcs_1/r/is_routines_embedded.result b/mysql-test/suite/funcs_1/r/is_routines_embedded.result index be2a3d45432..817817b01d2 100644 --- a/mysql-test/suite/funcs_1/r/is_routines_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_routines_embedded.result @@ -197,7 +197,7 @@ sp_6_408002_2 def db_datadict_2 sp_6_408002_2 PROCEDURE NULL NULL NULL NULL NUL SELECT * FROM db_datadict_2.res_6_408002_2; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost latin1 latin1_swedish_ci latin1_swedish_ci add_suppression def mtr add_suppression PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN INSERT INTO test_suppressions (pattern) VALUES (pattern); FLUSH NO_WRITE_TO_BINLOG TABLE test_suppressions; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8mb3 utf8mb3_general_ci latin1_swedish_ci -check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' AND variable_name != 'THREAD_POOL_SIZE' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY BINARY SCHEMA_NAME; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema') ORDER BY BINARY SCHEMA_NAME; SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert') AND TRIGGER_SCHEMA != 'sys'; SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA != 'sys'; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.plugin, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.global_priv; SELECT * FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_STATUS != 'INACTIVE'; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8mb3 utf8mb3_general_ci latin1_swedish_ci +check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_LOG_FILE_BUFFERING' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' AND variable_name != 'THREAD_POOL_SIZE' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY BINARY SCHEMA_NAME; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema') ORDER BY BINARY SCHEMA_NAME; SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert') AND TRIGGER_SCHEMA != 'sys'; SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA != 'sys'; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.plugin, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.global_priv; SELECT * FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_STATUS != 'INACTIVE'; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8mb3 utf8mb3_general_ci latin1_swedish_ci check_warnings def mtr check_warnings PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN DECLARE `pos` bigint unsigned; SET SQL_LOG_BIN=0, SQL_SAFE_UPDATES=0; UPDATE error_log el, global_suppressions gs SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP gs.pattern; UPDATE error_log el, test_suppressions ts SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP ts.pattern; SELECT COUNT(*) INTO @num_warnings FROM error_log WHERE suspicious=1; IF @num_warnings > 0 THEN SELECT line FROM error_log WHERE suspicious=1; SELECT 2 INTO result; ELSE SELECT 0 INTO RESULT; END IF; TRUNCATE test_suppressions; DROP TABLE error_log; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8mb3 utf8mb3_general_ci latin1_swedish_ci AddGeometryColumn def mysql AddGeometryColumn PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL begin set @qwe= concat('ALTER TABLE ', t_schema, '.', t_name, ' ADD ', geometry_column,' GEOMETRY REF_SYSTEM_ID=', t_srid); PREPARE ls from @qwe; execute ls; deallocate prepare ls; end NULL NULL SQL NO CONTAINS SQL NULL INVOKER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss mariadb.sys@localhost latin1 latin1_swedish_ci latin1_swedish_ci @@ -213,7 +213,7 @@ sp_6_408002_2 def db_datadict_2 sp_6_408002_2 PROCEDURE NULL NULL NULL NULL NUL SELECT * FROM db_datadict_2.res_6_408002_2; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost latin1 latin1_swedish_ci latin1_swedish_ci add_suppression def mtr add_suppression PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN INSERT INTO test_suppressions (pattern) VALUES (pattern); FLUSH NO_WRITE_TO_BINLOG TABLE test_suppressions; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8mb3 utf8mb3_general_ci latin1_swedish_ci -check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' AND variable_name != 'THREAD_POOL_SIZE' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY BINARY SCHEMA_NAME; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema') ORDER BY BINARY SCHEMA_NAME; SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert') AND TRIGGER_SCHEMA != 'sys'; SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA != 'sys'; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.plugin, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.global_priv; SELECT * FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_STATUS != 'INACTIVE'; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8mb3 utf8mb3_general_ci latin1_swedish_ci +check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_LOG_FILE_BUFFERING' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' AND variable_name != 'THREAD_POOL_SIZE' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY BINARY SCHEMA_NAME; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema') ORDER BY BINARY SCHEMA_NAME; SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert') AND TRIGGER_SCHEMA != 'sys'; SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA != 'sys'; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.plugin, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.global_priv; SELECT * FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_STATUS != 'INACTIVE'; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8mb3 utf8mb3_general_ci latin1_swedish_ci check_warnings def mtr check_warnings PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN DECLARE `pos` bigint unsigned; SET SQL_LOG_BIN=0, SQL_SAFE_UPDATES=0; UPDATE error_log el, global_suppressions gs SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP gs.pattern; UPDATE error_log el, test_suppressions ts SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP ts.pattern; SELECT COUNT(*) INTO @num_warnings FROM error_log WHERE suspicious=1; IF @num_warnings > 0 THEN SELECT line FROM error_log WHERE suspicious=1; SELECT 2 INTO result; ELSE SELECT 0 INTO RESULT; END IF; TRUNCATE test_suppressions; DROP TABLE error_log; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8mb3 utf8mb3_general_ci latin1_swedish_ci AddGeometryColumn def mysql AddGeometryColumn PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL begin set @qwe= concat('ALTER TABLE ', t_schema, '.', t_name, ' ADD ', geometry_column,' GEOMETRY REF_SYSTEM_ID=', t_srid); PREPARE ls from @qwe; execute ls; deallocate prepare ls; end NULL NULL SQL NO CONTAINS SQL NULL INVOKER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss mariadb.sys@localhost latin1 latin1_swedish_ci latin1_swedish_ci @@ -229,7 +229,7 @@ sp_6_408002_2 def db_datadict_2 sp_6_408002_2 PROCEDURE NULL NULL NULL NULL NUL SELECT * FROM db_datadict_2.res_6_408002_2; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost latin1 latin1_swedish_ci latin1_swedish_ci add_suppression def mtr add_suppression PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN INSERT INTO test_suppressions (pattern) VALUES (pattern); FLUSH NO_WRITE_TO_BINLOG TABLE test_suppressions; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8mb3 utf8mb3_general_ci latin1_swedish_ci -check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' AND variable_name != 'THREAD_POOL_SIZE' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY BINARY SCHEMA_NAME; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema') ORDER BY BINARY SCHEMA_NAME; SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert') AND TRIGGER_SCHEMA != 'sys'; SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA != 'sys'; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.plugin, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.global_priv; SELECT * FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_STATUS != 'INACTIVE'; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8mb3 utf8mb3_general_ci latin1_swedish_ci +check_testcase def mtr check_testcase PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name NOT IN ('timestamp') AND variable_name not like "Last_IO_Err*" AND variable_name != 'INNODB_IBUF_MAX_SIZE' AND variable_name != 'INNODB_LOG_FILE_BUFFERING' AND variable_name != 'INNODB_USE_NATIVE_AIO' AND variable_name != 'INNODB_BUFFER_POOL_LOAD_AT_STARTUP' AND variable_name not like 'GTID%POS' AND variable_name != 'GTID_BINLOG_STATE' AND variable_name != 'THREAD_POOL_SIZE' ORDER BY variable_name; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY BINARY SCHEMA_NAME; SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mtr_wsrep_notify', 'wsrep_schema') ORDER BY BINARY SCHEMA_NAME; SELECT table_name AS tables_in_test FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'; SELECT CONCAT(table_schema, '.', table_name) AS tables_in_mysql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='mysql' ORDER BY tables_in_mysql; SELECT CONCAT(table_schema, '.', table_name) AS columns_in_mysql, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, character_set_name, collation_name, column_type, column_key, extra, column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='mysql' ORDER BY columns_in_mysql; SELECT * FROM INFORMATION_SCHEMA.EVENTS; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME NOT IN ('gs_insert', 'ts_insert') AND TRIGGER_SCHEMA != 'sys'; SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA != 'sys'; SHOW STATUS LIKE 'slave_open_temp_tables'; checksum table mysql.columns_priv, mysql.db, mysql.func, mysql.help_category, mysql.help_keyword, mysql.help_relation, mysql.plugin, mysql.procs_priv, mysql.roles_mapping, mysql.tables_priv, mysql.time_zone, mysql.time_zone_leap_second, mysql.time_zone_name, mysql.time_zone_transition, mysql.time_zone_transition_type, mysql.global_priv; SELECT * FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_STATUS != 'INACTIVE'; select * from information_schema.session_variables where variable_name = 'debug_sync'; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8mb3 utf8mb3_general_ci latin1_swedish_ci check_warnings def mtr check_warnings PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL BEGIN DECLARE `pos` bigint unsigned; SET SQL_LOG_BIN=0, SQL_SAFE_UPDATES=0; UPDATE error_log el, global_suppressions gs SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP gs.pattern; UPDATE error_log el, test_suppressions ts SET suspicious=0 WHERE el.suspicious=1 AND el.line REGEXP ts.pattern; SELECT COUNT(*) INTO @num_warnings FROM error_log WHERE suspicious=1; IF @num_warnings > 0 THEN SELECT line FROM error_log WHERE suspicious=1; SELECT 2 INTO result; ELSE SELECT 0 INTO RESULT; END IF; TRUNCATE test_suppressions; DROP TABLE error_log; END NULL NULL SQL NO CONTAINS SQL NULL DEFINER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss root@localhost utf8mb3 utf8mb3_general_ci latin1_swedish_ci AddGeometryColumn def mysql AddGeometryColumn PROCEDURE NULL NULL NULL NULL NULL NULL NULL NULL SQL begin set @qwe= concat('ALTER TABLE ', t_schema, '.', t_name, ' ADD ', geometry_column,' GEOMETRY REF_SYSTEM_ID=', t_srid); PREPARE ls from @qwe; execute ls; deallocate prepare ls; end NULL NULL SQL NO CONTAINS SQL NULL INVOKER YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss mariadb.sys@localhost latin1 latin1_swedish_ci latin1_swedish_ci From b337e14440ba4fa79a5b4fd34341e6bce4eecbc7 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Mon, 13 Jan 2025 15:40:58 +0300 Subject: [PATCH 066/213] WITHOUT_ABI_CHECK ABI check takes several seconds on compilation. It is not needed in repetitive build during the development process. --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 642f7b39b99..2c1e2719e43 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -501,7 +501,9 @@ IF(UNIX) ADD_SUBDIRECTORY(man) ENDIF() -INCLUDE(cmake/abi_check.cmake) +IF (NOT WITHOUT_ABI_CHECK) + INCLUDE(cmake/abi_check.cmake) +ENDIF() INCLUDE(cmake/tags.cmake) INCLUDE(for_clients) ADD_SUBDIRECTORY(scripts) From 52dd4895157da932d152d8d762df0989613ffb9d Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Mon, 13 Jan 2025 15:40:58 +0300 Subject: [PATCH 067/213] MDEV-22441 implement a generic way to change a value of a variable in a scope Example: { auto _= make_scope_value(var, tmp_value); } make_scope_value(): a function which returns RAII object which temporary changes a value of a variable detail::Scope_value: actual implementation of such RAII class. It shouldn't be used directly! That's why it's inside a namespace detail. --- include/scope.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ sql/sql_acl.cc | 6 ++++-- sql/sql_show.cc | 4 ++-- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/include/scope.h b/include/scope.h index e0e9fc62969..836c4f77b35 100644 --- a/include/scope.h +++ b/include/scope.h @@ -72,3 +72,48 @@ make_scope_exit(Callable &&f) #define ANONYMOUS_VARIABLE CONCAT(_anonymous_variable, __LINE__) #define SCOPE_EXIT auto ANONYMOUS_VARIABLE= make_scope_exit + +namespace detail +{ + +template class Scope_value +{ +public: + Scope_value(T &variable, const T &scope_value) + : variable_(variable), saved_value_(variable) + { + variable= scope_value; + } + + Scope_value(Scope_value &&rhs) + : variable_(rhs.variable_), saved_value_(rhs.saved_value_), + engaged_(rhs.engaged_) + { + rhs.engaged_= false; + } + + Scope_value(const Scope_value &)= delete; + Scope_value &operator=(const Scope_value &)= delete; + Scope_value &operator=(Scope_value &&)= delete; + + ~Scope_value() + { + if (engaged_) + variable_= saved_value_; + } + +private: + T &variable_; + T saved_value_; + bool engaged_= true; +}; + +} // namespace detail + +// Use like this: +// auto _= make_scope_value(var, tmp_value); +template +detail::Scope_value make_scope_value(T &variable, const T &scope_value) +{ + return detail::Scope_value(variable, scope_value); +} diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 59980264741..98e79babcc3 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -54,6 +54,7 @@ #include "sql_array.h" #include "sql_hset.h" #include "password.h" +#include "scope.h" #include "sql_plugin_compat.h" #include "wsrep_mysqld.h" @@ -2552,10 +2553,11 @@ static bool acl_load(THD *thd, const Grant_tables& tables) { READ_RECORD read_record_info; char tmp_name[SAFE_NAME_LEN+1]; - Sql_mode_save old_mode_save(thd); DBUG_ENTER("acl_load"); - thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH; + auto _= make_scope_value(thd->variables.sql_mode, + thd->variables.sql_mode & + ~MODE_PAD_CHAR_TO_FULL_LENGTH); grant_version++; /* Privileges updated */ diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 2965cdf0199..ee3d85e6ba2 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -65,6 +65,7 @@ #include "transaction.h" #include "opt_trace.h" #include "my_cpu.h" +#include "scope.h" #include "lex_symbol.h" @@ -6437,8 +6438,7 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table, { Field *field; LEX_CSTRING tmp_string; - Sql_mode_save sql_mode_backup(thd); - thd->variables.sql_mode= sql_mode; + auto _= make_scope_value(thd->variables.sql_mode, sql_mode); if (sph->type() == SP_TYPE_FUNCTION) { From d8adc5286373f366c74c56a53cbb4258e9b315d3 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Mon, 13 Jan 2025 15:40:58 +0300 Subject: [PATCH 068/213] MDEV-22441 SCOPE_VALUE macro for temporary values - Needless engaged_ removed; - SCOPE_VALUE, SCOPE_SET, SCOPE_CLEAR macros for neater declaration; - IF_CLASS / IF_NOT_CLASS SFINAE checkers to pass arg by value or reference; - inline keyword; - couple of refactorings of temporary free_list. --- include/scope.h | 83 ++++++++++++++++++++++++++++++++++++---------- sql/sql_acl.cc | 4 +-- sql/sql_prepare.cc | 21 +++++------- sql/sql_show.cc | 2 +- 4 files changed, 76 insertions(+), 34 deletions(-) diff --git a/include/scope.h b/include/scope.h index 836c4f77b35..932ab410d78 100644 --- a/include/scope.h +++ b/include/scope.h @@ -32,6 +32,11 @@ public: { } + template + scope_exit(F &&f, bool engaged) : function_(std::forward(f)), engaged_(engaged) + { + } + scope_exit(scope_exit &&rhs) : function_(std::move(rhs.function_)), engaged_(rhs.engaged_) { @@ -43,6 +48,7 @@ public: scope_exit &operator=(const scope_exit &)= delete; void release() { engaged_= false; } + void engage() { DBUG_ASSERT(!engaged_); engaged_= true; } ~scope_exit() { @@ -58,38 +64,51 @@ private: } // end namespace detail template -detail::scope_exit::type> -make_scope_exit(Callable &&f) +inline +::detail::scope_exit::type> +make_scope_exit(Callable &&f, bool engaged= true) { - return detail::scope_exit::type>( - std::forward(f)); + return ::detail::scope_exit::type>( + std::forward(f), engaged); } #define CONCAT_IMPL(x, y) x##y - #define CONCAT(x, y) CONCAT_IMPL(x, y) - #define ANONYMOUS_VARIABLE CONCAT(_anonymous_variable, __LINE__) #define SCOPE_EXIT auto ANONYMOUS_VARIABLE= make_scope_exit +#define IF_CLASS(C) typename std::enable_if::value>::type +#define IF_NOT_CLASS(C) typename std::enable_if::value>::type + namespace detail { -template class Scope_value +template +class Scope_value { public: + // Use SFINAE for passing structs by reference and plain types by value. + // This ctor is defined only if T is a class or struct: + template Scope_value(T &variable, const T &scope_value) - : variable_(variable), saved_value_(variable) + : variable_(&variable), saved_value_(variable) + { + variable= scope_value; + } + + // This ctor is defined only if T is NOT a class or struct: + template + Scope_value(T &variable, const T scope_value) + : variable_(&variable), saved_value_(variable) { variable= scope_value; } Scope_value(Scope_value &&rhs) - : variable_(rhs.variable_), saved_value_(rhs.saved_value_), - engaged_(rhs.engaged_) + : variable_(rhs.variable_), saved_value_(rhs.saved_value_) { - rhs.engaged_= false; + rhs.variable_= NULL; } Scope_value(const Scope_value &)= delete; @@ -98,22 +117,50 @@ public: ~Scope_value() { - if (engaged_) - variable_= saved_value_; + if (variable_) + *variable_= saved_value_; } private: - T &variable_; + T *variable_; T saved_value_; - bool engaged_= true; }; } // namespace detail // Use like this: // auto _= make_scope_value(var, tmp_value); -template -detail::Scope_value make_scope_value(T &variable, const T &scope_value) + +template +inline +::detail::Scope_value make_scope_value(T &variable, const T &scope_value) { - return detail::Scope_value(variable, scope_value); + return ::detail::Scope_value(variable, scope_value); } + +template +inline +::detail::Scope_value make_scope_value(T &variable, T scope_value) +{ + return ::detail::Scope_value(variable, scope_value); +} + +/* + Note: perfect forwarding version can not pass const: + + template + inline + detail::Scope_value make_scope_value(T &variable, U &&scope_value) + { + return detail::Scope_value(variable, std::forward(scope_value)); + } + + as `const U &&` fails with error `expects an rvalue for 2nd argument`. That + happens because const U && is treated as rvalue only (this is the exact syntax + for declaring rvalues). +*/ + + +#define SCOPE_VALUE auto ANONYMOUS_VARIABLE= make_scope_value +#define SCOPE_SET(VAR, MASK) auto ANONYMOUS_VARIABLE= make_scope_value(VAR, VAR | MASK) +#define SCOPE_CLEAR(VAR, MASK) auto ANONYMOUS_VARIABLE= make_scope_value(VAR, VAR & ~MASK) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 98e79babcc3..c7f2a8d3d46 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2555,9 +2555,7 @@ static bool acl_load(THD *thd, const Grant_tables& tables) char tmp_name[SAFE_NAME_LEN+1]; DBUG_ENTER("acl_load"); - auto _= make_scope_value(thd->variables.sql_mode, - thd->variables.sql_mode & - ~MODE_PAD_CHAR_TO_FULL_LENGTH); + SCOPE_CLEAR(thd->variables.sql_mode, MODE_PAD_CHAR_TO_FULL_LENGTH); grant_version++; /* Privileges updated */ diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 9d53d7cf543..c102e2f734e 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2993,8 +2993,8 @@ void mysql_sql_stmt_execute_immediate(THD *thd) DBUG_VOID_RETURN; // out of memory // See comments on thd->free_list in mysql_sql_stmt_execute() - Item *free_list_backup= thd->free_list; - thd->free_list= NULL; + SCOPE_VALUE(thd->free_list, (Item *) NULL); + SCOPE_EXIT([thd]() mutable { thd->free_items(); }); /* Make sure we call Prepared_statement::execute_immediate() with an empty THD::change_list. It can be non empty as the above @@ -3017,8 +3017,6 @@ void mysql_sql_stmt_execute_immediate(THD *thd) Item_change_list_savepoint change_list_savepoint(thd); (void) stmt->execute_immediate(query.str, (uint) query.length); change_list_savepoint.rollback(thd); - thd->free_items(); - thd->free_list= free_list_backup; /* stmt->execute_immediately() sets thd->query_string with the executed @@ -3578,8 +3576,13 @@ void mysql_sql_stmt_execute(THD *thd) so they don't get freed in case of re-prepare. See MDEV-10702 Crash in SET STATEMENT FOR EXECUTE */ - Item *free_list_backup= thd->free_list; - thd->free_list= NULL; // Hide the external (e.g. "SET STATEMENT") Items + /* + Hide and restore at scope exit the "external" (e.g. "SET STATEMENT") Item list. + It will be freed normaly in THD::cleanup_after_query(). + */ + SCOPE_VALUE(thd->free_list, (Item *) NULL); + // Free items created by execute_loop() at scope exit + SCOPE_EXIT([thd]() mutable { thd->free_items(); }); /* Make sure we call Prepared_statement::execute_loop() with an empty THD::change_list. It can be non-empty because the above @@ -3603,12 +3606,6 @@ void mysql_sql_stmt_execute(THD *thd) (void) stmt->execute_loop(&expanded_query, FALSE, NULL, NULL); change_list_savepoint.rollback(thd); - thd->free_items(); // Free items created by execute_loop() - /* - Now restore the "external" (e.g. "SET STATEMENT") Item list. - It will be freed normaly in THD::cleanup_after_query(). - */ - thd->free_list= free_list_backup; stmt->lex->restore_set_statement_var(); DBUG_VOID_RETURN; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index ee3d85e6ba2..dff2a9c73da 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -6438,7 +6438,7 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table, { Field *field; LEX_CSTRING tmp_string; - auto _= make_scope_value(thd->variables.sql_mode, sql_mode); + SCOPE_VALUE(thd->variables.sql_mode, sql_mode); if (sph->type() == SP_TYPE_FUNCTION) { From 92383f8db17b0a3eb95b63c6aee4220017fe63da Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Mon, 13 Jan 2025 15:40:58 +0300 Subject: [PATCH 069/213] MDEV-26891 Segfault in Field::register_field_in_read_map upon INSERT DELAYED with virtual columns Segfault was cause by two different copies of same Field instance in prepared delayed insert. One was made by Delayed_insert::get_local_table() (see make_new_field()). That copy went through parse_vcol_defs() and received new vcol_info->expr. Another one was made by copy_keys_from_share() by this code: /* We are using only a prefix of the column as a key: Create a new field for the key part that matches the index */ field= key_part->field=field->make_new_field(root, outparam, 0); field->field_length= key_part->length; So, key_part and table got different objects of same field and the crash was because key_part->field->vcol_info->expr is NULL. The fix does update_keypart_vcol_info() to update vcol_info->expr in key_part->field. Cleanup: memdup_vcol() is static inline instead of macro + check OOM. --- mysql-test/suite/vcol/r/vcol_misc.result | 14 ++++++++++ mysql-test/suite/vcol/t/vcol_misc.test | 19 ++++++++++++++ sql/sql_insert.cc | 30 +++++++++++++++------ sql/table.cc | 33 ++++++++++++++---------- sql/table.h | 1 + 5 files changed, 75 insertions(+), 22 deletions(-) diff --git a/mysql-test/suite/vcol/r/vcol_misc.result b/mysql-test/suite/vcol/r/vcol_misc.result index 64c56e81815..2900cd4b4f4 100644 --- a/mysql-test/suite/vcol/r/vcol_misc.result +++ b/mysql-test/suite/vcol/r/vcol_misc.result @@ -577,3 +577,17 @@ drop table t; # # End of 10.4 tests # +# +# MDEV-26891 Segfault in Field::register_field_in_read_map upon INSERT DELAYED with virtual columns +# +CREATE TABLE t ( +id INT AUTO_INCREMENT, +a varchar(16) NOT NULL DEFAULT '', +b varchar(16) GENERATED ALWAYS AS (a) VIRTUAL, +KEY `col_year` (b(8),id) +) ENGINE=MyISAM; +INSERT DELAYED INTO t (a) VALUES ('foo'),('bar'); +DROP TABLE t; +# +# End of 10.5 tests +# diff --git a/mysql-test/suite/vcol/t/vcol_misc.test b/mysql-test/suite/vcol/t/vcol_misc.test index 83a06e83f6f..2709ff5b465 100644 --- a/mysql-test/suite/vcol/t/vcol_misc.test +++ b/mysql-test/suite/vcol/t/vcol_misc.test @@ -541,3 +541,22 @@ drop table t; --echo # --echo # End of 10.4 tests --echo # + +--echo # +--echo # MDEV-26891 Segfault in Field::register_field_in_read_map upon INSERT DELAYED with virtual columns +--echo # +CREATE TABLE t ( + id INT AUTO_INCREMENT, + a varchar(16) NOT NULL DEFAULT '', + b varchar(16) GENERATED ALWAYS AS (a) VIRTUAL, + KEY `col_year` (b(8),id) +) ENGINE=MyISAM; + +INSERT DELAYED INTO t (a) VALUES ('foo'),('bar'); + +# Cleanup +DROP TABLE t; + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 000695c5399..50a1a37e3ea 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2674,12 +2674,21 @@ end_create: DBUG_RETURN(thd->is_error()); } -#define memdup_vcol(thd, vcol) \ - if (vcol) \ - { \ - (vcol)= (Virtual_column_info*)(thd)->memdup((vcol), sizeof(*(vcol))); \ - (vcol)->expr= NULL; \ +static inline +bool memdup_vcol(THD *thd, Virtual_column_info *&vcol) +{ + if (vcol) + { + vcol= (Virtual_column_info*)(thd->memdup(vcol, sizeof(*vcol))); + if (!vcol) + { + my_error(ER_OUT_OF_RESOURCES, MYF(0)); + return true; + } + vcol->expr= NULL; } + return false; +} /** As we can't let many client threads modify the same TABLE @@ -2820,9 +2829,12 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) (*field)->move_field_offset(adjust_ptrs); // Point at copy->record[0] (*field)->flags|= ((*org_field)->flags & LONG_UNIQUE_HASH_FIELD); (*field)->invisible= (*org_field)->invisible; - memdup_vcol(client_thd, (*field)->vcol_info); - memdup_vcol(client_thd, (*field)->default_value); - memdup_vcol(client_thd, (*field)->check_constraint); + if (memdup_vcol(client_thd, (*field)->vcol_info)) + goto error; + if (memdup_vcol(client_thd, (*field)->default_value)) + goto error; + if (memdup_vcol(client_thd, (*field)->check_constraint)) + goto error; if (*org_field == found_next_number_field) (*field)->table->found_next_number_field= *field; } @@ -2839,6 +2851,8 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) &error_reported, VCOL_INIT_DEPENDENCY_FAILURE_IS_WARNING))) goto error; + + copy->update_keypart_vcol_info(); } switch_defaults_to_nullable_trigger_fields(copy); diff --git a/sql/table.cc b/sql/table.cc index aaec593df76..11564e85af0 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -3952,6 +3952,24 @@ bool copy_keys_from_share(TABLE *outparam, MEM_ROOT *root) return 0; } +void TABLE::update_keypart_vcol_info() +{ + for (uint k= 0; k < s->keys; k++) + { + KEY &info_k= key_info[k]; + uint parts = (s->use_ext_keys ? info_k.ext_key_parts : + info_k.user_defined_key_parts); + for (uint p= 0; p < parts; p++) + { + KEY_PART_INFO &kp= info_k.key_part[p]; + if (kp.field != field[kp.fieldnr - 1]) + { + kp.field->vcol_info = field[kp.fieldnr - 1]->vcol_info; + } + } + } +} + /* Open a table based on a TABLE_SHARE @@ -4184,20 +4202,7 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share, /* Update to use trigger fields */ switch_defaults_to_nullable_trigger_fields(outparam); - for (uint k= 0; k < share->keys; k++) - { - KEY &key_info= outparam->key_info[k]; - uint parts = (share->use_ext_keys ? key_info.ext_key_parts : - key_info.user_defined_key_parts); - for (uint p= 0; p < parts; p++) - { - KEY_PART_INFO &kp= key_info.key_part[p]; - if (kp.field != outparam->field[kp.fieldnr - 1]) - { - kp.field->vcol_info = outparam->field[kp.fieldnr - 1]->vcol_info; - } - } - } + outparam->update_keypart_vcol_info(); } #ifdef WITH_PARTITION_STORAGE_ENGINE diff --git a/sql/table.h b/sql/table.h index b3e23ab02e8..d46f91ee2dd 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1695,6 +1695,7 @@ public: bool is_filled_at_execution(); bool update_const_key_parts(COND *conds); + void update_keypart_vcol_info(); inline void initialize_opt_range_structures(); From 0cf2176b7975abeacc7c1e7c5f673440c26953c6 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Mon, 13 Jan 2025 15:40:58 +0300 Subject: [PATCH 070/213] MDEV-34033 Exchange partition with virtual columns fails MDEV-28127 did is_equal() which compared vcol expressions literally. But another table vcol expression is not equal because of different table name. We implement another comparison method is_identical() which respects different table name in vcol comparison. If any field item points to table_A and compared field item points to table_B, such items are treated as equal in (table_A, table_B) comparison. This is done by cloning table_B expression and renaming any table_B entries to table_A in it. --- mysql-test/main/partition_exchange.result | 22 ++++++++++++++++ mysql-test/main/partition_exchange.test | 32 +++++++++++++++++++++++ sql/field.h | 3 +++ sql/item.cc | 24 +++++++++++++++++ sql/item.h | 9 +++++++ sql/sql_class.h | 1 + sql/sql_partition_admin.cc | 2 ++ sql/sql_table.cc | 6 ++++- sql/table.cc | 21 +++++++++++++++ 9 files changed, 119 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/partition_exchange.result b/mysql-test/main/partition_exchange.result index c82d8d2071b..999517f4028 100644 --- a/mysql-test/main/partition_exchange.result +++ b/mysql-test/main/partition_exchange.result @@ -1321,3 +1321,25 @@ CREATE TABLE t2 (a INT, PRIMARY KEY(a)) CHECKSUM=1, ENGINE=InnoDB; ALTER TABLE t1 EXCHANGE PARTITION p0 WITH TABLE t2; ERROR HY000: Tables have different definitions DROP TABLE t1, t2; +# +# MDEV-34033 Exchange partition with virtual columns fails +# +create or replace table t1( +id int primary key, +col1 int, +col2 boolean as (col1 is null)) +partition by list (id) ( partition p1 values in (1) +); +create or replace table t1_working like t1; +alter table t1_working remove partitioning; +alter table t1 exchange partition p1 with table t1_working; +create or replace table t2( +id int primary key, +col1 int, +col2 boolean as (true)) +partition by list (id) ( partition p1 values in (1) +); +create or replace table t2_working like t2; +alter table t2_working remove partitioning; +alter table t2 exchange partition p1 with table t2_working; +drop tables t1, t1_working, t2, t2_working; diff --git a/mysql-test/main/partition_exchange.test b/mysql-test/main/partition_exchange.test index 4125e998623..e92b8dfff5c 100644 --- a/mysql-test/main/partition_exchange.test +++ b/mysql-test/main/partition_exchange.test @@ -554,3 +554,35 @@ ALTER TABLE t1 EXCHANGE PARTITION p0 WITH TABLE t2; # Cleanup DROP TABLE t1, t2; + +--echo # +--echo # MDEV-34033 Exchange partition with virtual columns fails +--echo # +# this fails when the virtual persistent column +# references another column +create or replace table t1( + id int primary key, + col1 int, + col2 boolean as (col1 is null)) + partition by list (id) ( partition p1 values in (1) +); + +create or replace table t1_working like t1; +alter table t1_working remove partitioning; +alter table t1 exchange partition p1 with table t1_working; + +# this works when the virtual persistent column +# does not reference another column +create or replace table t2( + id int primary key, + col1 int, + col2 boolean as (true)) + partition by list (id) ( partition p1 values in (1) +); + +create or replace table t2_working like t2; +alter table t2_working remove partitioning; +alter table t2 exchange partition p1 with table t2_working; + +# Cleanup +drop tables t1, t1_working, t2, t2_working; diff --git a/sql/field.h b/sql/field.h index 7ea431e8acb..3894c22e6da 100644 --- a/sql/field.h +++ b/sql/field.h @@ -659,6 +659,9 @@ public: bool cleanup_session_expr(); bool fix_and_check_expr(THD *thd, TABLE *table); inline bool is_equal(const Virtual_column_info* vcol) const; + /* Same as is_equal() but for comparing with different table */ + bool is_equivalent(THD *thd, TABLE_SHARE *share, TABLE_SHARE *vcol_share, + const Virtual_column_info* vcol, bool &error) const; inline void print(String*); }; diff --git a/sql/item.cc b/sql/item.cc index 44bd4bbfbba..e6e69629fe5 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -833,6 +833,30 @@ bool Item_field::rename_fields_processor(void *arg) return 0; } +/** + Rename table and clean field for EXCHANGE comparison +*/ + +bool Item_field::rename_table_processor(void *arg) +{ + Item::func_processor_rename_table *p= (Item::func_processor_rename_table*) arg; + + /* If (db_name, table_name) matches (p->old_db, p->old_table) + rename to (p->new_db, p->new_table) */ + if (((!db_name.str && !p->old_db.str) || + db_name.streq(p->old_db)) && + ((!table_name.str && !p->old_table.str) || + table_name.streq(p->old_table))) + { + db_name= p->new_db; + table_name= p->new_table; + } + + /* Item_field equality is done by field pointer if it is set, we need to avoid that */ + field= NULL; + return 0; +} + /** Check if an Item_field references some field from a list of fields. diff --git a/sql/item.h b/sql/item.h index 147b12dfa8b..a146107508f 100644 --- a/sql/item.h +++ b/sql/item.h @@ -2148,6 +2148,7 @@ public: virtual bool check_partition_func_processor(void *arg) { return 1;} virtual bool post_fix_fields_part_expr_processor(void *arg) { return 0; } virtual bool rename_fields_processor(void *arg) { return 0; } + virtual bool rename_table_processor(void *arg) { return 0; } /* TRUE if the function is knowingly TRUE or FALSE. Not to be used for AND/OR formulas. @@ -2176,6 +2177,13 @@ public: LEX_CSTRING table_name; List fields; }; + struct func_processor_rename_table + { + Lex_ident_db old_db; + Lex_ident_table old_table; + Lex_ident_db new_db; + Lex_ident_table new_table; + }; virtual bool check_vcol_func_processor(void *arg) { return mark_unsupported_function(full_name(), arg, VCOL_IMPOSSIBLE); @@ -3659,6 +3667,7 @@ public: bool switch_to_nullable_fields_processor(void *arg) override; bool update_vcol_processor(void *arg) override; bool rename_fields_processor(void *arg) override; + bool rename_table_processor(void *arg) override; bool check_vcol_func_processor(void *arg) override; bool set_fields_as_dependent_processor(void *arg) override { diff --git a/sql/sql_class.h b/sql/sql_class.h index 032d0bc2606..03860e5ff4e 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -50,6 +50,7 @@ #include "session_tracker.h" #include "backup.h" #include "xa.h" +#include "scope.h" extern "C" void set_thd_stage_info(void *thd, diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc index 68dd3379d64..0ee775687f9 100644 --- a/sql/sql_partition_admin.cc +++ b/sql/sql_partition_admin.cc @@ -241,6 +241,8 @@ static bool compare_table_with_partition(THD *thd, TABLE *table, part_create_info.row_type= table->s->row_type; } + part_create_info.table= part_table; + /* NOTE: ha_blackhole does not support check_if_compatible_data, so this always fail for blackhole tables. diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 2119b98a0a2..64c142e6df3 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -7874,8 +7874,12 @@ bool mysql_compare_tables(TABLE *table, Alter_info *alter_info, { if (!tmp_new_field->field->vcol_info) DBUG_RETURN(false); - if (!field->vcol_info->is_equal(tmp_new_field->field->vcol_info)) + bool err; + if (!field->vcol_info->is_equivalent(thd, table->s, create_info->table->s, + tmp_new_field->field->vcol_info, err)) DBUG_RETURN(false); + if (err) + DBUG_RETURN(true); } /* diff --git a/sql/table.cc b/sql/table.cc index 11564e85af0..b18ee64f480 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -3542,6 +3542,27 @@ bool Virtual_column_info::cleanup_session_expr() } +bool +Virtual_column_info::is_equivalent(THD *thd, TABLE_SHARE *share, TABLE_SHARE *vcol_share, + const Virtual_column_info* vcol, bool &error) const +{ + error= true; + Item *cmp_expr= vcol->expr->build_clone(thd); + if (!cmp_expr) + return false; + Item::func_processor_rename_table param; + param.old_db= Lex_ident_db(vcol_share->db); + param.old_table= Lex_ident_table(vcol_share->table_name); + param.new_db= Lex_ident_db(share->db); + param.new_table= Lex_ident_table(share->table_name); + cmp_expr->walk(&Item::rename_table_processor, 1, ¶m); + + error= false; + return type_handler() == vcol->type_handler() + && is_stored() == vcol->is_stored() + && expr->eq(cmp_expr, true); +} + class Vcol_expr_context { From 0dcd30197ade55b7afb248e99b29b80ead99b3e2 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Mon, 13 Jan 2025 15:40:58 +0300 Subject: [PATCH 071/213] MDEV-25654 Unexpected ER_CRASHED_ON_USAGE and Assertion `limit >= trx_id' failed in purge_node_t::skip For fast alter partition ALTER lost hash fields in frm field count. mysql_prepare_create_table() did not call add_hash_field() because the logic of ALTER-ing field types implies automatic promotion/demotion to/from hash index. So we don't pass hash algorithm to mysql_prepare_create_table() and let it decide itself, but it cannot decide it correctly for fast alter partition. So now mysql_prepare_alter_table() is a bit more sophisticated on what to pass in the algorithm. If not changed any fields it will force mysql_prepare_create_table() to re-add hash fields by setting HA_KEY_ALG_HASH. The problem with the original logic is mysql_prepare_alter_table() does not care 100% about hash property so the decision is blurred between mysql_prepare_alter_table() and mysql_prepare_create_table(). --- mysql-test/main/long_unique_bugs.result | 12 ++++++++++++ mysql-test/main/long_unique_bugs.test | 15 +++++++++++++++ sql/sql_table.cc | 15 ++++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/long_unique_bugs.result b/mysql-test/main/long_unique_bugs.result index c85f5d5b21e..1caec209d9f 100644 --- a/mysql-test/main/long_unique_bugs.result +++ b/mysql-test/main/long_unique_bugs.result @@ -729,4 +729,16 @@ alter table t1 enable keys; insert into t1 values (2); ERROR 23000: Duplicate entry '2' for key 'i' drop table t1; +# +# MDEV-25654 Unexpected ER_CRASHED_ON_USAGE and Assertion `limit >= trx_id' failed in purge_node_t::skip +# +create table t1 (a int, unique using hash (a)) engine=innodb +partition by range(a) ( +partition p1 values less than (2), +partition p2 values less than (101) +); +insert into t1 select seq from seq_1_to_100; +alter table t1 add partition (partition p3 values less than (maxvalue)); +alter table t1 force; +drop table t1; # End of 10.5 tests diff --git a/mysql-test/main/long_unique_bugs.test b/mysql-test/main/long_unique_bugs.test index 2f85328bda3..6ad59fe6495 100644 --- a/mysql-test/main/long_unique_bugs.test +++ b/mysql-test/main/long_unique_bugs.test @@ -706,4 +706,19 @@ alter table t1 enable keys; insert into t1 values (2); drop table t1; +--echo # +--echo # MDEV-25654 Unexpected ER_CRASHED_ON_USAGE and Assertion `limit >= trx_id' failed in purge_node_t::skip +--echo # +create table t1 (a int, unique using hash (a)) engine=innodb +partition by range(a) ( + partition p1 values less than (2), + partition p2 values less than (101) +); +insert into t1 select seq from seq_1_to_100; + +alter table t1 add partition (partition p3 values less than (maxvalue)); +alter table t1 force; + +drop table t1; + --echo # End of 10.5 tests diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 64c142e6df3..e744ab78a2f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -9264,7 +9264,20 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, LEX_CSTRING tmp_name; bzero((char*) &key_create_info, sizeof(key_create_info)); if (key_info->algorithm == HA_KEY_ALG_LONG_HASH) - key_info->algorithm= HA_KEY_ALG_UNDEF; + key_info->algorithm= (alter_info->flags & ALTER_CHANGE_COLUMN) ? + HA_KEY_ALG_UNDEF : HA_KEY_ALG_HASH; + /* + This one goes to mysql_prepare_create_table(): + + key_info->algorithm= key->key_create_info.algorithm; + + For HA_KEY_ALG_LONG_HASH if we didn't change ANY column, we pass + HA_KEY_ALG_HASH to ensure mysql_prepare_create_table() does add_hash_field(). + This protects fast alter partition from losing hash properties. + In case of any column changes we drop algorithm to HA_KEY_ALG_UNDEF and + let decide mysql_prepare_create_table() if the hash field is needed + depending on new types. + */ key_create_info.algorithm= key_info->algorithm; /* We copy block size directly as some engines, like Area, sets this From e760a6dc1ceab5b0f2809d194af0f321fa12b933 Mon Sep 17 00:00:00 2001 From: Nikita Malyavin Date: Mon, 13 Jan 2025 15:40:59 +0300 Subject: [PATCH 072/213] MDEV-35343 ha_heap: recover the cursor after failed ha_update_row --- storage/heap/hp_update.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/storage/heap/hp_update.c b/storage/heap/hp_update.c index da83a9c76a8..ad56ca979de 100644 --- a/storage/heap/hp_update.c +++ b/storage/heap/hp_update.c @@ -21,7 +21,8 @@ int heap_update(HP_INFO *info, const uchar *old, const uchar *heap_new) { HP_KEYDEF *keydef, *end, *p_lastinx; - uchar *pos; + uchar *pos, *recovery_ptr; + struct st_hp_hash_info *recovery_hash_ptr; my_bool auto_key_changed= 0, key_changed= 0; HP_SHARE *share= info->s; DBUG_ENTER("heap_update"); @@ -34,6 +35,10 @@ int heap_update(HP_INFO *info, const uchar *old, const uchar *heap_new) if (--(share->records) < share->blength >> 1) share->blength>>= 1; share->changed=1; + // Save the cursor position to recover if insert fails. + recovery_ptr= info->current_ptr; + recovery_hash_ptr= info->current_hash_ptr; + p_lastinx= share->keydef + info->lastinx; for (keydef= share->keydef, end= keydef + share->keys; keydef < end; keydef++) { @@ -84,6 +89,8 @@ int heap_update(HP_INFO *info, const uchar *old, const uchar *heap_new) } keydef--; } + info->current_ptr= recovery_ptr; + info->current_hash_ptr= recovery_hash_ptr; } if (++(share->records) == share->blength) share->blength+= share->blength; From e1e1e50bbaf3fd96ac0b5ca4fcd28a458132e9bd Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Mon, 13 Jan 2025 15:40:59 +0300 Subject: [PATCH 073/213] MDEV-35343 DML debug logging Usage: mtr --mysqld=--debug=d,dml,query:i:o,/tmp/dml.log Example output: T@6 : dispatch_command: query: insert into t1 values ('a') T@6 : handler::ha_write_row: exit: INSERT: t1(a) = 0 T@6 : dispatch_command: query: alter ignore table t1 add unique index (data) T@6 : handler::ha_write_row: exit: INSERT: t1(a) = 0 T@6 : dispatch_command: query: alter ignore table t1 add unique index (data) T@6 : handler::ha_write_row: exit: INSERT: t1(a) = 0 T@6 : dispatch_command: query: replace into t1 values ('b'), ('c'), ('a'), ('b') T@6 : handler::ha_write_row: exit: INSERT: t1(b) = 0 T@6 : handler::ha_write_row: exit: INSERT: t1(c) = 0 T@6 : handler::ha_write_row: exit: INSERT: t1(a) = 121 T@6 : write_record: exit: DELETE: t1(a) = 0 T@6 : handler::ha_write_row: exit: INSERT: t1(a) = 0 T@6 : handler::ha_write_row: exit: INSERT: t1(b) = 121 T@6 : write_record: exit: DELETE: t1(b) = 0 T@6 : handler::ha_write_row: exit: INSERT: t1(b) = 0 --- sql/filesort.cc | 70 +++++++++++++++++++++++++++---------------------- sql/handler.cc | 4 +++ sql/handler.h | 4 +++ 3 files changed, 46 insertions(+), 32 deletions(-) diff --git a/sql/filesort.cc b/sql/filesort.cc index 822c52700a6..af03067257c 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -634,13 +634,6 @@ static uchar *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count, } #ifndef DBUG_OFF - -/* Buffer where record is returned */ -char dbug_print_row_buff[512]; - -/* Temporary buffer for printing a column */ -char dbug_print_row_buff_tmp[512]; - /* Print table's current row into a buffer and return a pointer to it. @@ -653,37 +646,53 @@ char dbug_print_row_buff_tmp[512]; Only columns in table->read_set are printed */ -const char* dbug_print_table_row(TABLE *table) +const char* dbug_print_row(TABLE *table, const uchar *rec, bool print_names) { Field **pfield; - String tmp(dbug_print_row_buff_tmp, - sizeof(dbug_print_row_buff_tmp),&my_charset_bin); + const size_t alloc_size= 512; + char *row_buff= (char *) alloc_root(&table->mem_root, alloc_size); + char *row_buff_tmp= (char *) alloc_root(&table->mem_root, alloc_size); + String tmp(row_buff_tmp, alloc_size, &my_charset_bin); + String output(row_buff, alloc_size, &my_charset_bin); - String output(dbug_print_row_buff, sizeof(dbug_print_row_buff), - &my_charset_bin); + auto move_back_lambda= [table, rec]() mutable { + table->move_fields(table->field, table->record[0], rec); + }; + auto move_back_guard= make_scope_exit(move_back_lambda, false); + + if (rec != table->record[0]) + { + table->move_fields(table->field, rec, table->record[0]); + move_back_guard.engage(); + } + + SCOPE_VALUE(table->read_set, (table->read_set && table->write_set) ? + table->write_set : table->read_set); output.length(0); output.append(table->alias); output.append("("); bool first= true; - - for (pfield= table->field; *pfield ; pfield++) + if (print_names) { - if (table->read_set && !bitmap_is_set(table->read_set, (*pfield)->field_index)) - continue; - - if (first) - first= false; - else - output.append(","); + for (pfield= table->field; *pfield ; pfield++) + { + if (table->read_set && !bitmap_is_set(table->read_set, (*pfield)->field_index)) + continue; - output.append((*pfield)->field_name.str ? - (*pfield)->field_name.str: "NULL"); + if (first) + first= false; + else + output.append(", "); + + output.append((*pfield)->field_name.str ? + (*pfield)->field_name.str: "NULL"); + } + + output.append(")=("); + first= true; } - output.append(")=("); - - first= true; for (pfield= table->field; *pfield ; pfield++) { Field *field= *pfield; @@ -694,7 +703,7 @@ const char* dbug_print_table_row(TABLE *table) if (first) first= false; else - output.append(","); + output.append(", "); if (field->is_null()) output.append("NULL"); @@ -713,12 +722,9 @@ const char* dbug_print_table_row(TABLE *table) } -const char* dbug_print_row(TABLE *table, uchar *rec) +const char* dbug_print_table_row(TABLE *table) { - table->move_fields(table->field, rec, table->record[0]); - const char* ret= dbug_print_table_row(table); - table->move_fields(table->field, table->record[0], rec); - return ret; + return dbug_print_row(table, table->record[0]); } diff --git a/sql/handler.cc b/sql/handler.cc index 38453b5e2a7..50bcf86f25c 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -7350,6 +7350,7 @@ int handler::ha_write_row(const uchar *buf) TABLE_IO_WAIT(tracker, PSI_TABLE_WRITE_ROW, MAX_KEY, error, { error= write_row(buf); }) + DBUG_PRINT("dml", ("INSERT: %s = %d", dbug_print_row(table, buf, false), error)); MYSQL_INSERT_ROW_DONE(error); if (likely(!error)) @@ -7410,6 +7411,8 @@ int handler::ha_update_row(const uchar *old_data, const uchar *new_data) TABLE_IO_WAIT(tracker, PSI_TABLE_UPDATE_ROW, active_index, 0, { error= update_row(old_data, new_data);}) + DBUG_PRINT("dml", ("UPDATE: %s => %s = %d", dbug_print_row(table, old_data, false), + dbug_print_row(table, new_data, false), error)); MYSQL_UPDATE_ROW_DONE(error); if (likely(!error)) @@ -7489,6 +7492,7 @@ int handler::ha_delete_row(const uchar *buf) TABLE_IO_WAIT(tracker, PSI_TABLE_DELETE_ROW, active_index, error, { error= delete_row(buf);}) + DBUG_PRINT("dml", ("DELETE: %s = %d", dbug_print_row(table, buf, false), error)); MYSQL_DELETE_ROW_DONE(error); if (likely(!error)) { diff --git a/sql/handler.h b/sql/handler.h index ad1cbaff5b7..c06c27b08c9 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -5322,4 +5322,8 @@ bool non_existing_table_error(int error); int get_select_field_pos(Alter_info *alter_info, int select_field_count, bool versioned); + +#ifndef DBUG_OFF +const char* dbug_print_row(TABLE *table, const uchar *rec, bool print_names= true); +#endif /* DBUG_OFF */ #endif /* HANDLER_INCLUDED */ From 78c192644c093ec2968e5748cd1d66b66dfbc1a9 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Mon, 13 Jan 2025 15:40:59 +0300 Subject: [PATCH 074/213] MDEV-35343 unexpected replace behaviour when long unique index on system versioned table For versioned table REPLACE first tries to insert a row, if it gets duplicate key error and optimization is possible it does UPDATE + INSERT history. If optimization is not possible it goes normal branch for UPDATE to history and repeats the cycle of INSERT. The failure was in normal branch when we tried UPDATE to history but such history already exists from previous cycles. There is no such failures in optimized branch because vers_insert_history_row() already ignores duplicates. The fix ignores duplicate errors for UPDATE to history and does DELETE instead. --- mysql-test/suite/versioning/r/replace.result | 16 +++++++++++++++ mysql-test/suite/versioning/t/replace.test | 15 ++++++++++++++ sql/sql_insert.cc | 21 ++++++++++++++++++-- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/versioning/r/replace.result b/mysql-test/suite/versioning/r/replace.result index 8ac4047c5ff..c64f42ee7cf 100644 --- a/mysql-test/suite/versioning/r/replace.result +++ b/mysql-test/suite/versioning/r/replace.result @@ -27,7 +27,9 @@ id x current 1 2 0 1 3 1 drop table t; +# # MDEV-15645 Assertion `table->insert_values' failed in write_record upon REPLACE into a view with underlying versioned table +# create or replace table t1 (a int, b int, primary key (a), unique(b)) with system versioning; insert into t1 values (1,1); create or replace table t2 (c int); @@ -48,7 +50,9 @@ INSERT INTO t1 () VALUES (),(),(),(),(),(); UPDATE IGNORE t1 SET f = 1; REPLACE t1 SELECT * FROM t1; DROP TABLE t1; +# # MDEV-22540 ER_DUP_ENTRY upon REPLACE or Assertion failed +# set timestamp=1589245268.41934; create table t1 (a int primary key) with system versioning; insert into t1 values (1),(2); @@ -72,3 +76,15 @@ Warnings: Warning 1062 Duplicate entry '1' for key 'a' load data infile '15330.data' replace into table t1 (a,b,c); drop table t1; +# +# MDEV-35343 unexpected replace behaviour when long unique index on system versioned table +# +create table t1 (data char(10)); +insert into t1 values ('o'); +alter ignore table t1 add unique index (data); +alter ignore table t1 add unique index (data); +Warnings: +Note 1831 Duplicate index `data_2`. This is deprecated and will be disallowed in a future release +alter table t1 add system versioning; +replace into t1 values ('o'), ('o'); +drop table t1; diff --git a/mysql-test/suite/versioning/t/replace.test b/mysql-test/suite/versioning/t/replace.test index d69eebd1b9c..c10b6aa443d 100644 --- a/mysql-test/suite/versioning/t/replace.test +++ b/mysql-test/suite/versioning/t/replace.test @@ -35,7 +35,9 @@ replace t values (1, 3); select *, current_row(row_end) as current from t for system_time all order by x; drop table t; +--echo # --echo # MDEV-15645 Assertion `table->insert_values' failed in write_record upon REPLACE into a view with underlying versioned table +--echo # create or replace table t1 (a int, b int, primary key (a), unique(b)) with system versioning; insert into t1 values (1,1); create or replace table t2 (c int); @@ -59,7 +61,9 @@ UPDATE IGNORE t1 SET f = 1; REPLACE t1 SELECT * FROM t1; DROP TABLE t1; +--echo # --echo # MDEV-22540 ER_DUP_ENTRY upon REPLACE or Assertion failed +--echo # set timestamp=1589245268.41934; create table t1 (a int primary key) with system versioning; insert into t1 values (1),(2); @@ -105,4 +109,15 @@ drop table t1; eval set default_storage_engine= $default_engine; --enable_query_log +--echo # +--echo # MDEV-35343 unexpected replace behaviour when long unique index on system versioned table +--echo # +create table t1 (data char(10)); +insert into t1 values ('o'); +alter ignore table t1 add unique index (data); +alter ignore table t1 add unique index (data); +alter table t1 add system versioning; +replace into t1 values ('o'), ('o'); +drop table t1; + --source suite/versioning/common_finish.inc diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 50a1a37e3ea..acc841e27f0 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2126,6 +2126,9 @@ int write_record(THD *thd, TABLE *table, COPY_INFO *info, select_result *sink) !table->file->referenced_by_foreign_key() && (!table->triggers || !table->triggers->has_delete_triggers())) { + /* + Optimized dup handling via UPDATE (and insert history for versioned). + */ if (table->versioned(VERS_TRX_ID)) { bitmap_set_bit(table->write_set, table->vers_start_field()->field_index); @@ -2160,25 +2163,39 @@ int write_record(THD *thd, TABLE *table, COPY_INFO *info, select_result *sink) } else { + /* + Normal dup handling via DELETE (or UPDATE to history for versioned) + and repeating the cycle of INSERT. + */ if (table->triggers && table->triggers->process_triggers(thd, TRG_EVENT_DELETE, TRG_ACTION_BEFORE, TRUE)) goto before_trg_err; - if (!table->versioned(VERS_TIMESTAMP)) + bool do_delete= !table->versioned(VERS_TIMESTAMP); + if (do_delete) error= table->file->ha_delete_row(table->record[1]); else { + /* Update existing row to history */ store_record(table, record[2]); restore_record(table, record[1]); table->vers_update_end(); error= table->file->ha_update_row(table->record[1], table->record[0]); restore_record(table, record[2]); + if (error == HA_ERR_FOUND_DUPP_KEY || /* Unique index, any SE */ + error == HA_ERR_FOREIGN_DUPLICATE_KEY || /* Unique index, InnoDB */ + error == HA_ERR_RECORD_IS_THE_SAME) /* No index */ + { + /* Such history row was already generated from previous cycles */ + error= table->file->ha_delete_row(table->record[1]); + do_delete= true; + } } if (unlikely(error)) goto err; - if (!table->versioned(VERS_TIMESTAMP)) + if (do_delete) info->deleted++; else info->updated++; From 4a58d1085dfc7e2dea7affdd7e389493fc0fd430 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Mon, 13 Jan 2025 15:40:59 +0300 Subject: [PATCH 075/213] MDEV-35612 EXCHANGE PARTITION does not work for tables with unique blobs mysql_compare_tables() failed because of no long hash index generated fields in prepared tmp_create_info. In comparison we should skip these fields in the original table by: 1. skipping INVISIBLE_SYSTEM fields; 2. getting key_info from table->s instead of table as TABLE_SHARE contains unwrapped key_info. --- mysql-test/main/partition_exchange.result | 10 ++++++++++ mysql-test/main/partition_exchange.test | 14 ++++++++++++++ sql/sql_table.cc | 22 +++++++++++++++++----- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/mysql-test/main/partition_exchange.result b/mysql-test/main/partition_exchange.result index 999517f4028..c9169c5c818 100644 --- a/mysql-test/main/partition_exchange.result +++ b/mysql-test/main/partition_exchange.result @@ -1343,3 +1343,13 @@ create or replace table t2_working like t2; alter table t2_working remove partitioning; alter table t2 exchange partition p1 with table t2_working; drop tables t1, t1_working, t2, t2_working; +# +# MDEV-35612 EXCHANGE PARTITION does not work for tables with unique blobs +# +create table t (a int, b text, unique (b), unique(a, b)) partition by list (a) (partition p0 values in (1,2), partition pdef default); +create table tp (a int, b text, c int invisible, unique (b), unique(a, b)); +alter table t exchange partition p0 with table tp; +ERROR HY000: Tables have different definitions +create or replace table tp (a int, b text, unique (b), unique(a, b)); +alter table t exchange partition p0 with table tp; +drop table t, tp; diff --git a/mysql-test/main/partition_exchange.test b/mysql-test/main/partition_exchange.test index e92b8dfff5c..767f682ea0d 100644 --- a/mysql-test/main/partition_exchange.test +++ b/mysql-test/main/partition_exchange.test @@ -586,3 +586,17 @@ alter table t2 exchange partition p1 with table t2_working; # Cleanup drop tables t1, t1_working, t2, t2_working; + +--echo # +--echo # MDEV-35612 EXCHANGE PARTITION does not work for tables with unique blobs +--echo # +create table t (a int, b text, unique (b), unique(a, b)) partition by list (a) (partition p0 values in (1,2), partition pdef default); +create table tp (a int, b text, c int invisible, unique (b), unique(a, b)); +--error ER_TABLES_DIFFERENT_METADATA +alter table t exchange partition p0 with table tp; + +create or replace table tp (a int, b text, unique (b), unique(a, b)); +alter table t exchange partition p0 with table tp; + +# cleanup +drop table t, tp; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index e744ab78a2f..3563c0fa982 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -7852,7 +7852,16 @@ bool mysql_compare_tables(TABLE *table, Alter_info *alter_info, DBUG_RETURN(1); /* Some very basic checks. */ - if (table->s->fields != alter_info->create_list.elements || + uint fields= table->s->fields; + + /* There is no field count on system-invisible fields, count them. */ + for (Field **f_ptr= table->field; *f_ptr; f_ptr++) + { + if ((*f_ptr)->invisible >= INVISIBLE_SYSTEM) + fields--; + } + + if (fields != alter_info->create_list.elements || table->s->db_type() != create_info->db_type || table->s->tmp_table || (table->s->row_type != create_info->row_type)) @@ -7863,6 +7872,9 @@ bool mysql_compare_tables(TABLE *table, Alter_info *alter_info, for (Field **f_ptr= table->field; *f_ptr; f_ptr++) { Field *field= *f_ptr; + /* Skip hidden generated field like long hash index. */ + if (field->invisible >= INVISIBLE_SYSTEM) + continue; Create_field *tmp_new_field= tmp_new_field_it++; /* Check that NULL behavior is the same. */ @@ -7915,13 +7927,13 @@ bool mysql_compare_tables(TABLE *table, Alter_info *alter_info, DBUG_RETURN(false); /* Go through keys and check if they are compatible. */ - KEY *table_key; - KEY *table_key_end= table->key_info + table->s->keys; + KEY *table_key= table->s->key_info; + KEY *table_key_end= table_key + table->s->keys; KEY *new_key; KEY *new_key_end= key_info_buffer + key_count; /* Step through all keys of the first table and search matching keys. */ - for (table_key= table->key_info; table_key < table_key_end; table_key++) + for (; table_key < table_key_end; table_key++) { /* Search a key with the same name. */ for (new_key= key_info_buffer; new_key < new_key_end; new_key++) @@ -7964,7 +7976,7 @@ bool mysql_compare_tables(TABLE *table, Alter_info *alter_info, for (new_key= key_info_buffer; new_key < new_key_end; new_key++) { /* Search a key with the same name. */ - for (table_key= table->key_info; table_key < table_key_end; table_key++) + for (table_key= table->s->key_info; table_key < table_key_end; table_key++) { if (!lex_string_cmp(system_charset_info, &table_key->name, &new_key->name)) From ab90eaad792996d10c5c67cde09cffa3d5baebbd Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Mon, 13 Jan 2025 15:40:59 +0300 Subject: [PATCH 076/213] MDEV-22695 Server crashes in heap_rnext upon DELETE from a HEAP table Quick read record uses different handler (H1) for finding records. It cannot use ha_delete_row() handler (H2) as it is different search mode: inited == INDEX for H1, inited == RND for H2. So, read handler H1 uses index while write handler H2 uses random access. For going next record in H1 there is info->last_pos optimization for stepping index via tree_search_next(). This optimization can work with deleted rows only if delete is conducted in the same handler, there is: 67 int hp_rb_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, 68 const uchar *record, uchar *recpos, int flag) 69 { ... 74 if (flag) 75 info->last_pos= NULL; /* For heap_rnext/heap_rprev */ But this cannot work for different handler. So, last_pos in H1 after delete in H2 contains stale info->parents array and last_pos points into that parents. In the specific test case last_pos' parent is already freed node and tree_search_next() steps into it. The fix invalidates local savings of info->parents and info->last_pos based on key_version. Record deletion increments share->key_version in H2, so in H1 we know the tree might be changed. Another good measure would be to use H1 for delete. But this is bigger refactoring than just bug fixing. --- mysql-test/suite/heap/heap.result | 7 +++++++ mysql-test/suite/heap/heap.test | 9 +++++++++ storage/heap/hp_rnext.c | 4 +++- storage/heap/hp_rprev.c | 3 ++- 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/heap/heap.result b/mysql-test/suite/heap/heap.result index 67641d51b02..11c50d97475 100644 --- a/mysql-test/suite/heap/heap.result +++ b/mysql-test/suite/heap/heap.result @@ -877,3 +877,10 @@ DELETE FROM t1 WHERE ts = 1 AND color = 'GREEN'; SELECT * from t1 WHERE ts = 1 AND color = 'GREEN'; id color ts DROP TABLE t1; +# +# MDEV-22695 Server crashes in heap_rnext upon DELETE from a HEAP table +# +CREATE TABLE t1 (a VARCHAR(128), b VARCHAR(32), KEY(a) USING BTREE, KEY(b) USING BTREE) ENGINE=HEAP; +INSERT INTO t1 VALUES ('foo',NULL),('m','b'),(6,'j'),('bar','qux'),(NULL,NULL); +DELETE FROM t1 WHERE a <=> 'm' OR b <=> NULL; +DROP TABLE t1; diff --git a/mysql-test/suite/heap/heap.test b/mysql-test/suite/heap/heap.test index ef950da5484..02a2586f605 100644 --- a/mysql-test/suite/heap/heap.test +++ b/mysql-test/suite/heap/heap.test @@ -659,3 +659,12 @@ INSERT INTO t1 VALUES("7","GREEN", 2); DELETE FROM t1 WHERE ts = 1 AND color = 'GREEN'; SELECT * from t1 WHERE ts = 1 AND color = 'GREEN'; DROP TABLE t1; + +--echo # +--echo # MDEV-22695 Server crashes in heap_rnext upon DELETE from a HEAP table +--echo # +CREATE TABLE t1 (a VARCHAR(128), b VARCHAR(32), KEY(a) USING BTREE, KEY(b) USING BTREE) ENGINE=HEAP; +INSERT INTO t1 VALUES ('foo',NULL),('m','b'),(6,'j'),('bar','qux'),(NULL,NULL); +DELETE FROM t1 WHERE a <=> 'm' OR b <=> NULL; +# Cleanup +DROP TABLE t1; diff --git a/storage/heap/hp_rnext.c b/storage/heap/hp_rnext.c index f227ce4d274..ac21ed83da2 100644 --- a/storage/heap/hp_rnext.c +++ b/storage/heap/hp_rnext.c @@ -46,7 +46,7 @@ int heap_rnext(HP_INFO *info, uchar *record) &info->last_pos, offsetof(TREE_ELEMENT, left)); } } - else if (info->last_pos) + else if (info->last_pos && info->key_version == info->s->key_version) { /* We enter this branch for non-DELETE queries after heap_rkey() @@ -72,6 +72,7 @@ int heap_rnext(HP_INFO *info, uchar *record) */ pos= tree_search_edge(&keyinfo->rb_tree, info->parents, &info->last_pos, offsetof(TREE_ELEMENT, left)); + info->key_version= info->s->key_version; } else { @@ -87,6 +88,7 @@ int heap_rnext(HP_INFO *info, uchar *record) info->last_find_flag= HA_READ_KEY_OR_NEXT; pos = tree_search_key(&keyinfo->rb_tree, info->lastkey, info->parents, &info->last_pos, info->last_find_flag, &custom_arg); + info->key_version= info->s->key_version; } if (pos) { diff --git a/storage/heap/hp_rprev.c b/storage/heap/hp_rprev.c index 1d9420ba8b6..cc81d179570 100644 --- a/storage/heap/hp_rprev.c +++ b/storage/heap/hp_rprev.c @@ -46,7 +46,7 @@ int heap_rprev(HP_INFO *info, uchar *record) &info->last_pos, offsetof(TREE_ELEMENT, right)); } } - else if (info->last_pos) + else if (info->last_pos && info->key_version == info->s->key_version) pos = tree_search_next(&keyinfo->rb_tree, &info->last_pos, offsetof(TREE_ELEMENT, right), offsetof(TREE_ELEMENT, left)); @@ -58,6 +58,7 @@ int heap_rprev(HP_INFO *info, uchar *record) info->last_find_flag= HA_READ_KEY_OR_PREV; pos = tree_search_key(&keyinfo->rb_tree, info->lastkey, info->parents, &info->last_pos, info->last_find_flag, &custom_arg); + info->key_version= info->s->key_version; } if (pos) { From 0fa1a7cc6af2d1ca90363f73d6bff97c805caf22 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Mon, 13 Jan 2025 15:40:59 +0300 Subject: [PATCH 077/213] MDEV-28130 MariaDB SEGV issue at tree_search_next In case of error last_pos points to null_element and there is no any other children. tree_search_next() walks the children from last_pos until the leaves (null_element) ignoring the case the topmost parent in search state is the leaf itself. --- mysql-test/suite/heap/heap.result | 12 ++++++++++++ mysql-test/suite/heap/heap.test | 10 ++++++++++ mysys/tree.c | 3 +++ 3 files changed, 25 insertions(+) diff --git a/mysql-test/suite/heap/heap.result b/mysql-test/suite/heap/heap.result index 11c50d97475..d42e898a0ae 100644 --- a/mysql-test/suite/heap/heap.result +++ b/mysql-test/suite/heap/heap.result @@ -884,3 +884,15 @@ CREATE TABLE t1 (a VARCHAR(128), b VARCHAR(32), KEY(a) USING BTREE, KEY(b) USING INSERT INTO t1 VALUES ('foo',NULL),('m','b'),(6,'j'),('bar','qux'),(NULL,NULL); DELETE FROM t1 WHERE a <=> 'm' OR b <=> NULL; DROP TABLE t1; +# +# MDEV-28130 MariaDB SEGV issue at tree_search_next +# +CREATE TABLE v(t1 INT, pk INT, KEY(t1), KEY pk using btree (pk), KEY v using btree(t1, pk)) engine=memory; +HANDLER v OPEN; +HANDLER v READ t1=(2) limit 3; +t1 pk +HANDLER v READ pk PREV; +t1 pk +HANDLER v READ pk PREV; +t1 pk +drop table v; diff --git a/mysql-test/suite/heap/heap.test b/mysql-test/suite/heap/heap.test index 02a2586f605..97784aefc0f 100644 --- a/mysql-test/suite/heap/heap.test +++ b/mysql-test/suite/heap/heap.test @@ -668,3 +668,13 @@ INSERT INTO t1 VALUES ('foo',NULL),('m','b'),(6,'j'),('bar','qux'),(NULL,NULL); DELETE FROM t1 WHERE a <=> 'm' OR b <=> NULL; # Cleanup DROP TABLE t1; + +--echo # +--echo # MDEV-28130 MariaDB SEGV issue at tree_search_next +--echo # +CREATE TABLE v(t1 INT, pk INT, KEY(t1), KEY pk using btree (pk), KEY v using btree(t1, pk)) engine=memory; +HANDLER v OPEN; +HANDLER v READ t1=(2) limit 3; +HANDLER v READ pk PREV; +HANDLER v READ pk PREV; +drop table v; diff --git a/mysys/tree.c b/mysys/tree.c index cd44f779e6f..db0442fa827 100644 --- a/mysys/tree.c +++ b/mysys/tree.c @@ -494,6 +494,9 @@ void *tree_search_next(TREE *tree, TREE_ELEMENT ***last_pos, int l_offs, int r_offs) { TREE_ELEMENT *x= **last_pos; + + if (x == &null_element) + return NULL; if (ELEMENT_CHILD(x, r_offs) != &null_element) { From c40709660f805b53949708c6a10fa5e3d1f65b6f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 15 Jan 2025 09:49:33 +0100 Subject: [PATCH 078/213] MDEV-35773 fix test results followup for 437550b7cf87 --- storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_xa.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_xa.result b/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_xa.result index 4edcd573d45..ba97d43d515 100644 --- a/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_xa.result +++ b/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_xa.result @@ -36,7 +36,7 @@ insert into t2 values (0); xa end 's'; xa prepare 's'; Warnings: -Warning 4196 Pseudo thread id should not be modified by the client as it will be overwritten +Warning 4205 Pseudo thread id should not be modified by the client as it will be overwritten include/save_master_gtid.inc connection slave; include/sync_with_master_gtid.inc From f1da9dbf5e433949ce93062fd6b29235b81efcc7 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 15 Jan 2025 09:51:19 +0100 Subject: [PATCH 079/213] MDEV-20912 fix test results followup for 7fcaab7aaac4 --- .../funcs/r/db_alter_collate_ascii.result | 44 +++++++++++++++++++ .../funcs/r/db_alter_collate_utf8.result | 44 +++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/mysql-test/suite/engines/funcs/r/db_alter_collate_ascii.result b/mysql-test/suite/engines/funcs/r/db_alter_collate_ascii.result index ea092d1211f..da6beedf137 100644 --- a/mysql-test/suite/engines/funcs/r/db_alter_collate_ascii.result +++ b/mysql-test/suite/engines/funcs/r/db_alter_collate_ascii.result @@ -217,6 +217,50 @@ utf8mb4_german2_ci utf8mb4 244 # # utf8mb4_croatian_mysql561_ci utf8mb4 245 # # utf8mb4_unicode_520_ci utf8mb4 246 # # utf8mb4_vietnamese_ci utf8mb4 247 # # +utf8mb4_0900_ai_ci utf8mb4 255 # # +utf8mb4_de_pb_0900_ai_ci utf8mb4 256 # # +utf8mb4_is_0900_ai_ci utf8mb4 257 # # +utf8mb4_lv_0900_ai_ci utf8mb4 258 # # +utf8mb4_ro_0900_ai_ci utf8mb4 259 # # +utf8mb4_sl_0900_ai_ci utf8mb4 260 # # +utf8mb4_pl_0900_ai_ci utf8mb4 261 # # +utf8mb4_et_0900_ai_ci utf8mb4 262 # # +utf8mb4_es_0900_ai_ci utf8mb4 263 # # +utf8mb4_sv_0900_ai_ci utf8mb4 264 # # +utf8mb4_tr_0900_ai_ci utf8mb4 265 # # +utf8mb4_cs_0900_ai_ci utf8mb4 266 # # +utf8mb4_da_0900_ai_ci utf8mb4 267 # # +utf8mb4_lt_0900_ai_ci utf8mb4 268 # # +utf8mb4_sk_0900_ai_ci utf8mb4 269 # # +utf8mb4_es_trad_0900_ai_ci utf8mb4 270 # # +utf8mb4_la_0900_ai_ci utf8mb4 271 # # +utf8mb4_eo_0900_ai_ci utf8mb4 273 # # +utf8mb4_hu_0900_ai_ci utf8mb4 274 # # +utf8mb4_hr_0900_ai_ci utf8mb4 275 # # +utf8mb4_vi_0900_ai_ci utf8mb4 277 # # +utf8mb4_0900_as_cs utf8mb4 278 # # +utf8mb4_de_pb_0900_as_cs utf8mb4 279 # # +utf8mb4_is_0900_as_cs utf8mb4 280 # # +utf8mb4_lv_0900_as_cs utf8mb4 281 # # +utf8mb4_ro_0900_as_cs utf8mb4 282 # # +utf8mb4_sl_0900_as_cs utf8mb4 283 # # +utf8mb4_pl_0900_as_cs utf8mb4 284 # # +utf8mb4_et_0900_as_cs utf8mb4 285 # # +utf8mb4_es_0900_as_cs utf8mb4 286 # # +utf8mb4_sv_0900_as_cs utf8mb4 287 # # +utf8mb4_tr_0900_as_cs utf8mb4 288 # # +utf8mb4_cs_0900_as_cs utf8mb4 289 # # +utf8mb4_da_0900_as_cs utf8mb4 290 # # +utf8mb4_lt_0900_as_cs utf8mb4 291 # # +utf8mb4_sk_0900_as_cs utf8mb4 292 # # +utf8mb4_es_trad_0900_as_cs utf8mb4 293 # # +utf8mb4_la_0900_as_cs utf8mb4 294 # # +utf8mb4_eo_0900_as_cs utf8mb4 296 # # +utf8mb4_hu_0900_as_cs utf8mb4 297 # # +utf8mb4_hr_0900_as_cs utf8mb4 298 # # +utf8mb4_vi_0900_as_cs utf8mb4 300 # # +utf8mb4_0900_as_ci utf8mb4 305 # # +utf8mb4_0900_bin utf8mb4 309 # # utf8mb4_croatian_ci utf8mb4 608 # # utf8mb4_myanmar_ci utf8mb4 609 # # utf8mb4_thai_520_w2 utf8mb4 610 # # diff --git a/mysql-test/suite/engines/funcs/r/db_alter_collate_utf8.result b/mysql-test/suite/engines/funcs/r/db_alter_collate_utf8.result index 0bc617071ca..32b2fffffa6 100644 --- a/mysql-test/suite/engines/funcs/r/db_alter_collate_utf8.result +++ b/mysql-test/suite/engines/funcs/r/db_alter_collate_utf8.result @@ -217,6 +217,50 @@ utf8mb4_german2_ci utf8mb4 244 # # utf8mb4_croatian_mysql561_ci utf8mb4 245 # # utf8mb4_unicode_520_ci utf8mb4 246 # # utf8mb4_vietnamese_ci utf8mb4 247 # # +utf8mb4_0900_ai_ci utf8mb4 255 # # +utf8mb4_de_pb_0900_ai_ci utf8mb4 256 # # +utf8mb4_is_0900_ai_ci utf8mb4 257 # # +utf8mb4_lv_0900_ai_ci utf8mb4 258 # # +utf8mb4_ro_0900_ai_ci utf8mb4 259 # # +utf8mb4_sl_0900_ai_ci utf8mb4 260 # # +utf8mb4_pl_0900_ai_ci utf8mb4 261 # # +utf8mb4_et_0900_ai_ci utf8mb4 262 # # +utf8mb4_es_0900_ai_ci utf8mb4 263 # # +utf8mb4_sv_0900_ai_ci utf8mb4 264 # # +utf8mb4_tr_0900_ai_ci utf8mb4 265 # # +utf8mb4_cs_0900_ai_ci utf8mb4 266 # # +utf8mb4_da_0900_ai_ci utf8mb4 267 # # +utf8mb4_lt_0900_ai_ci utf8mb4 268 # # +utf8mb4_sk_0900_ai_ci utf8mb4 269 # # +utf8mb4_es_trad_0900_ai_ci utf8mb4 270 # # +utf8mb4_la_0900_ai_ci utf8mb4 271 # # +utf8mb4_eo_0900_ai_ci utf8mb4 273 # # +utf8mb4_hu_0900_ai_ci utf8mb4 274 # # +utf8mb4_hr_0900_ai_ci utf8mb4 275 # # +utf8mb4_vi_0900_ai_ci utf8mb4 277 # # +utf8mb4_0900_as_cs utf8mb4 278 # # +utf8mb4_de_pb_0900_as_cs utf8mb4 279 # # +utf8mb4_is_0900_as_cs utf8mb4 280 # # +utf8mb4_lv_0900_as_cs utf8mb4 281 # # +utf8mb4_ro_0900_as_cs utf8mb4 282 # # +utf8mb4_sl_0900_as_cs utf8mb4 283 # # +utf8mb4_pl_0900_as_cs utf8mb4 284 # # +utf8mb4_et_0900_as_cs utf8mb4 285 # # +utf8mb4_es_0900_as_cs utf8mb4 286 # # +utf8mb4_sv_0900_as_cs utf8mb4 287 # # +utf8mb4_tr_0900_as_cs utf8mb4 288 # # +utf8mb4_cs_0900_as_cs utf8mb4 289 # # +utf8mb4_da_0900_as_cs utf8mb4 290 # # +utf8mb4_lt_0900_as_cs utf8mb4 291 # # +utf8mb4_sk_0900_as_cs utf8mb4 292 # # +utf8mb4_es_trad_0900_as_cs utf8mb4 293 # # +utf8mb4_la_0900_as_cs utf8mb4 294 # # +utf8mb4_eo_0900_as_cs utf8mb4 296 # # +utf8mb4_hu_0900_as_cs utf8mb4 297 # # +utf8mb4_hr_0900_as_cs utf8mb4 298 # # +utf8mb4_vi_0900_as_cs utf8mb4 300 # # +utf8mb4_0900_as_ci utf8mb4 305 # # +utf8mb4_0900_bin utf8mb4 309 # # utf8mb4_croatian_ci utf8mb4 608 # # utf8mb4_myanmar_ci utf8mb4 609 # # utf8mb4_thai_520_w2 utf8mb4 610 # # From f4e999d753559fcf27302f0b76c2a404e9542997 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 15 Jan 2025 13:18:12 +0400 Subject: [PATCH 080/213] MDEV-35427 Assertion `is_null() >= item->null_value' failed in Timestamp_or_zero_datetime_native_null::Timestamp_or_zero_datetime_native_null on EXECUTE This problem was earlier fixed by MDEV-25593. Adding a test case only. --- .../mysql-test/type_uuid/type_uuid_ps.result | 15 +++++++++++++++ .../mysql-test/type_uuid/type_uuid_ps.test | 14 ++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 plugin/type_uuid/mysql-test/type_uuid/type_uuid_ps.result create mode 100644 plugin/type_uuid/mysql-test/type_uuid/type_uuid_ps.test diff --git a/plugin/type_uuid/mysql-test/type_uuid/type_uuid_ps.result b/plugin/type_uuid/mysql-test/type_uuid/type_uuid_ps.result new file mode 100644 index 00000000000..ea74a8d45e4 --- /dev/null +++ b/plugin/type_uuid/mysql-test/type_uuid/type_uuid_ps.result @@ -0,0 +1,15 @@ +# Start of 10.11 tests +# +# MDEV-35427 Assertion `is_null() >= item->null_value' failed in Timestamp_or_zero_datetime_native_null::Timestamp_or_zero_datetime_native_null on EXECUTE +# +SET time_zone='+00:00'; +PREPARE s FROM 'SELECT CONCAT (UNIX_TIMESTAMP(?))'; +EXECUTE s USING CAST('00000000-0000-0000-0000-000000000001' AS UUID); +CONCAT (UNIX_TIMESTAMP(?)) +1736899200 +EXECUTE s USING @unknown_variable; +CONCAT (UNIX_TIMESTAMP(?)) +NULL +DEALLOCATE PREPARE s; +SET time_zone=DEFAULT; +# End of 10.11 tests diff --git a/plugin/type_uuid/mysql-test/type_uuid/type_uuid_ps.test b/plugin/type_uuid/mysql-test/type_uuid/type_uuid_ps.test new file mode 100644 index 00000000000..712b2ab5eaf --- /dev/null +++ b/plugin/type_uuid/mysql-test/type_uuid/type_uuid_ps.test @@ -0,0 +1,14 @@ +--echo # Start of 10.11 tests + +--echo # +--echo # MDEV-35427 Assertion `is_null() >= item->null_value' failed in Timestamp_or_zero_datetime_native_null::Timestamp_or_zero_datetime_native_null on EXECUTE +--echo # + +SET time_zone='+00:00'; +PREPARE s FROM 'SELECT CONCAT (UNIX_TIMESTAMP(?))'; +EXECUTE s USING CAST('00000000-0000-0000-0000-000000000001' AS UUID); +EXECUTE s USING @unknown_variable; +DEALLOCATE PREPARE s; +SET time_zone=DEFAULT; + +--echo # End of 10.11 tests From a5174aaffb8f22b211945170588828557dbdb211 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Tue, 14 Jan 2025 22:42:18 +0200 Subject: [PATCH 081/213] MDEV-35828: Assertion fails in alloc_root() when memory causes it to call itself (Variant 2: use stack for buffers) my_malloc_size_cb_func() has a call to thd->alloc() to produce an error message. thd->alloc() calls alloc_root(), so one can end up with this stack trace: alloc_root() THD::alloc() my_malloc_size_cb_func() my_malloc() alloc_root() where alloc_root() calls itself. This is a problem, as alloc_root() is not reenterable. Fixed this by switching my_malloc_size_cb_func() to use space on the stack instead. --- mysql-test/main/errors.result | 13 +++++++++++++ mysql-test/main/errors.test | 20 ++++++++++++++++++++ sql/mysqld.cc | 18 +++++------------- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/mysql-test/main/errors.result b/mysql-test/main/errors.result index baa2e0ad3c0..5b469b640f8 100644 --- a/mysql-test/main/errors.result +++ b/mysql-test/main/errors.result @@ -231,3 +231,16 @@ Error 1327 Undeclared variable: foo Error 1305 PROCEDURE P1 does not exist drop procedure P1; # End of 10.4 tests +# +# MDEV-35828: Assertion fails in alloc_root() when memory causes it to call itself +# +CREATE TEMPORARY TABLE t1 (a INT,b INT); +INSERT INTO t1 VALUES (1,1),(2,2); +SET +@tmp=@@max_session_mem_used, +max_session_mem_used=8192; +SELECT * FROM (t1 AS t2 LEFT JOIN t1 AS t3 USING (a)),t1; +ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement +DROP TABLE t1; +SET max_session_mem_used=@tmp; +# End of 10.6 tests diff --git a/mysql-test/main/errors.test b/mysql-test/main/errors.test index cc5cad2a68e..87d6d2fdec9 100644 --- a/mysql-test/main/errors.test +++ b/mysql-test/main/errors.test @@ -284,3 +284,23 @@ show warnings; drop procedure P1; -- echo # End of 10.4 tests + + +--echo # +--echo # MDEV-35828: Assertion fails in alloc_root() when memory causes it to call itself +--echo # +CREATE TEMPORARY TABLE t1 (a INT,b INT); +INSERT INTO t1 VALUES (1,1),(2,2); + +SET + @tmp=@@max_session_mem_used, + max_session_mem_used=8192; + +--error ER_OPTION_PREVENTS_STATEMENT +SELECT * FROM (t1 AS t2 LEFT JOIN t1 AS t3 USING (a)),t1; + +DROP TABLE t1; +SET max_session_mem_used=@tmp; + + +--echo # End of 10.6 tests diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c798956910f..d6dd8a566af 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3513,22 +3513,14 @@ static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific) LOCK_thd_kill here (the limit will be enforced on the next allocation). */ if (!mysql_mutex_trylock(&thd->LOCK_thd_kill)) { - char buf[50], *buf2; + char buf[50], buf2[256]; thd->set_killed_no_mutex(KILL_QUERY); my_snprintf(buf, sizeof(buf), "--max-session-mem-used=%llu", thd->variables.max_mem_used); - if ((buf2= (char*) thd->alloc(256))) - { - my_snprintf(buf2, 256, - ER_THD(thd, ER_OPTION_PREVENTS_STATEMENT), buf); - thd->set_killed_no_mutex(KILL_QUERY, - ER_OPTION_PREVENTS_STATEMENT, buf2); - } - else - { - thd->set_killed_no_mutex(KILL_QUERY, ER_OPTION_PREVENTS_STATEMENT, - "--max-session-mem-used"); - } + my_snprintf(buf2, 256, + ER_THD(thd, ER_OPTION_PREVENTS_STATEMENT), buf); + thd->set_killed_no_mutex(KILL_QUERY, + ER_OPTION_PREVENTS_STATEMENT, buf2); mysql_mutex_unlock(&thd->LOCK_thd_kill); } } From b82abc71639661c642b9d753393be0f85e09c101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 15 Jan 2025 16:55:01 +0200 Subject: [PATCH 082/213] MDEV-35701 trx_t::autoinc_locks causes unnecessary dynamic memory allocation trx_t::autoinc_locks: Use small_vector in order to avoid any dynamic memory allocation in the most common case (a statement is holding AUTO_INCREMENT locks on at most 4 tables or partitions). lock_cancel_waiting_and_release(): Instead of removing elements from the middle, simply assign nullptr, like lock_table_remove_autoinc_lock(). The added test innodb.auto_increment_lock_mode covers the dynamic memory allocation as well as nondeterministically (occasionally) covers the out-of-order lock release in lock_table_remove_autoinc_lock(). Reviewed by: Debarun Banerjee --- .../innodb/r/auto_increment_lock_mode.result | 43 +++++ .../innodb/r/innodb-autoinc-56228.result | 35 ++-- .../t/auto_increment_lock_mode.combinations | 6 + .../innodb/t/auto_increment_lock_mode.test | 61 +++++++ .../suite/innodb/t/innodb-autoinc-56228.test | 36 ++-- storage/innobase/dict/drop.cc | 2 +- storage/innobase/handler/ha_innodb.cc | 2 +- storage/innobase/include/small_vector.h | 65 +++++-- storage/innobase/include/trx0trx.h | 14 +- storage/innobase/lock/lock0lock.cc | 158 +++++++----------- storage/innobase/mtr/mtr0mtr.cc | 4 +- storage/innobase/trx/trx0trx.cc | 28 +--- 12 files changed, 272 insertions(+), 182 deletions(-) create mode 100644 mysql-test/suite/innodb/r/auto_increment_lock_mode.result create mode 100644 mysql-test/suite/innodb/t/auto_increment_lock_mode.combinations create mode 100644 mysql-test/suite/innodb/t/auto_increment_lock_mode.test diff --git a/mysql-test/suite/innodb/r/auto_increment_lock_mode.result b/mysql-test/suite/innodb/r/auto_increment_lock_mode.result new file mode 100644 index 00000000000..b19d5cf40fc --- /dev/null +++ b/mysql-test/suite/innodb/r/auto_increment_lock_mode.result @@ -0,0 +1,43 @@ +CREATE TABLE t1(a TINYINT UNSIGNED AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t2(a TINYINT UNSIGNED AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t3(a TINYINT UNSIGNED AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t4(a TINYINT UNSIGNED AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t5(a TINYINT UNSIGNED AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t6(a SERIAL, b INT) ENGINE=InnoDB; +CREATE FUNCTION p1() RETURNS INT +BEGIN +INSERT INTO t1() VALUES(); +INSERT INTO t2() VALUES(); +INSERT INTO t3() VALUES(); +INSERT INTO t4() VALUES(); +INSERT INTO t5() VALUES(); +RETURN 1; +END$$ +INSERT INTO t6(b) SELECT p1(); +UPDATE t1,t2,t3,t4,t5 SET t1.a=2,t2.a=2,t3.a=2,t4.a=2,t5.a=2; +SELECT * FROM t1; +a +2 +connect con1,localhost,root,,; +connect con2,localhost,root,,; +connect con3,localhost,root,,; +connection con1; +INSERT INTO t6(b) SELECT SLEEP(p1()); +connection con2; +INSERT INTO t6(b) SELECT SLEEP(p1()); +connection con3; +UPDATE t1,t2,t3,t4,t5 SET t1.a=0,t2.a=0,t3.a=0,t4.a=0,t5.a=0 +WHERE t1.a=2 AND t2.a=2 AND t3.a=2 AND t4.a=2 AND t5.a=2; +connection default; +KILL QUERY $ID1; +KILL QUERY $ID2; +KILL QUERY $ID3; +connection con1; +disconnect con1; +connection con2; +disconnect con2; +connection con3; +disconnect con3; +connection default; +DROP FUNCTION p1; +DROP TABLE t1,t2,t3,t4,t5,t6; diff --git a/mysql-test/suite/innodb/r/innodb-autoinc-56228.result b/mysql-test/suite/innodb/r/innodb-autoinc-56228.result index 6a3fd85ebd3..f8616772151 100644 --- a/mysql-test/suite/innodb/r/innodb-autoinc-56228.result +++ b/mysql-test/suite/innodb/r/innodb-autoinc-56228.result @@ -1,15 +1,6 @@ -DROP TABLE IF EXISTS t1_56228; -Warnings: -Note 1051 Unknown table 'test.t1_56228' -DROP TABLE IF EXISTS t2_56228; -Warnings: -Note 1051 Unknown table 'test.t2_56228' -DROP FUNCTION IF EXISTS bug56228; -Warnings: -Note 1305 FUNCTION test.bug56228 does not exist -CREATE TEMPORARY TABLE t1_56228( +CREATE TABLE t1_56228( c1 iNT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB; -CREATE TEMPORARY TABLE t2_56228( +CREATE TABLE t2_56228( c1 iNT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB; CREATE FUNCTION bug56228() RETURNS INT DETERMINISTIC BEGIN @@ -17,14 +8,18 @@ INSERT INTO t1_56228 VALUES(NULL); INSERT INTO t2_56228 VALUES(NULL); INSERT INTO t1_56228 VALUES(NULL); INSERT INTO t2_56228 VALUES(NULL); -DROP TEMPORARY TABLE t1_56228; +DROP TABLE t1_56228; RETURN 42; END // -SELECT bug56228(); -bug56228() -42 -DROP FUNCTION bug56228; -DROP TEMPORARY TABLE t2_56228; -DROP TEMPORARY TABLE IF EXISTS t1_56228; -Warnings: -Note 1051 Unknown table 'test.t1_56228' +ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger +CREATE PROCEDURE bug56228() +BEGIN +INSERT INTO t1_56228 VALUES(NULL); +INSERT INTO t2_56228 VALUES(NULL); +INSERT INTO t1_56228 VALUES(NULL); +INSERT INTO t2_56228 VALUES(NULL); +DROP TABLE t1_56228; +END // +CALL bug56228(); +DROP PROCEDURE bug56228; +DROP TABLE t2_56228; diff --git a/mysql-test/suite/innodb/t/auto_increment_lock_mode.combinations b/mysql-test/suite/innodb/t/auto_increment_lock_mode.combinations new file mode 100644 index 00000000000..efaee252a4e --- /dev/null +++ b/mysql-test/suite/innodb/t/auto_increment_lock_mode.combinations @@ -0,0 +1,6 @@ +[old] +--innodb-autoinc-lock-mode=0 +[new] +--innodb-autoinc-lock-mode=1 +[none] +--innodb-autoinc-lock-mode=2 diff --git a/mysql-test/suite/innodb/t/auto_increment_lock_mode.test b/mysql-test/suite/innodb/t/auto_increment_lock_mode.test new file mode 100644 index 00000000000..27497960e72 --- /dev/null +++ b/mysql-test/suite/innodb/t/auto_increment_lock_mode.test @@ -0,0 +1,61 @@ +--source include/have_innodb.inc + +CREATE TABLE t1(a TINYINT UNSIGNED AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t2(a TINYINT UNSIGNED AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t3(a TINYINT UNSIGNED AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t4(a TINYINT UNSIGNED AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t5(a TINYINT UNSIGNED AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t6(a SERIAL, b INT) ENGINE=InnoDB; + +DELIMITER $$; +CREATE FUNCTION p1() RETURNS INT +BEGIN + INSERT INTO t1() VALUES(); + INSERT INTO t2() VALUES(); + INSERT INTO t3() VALUES(); + INSERT INTO t4() VALUES(); + INSERT INTO t5() VALUES(); + RETURN 1; +END$$ +DELIMITER ;$$ + +INSERT INTO t6(b) SELECT p1(); + +UPDATE t1,t2,t3,t4,t5 SET t1.a=2,t2.a=2,t3.a=2,t4.a=2,t5.a=2; +SELECT * FROM t1; +--source include/count_sessions.inc + +--connect(con1,localhost,root,,) +let $ID1= `SELECT @id := CONNECTION_ID()`; +--connect(con2,localhost,root,,) +let $ID2= `SELECT @id := CONNECTION_ID()`; +--connect(con3,localhost,root,,) +let $ID3= `SELECT @id := CONNECTION_ID()`; +--connection con1 +send INSERT INTO t6(b) SELECT SLEEP(p1()); +--connection con2 +send INSERT INTO t6(b) SELECT SLEEP(p1()); +--connection con3 +send UPDATE t1,t2,t3,t4,t5 SET t1.a=0,t2.a=0,t3.a=0,t4.a=0,t5.a=0 +WHERE t1.a=2 AND t2.a=2 AND t3.a=2 AND t4.a=2 AND t5.a=2; +--connection default +evalp KILL QUERY $ID1; +evalp KILL QUERY $ID2; +evalp KILL QUERY $ID3; +--connection con1 +--error 0,ER_QUERY_INTERRUPTED,ER_AUTOINC_READ_FAILED +--reap +--disconnect con1 +--connection con2 +--error 0,ER_QUERY_INTERRUPTED,ER_AUTOINC_READ_FAILED +--reap +--disconnect con2 +--connection con3 +--error 0,ER_QUERY_INTERRUPTED,ER_AUTOINC_READ_FAILED +--reap +--disconnect con3 +--connection default + +DROP FUNCTION p1; +DROP TABLE t1,t2,t3,t4,t5,t6; +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/innodb/t/innodb-autoinc-56228.test b/mysql-test/suite/innodb/t/innodb-autoinc-56228.test index a02f7b4383a..e1d8741c730 100644 --- a/mysql-test/suite/innodb/t/innodb-autoinc-56228.test +++ b/mysql-test/suite/innodb/t/innodb-autoinc-56228.test @@ -2,33 +2,45 @@ ## # Bug #56228: dropping tables from within an active statement crashes server # -DROP TABLE IF EXISTS t1_56228; -DROP TABLE IF EXISTS t2_56228; -DROP FUNCTION IF EXISTS bug56228; -CREATE TEMPORARY TABLE t1_56228( +# This test used to use TEMPORARY TABLE, which before MySQL 5.7 or +# MariaDB Server 10.2 were covered by InnoDB locks. +# In MariaDB Server 10.6, the locking and logging was corrected for Atomic DDL. +# Hence, even if we tweaked create_table_info_t::innobase_table_flags() +# so that TEMPORARY TABLE are created as persistent tables, +# the DROP TEMPORARY TABLE statement inside the function would +# fail due to HA_ERR_LOCK_WAIT_TIMEOUT, instead of breaking locks +# like it used to do before MDEV-26603 and possibly other changes. +CREATE TABLE t1_56228( c1 iNT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB; -CREATE TEMPORARY TABLE t2_56228( +CREATE TABLE t2_56228( c1 iNT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB; DELIMITER //; +--error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG CREATE FUNCTION bug56228() RETURNS INT DETERMINISTIC BEGIN INSERT INTO t1_56228 VALUES(NULL); INSERT INTO t2_56228 VALUES(NULL); INSERT INTO t1_56228 VALUES(NULL); INSERT INTO t2_56228 VALUES(NULL); - DROP TEMPORARY TABLE t1_56228; + DROP TABLE t1_56228; RETURN 42; END // +CREATE PROCEDURE bug56228() +BEGIN + INSERT INTO t1_56228 VALUES(NULL); + INSERT INTO t2_56228 VALUES(NULL); + INSERT INTO t1_56228 VALUES(NULL); + INSERT INTO t2_56228 VALUES(NULL); + DROP TABLE t1_56228; +END // + DELIMITER ;// ---disable_ps_protocol -SELECT bug56228(); ---enable_ps2_protocol +CALL bug56228(); -DROP FUNCTION bug56228; -DROP TEMPORARY TABLE t2_56228; -DROP TEMPORARY TABLE IF EXISTS t1_56228; +DROP PROCEDURE bug56228; +DROP TABLE t2_56228; diff --git a/storage/innobase/dict/drop.cc b/storage/innobase/dict/drop.cc index f46b4b04752..80bf8c97ead 100644 --- a/storage/innobase/dict/drop.cc +++ b/storage/innobase/dict/drop.cc @@ -247,7 +247,7 @@ void trx_t::commit(std::vector &deleted) mutex_lock(); lock_release_on_drop(this); ut_ad(UT_LIST_GET_LEN(lock.trx_locks) == 0); - ut_ad(ib_vector_is_empty(autoinc_locks)); + ut_ad(autoinc_locks.empty()); mem_heap_empty(lock.lock_heap); lock.table_locks.clear(); /* commit_persist() already reset this. */ diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 4fedd79790b..31c4f525adf 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -5097,7 +5097,7 @@ static void innobase_kill_query(handlerton*, THD *thd, enum thd_kill_levels) may be executed as part of a multi-transaction DDL operation, such as rollback_inplace_alter_table() or ha_innobase::delete_table(). */; trx->error_state= DB_INTERRUPTED; - lock_sys_t::cancel(trx, lock); + lock_sys.cancel(trx, lock); } lock_sys.deadlock_check(); } diff --git a/storage/innobase/include/small_vector.h b/storage/innobase/include/small_vector.h index d28a36184b8..2acdc49f668 100644 --- a/storage/innobase/include/small_vector.h +++ b/storage/innobase/include/small_vector.h @@ -31,14 +31,14 @@ protected: small_vector_base()= delete; small_vector_base(void *small, size_t small_size) : BeginX(small), Capacity(Size_T(small_size)) {} - ATTRIBUTE_COLD void grow_by_1(void *small, size_t element_size); + ATTRIBUTE_COLD void grow_by_1(void *small, size_t element_size) noexcept; public: - size_t size() const { return Size; } - size_t capacity() const { return Capacity; } - bool empty() const { return !Size; } - void clear() { Size= 0; } + size_t size() const noexcept { return Size; } + size_t capacity() const noexcept { return Capacity; } + bool empty() const noexcept { return !Size; } + void clear() noexcept { Size= 0; } protected: - void set_size(size_t N) { Size= Size_T(N); } + void set_size(size_t N) noexcept { Size= Size_T(N); } }; template @@ -49,7 +49,7 @@ class small_vector : public small_vector_base using small_vector_base::set_size; - void grow_if_needed() + void grow_if_needed() noexcept { if (unlikely(size() >= capacity())) grow_by_1(small, sizeof *small); @@ -60,38 +60,67 @@ public: { TRASH_ALLOC(small, sizeof small); } - ~small_vector() + ~small_vector() noexcept { if (small != begin()) my_free(begin()); MEM_MAKE_ADDRESSABLE(small, sizeof small); } + void fake_defined() const noexcept + { + ut_ad(empty()); + MEM_MAKE_DEFINED(small, sizeof small); + } + void make_undefined() const noexcept { MEM_UNDEFINED(small, sizeof small); } + + bool is_small() const noexcept { return small == BeginX; } + + void deep_clear() noexcept + { + if (!is_small()) + { + my_free(BeginX); + BeginX= small; + Capacity= N; + } + ut_ad(capacity() == N); + set_size(0); + } + using iterator= T *; using const_iterator= const T *; using reverse_iterator= std::reverse_iterator; using reference= T &; using const_reference= const T&; - iterator begin() { return static_cast(BeginX); } - const_iterator begin() const { return static_cast(BeginX); } - iterator end() { return begin() + size(); } - const_iterator end() const { return begin() + size(); } + iterator begin() noexcept { return static_cast(BeginX); } + const_iterator begin() const noexcept + { return static_cast(BeginX); } + iterator end() noexcept { return begin() + size(); } + const_iterator end() const noexcept { return begin() + size(); } - reverse_iterator rbegin() { return reverse_iterator(end()); } - reverse_iterator rend() { return reverse_iterator(begin()); } + reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } + reverse_iterator rend() noexcept { return reverse_iterator(begin()); } - reference operator[](size_t i) { assert(i < size()); return begin()[i]; } - const_reference operator[](size_t i) const + reference operator[](size_t i) noexcept + { assert(i < size()); return begin()[i]; } + const_reference operator[](size_t i) const noexcept { return const_cast(*this)[i]; } - void erase(const_iterator S, const_iterator E) + void erase(const_iterator S, const_iterator E) noexcept { set_size(std::move(const_cast(E), end(), const_cast(S)) - begin()); } - void emplace_back(T &&arg) + void emplace_back(T &&arg) noexcept + { + grow_if_needed(); + ::new (end()) T(arg); + set_size(size() + 1); + } + void emplace_back(T &arg) noexcept { grow_if_needed(); ::new (end()) T(arg); diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 9a1c5edd43f..d79aafb1ced 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -32,10 +32,10 @@ Created 3/26/1996 Heikki Tuuri #include "que0types.h" #include "mem0mem.h" #include "trx0xa.h" -#include "ut0vec.h" #include "fts0fts.h" #include "read0types.h" #include "ilist.h" +#include "small_vector.h" #include @@ -857,12 +857,10 @@ public: ulint n_autoinc_rows; /*!< no. of AUTO-INC rows required for an SQL statement. This is useful for multi-row INSERTs */ - ib_vector_t* autoinc_locks; /* AUTOINC locks held by this - transaction. Note that these are - also in the lock list trx_locks. This - vector needs to be freed explicitly - when the trx instance is destroyed. - Protected by lock_sys.latch. */ + typedef small_vector autoinc_lock_vector; + /** AUTO_INCREMENT locks held by this transaction; a subset of trx_locks, + protected by lock_sys.latch. */ + autoinc_lock_vector autoinc_locks; /*------------------------------*/ bool read_only; /*!< true if transaction is flagged as a READ-ONLY transaction. @@ -1059,7 +1057,7 @@ public: ut_ad(!lock.wait_lock); ut_ad(UT_LIST_GET_LEN(lock.trx_locks) == 0); ut_ad(lock.table_locks.empty()); - ut_ad(!autoinc_locks || ib_vector_is_empty(autoinc_locks)); + ut_ad(autoinc_locks.empty()); ut_ad(UT_LIST_GET_LEN(lock.evicted_tables) == 0); ut_ad(!dict_operation); ut_ad(!apply_online_log); diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 5a6857678fc..5e6ed1502af 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -2302,7 +2302,7 @@ static void lock_grant(lock_t *lock) dict_table_t *table= lock->un_member.tab_lock.table; ut_ad(!table->autoinc_trx); table->autoinc_trx= trx; - ib_vector_push(trx->autoinc_locks, &lock); + trx->autoinc_locks.emplace_back(lock); } DBUG_PRINT("ib_lock", ("wait for trx " TRX_ID_FMT " ends", trx->id)); @@ -3646,7 +3646,7 @@ lock_t *lock_table_create(dict_table_t *table, unsigned type_mode, trx_t *trx, ut_ad(!table->autoinc_trx); table->autoinc_trx = trx; - ib_vector_push(trx->autoinc_locks, &lock); + trx->autoinc_locks.emplace_back(lock); goto allocated; } @@ -3695,79 +3695,45 @@ allocated: return(lock); } -/*************************************************************//** -Pops autoinc lock requests from the transaction's autoinc_locks. We -handle the case where there are gaps in the array and they need to -be popped off the stack. */ -UNIV_INLINE -void -lock_table_pop_autoinc_locks( -/*=========================*/ - trx_t* trx) /*!< in/out: transaction that owns the AUTOINC locks */ +/** Release a granted AUTO_INCREMENT lock. +@param lock AUTO_INCREMENT lock +@param trx transaction that owns the lock */ +static void lock_table_remove_autoinc_lock(lock_t *lock, trx_t *trx) noexcept { - ut_ad(!ib_vector_is_empty(trx->autoinc_locks)); + ut_ad(lock->type_mode == (LOCK_AUTO_INC | LOCK_TABLE)); + lock_sys.assert_locked(*lock->un_member.tab_lock.table); + ut_ad(trx->mutex_is_owner()); - /* Skip any gaps, gaps are NULL lock entries in the - trx->autoinc_locks vector. */ + auto begin= trx->autoinc_locks.begin(), end= trx->autoinc_locks.end(), i=end; + ut_ad(begin != end); + if (*--i == lock) + { + /* Normally, the last acquired lock is released first, in order to + avoid unnecessary traversal of trx->autoinc_locks, which + only stores granted locks. */ - do { - ib_vector_pop(trx->autoinc_locks); + /* We remove the last lock, as well as any nullptr entries + immediately preceding it, which might have been created by the + "else" branch below, or by lock_cancel_waiting_and_release(). */ + while (begin != i && !i[-1]) i--; + trx->autoinc_locks.erase(i, end); + } + else + { + ut_a(*i); + /* Clear the lock when it is not the last one. */ + while (begin != i) + { + if (*--i == lock) + { + *i= nullptr; + return; + } + } - if (ib_vector_is_empty(trx->autoinc_locks)) { - return; - } - - } while (*(lock_t**) ib_vector_get_last(trx->autoinc_locks) == NULL); -} - -/*************************************************************//** -Removes an autoinc lock request from the transaction's autoinc_locks. */ -UNIV_INLINE -void -lock_table_remove_autoinc_lock( -/*===========================*/ - lock_t* lock, /*!< in: table lock */ - trx_t* trx) /*!< in/out: transaction that owns the lock */ -{ - ut_ad(lock->type_mode == (LOCK_AUTO_INC | LOCK_TABLE)); - lock_sys.assert_locked(*lock->un_member.tab_lock.table); - ut_ad(trx->mutex_is_owner()); - - auto s = ib_vector_size(trx->autoinc_locks); - ut_ad(s); - - /* With stored functions and procedures the user may drop - a table within the same "statement". This special case has - to be handled by deleting only those AUTOINC locks that were - held by the table being dropped. */ - - lock_t* autoinc_lock = *static_cast( - ib_vector_get(trx->autoinc_locks, --s)); - - /* This is the default fast case. */ - - if (autoinc_lock == lock) { - lock_table_pop_autoinc_locks(trx); - } else { - /* The last element should never be NULL */ - ut_a(autoinc_lock != NULL); - - /* Handle freeing the locks from within the stack. */ - - while (s) { - autoinc_lock = *static_cast( - ib_vector_get(trx->autoinc_locks, --s)); - - if (autoinc_lock == lock) { - void* null_var = NULL; - ib_vector_set(trx->autoinc_locks, s, &null_var); - return; - } - } - - /* Must find the autoinc lock. */ - ut_error; - } + /* The lock must exist. */ + ut_error; + } } /*************************************************************//** @@ -3799,14 +3765,7 @@ lock_table_remove_low( ut_ad((table->autoinc_trx == trx) == !lock->is_waiting()); if (table->autoinc_trx == trx) { - table->autoinc_trx = NULL; - /* The locks must be freed in the reverse order from - the one in which they were acquired. This is to avoid - traversing the AUTOINC lock vector unnecessarily. - - We only store locks that were granted in the - trx->autoinc_locks vector (see lock_table_create() - and lock_grant()). */ + table->autoinc_trx = nullptr; lock_table_remove_autoinc_lock(lock, trx); } @@ -6443,44 +6402,31 @@ lock_clust_rec_read_check_and_lock_alt( return(err); } -/*******************************************************************//** -Check if a transaction holds any autoinc locks. -@return TRUE if the transaction holds any AUTOINC locks. */ -static -ibool -lock_trx_holds_autoinc_locks( -/*=========================*/ - const trx_t* trx) /*!< in: transaction */ -{ - ut_a(trx->autoinc_locks != NULL); - - return(!ib_vector_is_empty(trx->autoinc_locks)); -} - /** Release all AUTO_INCREMENT locks of the transaction. */ static void lock_release_autoinc_locks(trx_t *trx) { { + auto begin= trx->autoinc_locks.begin(), end= trx->autoinc_locks.end(); + ut_ad(begin != end); LockMutexGuard g{SRW_LOCK_CALL}; mysql_mutex_lock(&lock_sys.wait_mutex); trx->mutex_lock(); - auto autoinc_locks= trx->autoinc_locks; - ut_a(autoinc_locks); /* We release the locks in the reverse order. This is to avoid searching the vector for the element to delete at the lower level. See (lock_table_remove_low()) for details. */ - while (ulint size= ib_vector_size(autoinc_locks)) + do { - lock_t *lock= *static_cast - (ib_vector_get(autoinc_locks, size - 1)); + lock_t *lock= *--end; ut_ad(lock->type_mode == (LOCK_AUTO_INC | LOCK_TABLE)); lock_table_dequeue(lock, true); lock_trx_table_locks_remove(lock); } + while (begin != end); } mysql_mutex_unlock(&lock_sys.wait_mutex); trx->mutex_unlock(); + trx->autoinc_locks.clear(); } /** Cancel a waiting lock request and release possibly waiting transactions */ @@ -6502,8 +6448,18 @@ void lock_cancel_waiting_and_release(lock_t *lock) { if (lock->type_mode == (LOCK_AUTO_INC | LOCK_TABLE)) { - ut_ad(trx->autoinc_locks); - ib_vector_remove(trx->autoinc_locks, lock); + /* This is similar to lock_table_remove_autoinc_lock() */ + auto begin= trx->autoinc_locks.begin(), end= trx->autoinc_locks.end(); + ut_ad(begin != end); + if (*--end == lock) + trx->autoinc_locks.erase(end, end + 1); + else + while (begin != end) + if (*--end == lock) + { + *end= nullptr; + break; + } } lock_table_dequeue(lock, true); /* Remove the lock from table lock vector too. */ @@ -6703,7 +6659,7 @@ lock_unlock_table_autoinc( ut_ad(trx_state == TRX_STATE_ACTIVE || trx_state == TRX_STATE_PREPARED || trx_state == TRX_STATE_NOT_STARTED); - if (lock_trx_holds_autoinc_locks(trx)) + if (!trx->autoinc_locks.empty()) lock_release_autoinc_locks(trx); } diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index bd0ef0eee1b..d8f694d80f0 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -1268,14 +1268,14 @@ void mtr_t::free(const fil_space_t &space, uint32_t offset) m_log.close(log_write(id, nullptr)); } -void small_vector_base::grow_by_1(void *small, size_t element_size) +void small_vector_base::grow_by_1(void *small, size_t element_size) noexcept { const size_t cap= Capacity*= 2, s= cap * element_size; void *new_begin; if (BeginX == small) { new_begin= my_malloc(PSI_NOT_INSTRUMENTED, s, MYF(0)); - memcpy(new_begin, BeginX, size() * element_size); + memcpy(new_begin, BeginX, s / 2); TRASH_FREE(small, size() * element_size); } else diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 7935cdb6bc6..ade8dea929a 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -170,6 +170,8 @@ struct TrxFactory { allocated object. trx_t objects are allocated by ut_zalloc_nokey() in Pool::Pool() which would not call the constructors of the trx_t members. */ + new(&trx->autoinc_locks) trx_t::autoinc_lock_vector(); + new(&trx->mod_tables) trx_mod_tables_t(); new(&trx->lock.table_locks) lock_list(); @@ -232,6 +234,8 @@ struct TrxFactory { trx->mutex_destroy(); + trx->autoinc_locks.~small_vector(); + trx->mod_tables.~trx_mod_tables_t(); ut_ad(!trx->read_view.is_open()); @@ -334,21 +338,12 @@ trx_t *trx_create() trx->assert_freed(); - mem_heap_t* heap; - ib_alloc_t* alloc; - /* We just got trx from pool, it should be non locking */ ut_ad(!trx->will_lock); ut_ad(!trx->rw_trx_hash_pins); DBUG_LOG("trx", "Create: " << trx); - heap = mem_heap_create(sizeof(ib_vector_t) + sizeof(void*) * 8); - - alloc = ib_heap_allocator_create(heap); - - trx->autoinc_locks = ib_vector_create(alloc, sizeof(void**), 4); - ut_ad(trx->mod_tables.empty()); ut_ad(trx->lock.n_rec_locks == 0); ut_ad(trx->lock.set_nth_bit_calls == 0); @@ -364,6 +359,7 @@ trx_t *trx_create() /** Free the memory to trx_pools */ void trx_t::free() { + autoinc_locks.fake_defined(); #ifdef HAVE_MEM_CHECK if (xid.is_null()) MEM_MAKE_DEFINED(&xid, sizeof xid); @@ -372,6 +368,7 @@ void trx_t::free() sizeof xid.data - (xid.gtrid_length + xid.bqual_length)); #endif MEM_CHECK_DEFINED(this, sizeof *this); + autoinc_locks.make_undefined(); ut_ad(!n_mysql_tables_in_use); ut_ad(!mysql_log_file_name); @@ -390,14 +387,7 @@ void trx_t::free() trx_sys.rw_trx_hash.put_pins(this); mysql_thd= nullptr; - // FIXME: We need to avoid this heap free/alloc for each commit. - if (autoinc_locks) - { - ut_ad(ib_vector_is_empty(autoinc_locks)); - /* We allocated a dedicated heap for the vector. */ - ib_vector_free(autoinc_locks); - autoinc_locks= NULL; - } + autoinc_locks.deep_clear(); MEM_NOACCESS(&skip_lock_inheritance_and_n_ref, sizeof skip_lock_inheritance_and_n_ref); @@ -495,7 +485,7 @@ inline void trx_t::release_locks() lock_release(this); ut_ad(!lock.n_rec_locks); ut_ad(UT_LIST_GET_LEN(lock.trx_locks) == 0); - ut_ad(ib_vector_is_empty(autoinc_locks)); + ut_ad(autoinc_locks.empty()); mem_heap_empty(lock.lock_heap); } @@ -923,7 +913,7 @@ trx_start_low( trx->wsrep = wsrep_on(trx->mysql_thd); #endif /* WITH_WSREP */ - ut_a(ib_vector_is_empty(trx->autoinc_locks)); + ut_a(trx->autoinc_locks.empty()); ut_a(trx->lock.table_locks.empty()); /* No other thread can access this trx object through rw_trx_hash, From 0abef37ccdba25a4a1e8e3209abd2be64ff1f19a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 15 Jan 2025 16:55:29 +0200 Subject: [PATCH 083/213] Minor lock_sys cleanup Let us make some member functions of lock_sys_t non-static to avoid some shuffling of function parameter registers. lock_cancel_waiting_and_release(): Declare static, because there are no external callers. Reviewed by: Debarun Banerjee --- storage/innobase/include/lock0lock.h | 4 +- storage/innobase/lock/lock0lock.cc | 80 ++++++++++++++-------------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index c996e5f8227..a604b5ef7b5 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -869,7 +869,7 @@ public: @retval DB_DEADLOCK if trx->lock.was_chosen_as_deadlock_victim was set @retval DB_LOCK_WAIT if the lock was canceled */ template - static dberr_t cancel(trx_t *trx, lock_t *lock); + dberr_t cancel(trx_t *trx, lock_t *lock) noexcept; /** Note that a record lock wait started */ inline void wait_start(); @@ -924,7 +924,7 @@ public: void prdt_page_free_from_discard(const page_id_t id, bool all= false); /** Cancel possible lock waiting for a transaction */ - static void cancel_lock_wait_for_trx(trx_t *trx); + inline void cancel_lock_wait_for_trx(trx_t *trx) noexcept; #ifdef WITH_WSREP /** Cancel lock waiting for a wsrep BF abort. */ static void cancel_lock_wait_for_wsrep_bf_abort(trx_t *trx); diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 5e6ed1502af..94eeef57bd7 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -2232,7 +2232,7 @@ end_loop: if (wait_lock) { abort_wait: - lock_sys_t::cancel(trx, wait_lock); + lock_sys.cancel(trx, wait_lock); lock_sys.deadlock_check(); } @@ -6431,7 +6431,7 @@ static void lock_release_autoinc_locks(trx_t *trx) /** Cancel a waiting lock request and release possibly waiting transactions */ template -void lock_cancel_waiting_and_release(lock_t *lock) +static void lock_cancel_waiting_and_release(lock_t *lock) noexcept { lock_sys.assert_locked(*lock); mysql_mutex_assert_owner(&lock_sys.wait_mutex); @@ -6475,18 +6475,18 @@ void lock_cancel_waiting_and_release(lock_t *lock) trx->mutex_unlock(); } -void lock_sys_t::cancel_lock_wait_for_trx(trx_t *trx) +inline void lock_sys_t::cancel_lock_wait_for_trx(trx_t *trx) noexcept { - lock_sys.wr_lock(SRW_LOCK_CALL); - mysql_mutex_lock(&lock_sys.wait_mutex); + wr_lock(SRW_LOCK_CALL); + mysql_mutex_lock(&wait_mutex); if (lock_t *lock= trx->lock.wait_lock) { /* check if victim is still waiting */ if (lock->is_waiting()) lock_cancel_waiting_and_release(lock); } - lock_sys.wr_unlock(); - mysql_mutex_unlock(&lock_sys.wait_mutex); + wr_unlock(); + mysql_mutex_unlock(&wait_mutex); } #ifdef WITH_WSREP @@ -6510,10 +6510,10 @@ void lock_sys_t::cancel_lock_wait_for_wsrep_bf_abort(trx_t *trx) @retval DB_DEADLOCK if trx->lock.was_chosen_as_deadlock_victim was set @retval DB_LOCK_WAIT if the lock was canceled */ template -dberr_t lock_sys_t::cancel(trx_t *trx, lock_t *lock) +dberr_t lock_sys_t::cancel(trx_t *trx, lock_t *lock) noexcept { DEBUG_SYNC_C("lock_sys_t_cancel_enter"); - mysql_mutex_assert_owner(&lock_sys.wait_mutex); + mysql_mutex_assert_owner(&wait_mutex); ut_ad(trx->state == TRX_STATE_ACTIVE); /* trx->lock.wait_lock may be changed by other threads as long as we are not holding lock_sys.latch. @@ -6521,27 +6521,27 @@ dberr_t lock_sys_t::cancel(trx_t *trx, lock_t *lock) So, trx->lock.wait_lock==lock does not necessarily hold, but both pointers should be valid, because other threads cannot assign trx->lock.wait_lock=nullptr (or invalidate *lock) while we are - holding lock_sys.wait_mutex. Also, the type of trx->lock.wait_lock + holding wait_mutex. Also, the type of trx->lock.wait_lock (record or table lock) cannot be changed by other threads. So, it is - safe to call lock->is_table() while not holding lock_sys.latch. If - we have to release and reacquire lock_sys.wait_mutex, we must reread + safe to call lock->is_table() while not holding latch. If + we have to release and reacquire wait_mutex, we must reread trx->lock.wait_lock. We must also reread trx->lock.wait_lock after - lock_sys.latch acquiring, as it can be changed to not-null in lock moving - functions even if we hold lock_sys.wait_mutex. */ + latch acquiring, as it can be changed to not-null in lock moving + functions even if we hold wait_mutex. */ dberr_t err= DB_SUCCESS; /* This would be too large for a memory transaction, except in the DB_DEADLOCK case, which was already tested in lock_trx_handle_wait(). */ if (lock->is_table()) { - if (!lock_sys.rd_lock_try()) + if (!rd_lock_try()) { - mysql_mutex_unlock(&lock_sys.wait_mutex); - lock_sys.rd_lock(SRW_LOCK_CALL); - mysql_mutex_lock(&lock_sys.wait_mutex); + mysql_mutex_unlock(&wait_mutex); + rd_lock(SRW_LOCK_CALL); + mysql_mutex_lock(&wait_mutex); lock= trx->lock.wait_lock; - /* Even if waiting lock was cancelled while lock_sys.wait_mutex was - unlocked, we need to return deadlock error if transaction was chosen - as deadlock victim to rollback it */ + /* Even if the waiting lock was cancelled while we did not hold + wait_mutex, we need to return deadlock error if the transaction + was chosen as deadlock victim to be rolled back. */ if (check_victim && trx->lock.was_chosen_as_deadlock_victim) err= DB_DEADLOCK; else if (lock) @@ -6552,10 +6552,10 @@ dberr_t lock_sys_t::cancel(trx_t *trx, lock_t *lock) /* This function is invoked from the thread which executes the transaction. Table locks are requested before record locks. Some other transaction can't change trx->lock.wait_lock from table to record for the - current transaction at this point, because the current transaction has not - requested record locks yet. There is no need to move any table locks by - other threads. And trx->lock.wait_lock can't be set to null while we are - holding lock_sys.wait_mutex. That's why there is no need to reload + current transaction at this point, because the current transaction has + not requested record locks yet. There is no need to move any table locks + by other threads. And trx->lock.wait_lock can't be set to null while we + are holding wait_mutex. That's why there is no need to reload trx->lock.wait_lock here. */ ut_ad(lock == trx->lock.wait_lock); resolve_table_lock: @@ -6563,11 +6563,11 @@ resolve_table_lock: if (!table->lock_mutex_trylock()) { /* The correct latching order is: - lock_sys.latch, table->lock_latch, lock_sys.wait_mutex. - Thus, we must release lock_sys.wait_mutex for a blocking wait. */ - mysql_mutex_unlock(&lock_sys.wait_mutex); + latch, table->lock_latch, wait_mutex. + Thus, we must release wait_mutex for a blocking wait. */ + mysql_mutex_unlock(&wait_mutex); table->lock_mutex_lock(); - mysql_mutex_lock(&lock_sys.wait_mutex); + mysql_mutex_lock(&wait_mutex); /* Cache trx->lock.wait_lock under the corresponding latches. */ lock= trx->lock.wait_lock; if (!lock) @@ -6594,20 +6594,20 @@ resolve_table_lock: retreat: table->lock_mutex_unlock(); } - lock_sys.rd_unlock(); + rd_unlock(); } else { /* To prevent the record lock from being moved between pages - during a page split or merge, we must hold exclusive lock_sys.latch. */ - if (!lock_sys.wr_lock_try()) + during a page split or merge, we must hold exclusive latch. */ + if (!wr_lock_try()) { - mysql_mutex_unlock(&lock_sys.wait_mutex); - lock_sys.wr_lock(SRW_LOCK_CALL); - mysql_mutex_lock(&lock_sys.wait_mutex); + mysql_mutex_unlock(&wait_mutex); + wr_lock(SRW_LOCK_CALL); + mysql_mutex_lock(&wait_mutex); /* Cache trx->lock.wait_lock under the corresponding latches. */ lock= trx->lock.wait_lock; - /* Even if waiting lock was cancelled while lock_sys.wait_mutex was + /* Even if waiting lock was cancelled while wait_mutex was unlocked, we need to return deadlock error if transaction was chosen as deadlock victim to rollback it */ if (check_victim && trx->lock.was_chosen_as_deadlock_victim) @@ -6631,13 +6631,13 @@ resolve_record_lock: rpl.rpl_parallel_optimistic_xa_lsu_off */ err= DB_LOCK_WAIT; } - lock_sys.wr_unlock(); + wr_unlock(); } return err; } -template dberr_t lock_sys_t::cancel(trx_t *, lock_t *); +template dberr_t lock_sys_t::cancel(trx_t *, lock_t *) noexcept; /*********************************************************************//** Unlocks AUTO_INC type locks that were possibly reserved by a trx. This @@ -6689,7 +6689,7 @@ dberr_t lock_trx_handle_wait(trx_t *trx) err= DB_DEADLOCK; /* Cache trx->lock.wait_lock to avoid unnecessary atomic variable load */ else if (lock_t *wait_lock= trx->lock.wait_lock) - err= lock_sys_t::cancel(trx, wait_lock); + err= lock_sys.cancel(trx, wait_lock); lock_sys.deadlock_check(); mysql_mutex_unlock(&lock_sys.wait_mutex); return err; @@ -7153,7 +7153,7 @@ static lock_t *Deadlock::check_and_resolve(trx_t *trx, lock_t *wait_lock) return wait_lock; if (wait_lock) - lock_sys_t::cancel(trx, wait_lock); + lock_sys.cancel(trx, wait_lock); lock_sys.deadlock_check(); return reinterpret_cast(-1); From 2d42e9ff7d7bd61bf24b04c483d7a8fcff22abb5 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Wed, 15 Jan 2025 18:30:03 +0530 Subject: [PATCH 084/213] MDEV-34703 LOAD DATA INFILE using Innodb bulk load aborts problem: ======= - During load statement, InnoDB bulk operation relies on temporary directory and it got crash when tmpdir is exhausted. Solution: ======== During bulk insert, LOAD statement is building the clustered index one record at a time instead of page. By doing this, InnoDB does the following 1) Avoids creation of temporary file for clustered index. 2) Writes the undo log for first insert operation alone --- mysql-test/suite/innodb/r/bulk_load.result | 50 +++++++++++++++++++++ mysql-test/suite/innodb/t/bulk_load.opt | 1 + mysql-test/suite/innodb/t/bulk_load.test | 52 ++++++++++++++++++++++ sql/sql_load.cc | 10 ++++- storage/innobase/handler/ha_innodb.cc | 3 +- storage/innobase/include/row0merge.h | 18 +++++++- storage/innobase/include/trx0trx.h | 30 +++++++++---- storage/innobase/row/row0ins.cc | 9 +++- storage/innobase/row/row0merge.cc | 46 +++++++++++++++++-- storage/innobase/trx/trx0rec.cc | 4 +- 10 files changed, 203 insertions(+), 20 deletions(-) create mode 100644 mysql-test/suite/innodb/r/bulk_load.result create mode 100644 mysql-test/suite/innodb/t/bulk_load.opt create mode 100644 mysql-test/suite/innodb/t/bulk_load.test diff --git a/mysql-test/suite/innodb/r/bulk_load.result b/mysql-test/suite/innodb/r/bulk_load.result new file mode 100644 index 00000000000..1e3d9ba877a --- /dev/null +++ b/mysql-test/suite/innodb/r/bulk_load.result @@ -0,0 +1,50 @@ +CREATE TABLE t1(f1 INT NOT NULL,f2 INT NOT NULL)ENGINE=InnoDB; +INSERT INTO t1 SELECT seq, seq from seq_1_to_131072; +INSERT INTO t1 VALUES(131073, 131073), (131074, 131073); +SELECT * INTO OUTFILE "VARDIR/tmp/t1.outfile" FROM t1; +# successful load statement using bulk insert +CREATE TABLE t2(f1 INT NOT NULL PRIMARY KEY, +f2 INT NOT NULL)ENGINE=InnoDB; +SET unique_checks=0, foreign_key_checks=0; +LOAD DATA INFILE 'VARDIR/tmp/t1.outfile' INTO TABLE t2; +SELECT COUNT(*) FROM t2; +COUNT(*) +131074 +CHECK TABLE t2 EXTENDED; +Table Op Msg_type Msg_text +test.t2 check status OK +DROP TABLE t2; +CREATE TABLE t2(f1 INT NOT NULL, PRIMARY KEY(f1 DESC), +f2 INT NOT NULL)ENGINE=InnoDB; +LOAD DATA INFILE 'VARDIR/tmp/t1.outfile' INTO TABLE t2; +SELECT COUNT(*) FROM t2; +COUNT(*) +131074 +CHECK TABLE t2 EXTENDED; +Table Op Msg_type Msg_text +test.t2 check status OK +DROP TABLE t2; +# load statement using bulk insert fails during secondary index +CREATE TABLE t2(f1 INT NOT NULL PRIMARY KEY, +f2 INT NOT NULL UNIQUE KEY)ENGINE=InnoDB; +LOAD DATA INFILE 'VARDIR/tmp/t1.outfile' INTO TABLE t2; +ERROR HY000: Got error 1 "Operation not permitted" during COMMIT +SELECT COUNT(*) FROM t2; +COUNT(*) +0 +CHECK TABLE t2 EXTENDED; +Table Op Msg_type Msg_text +test.t2 check status OK +DROP TABLE t2; +# load statement using bulk insert fails during primary index +CREATE TABLE t2(f1 INT NOT NULL, +f2 INT NOT NULL PRIMARY KEY)ENGINE=InnoDB; +LOAD DATA INFILE 'VARDIR/tmp/t1.outfile' INTO TABLE t2; +ERROR 23000: Duplicate entry '131073' for key 'PRIMARY' +SELECT COUNT(*) FROM t2; +COUNT(*) +0 +CHECK TABLE t2 EXTENDED; +Table Op Msg_type Msg_text +test.t2 check status OK +DROP TABLE t2, t1; diff --git a/mysql-test/suite/innodb/t/bulk_load.opt b/mysql-test/suite/innodb/t/bulk_load.opt new file mode 100644 index 00000000000..c856c2d215a --- /dev/null +++ b/mysql-test/suite/innodb/t/bulk_load.opt @@ -0,0 +1 @@ +--innodb_sort_buffer_size=65536 diff --git a/mysql-test/suite/innodb/t/bulk_load.test b/mysql-test/suite/innodb/t/bulk_load.test new file mode 100644 index 00000000000..30c25839ba2 --- /dev/null +++ b/mysql-test/suite/innodb/t/bulk_load.test @@ -0,0 +1,52 @@ +--source include/have_innodb.inc +--source include/have_sequence.inc +--source include/big_test.inc + +CREATE TABLE t1(f1 INT NOT NULL,f2 INT NOT NULL)ENGINE=InnoDB; +INSERT INTO t1 SELECT seq, seq from seq_1_to_131072; +INSERT INTO t1 VALUES(131073, 131073), (131074, 131073); +--replace_result $MYSQLTEST_VARDIR VARDIR +--disable_cursor_protocol +--disable_ps2_protocol +eval SELECT * INTO OUTFILE "$MYSQLTEST_VARDIR/tmp/t1.outfile" FROM t1; +--enable_ps2_protocol +--enable_cursor_protocol + +--echo # successful load statement using bulk insert +CREATE TABLE t2(f1 INT NOT NULL PRIMARY KEY, + f2 INT NOT NULL)ENGINE=InnoDB; +SET unique_checks=0, foreign_key_checks=0; +--replace_result $MYSQLTEST_VARDIR VARDIR +eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/t1.outfile' INTO TABLE t2; +SELECT COUNT(*) FROM t2; +CHECK TABLE t2 EXTENDED; +DROP TABLE t2; + +CREATE TABLE t2(f1 INT NOT NULL, PRIMARY KEY(f1 DESC), + f2 INT NOT NULL)ENGINE=InnoDB; +--replace_result $MYSQLTEST_VARDIR VARDIR +eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/t1.outfile' INTO TABLE t2; +SELECT COUNT(*) FROM t2; +CHECK TABLE t2 EXTENDED; +DROP TABLE t2; + +--echo # load statement using bulk insert fails during secondary index +CREATE TABLE t2(f1 INT NOT NULL PRIMARY KEY, + f2 INT NOT NULL UNIQUE KEY)ENGINE=InnoDB; +--replace_result $MYSQLTEST_VARDIR VARDIR +--error ER_ERROR_DURING_COMMIT +eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/t1.outfile' INTO TABLE t2; +SELECT COUNT(*) FROM t2; +CHECK TABLE t2 EXTENDED; +DROP TABLE t2; + +--echo # load statement using bulk insert fails during primary index +CREATE TABLE t2(f1 INT NOT NULL, + f2 INT NOT NULL PRIMARY KEY)ENGINE=InnoDB; +--replace_result $MYSQLTEST_VARDIR VARDIR +--error ER_DUP_ENTRY +eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/t1.outfile' INTO TABLE t2; +SELECT COUNT(*) FROM t2; +CHECK TABLE t2 EXTENDED; +--remove_file $MYSQLTEST_VARDIR/tmp/t1.outfile +DROP TABLE t2, t1; diff --git a/sql/sql_load.cc b/sql/sql_load.cc index b51c9ca12eb..0d329f5e029 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -725,7 +725,15 @@ int mysql_load(THD *thd, const sql_exchange *ex, TABLE_LIST *table_list, table->file->print_error(my_errno, MYF(0)); error= 1; } - table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); + if (!error) + { + int err= table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); + if (err == HA_ERR_FOUND_DUPP_KEY) + { + error= 1; + my_error(ER_ERROR_DURING_COMMIT, MYF(0), 1); + } + } table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); table->next_number_field=0; } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index a97dcba1b35..e8279ad819a 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -15851,7 +15851,8 @@ ha_innobase::extra( /* Allow a subsequent INSERT into an empty table if !unique_checks && !foreign_key_checks. */ if (dberr_t err = trx->bulk_insert_apply()) { - return err; + return convert_error_code_to_mysql( + err, 0, trx->mysql_thd); } break; } diff --git a/storage/innobase/include/row0merge.h b/storage/innobase/include/row0merge.h index fc39a9d24d9..47961ab3146 100644 --- a/storage/innobase/include/row0merge.h +++ b/storage/innobase/include/row0merge.h @@ -447,12 +447,21 @@ class row_merge_bulk_t /** Block for encryption */ row_merge_block_t *m_crypt_block= nullptr; public: + /** If this is false, then there will be only one + bulk_insert_buffered() call for the primary key followed by + load_one_row() and row_ins_clust_index_entry() for subsequent rows. + For secondary indexes or for true, bulk_insert_buffered() will be + invoked for each row. */ + const bool m_sort_primary_key; /** Constructor. Create all merge files, merge buffer for all the table indexes expect fts indexes. Create a merge block which is used to write IO operation - @param table table which undergoes bulk insert operation */ - row_merge_bulk_t(dict_table_t *table); + @param table table which undergoes bulk insert operation + @param sort_primary_key Allow primary key sort for bulk + operation. In case of load, InnoDB skips the + primary key sorting */ + row_merge_bulk_t(dict_table_t *table, bool sort_primary_key); /** Destructor. Remove all merge files, merge buffer for all table indexes. */ @@ -498,4 +507,9 @@ public: /** Init temporary files for each index */ void init_tmp_file(); + + /** Load one row into the primary index + @param trx bulk transaction + @return error code */ + dberr_t load_one_row(trx_t *trx); }; diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 84973040b4c..4af53053b77 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -451,12 +451,13 @@ public: } /** Notify the start of a bulk insert operation - @param table table to do bulk operation */ - void start_bulk_insert(dict_table_t *table) + @param table table to do bulk operation + @param also_primary start bulk insert operation for primary index */ + void start_bulk_insert(dict_table_t *table, bool also_primary) { first|= BULK; if (!table->is_temporary()) - bulk_store= new row_merge_bulk_t(table); + bulk_store= new row_merge_bulk_t(table, also_primary); } /** Notify the end of a bulk insert operation */ @@ -511,6 +512,12 @@ public: return bulk_store && is_bulk_insert(); } + /** @return whether InnoDB has to skip sort for clustered index */ + bool skip_sort_pk() const + { + return bulk_store && !bulk_store->m_sort_primary_key; + } + /** Free bulk insert operation */ void clear_bulk_buffer() { @@ -1152,17 +1159,22 @@ public: return false; } - /** @return logical modification time of a table only - if the table has bulk buffer exist in the transaction */ - trx_mod_table_time_t *check_bulk_buffer(dict_table_t *table) + /** + @return logical modification time of a table + @retval nullptr if the table doesn't have bulk buffer or + can skip sorting for primary key */ + trx_mod_table_time_t *use_bulk_buffer(dict_index_t *index) noexcept { if (UNIV_LIKELY(!bulk_insert)) return nullptr; - ut_ad(table->skip_alter_undo || !check_unique_secondary); - ut_ad(table->skip_alter_undo || !check_foreigns); - auto it= mod_tables.find(table); + ut_ad(index->table->skip_alter_undo || !check_unique_secondary); + ut_ad(index->table->skip_alter_undo || !check_foreigns); + auto it= mod_tables.find(index->table); if (it == mod_tables.end() || !it->second.bulk_buffer_exist()) return nullptr; + /* Avoid using bulk buffer for load statement */ + if (index->is_clust() && it->second.skip_sort_pk()) + return nullptr; return &it->second; } diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 2d297ade4c2..4df909afb27 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -2811,7 +2811,7 @@ avoid_bulk: trx_start_if_not_started(trx, true); trx->bulk_insert = true; auto m = trx->mod_tables.emplace(index->table, 0); - m.first->second.start_bulk_insert(index->table); + m.first->second.start_bulk_insert(index->table, true); err = m.first->second.bulk_insert_buffered( *entry, *index, trx); goto err_exit; @@ -3430,7 +3430,12 @@ row_ins_index_entry( return(DB_LOCK_WAIT);}); if (index->is_btree()) { - if (auto t= trx->check_bulk_buffer(index->table)) { + /* If the InnoDB skips the sorting of primary + index for bulk insert operation then InnoDB + should have called load_one_row() for the + first insert statement and shouldn't use + buffer for consecutive insert statement */ + if (auto t= trx->use_bulk_buffer(index)) { /* MDEV-25036 FIXME: row_ins_check_foreign_constraint() check should be done before buffering the insert diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 944ca66aeb3..fba8467f095 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -5053,7 +5053,9 @@ dberr_t row_merge_bulk_t::alloc_block() return DB_SUCCESS; } -row_merge_bulk_t::row_merge_bulk_t(dict_table_t *table) +row_merge_bulk_t::row_merge_bulk_t(dict_table_t *table, + bool sort_primary_key) + : m_sort_primary_key(sort_primary_key) { ulint n_index= 0; for (dict_index_t *index= UT_LIST_GET_FIRST(table->indexes); @@ -5179,6 +5181,33 @@ dberr_t row_merge_bulk_t::write_to_tmp_file(ulint index_no) return DB_SUCCESS; } +ATTRIBUTE_COLD +dberr_t row_merge_bulk_t::load_one_row(trx_t *trx) +{ + /* Load the single row into the clustered index. BtrBulk has + nothing to do for bulk insert here and used only as a interface + to insert single row. */ + dict_index_t *index= m_merge_buf[0].index; + BtrBulk btr_bulk(index, trx); + ut_ad(m_merge_buf[0].n_tuples == 1); + dberr_t err= row_merge_insert_index_tuples(index, index->table, + OS_FILE_CLOSED, nullptr, + &m_merge_buf[0], &btr_bulk, + 0, 0, 0, nullptr, + index->table->space_id, + nullptr, + m_blob_file.fd == OS_FILE_CLOSED + ? nullptr : &m_blob_file); + if (err != DB_SUCCESS) + trx->error_info= index; + else if (index->table->persistent_autoinc) + btr_write_autoinc(index, 1); + err= btr_bulk.finish(err); + if (err == DB_SUCCESS && index->is_clust()) + index->table->stat_n_rows= 1; + return err; +} + dberr_t row_merge_bulk_t::bulk_insert_buffered(const dtuple_t &row, const dict_index_t &ind, trx_t *trx) @@ -5254,6 +5283,8 @@ add_to_buf: } func_exit: + if (!m_sort_primary_key && ind.is_clust()) + err= load_one_row(trx); if (large_tuple_heap) mem_heap_free(large_tuple_heap); return err; @@ -5325,9 +5356,16 @@ func_exit: dberr_t row_merge_bulk_t::write_to_table(dict_table_t *table, trx_t *trx) { - ulint i= 0; - for (dict_index_t *index= UT_LIST_GET_FIRST(table->indexes); - index; index= UT_LIST_GET_NEXT(indexes, index)) + dict_index_t *index= UT_LIST_GET_FIRST(table->indexes); + ut_ad(index->is_clust()); + ulint i= !m_sort_primary_key; + if (i) + /* For clustered index, InnoDB does call load_one_row() while + buffering the first insert and uses row_ins_clust_index_entry() + for subsequent rows. So skip the clustered index while applying + the buffered insert operation */ + index= UT_LIST_GET_NEXT(indexes, index); + for (; index; index= UT_LIST_GET_NEXT(indexes, index)) { if (!index->is_btree()) continue; diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc index 302947af9a5..53acf06fae6 100644 --- a/storage/innobase/trx/trx0rec.cc +++ b/storage/innobase/trx/trx0rec.cc @@ -1865,7 +1865,9 @@ trx_undo_report_row_operation( } else if (index->table->is_temporary()) { } else if (trx_has_lock_x(*trx, *index->table) && index->table->bulk_trx_id == trx->id) { - m.first->second.start_bulk_insert(index->table); + m.first->second.start_bulk_insert( + index->table, + thd_sql_command(trx->mysql_thd) != SQLCOM_LOAD); if (dberr_t err = m.first->second.bulk_insert_buffered( *clust_entry, *index, trx)) { From 904f2e4b2deb21741470b95bc816a83a5d4aea88 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 15 Jan 2025 21:22:48 +0100 Subject: [PATCH 085/213] fix galera tests for 11.4 --- mysql-test/suite/galera/t/galera_as_slave_ctas.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/galera/t/galera_as_slave_ctas.test b/mysql-test/suite/galera/t/galera_as_slave_ctas.test index eced636c600..e9cc8bedb25 100644 --- a/mysql-test/suite/galera/t/galera_as_slave_ctas.test +++ b/mysql-test/suite/galera/t/galera_as_slave_ctas.test @@ -16,7 +16,7 @@ SELECT @@wsrep_on; --connection node_1 --disable_query_log ---eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_3; +--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_3, master_ssl_verify_server_cert=0; --enable_query_log START SLAVE; From 1643a258d26bf32a8a22c330d107300e4f51aafe Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 15 Jan 2025 21:23:33 +0100 Subject: [PATCH 086/213] update wsrep test for 26.4.21 --- .../suite/wsrep/r/wsrep_provider_plugin_defaults.result | 8 ++++---- .../suite/wsrep/t/wsrep_provider_plugin_defaults.test | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mysql-test/suite/wsrep/r/wsrep_provider_plugin_defaults.result b/mysql-test/suite/wsrep/r/wsrep_provider_plugin_defaults.result index cefeb85d3e3..e5651383235 100644 --- a/mysql-test/suite/wsrep/r/wsrep_provider_plugin_defaults.result +++ b/mysql-test/suite/wsrep/r/wsrep_provider_plugin_defaults.result @@ -1184,16 +1184,16 @@ COMMAND_LINE_ARGUMENT REQUIRED GLOBAL_VALUE_PATH NULL VARIABLE_NAME WSREP_PROVIDER_SOCKET_SSL_CIPHER SESSION_VALUE NULL -GLOBAL_VALUE OFF +GLOBAL_VALUE GLOBAL_VALUE_ORIGIN COMPILE-TIME -DEFAULT_VALUE OFF +DEFAULT_VALUE VARIABLE_SCOPE GLOBAL -VARIABLE_TYPE BOOLEAN +VARIABLE_TYPE VARCHAR VARIABLE_COMMENT Wsrep provider option NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL -ENUM_VALUE_LIST OFF,ON +ENUM_VALUE_LIST NULL READ_ONLY YES COMMAND_LINE_ARGUMENT REQUIRED GLOBAL_VALUE_PATH NULL diff --git a/mysql-test/suite/wsrep/t/wsrep_provider_plugin_defaults.test b/mysql-test/suite/wsrep/t/wsrep_provider_plugin_defaults.test index e65d5130cbe..78198051f34 100644 --- a/mysql-test/suite/wsrep/t/wsrep_provider_plugin_defaults.test +++ b/mysql-test/suite/wsrep/t/wsrep_provider_plugin_defaults.test @@ -1,7 +1,7 @@ --source include/have_wsrep.inc --source include/have_innodb.inc ---let $galera_version=26.4.16 +--let $galera_version=26.4.21 source include/check_galera_version.inc; SELECT COUNT(*) FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIKE 'wsrep_provider%' AND VARIABLE_NAME NOT IN ( From 78157c4765f2c086fabe183d51d7734ecffdbdd8 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Tue, 14 Jan 2025 17:47:08 +1100 Subject: [PATCH 087/213] MDEV-35840 Eliminate -warray-bounds triggered by TABLE_SHARE::db_type() The warnings are triggered with -O3 --- sql/sql_base.cc | 3 ++- sql/sql_partition.cc | 27 ++++++++++++++++----------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 5c03ba3d42d..aaa86e7bfa0 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -8953,8 +8953,9 @@ my_bool mysql_rm_tmp_tables(void) memcpy(path_copy, path, path_len - ext_len); path_copy[path_len - ext_len]= 0; init_tmp_table_share(thd, &share, "", 0, "", path_copy); + handlerton *ht= share.db_type(); if (!open_table_def(thd, &share)) - share.db_type()->drop_table(share.db_type(), path_copy); + ht->drop_table(share.db_type(), path_copy); free_table_share(&share); } /* diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 6228991d46c..e17f6e5a00a 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -721,9 +721,11 @@ static bool handle_list_of_fields(THD *thd, List_iterator it, } else { - if (table->s->db_type()->partition_flags && - (table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION) && - (table->s->db_type()->partition_flags() & HA_CAN_PARTITION)) + handlerton *ht= table->s->db_type(); + if (ht->partition_flags && + ((ht->partition_flags() & + (HA_USE_AUTO_PARTITION | HA_CAN_PARTITION)) == + (HA_USE_AUTO_PARTITION | HA_CAN_PARTITION))) { /* This engine can handle automatic partitioning and there is no @@ -1927,6 +1929,7 @@ bool fix_partition_func(THD *thd, TABLE *table, bool is_create_table_ind) bool result= TRUE; partition_info *part_info= table->part_info; enum_column_usage saved_column_usage= thd->column_usage; + handlerton *ht; DBUG_ENTER("fix_partition_func"); if (part_info->fixed) @@ -2056,8 +2059,9 @@ bool fix_partition_func(THD *thd, TABLE *table, bool is_create_table_ind) goto end; if (unlikely(check_primary_key(table))) goto end; - if (unlikely((!(table->s->db_type()->partition_flags && - (table->s->db_type()->partition_flags() & HA_CAN_PARTITION_UNIQUE))) && + ht= table->s->db_type(); + if (unlikely((!(ht->partition_flags && + (ht->partition_flags() & HA_CAN_PARTITION_UNIQUE))) && check_unique_keys(table))) goto end; if (unlikely(set_up_partition_bitmaps(thd, part_info))) @@ -2713,12 +2717,14 @@ bool partition_key_modified(TABLE *table, const MY_BITMAP *fields) { Field **fld; partition_info *part_info= table->part_info; + handlerton *ht; DBUG_ENTER("partition_key_modified"); if (!part_info) DBUG_RETURN(FALSE); - if (table->s->db_type()->partition_flags && - (table->s->db_type()->partition_flags() & HA_CAN_UPDATE_PARTITION_KEY)) + ht= table->s->db_type(); + if (ht->partition_flags && + (ht->partition_flags() & HA_CAN_UPDATE_PARTITION_KEY)) DBUG_RETURN(FALSE); for (fld= part_info->full_part_field_array; *fld; fld++) if (bitmap_is_set(fields, (*fld)->field_index)) @@ -4927,11 +4933,10 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, if default partitioning is used. */ + handlerton *ht= table->s->db_type(); if (tab_part_info->part_type != HASH_PARTITION || - ((table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION) && - !tab_part_info->use_default_num_partitions) || - ((!(table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION)) && - tab_part_info->use_default_num_partitions)) + !(ht->partition_flags() & HA_USE_AUTO_PARTITION) == + tab_part_info->use_default_num_partitions) { my_error(ER_REORG_NO_PARAM_ERROR, MYF(0)); goto err; From a6ab0e6c0be218761e4dadf8959c7f42e5fea762 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Thu, 16 Jan 2025 18:14:26 +0530 Subject: [PATCH 088/213] MDEV-34898 Doublewrite recovery of innodb_checksum_algorithm=full_crc32 encrypted pages does not work - Use file_key_management encryption plugin instead of example_key_management_plugin for the encryption.doublewrite_debug test case --- mysql-test/suite/encryption/t/doublewrite_debug.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/encryption/t/doublewrite_debug.test b/mysql-test/suite/encryption/t/doublewrite_debug.test index 4dc6032c902..761f9cd3e47 100644 --- a/mysql-test/suite/encryption/t/doublewrite_debug.test +++ b/mysql-test/suite/encryption/t/doublewrite_debug.test @@ -1,7 +1,7 @@ --source include/have_innodb.inc --source include/have_debug.inc --source include/not_embedded.inc ---source include/have_example_key_management_plugin.inc +--source include/have_file_key_management_plugin.inc call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=3\\] in file .*test.t[12]\\.ibd looks corrupted"); call mtr.add_suppression("InnoDB: Unable to apply log to corrupted page "); call mtr.add_suppression("InnoDB: Plugin initialization aborted"); From 86b257f8705031730f011998a7e664cf981b39b6 Mon Sep 17 00:00:00 2001 From: Dave Gosselin Date: Thu, 16 Jan 2025 10:35:44 -0500 Subject: [PATCH 089/213] MDEV-35632 HandlerSocket uses deprecated C++98 auto_ptr Change uses of auto_ptr to unique_ptr --- plugin/handler_socket/client/hslongrun.cpp | 4 ++-- plugin/handler_socket/client/hstest.cpp | 4 ++-- plugin/handler_socket/handlersocket/database.cpp | 2 +- plugin/handler_socket/handlersocket/database.hpp | 9 ++------- plugin/handler_socket/handlersocket/handlersocket.cpp | 2 +- plugin/handler_socket/handlersocket/hstcpsvr.cpp | 2 +- plugin/handler_socket/handlersocket/hstcpsvr.hpp | 2 +- plugin/handler_socket/handlersocket/hstcpsvr_worker.cpp | 4 ++-- plugin/handler_socket/handlersocket/hstcpsvr_worker.hpp | 2 +- plugin/handler_socket/libhsclient/hstcpcli.hpp | 7 +------ 10 files changed, 14 insertions(+), 24 deletions(-) diff --git a/plugin/handler_socket/client/hslongrun.cpp b/plugin/handler_socket/client/hslongrun.cpp index b7c02951340..a9fba1dc7c3 100644 --- a/plugin/handler_socket/client/hslongrun.cpp +++ b/plugin/handler_socket/client/hslongrun.cpp @@ -927,7 +927,7 @@ hs_longrun_main(int argc, char **argv) shared.verbose = shared.conf.get_int("verbose", 1); const int table_size = shared.conf.get_int("table_size", 10000); for (int i = 0; i < table_size; ++i) { - std::auto_ptr rec(new record_value()); + std::unique_ptr rec(new record_value()); rec->key = to_stdstring(i); shared.records.push_back_ptr(rec); } @@ -966,7 +966,7 @@ hs_longrun_main(int argc, char **argv) int id = thrs.size(); const hs_longrun_thread_hs::arg_type arg(id, e.type, e.op, e.lock, shared); - std::auto_ptr thr; + std::unique_ptr thr; if (e.hs) { thr.reset(new hs_longrun_thread_hs(arg)); } else { diff --git a/plugin/handler_socket/client/hstest.cpp b/plugin/handler_socket/client/hstest.cpp index b5551fed81c..72e8a225de9 100644 --- a/plugin/handler_socket/client/hstest.cpp +++ b/plugin/handler_socket/client/hstest.cpp @@ -561,7 +561,7 @@ hstest_thread::test_9(int test_num) flds += std::string(buf); } int connected = 0; - std::auto_ptr stmt; + std::unique_ptr stmt; string_buffer wbuf; for (int i = 0; i < num; ++i) { const double tm1 = gettimeofday_double(); @@ -1474,7 +1474,7 @@ hstest_main(int argc, char **argv) #endif const int num_thrs = shared.num_threads; typedef thread thread_type; - typedef std::auto_ptr thread_ptr; + typedef std::unique_ptr thread_ptr; typedef auto_ptrcontainer< std::vector > thrs_type; thrs_type thrs; for (int i = 0; i < num_thrs; ++i) { diff --git a/plugin/handler_socket/handlersocket/database.cpp b/plugin/handler_socket/handlersocket/database.cpp index 0a006a42f00..9441863070c 100644 --- a/plugin/handler_socket/handlersocket/database.cpp +++ b/plugin/handler_socket/handlersocket/database.cpp @@ -175,7 +175,7 @@ struct dbcontext : public dbcontext_i, private noncopyable { THD *thd; MYSQL_LOCK *lock; bool lock_failed; - std::auto_ptr user_lock; + std::unique_ptr user_lock; int user_level_lock_timeout; bool user_level_lock_locked; bool commit_error; diff --git a/plugin/handler_socket/handlersocket/database.hpp b/plugin/handler_socket/handlersocket/database.hpp index 9e2aadf7380..87761050704 100644 --- a/plugin/handler_socket/handlersocket/database.hpp +++ b/plugin/handler_socket/handlersocket/database.hpp @@ -9,11 +9,6 @@ #ifndef DENA_DATABASE_HPP #define DENA_DATABASE_HPP -#ifdef __GNUC__ -/* auto_ptr is deprecated */ -# pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif - #include #include #include @@ -26,10 +21,10 @@ namespace dena { struct database_i; -typedef std::auto_ptr database_ptr; +typedef std::unique_ptr database_ptr; struct dbcontext_i; -typedef std::auto_ptr dbcontext_ptr; +typedef std::unique_ptr dbcontext_ptr; struct database_i { virtual ~database_i() = default; diff --git a/plugin/handler_socket/handlersocket/handlersocket.cpp b/plugin/handler_socket/handlersocket/handlersocket.cpp index 45c9e13b2ca..c513afb7dd5 100644 --- a/plugin/handler_socket/handlersocket/handlersocket.cpp +++ b/plugin/handler_socket/handlersocket/handlersocket.cpp @@ -76,7 +76,7 @@ daemon_handlersocket_init(void *p) conf["readsize"] = to_stdstring(handlersocket_readsize); conf["accept_balance"] = to_stdstring(handlersocket_accept_balance); conf["wrlock_timeout"] = to_stdstring(handlersocket_wrlock_timeout); - std::auto_ptr ap(new daemon_handlersocket_data); + std::unique_ptr ap(new daemon_handlersocket_data); if (handlersocket_port != 0 && handlersocket_port_wr != handlersocket_port) { conf["port"] = handlersocket_port; if (handlersocket_plain_secret) { diff --git a/plugin/handler_socket/handlersocket/hstcpsvr.cpp b/plugin/handler_socket/handlersocket/hstcpsvr.cpp index 336d36422b0..72435b80331 100644 --- a/plugin/handler_socket/handlersocket/hstcpsvr.cpp +++ b/plugin/handler_socket/handlersocket/hstcpsvr.cpp @@ -115,7 +115,7 @@ hstcpsvr::start_listen() arg.cshared = &cshared; arg.vshared = &vshared; arg.worker_id = i; - std::auto_ptr< thread > thr( + std::unique_ptr< thread > thr( new thread(arg, stack_size)); threads.push_back_ptr(thr); } diff --git a/plugin/handler_socket/handlersocket/hstcpsvr.hpp b/plugin/handler_socket/handlersocket/hstcpsvr.hpp index 5fbed92402b..3bb17c9ea0b 100644 --- a/plugin/handler_socket/handlersocket/hstcpsvr.hpp +++ b/plugin/handler_socket/handlersocket/hstcpsvr.hpp @@ -44,7 +44,7 @@ struct hstcpsvr_shared_v : public mutex { }; struct hstcpsvr_i; -typedef std::auto_ptr hstcpsvr_ptr; +typedef std::unique_ptr hstcpsvr_ptr; struct hstcpsvr_i { virtual ~hstcpsvr_i() = default; diff --git a/plugin/handler_socket/handlersocket/hstcpsvr_worker.cpp b/plugin/handler_socket/handlersocket/hstcpsvr_worker.cpp index 0796546cb5e..818d7327896 100644 --- a/plugin/handler_socket/handlersocket/hstcpsvr_worker.cpp +++ b/plugin/handler_socket/handlersocket/hstcpsvr_worker.cpp @@ -451,7 +451,7 @@ hstcpsvr_worker::run_one_nb() { pollfd& pfd = pfds[nfds - 1]; if ((pfd.revents & mask_in) != 0) { - std::auto_ptr c(new hstcpsvr_conn()); + std::unique_ptr c(new hstcpsvr_conn()); c->nonblocking = true; c->readsize = cshared.readsize; c->accept(cshared); @@ -498,7 +498,7 @@ hstcpsvr_worker::run_one_ep() /* listener */ ++accept_count; DBG_EP(fprintf(stderr, "IN listener\n")); - std::auto_ptr c(new hstcpsvr_conn()); + std::unique_ptr c(new hstcpsvr_conn()); c->nonblocking = true; c->readsize = cshared.readsize; c->accept(cshared); diff --git a/plugin/handler_socket/handlersocket/hstcpsvr_worker.hpp b/plugin/handler_socket/handlersocket/hstcpsvr_worker.hpp index 25612adec0f..2a2a5083e31 100644 --- a/plugin/handler_socket/handlersocket/hstcpsvr_worker.hpp +++ b/plugin/handler_socket/handlersocket/hstcpsvr_worker.hpp @@ -14,7 +14,7 @@ namespace dena { struct hstcpsvr_worker_i; -typedef std::auto_ptr hstcpsvr_worker_ptr; +typedef std::unique_ptr hstcpsvr_worker_ptr; struct hstcpsvr_worker_arg { const hstcpsvr_shared_c *cshared; diff --git a/plugin/handler_socket/libhsclient/hstcpcli.hpp b/plugin/handler_socket/libhsclient/hstcpcli.hpp index d078bdfd533..3428c2f240e 100644 --- a/plugin/handler_socket/libhsclient/hstcpcli.hpp +++ b/plugin/handler_socket/libhsclient/hstcpcli.hpp @@ -19,11 +19,6 @@ #include "string_ref.hpp" #include "string_buffer.hpp" -#ifdef __GNUC__ -/* auto_ptr is deprecated */ -# pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif - namespace dena { struct hstcpcli_filter { @@ -35,7 +30,7 @@ struct hstcpcli_filter { }; struct hstcpcli_i; -typedef std::auto_ptr hstcpcli_ptr; +typedef std::unique_ptr hstcpcli_ptr; struct hstcpcli_i { virtual ~hstcpcli_i() = default; From c8ef86cc8b9a8d3fe9ffff91c74122f2ae0a1b69 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 16 Jan 2025 21:04:39 +0400 Subject: [PATCH 090/213] A cleanup for MDEV-35427 to avoid dependency from the current date Adding a "SET timestamp" command before the test body. --- plugin/type_uuid/mysql-test/type_uuid/type_uuid_ps.test | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugin/type_uuid/mysql-test/type_uuid/type_uuid_ps.test b/plugin/type_uuid/mysql-test/type_uuid/type_uuid_ps.test index 712b2ab5eaf..776859e7354 100644 --- a/plugin/type_uuid/mysql-test/type_uuid/type_uuid_ps.test +++ b/plugin/type_uuid/mysql-test/type_uuid/type_uuid_ps.test @@ -5,10 +5,12 @@ --echo # SET time_zone='+00:00'; +SET timestamp=UNIX_TIMESTAMP('2025-01-15 00:00:00'); PREPARE s FROM 'SELECT CONCAT (UNIX_TIMESTAMP(?))'; EXECUTE s USING CAST('00000000-0000-0000-0000-000000000001' AS UUID); EXECUTE s USING @unknown_variable; DEALLOCATE PREPARE s; +SET timestamp=DEFAULT; SET time_zone=DEFAULT; --echo # End of 10.11 tests From 3158af03bdf2cdcac16de5bf40bbaa979981717d Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 16 Jan 2025 21:20:58 +0400 Subject: [PATCH 091/213] A cleanup for MDEV-35427: recording new type_uuid_ps.result Forgot to "git add" it in the previous commit. --- plugin/type_uuid/mysql-test/type_uuid/type_uuid_ps.result | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugin/type_uuid/mysql-test/type_uuid/type_uuid_ps.result b/plugin/type_uuid/mysql-test/type_uuid/type_uuid_ps.result index ea74a8d45e4..ddb818f4dd3 100644 --- a/plugin/type_uuid/mysql-test/type_uuid/type_uuid_ps.result +++ b/plugin/type_uuid/mysql-test/type_uuid/type_uuid_ps.result @@ -3,6 +3,7 @@ # MDEV-35427 Assertion `is_null() >= item->null_value' failed in Timestamp_or_zero_datetime_native_null::Timestamp_or_zero_datetime_native_null on EXECUTE # SET time_zone='+00:00'; +SET timestamp=UNIX_TIMESTAMP('2025-01-15 00:00:00'); PREPARE s FROM 'SELECT CONCAT (UNIX_TIMESTAMP(?))'; EXECUTE s USING CAST('00000000-0000-0000-0000-000000000001' AS UUID); CONCAT (UNIX_TIMESTAMP(?)) @@ -11,5 +12,6 @@ EXECUTE s USING @unknown_variable; CONCAT (UNIX_TIMESTAMP(?)) NULL DEALLOCATE PREPARE s; +SET timestamp=DEFAULT; SET time_zone=DEFAULT; # End of 10.11 tests From df602ff7fa5ed9424a1d7ebaba67b665e2f6d1f6 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Thu, 16 Jan 2025 23:04:59 +0100 Subject: [PATCH 092/213] Fix main.stack on Windows A part of the test, that tests that a frame of recursive SP takes the same amount of stack, relies on the fact that 3 calls to that SP are executed in the same OS thread. This is not guaranteed with threadpool(not with Windows native threadpool, anyway) Fix the test to execute SP calls in the same thread, as semicolon-separated batched command. --- mysql-test/main/stack.result | 1 + mysql-test/main/stack.test | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/stack.result b/mysql-test/main/stack.result index 5444381327d..d30a55cd21a 100644 --- a/mysql-test/main/stack.result +++ b/mysql-test/main/stack.result @@ -37,6 +37,7 @@ $$ call recursion(0,2,@s1); call recursion(0,3,@s2); call recursion(0,4,@s3); +$$ select @s1 > 0 && @s2 > 0 && @s3 > 0; @s1 > 0 && @s2 > 0 && @s3 > 0 1 diff --git a/mysql-test/main/stack.test b/mysql-test/main/stack.test index 2277b0f48ff..8884ad45572 100644 --- a/mysql-test/main/stack.test +++ b/mysql-test/main/stack.test @@ -40,11 +40,13 @@ begin end; $$ -delimiter ;$$ - call recursion(0,2,@s1); call recursion(0,3,@s2); call recursion(0,4,@s3); +$$ + +delimiter ;$$ + select @s1 > 0 && @s2 > 0 && @s3 > 0; if (`select @s2-@s1 <> @s3 - @s2`) From e551070ba4d59e89ef24bf07e5b8c673bbbce1c3 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 29 Nov 2024 19:04:06 +0400 Subject: [PATCH 093/213] MDEV-35468 UUID primary key filtering return incorrect results UUID::cmp() correctly compared: - two swapped v1 UUIDs - two non-swapped v6 UIDs but v1 vs v6 were not compared correctly. Adding a new method cmp_swap_noswap() and using it in UUID::cmp() to compare two value of different swapness. --- .../mysql-test/type_uuid/type_uuid_in.result | 101 ++++++++++++++++++ .../mysql-test/type_uuid/type_uuid_in.test | 82 ++++++++++++++ plugin/type_uuid/sql_type_uuid.h | 20 ++++ 3 files changed, 203 insertions(+) create mode 100644 plugin/type_uuid/mysql-test/type_uuid/type_uuid_in.result create mode 100644 plugin/type_uuid/mysql-test/type_uuid/type_uuid_in.test diff --git a/plugin/type_uuid/mysql-test/type_uuid/type_uuid_in.result b/plugin/type_uuid/mysql-test/type_uuid/type_uuid_in.result new file mode 100644 index 00000000000..4e47aeebfe8 --- /dev/null +++ b/plugin/type_uuid/mysql-test/type_uuid/type_uuid_in.result @@ -0,0 +1,101 @@ +CREATE TABLE t1 (id UUID NOT NULL); +INSERT INTO t1 (`id`) VALUES ('e8748eee-fabe-11eb-af18-005056bc575d'); +INSERT INTO t1 (`id`) VALUES ('036d4fc5-fabf-11eb-af18-005056bc575d'); +INSERT INTO t1 (`id`) VALUES ('2acf42cc-fabf-11eb-af18-005056bc575d'); +INSERT INTO t1 (`id`) VALUES ('594a8970-fabf-11eb-af18-005056bc575d'); +INSERT INTO t1 (`id`) VALUES ('4238a6e5-fac1-11eb-af18-005056bc575d'); +INSERT INTO t1 (`id`) VALUES ('6d001a4d-fac1-11eb-af18-005056bc575d'); +INSERT INTO t1 (`id`) VALUES ('e4e67615-fad5-11eb-af18-005056bc575d'); +INSERT INTO t1 (`id`) VALUES ('1ec69927-30f3-62ca-a0a0-4b98bb6957f8'); +INSERT INTO t1 (`id`) VALUES ('1ec6992e-5c9e-6b2a-a21b-fbc054a2075e'); +INSERT INTO t1 (`id`) VALUES ('1ec6992e-e5be-6342-8293-e107448b2cd5'); +SELECT * FROM t1 WHERE id IN ( +'036d4fc5-fabf-11eb-af18-005056bc575d', +'e8748eee-fabe-11eb-af18-005056bc575d', +'2acf42cc-fabf-11eb-af18-005056bc575d', +'594a8970-fabf-11eb-af18-005056bc575d', +'4238a6e5-fac1-11eb-af18-005056bc575d', +'6d001a4d-fac1-11eb-af18-005056bc575d', +'e4e67615-fad5-11eb-af18-005056bc575d', +'1ec69927-30f3-62ca-a0a0-4b98bb6957f8', +'1ec6992e-5c9e-6b2a-a21b-fbc054a2075e', +'1ec6992e-e5be-6342-8293-e107448b2cd5' +) ORDER BY id; +id +e8748eee-fabe-11eb-af18-005056bc575d +036d4fc5-fabf-11eb-af18-005056bc575d +2acf42cc-fabf-11eb-af18-005056bc575d +594a8970-fabf-11eb-af18-005056bc575d +4238a6e5-fac1-11eb-af18-005056bc575d +6d001a4d-fac1-11eb-af18-005056bc575d +e4e67615-fad5-11eb-af18-005056bc575d +1ec69927-30f3-62ca-a0a0-4b98bb6957f8 +1ec6992e-5c9e-6b2a-a21b-fbc054a2075e +1ec6992e-e5be-6342-8293-e107448b2cd5 +SELECT * FROM t1 WHERE id IN ( +'e8748eee-fabe-11eb-af18-005056bc575d', +'036d4fc5-fabf-11eb-af18-005056bc575d', +'2acf42cc-fabf-11eb-af18-005056bc575d', +'594a8970-fabf-11eb-af18-005056bc575d', +'4238a6e5-fac1-11eb-af18-005056bc575d', +'6d001a4d-fac1-11eb-af18-005056bc575d', +'e4e67615-fad5-11eb-af18-005056bc575d', +'1ec69927-30f3-62ca-a0a0-4b98bb6957f8', +'1ec6992e-5c9e-6b2a-a21b-fbc054a2075e', +'1ec6992e-e5be-6342-8293-e107448b2cd5' +) ORDER BY id; +id +e8748eee-fabe-11eb-af18-005056bc575d +036d4fc5-fabf-11eb-af18-005056bc575d +2acf42cc-fabf-11eb-af18-005056bc575d +594a8970-fabf-11eb-af18-005056bc575d +4238a6e5-fac1-11eb-af18-005056bc575d +6d001a4d-fac1-11eb-af18-005056bc575d +e4e67615-fad5-11eb-af18-005056bc575d +1ec69927-30f3-62ca-a0a0-4b98bb6957f8 +1ec6992e-5c9e-6b2a-a21b-fbc054a2075e +1ec6992e-e5be-6342-8293-e107448b2cd5 +DROP TABLE t1; +CREATE TABLE t1 (id uuid); +INSERT INTO t1 (id) VALUES +('e8748eee-fabe-11eb-af18-005056bc575d'), +('036d4fc5-fabf-11eb-af18-005056bc575d'); +SELECT * FROM t1 WHERE id IN ( +'e8748eee-fabe-11eb-af18-005056bc575d', +'036d4fc5-fabf-11eb-af18-005056bc575d', +'2acf42cc-fabf-11eb-af18-005056bc575d', +'594a8970-fabf-11eb-af18-005056bc575d', +'4238a6e5-fac1-11eb-af18-005056bc575d', +'6d001a4d-fac1-11eb-af18-005056bc575d', +'e4e67615-fad5-11eb-af18-005056bc575d', +'1ec69927-30f3-62ca-a0a0-4b98bb6957f8' +) ORDER BY id; +id +e8748eee-fabe-11eb-af18-005056bc575d +036d4fc5-fabf-11eb-af18-005056bc575d +SELECT * FROM t1 WHERE id IN ( +'e8748eee-fabe-11eb-af18-005056bc575d', +'036d4fc5-fabf-11eb-af18-005056bc575d', +'2acf42cc-fabf-11eb-af18-005056bc575d', +'594a8970-fabf-11eb-af18-005056bc575d', +'4238a6e5-fac1-11eb-af18-005056bc575d', +'6d001a4d-fac1-11eb-af18-005056bc575d', +'e4e67615-fad5-11eb-af18-005056bc575d' +) ORDER BY id; +id +e8748eee-fabe-11eb-af18-005056bc575d +036d4fc5-fabf-11eb-af18-005056bc575d +SELECT * FROM t1 WHERE id IN ( +'1ec69927-30f3-62ca-a0a0-4b98bb6957f8', +'036d4fc5-fabf-11eb-af18-005056bc575d', +'2acf42cc-fabf-11eb-af18-005056bc575d', +'594a8970-fabf-11eb-af18-005056bc575d', +'4238a6e5-fac1-11eb-af18-005056bc575d', +'6d001a4d-fac1-11eb-af18-005056bc575d', +'e4e67615-fad5-11eb-af18-005056bc575d', +'e8748eee-fabe-11eb-af18-005056bc575d' +) ORDER BY id; +id +e8748eee-fabe-11eb-af18-005056bc575d +036d4fc5-fabf-11eb-af18-005056bc575d +DROP TABLE t1; diff --git a/plugin/type_uuid/mysql-test/type_uuid/type_uuid_in.test b/plugin/type_uuid/mysql-test/type_uuid/type_uuid_in.test new file mode 100644 index 00000000000..c2545a423b7 --- /dev/null +++ b/plugin/type_uuid/mysql-test/type_uuid/type_uuid_in.test @@ -0,0 +1,82 @@ +# Start of 10.11 tests + +# +# MDEV-35468 UUID primary key filtering return incorrect results +# +CREATE TABLE t1 (id UUID NOT NULL); + +INSERT INTO t1 (`id`) VALUES ('e8748eee-fabe-11eb-af18-005056bc575d'); +INSERT INTO t1 (`id`) VALUES ('036d4fc5-fabf-11eb-af18-005056bc575d'); +INSERT INTO t1 (`id`) VALUES ('2acf42cc-fabf-11eb-af18-005056bc575d'); +INSERT INTO t1 (`id`) VALUES ('594a8970-fabf-11eb-af18-005056bc575d'); +INSERT INTO t1 (`id`) VALUES ('4238a6e5-fac1-11eb-af18-005056bc575d'); +INSERT INTO t1 (`id`) VALUES ('6d001a4d-fac1-11eb-af18-005056bc575d'); +INSERT INTO t1 (`id`) VALUES ('e4e67615-fad5-11eb-af18-005056bc575d'); +INSERT INTO t1 (`id`) VALUES ('1ec69927-30f3-62ca-a0a0-4b98bb6957f8'); +INSERT INTO t1 (`id`) VALUES ('1ec6992e-5c9e-6b2a-a21b-fbc054a2075e'); +INSERT INTO t1 (`id`) VALUES ('1ec6992e-e5be-6342-8293-e107448b2cd5'); + +SELECT * FROM t1 WHERE id IN ( +'036d4fc5-fabf-11eb-af18-005056bc575d', +'e8748eee-fabe-11eb-af18-005056bc575d', +'2acf42cc-fabf-11eb-af18-005056bc575d', +'594a8970-fabf-11eb-af18-005056bc575d', +'4238a6e5-fac1-11eb-af18-005056bc575d', +'6d001a4d-fac1-11eb-af18-005056bc575d', +'e4e67615-fad5-11eb-af18-005056bc575d', +'1ec69927-30f3-62ca-a0a0-4b98bb6957f8', +'1ec6992e-5c9e-6b2a-a21b-fbc054a2075e', +'1ec6992e-e5be-6342-8293-e107448b2cd5' +) ORDER BY id; + +SELECT * FROM t1 WHERE id IN ( +'e8748eee-fabe-11eb-af18-005056bc575d', +'036d4fc5-fabf-11eb-af18-005056bc575d', +'2acf42cc-fabf-11eb-af18-005056bc575d', +'594a8970-fabf-11eb-af18-005056bc575d', +'4238a6e5-fac1-11eb-af18-005056bc575d', +'6d001a4d-fac1-11eb-af18-005056bc575d', +'e4e67615-fad5-11eb-af18-005056bc575d', +'1ec69927-30f3-62ca-a0a0-4b98bb6957f8', +'1ec6992e-5c9e-6b2a-a21b-fbc054a2075e', +'1ec6992e-e5be-6342-8293-e107448b2cd5' +) ORDER BY id; + +DROP TABLE t1; + +CREATE TABLE t1 (id uuid); +INSERT INTO t1 (id) VALUES +('e8748eee-fabe-11eb-af18-005056bc575d'), +('036d4fc5-fabf-11eb-af18-005056bc575d'); +SELECT * FROM t1 WHERE id IN ( +'e8748eee-fabe-11eb-af18-005056bc575d', +'036d4fc5-fabf-11eb-af18-005056bc575d', +'2acf42cc-fabf-11eb-af18-005056bc575d', +'594a8970-fabf-11eb-af18-005056bc575d', +'4238a6e5-fac1-11eb-af18-005056bc575d', +'6d001a4d-fac1-11eb-af18-005056bc575d', +'e4e67615-fad5-11eb-af18-005056bc575d', +'1ec69927-30f3-62ca-a0a0-4b98bb6957f8' +) ORDER BY id; +SELECT * FROM t1 WHERE id IN ( +'e8748eee-fabe-11eb-af18-005056bc575d', +'036d4fc5-fabf-11eb-af18-005056bc575d', +'2acf42cc-fabf-11eb-af18-005056bc575d', +'594a8970-fabf-11eb-af18-005056bc575d', +'4238a6e5-fac1-11eb-af18-005056bc575d', +'6d001a4d-fac1-11eb-af18-005056bc575d', +'e4e67615-fad5-11eb-af18-005056bc575d' +) ORDER BY id; +SELECT * FROM t1 WHERE id IN ( +'1ec69927-30f3-62ca-a0a0-4b98bb6957f8', +'036d4fc5-fabf-11eb-af18-005056bc575d', +'2acf42cc-fabf-11eb-af18-005056bc575d', +'594a8970-fabf-11eb-af18-005056bc575d', +'4238a6e5-fac1-11eb-af18-005056bc575d', +'6d001a4d-fac1-11eb-af18-005056bc575d', +'e4e67615-fad5-11eb-af18-005056bc575d', +'e8748eee-fabe-11eb-af18-005056bc575d' +) ORDER BY id; +DROP TABLE t1; + +# End of 10.11 tests diff --git a/plugin/type_uuid/sql_type_uuid.h b/plugin/type_uuid/sql_type_uuid.h index 05d6cef63c2..ac9bafbe4b5 100644 --- a/plugin/type_uuid/sql_type_uuid.h +++ b/plugin/type_uuid/sql_type_uuid.h @@ -154,6 +154,10 @@ public: { return memcmp(a + m_memory_pos, b + m_memory_pos, m_length); } + int cmp_swap_noswap(const char *a, const char *b) const + { + return memcmp(a + m_memory_pos, b + m_record_pos, m_length); + } void hash_record(const uchar *ptr, Hasher *hasher) const { hasher->add(&my_charset_bin, ptr + m_record_pos, m_length); @@ -236,6 +240,18 @@ public: segment(4).hash_record(ptr, hasher); } + static int cmp_swap_noswap(const LEX_CSTRING &a, const LEX_CSTRING &b) + { + int res; + if ((res= segment(4).cmp_swap_noswap(a.str, b.str)) || + (res= segment(3).cmp_swap_noswap(a.str, b.str)) || + (res= segment(2).cmp_swap_noswap(a.str, b.str)) || + (res= segment(1).cmp_swap_noswap(a.str, b.str)) || + (res= segment(0).cmp_swap_noswap(a.str, b.str))) + return res; + return 0; + } + // Compare two in-memory values static int cmp(const LEX_CSTRING &a, const LEX_CSTRING &b) { @@ -254,6 +270,10 @@ public: return res; return 0; } + else if (swap_a && !swap_b) + return cmp_swap_noswap(a, b); + else if (!swap_a && swap_b) + return -cmp_swap_noswap(b, a); return memcmp(a.str, b.str, binary_length()); } From c69fb1a6273f759ad8afb4d6466aca5524df9e2f Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 17 Jan 2025 13:28:02 +0400 Subject: [PATCH 094/213] MDEV-35864 UBSAN: "applying zero offset to null pointer" when using a Field_set with empty values The val_buffer variable can come to Field_set::val_str() with the Ptr member equal to nullptr. This caused UBSAN errors "applying zero offset to null pointer" in my_strnncollsp_simple() and other strnncollsp() virtual implementations. Fixing the code to make sure its Ptr is not equal to nullptr. --- mysql-test/main/type_set.result | 12 ++++++++++++ mysql-test/main/type_set.test | 12 ++++++++++++ sql/field.cc | 3 +-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/type_set.result b/mysql-test/main/type_set.result index da1e579487d..428618c9efd 100644 --- a/mysql-test/main/type_set.result +++ b/mysql-test/main/type_set.result @@ -660,3 +660,15 @@ Note 1105 Cannot use key parts with `test`.`t1`.`indexed_col` in the rewritten c DROP TABLE t2; DROP TABLE t1; SET note_verbosity=DEFAULT; +# +# MDEV-35864 UBSAN: "applying zero offset to null pointer" when using a Field_set with empty values +# +SET sql_mode=''; +CREATE OR REPLACE TABLE t (c SET('','','') KEY,c2 DECIMAL UNSIGNED ZEROFILL,c3 CHAR(1) BINARY) ENGINE=MyISAM; +Warnings: +Note 1291 Column 'c' has duplicated value '' in SET +Note 1291 Column 'c' has duplicated value '' in SET +INSERT INTO t VALUES ('',CURRENT_TIME,''); +UPDATE t SET c2=c2+5 WHERE c BETWEEN '' AND ''; +DROP TABLE t; +SET sql_mode=DEFAULT; diff --git a/mysql-test/main/type_set.test b/mysql-test/main/type_set.test index df29364f551..60427c35c01 100644 --- a/mysql-test/main/type_set.test +++ b/mysql-test/main/type_set.test @@ -291,3 +291,15 @@ DELIMITER ;$$ --source unusable_keys_joins.inc DROP TABLE t1; SET note_verbosity=DEFAULT; + + +--echo # +--echo # MDEV-35864 UBSAN: "applying zero offset to null pointer" when using a Field_set with empty values +--echo # + +SET sql_mode=''; +CREATE OR REPLACE TABLE t (c SET('','','') KEY,c2 DECIMAL UNSIGNED ZEROFILL,c3 CHAR(1) BINARY) ENGINE=MyISAM; +INSERT INTO t VALUES ('',CURRENT_TIME,''); +UPDATE t SET c2=c2+5 WHERE c BETWEEN '' AND ''; +DROP TABLE t; +SET sql_mode=DEFAULT; diff --git a/sql/field.cc b/sql/field.cc index 2d690cfe591..a1c4fd8f4cf 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -9573,8 +9573,7 @@ String *Field_set::val_str(String *val_buffer, ulonglong tmp=(ulonglong) Field_enum::val_int(); uint bitnr=0; - val_buffer->set_charset(field_charset()); - val_buffer->length(0); + val_buffer->copy("", 0, field_charset()); while (tmp && bitnr < (uint) typelib->count) { From f521b8ac219102332eec99f854809e6331b3dbce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 17 Jan 2025 12:34:03 +0200 Subject: [PATCH 095/213] MDEV-35723: applying non-zero offset to null pointer in INSERT row_mysql_read_blob_ref(): Correctly handle what Field_blob::store() generates for length=0. --- mysql-test/suite/innodb/r/innodb.result | 6 ++++++ mysql-test/suite/innodb/t/innodb.test | 7 +++++++ storage/innobase/row/row0mysql.cc | 8 ++++++++ 3 files changed, 21 insertions(+) diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result index e1d99c3b731..8d6aa0332e0 100644 --- a/mysql-test/suite/innodb/r/innodb.result +++ b/mysql-test/suite/innodb/r/innodb.result @@ -3337,3 +3337,9 @@ Table Op Msg_type Msg_text test.t1 check status OK ALTER TABLE t1 FORCE; DROP TABLE t1; +# +# MDEV-35723: applying zero offset to null pointer on INSERT +# +CREATE TABLE t1(c TEXT(1) NOT NULL, INDEX (c)) ENGINE=InnoDB; +INSERT INTO t1 SET c=''; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test index ec217715aef..73baf7ed7ba 100644 --- a/mysql-test/suite/innodb/t/innodb.test +++ b/mysql-test/suite/innodb/t/innodb.test @@ -2605,3 +2605,10 @@ CHECK TABLE t1; ALTER TABLE t1 FORCE; # Cleanup DROP TABLE t1; + +--echo # +--echo # MDEV-35723: applying zero offset to null pointer on INSERT +--echo # +CREATE TABLE t1(c TEXT(1) NOT NULL, INDEX (c)) ENGINE=InnoDB; +INSERT INTO t1 SET c=''; +DROP TABLE t1; diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 4e7cd6b0b37..09b4bff16b9 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -244,6 +244,14 @@ row_mysql_read_blob_ref( *len = mach_read_from_n_little_endian(ref, col_len - 8); + if (!*len) { + /* Field_blob::store() if (!length) would encode both + the length and the pointer in the same area. An empty + string must be a valid (nonnull) pointer in the + collation functions that cmp_data() may invoke. */ + return ref; + } + memcpy(&data, ref + col_len - 8, sizeof data); return(data); From 350cc77fee66bf0ab6e6eabbbf6ec6012c72da99 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 26 Nov 2024 13:34:28 +0400 Subject: [PATCH 096/213] MDEV-29968 Functions in default values in tables with some character sets break SHOW CREATE (and mysqldump) Item:print_for_table_def() uses QT_TO_SYSTEM_CHARSET to print the DEFAULT expression into FRM file during CREATE TABLE. Therefore, the expression is encoded in utf8 in FRM. get_field_default_value() erroneously used field->charset() to print the DEFAULT expression at SHOW CREATE TABLE time. Fixing get_field_default_value() to use &my_charset_utf8mb4_general_ci instead. This makes DEFAULT work in the way way with: - virtual column expressions: if (field->vcol_info) { StringBuffer str(&my_charset_utf8mb4_general_ci); field->vcol_info->print(&str); - check constraint expressions: if (field->check_constraint) { StringBuffer str(&my_charset_utf8mb4_general_ci); field->check_constraint->print(&str); Additional cleanup: Fixing system_charset_info to &my_charset_utf8mb4_general_ci in a few places to make non-BMP characters work in DEFAULT, virtual column, check constraint expressions. --- client/mysqldump.c | 4 +- .../include/ctype_supplementary_chars.inc | 26 ++ mysql-test/main/ctype_utf32.result | 59 ++++- mysql-test/main/ctype_utf32.test | 9 +- .../main/ctype_utf32_not_embedded.result | 106 ++++++++ mysql-test/main/ctype_utf32_not_embedded.test | 38 +++ mysql-test/main/ddl_i18n_koi8r.result | 8 +- mysql-test/main/ddl_i18n_utf8.result | 8 +- mysql-test/main/lock_view.result | 16 +- mysql-test/main/mysql.result | 4 +- mysql-test/main/mysqldump-max.result | 24 +- mysql-test/main/mysqldump-nl.result | 4 +- mysql-test/main/mysqldump-timing.result | 4 +- mysql-test/main/mysqldump-utf8mb4.result | 2 +- mysql-test/main/mysqldump.result | 226 +++++++++--------- mysql-test/main/openssl_1.result | 6 +- mysql-test/main/trigger_wl3253.result | 4 +- .../r/mysqldump_restore_func_qualified.result | 8 +- mysql-test/suite/federated/federatedx.result | 2 +- mysql-test/suite/roles/definer.result | 14 +- .../suite/sql_sequence/mysqldump.result | 8 +- sql/item.cc | 2 +- sql/sql_show.cc | 8 +- .../connect/mysql-test/connect/r/mysql.result | 2 +- 24 files changed, 413 insertions(+), 179 deletions(-) create mode 100644 mysql-test/include/ctype_supplementary_chars.inc create mode 100644 mysql-test/main/ctype_utf32_not_embedded.result create mode 100644 mysql-test/main/ctype_utf32_not_embedded.test diff --git a/client/mysqldump.c b/client/mysqldump.c index 716e1f368e4..1cb41b66e30 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -3182,7 +3182,7 @@ static uint get_table_structure(const char *table, const char *db, char *table_t fprintf(sql_file, "SET @saved_cs_client = @@character_set_client;\n" - "SET character_set_client = utf8;\n" + "SET character_set_client = utf8mb4;\n" "/*!50001 CREATE VIEW %s AS SELECT\n", result_table); @@ -3250,7 +3250,7 @@ static uint get_table_structure(const char *table, const char *db, char *table_t { fprintf(sql_file, "/*!40101 SET @saved_cs_client = @@character_set_client */;\n" - "/*!40101 SET character_set_client = utf8 */;\n" + "/*!40101 SET character_set_client = utf8mb4 */;\n" "%s%s;\n" "/*!40101 SET character_set_client = @saved_cs_client */;\n", is_log_table ? "CREATE TABLE IF NOT EXISTS " : "", diff --git a/mysql-test/include/ctype_supplementary_chars.inc b/mysql-test/include/ctype_supplementary_chars.inc new file mode 100644 index 00000000000..dfc2497125b --- /dev/null +++ b/mysql-test/include/ctype_supplementary_chars.inc @@ -0,0 +1,26 @@ +--eval CREATE TABLE t1 (a CHAR(8) DEFAULT REVERSE('aha')) $table_charset +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES (); +SELECT * FROM t1; + +--eval CREATE TABLE t2 (a CHAR(8) DEFAULT REVERSE('åäá')) $table_charset +SHOW CREATE TABLE t2; +INSERT INTO t2 VALUES (); +SELECT * FROM t2; + +--eval CREATE TABLE t3 (a CHAR(8) DEFAULT REVERSE('😎😀')) $table_charset +SHOW CREATE TABLE t3; +INSERT INTO t3 VALUES (); +SELECT * FROM t3; + +--eval CREATE TABLE t4 (a CHAR(8), b CHAR(8) AS (REVERSE('😎😀'))) $table_charset +SHOW CREATE TABLE t4; +INSERT INTO t4 (a) VALUES (''); +SELECT * FROM t4; + +--eval CREATE TABLE t5 (a CHAR(8), b CHAR(8) CHECK (b=BINARY REVERSE('😎😀'))) $table_charset +SHOW CREATE TABLE t5; +--error ER_CONSTRAINT_FAILED +INSERT INTO t5 VALUES ('','😎😀'); +INSERT INTO t5 VALUES ('','😀😎'); +SELECT * FROM t5; diff --git a/mysql-test/main/ctype_utf32.result b/mysql-test/main/ctype_utf32.result index 546a7415603..193ad73c7dc 100644 --- a/mysql-test/main/ctype_utf32.result +++ b/mysql-test/main/ctype_utf32.result @@ -3031,5 +3031,62 @@ SELECT CAST(CONVERT('-9223372036854775808' USING utf32) AS SIGNED) AS c1; c1 -9223372036854775808 # -# End of 10.5 tests +# MDEV-29968 Functions in default values in tables with some character sets break SHOW CREATE (and mysqldump) # +SET NAMES utf8mb4; +CREATE TABLE t1 (a CHAR(8) DEFAULT REVERSE('aha')) CHARACTER SET utf32; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(8) DEFAULT reverse('aha') +) ENGINE=MyISAM DEFAULT CHARSET=utf32 COLLATE=utf32_general_ci +INSERT INTO t1 VALUES (); +SELECT * FROM t1; +a +aha +CREATE TABLE t2 (a CHAR(8) DEFAULT REVERSE('åäá')) CHARACTER SET utf32; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` char(8) DEFAULT reverse('åäá') +) ENGINE=MyISAM DEFAULT CHARSET=utf32 COLLATE=utf32_general_ci +INSERT INTO t2 VALUES (); +SELECT * FROM t2; +a +áäå +CREATE TABLE t3 (a CHAR(8) DEFAULT REVERSE('😎😀')) CHARACTER SET utf32; +SHOW CREATE TABLE t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `a` char(8) DEFAULT reverse('😎😀') +) ENGINE=MyISAM DEFAULT CHARSET=utf32 COLLATE=utf32_general_ci +INSERT INTO t3 VALUES (); +SELECT * FROM t3; +a +😀😎 +CREATE TABLE t4 (a CHAR(8), b CHAR(8) AS (REVERSE('😎😀'))) CHARACTER SET utf32; +SHOW CREATE TABLE t4; +Table Create Table +t4 CREATE TABLE `t4` ( + `a` char(8) DEFAULT NULL, + `b` char(8) GENERATED ALWAYS AS (reverse('😎😀')) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=utf32 COLLATE=utf32_general_ci +INSERT INTO t4 (a) VALUES (''); +SELECT * FROM t4; +a b + 😀😎 +CREATE TABLE t5 (a CHAR(8), b CHAR(8) CHECK (b=BINARY REVERSE('😎😀'))) CHARACTER SET utf32; +SHOW CREATE TABLE t5; +Table Create Table +t5 CREATE TABLE `t5` ( + `a` char(8) DEFAULT NULL, + `b` char(8) DEFAULT NULL CHECK (`b` = cast(reverse('😎😀') as char charset binary)) +) ENGINE=MyISAM DEFAULT CHARSET=utf32 COLLATE=utf32_general_ci +INSERT INTO t5 VALUES ('','😎😀'); +ERROR 23000: CONSTRAINT `t5.b` failed for `test`.`t5` +INSERT INTO t5 VALUES ('','😀😎'); +SELECT * FROM t5; +a b + 😀😎 +DROP TABLE t1, t2, t3, t4, t5; +# End of 10.5 tests diff --git a/mysql-test/main/ctype_utf32.test b/mysql-test/main/ctype_utf32.test index 4a1f27260c6..49e8b6f9bdb 100644 --- a/mysql-test/main/ctype_utf32.test +++ b/mysql-test/main/ctype_utf32.test @@ -1171,5 +1171,12 @@ SELECT HEX(DATE_FORMAT(TIME'11:22:33',@format)); SELECT CAST(CONVERT('-9223372036854775808' USING utf32) AS SIGNED) AS c1; --echo # ---echo # End of 10.5 tests +--echo # MDEV-29968 Functions in default values in tables with some character sets break SHOW CREATE (and mysqldump) --echo # + +SET NAMES utf8mb4; +--let $table_charset=CHARACTER SET utf32 +--source include/ctype_supplementary_chars.inc +DROP TABLE t1, t2, t3, t4, t5; + +--echo # End of 10.5 tests diff --git a/mysql-test/main/ctype_utf32_not_embedded.result b/mysql-test/main/ctype_utf32_not_embedded.result new file mode 100644 index 00000000000..55840fb4893 --- /dev/null +++ b/mysql-test/main/ctype_utf32_not_embedded.result @@ -0,0 +1,106 @@ +# Start of 10.5 tests +# +# MDEV-29968 Functions in default values in tables with some character sets break SHOW CREATE (and mysqldump) +# +SET NAMES utf8mb4; +CREATE TABLE t1 (a CHAR(8) DEFAULT REVERSE('aha')) CHARACTER SET utf32; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(8) DEFAULT reverse('aha') +) ENGINE=MyISAM DEFAULT CHARSET=utf32 COLLATE=utf32_general_ci +INSERT INTO t1 VALUES (); +SELECT * FROM t1; +a +aha +CREATE TABLE t2 (a CHAR(8) DEFAULT REVERSE('åäá')) CHARACTER SET utf32; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` char(8) DEFAULT reverse('åäá') +) ENGINE=MyISAM DEFAULT CHARSET=utf32 COLLATE=utf32_general_ci +INSERT INTO t2 VALUES (); +SELECT * FROM t2; +a +áäå +CREATE TABLE t3 (a CHAR(8) DEFAULT REVERSE('😎😀')) CHARACTER SET utf32; +SHOW CREATE TABLE t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `a` char(8) DEFAULT reverse('😎😀') +) ENGINE=MyISAM DEFAULT CHARSET=utf32 COLLATE=utf32_general_ci +INSERT INTO t3 VALUES (); +SELECT * FROM t3; +a +😀😎 +CREATE TABLE t4 (a CHAR(8), b CHAR(8) AS (REVERSE('😎😀'))) CHARACTER SET utf32; +SHOW CREATE TABLE t4; +Table Create Table +t4 CREATE TABLE `t4` ( + `a` char(8) DEFAULT NULL, + `b` char(8) GENERATED ALWAYS AS (reverse('😎😀')) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=utf32 COLLATE=utf32_general_ci +INSERT INTO t4 (a) VALUES (''); +SELECT * FROM t4; +a b + 😀😎 +CREATE TABLE t5 (a CHAR(8), b CHAR(8) CHECK (b=BINARY REVERSE('😎😀'))) CHARACTER SET utf32; +SHOW CREATE TABLE t5; +Table Create Table +t5 CREATE TABLE `t5` ( + `a` char(8) DEFAULT NULL, + `b` char(8) DEFAULT NULL CHECK (`b` = cast(reverse('😎😀') as char charset binary)) +) ENGINE=MyISAM DEFAULT CHARSET=utf32 COLLATE=utf32_general_ci +INSERT INTO t5 VALUES ('','😎😀'); +ERROR 23000: CONSTRAINT `t5.b` failed for `test`.`t5` +INSERT INTO t5 VALUES ('','😀😎'); +SELECT * FROM t5; +a b + 😀😎 +# Running dump +DROP TABLE t1, t2, t3, t4, t5; +# Running restore +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(8) DEFAULT reverse('aha') +) ENGINE=MyISAM DEFAULT CHARSET=utf32 COLLATE=utf32_general_ci +SELECT * FROM t1; +a +aha +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` char(8) DEFAULT reverse('åäá') +) ENGINE=MyISAM DEFAULT CHARSET=utf32 COLLATE=utf32_general_ci +SELECT * FROM t2; +a +áäå +SHOW CREATE TABLE t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `a` char(8) DEFAULT reverse('😎😀') +) ENGINE=MyISAM DEFAULT CHARSET=utf32 COLLATE=utf32_general_ci +SELECT * FROM t3; +a +😀😎 +SHOW CREATE TABLE t4; +Table Create Table +t4 CREATE TABLE `t4` ( + `a` char(8) DEFAULT NULL, + `b` char(8) GENERATED ALWAYS AS (reverse('😎😀')) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=utf32 COLLATE=utf32_general_ci +SELECT * FROM t4; +a b + 😀😎 +SHOW CREATE TABLE t5; +Table Create Table +t5 CREATE TABLE `t5` ( + `a` char(8) DEFAULT NULL, + `b` char(8) DEFAULT NULL CHECK (`b` = cast(reverse('😎😀') as char charset binary)) +) ENGINE=MyISAM DEFAULT CHARSET=utf32 COLLATE=utf32_general_ci +SELECT * FROM t5; +a b + 😀😎 +DROP TABLE t1, t2, t3, t4, t5; +# End of 10.5 tests diff --git a/mysql-test/main/ctype_utf32_not_embedded.test b/mysql-test/main/ctype_utf32_not_embedded.test new file mode 100644 index 00000000000..622ba074078 --- /dev/null +++ b/mysql-test/main/ctype_utf32_not_embedded.test @@ -0,0 +1,38 @@ +# Embedded server doesn't support external clients +--source include/not_embedded.inc + +--echo # Start of 10.5 tests + +--echo # +--echo # MDEV-29968 Functions in default values in tables with some character sets break SHOW CREATE (and mysqldump) +--echo # + +SET NAMES utf8mb4; +--let $table_charset=CHARACTER SET utf32 +--source include/ctype_supplementary_chars.inc + +--echo # Running dump +--let $mysqldumpfile = $MYSQLTEST_VARDIR/tmp/ctype_utf32_not_embedded_dump.sql +--exec $MYSQL_DUMP test > $mysqldumpfile + +DROP TABLE t1, t2, t3, t4, t5; + +--echo # Running restore +--exec $MYSQL test < $mysqldumpfile +SHOW CREATE TABLE t1; +SELECT * FROM t1; +SHOW CREATE TABLE t2; +SELECT * FROM t2; +SHOW CREATE TABLE t3; +SELECT * FROM t3; +SHOW CREATE TABLE t4; +SELECT * FROM t4; +SHOW CREATE TABLE t5; +SELECT * FROM t5; + +DROP TABLE t1, t2, t3, t4, t5; + +--error 0,1 +--remove_file $mysqldumpfile + +--echo # End of 10.5 tests diff --git a/mysql-test/main/ddl_i18n_koi8r.result b/mysql-test/main/ddl_i18n_koi8r.result index be375e501cd..fa489aa9c15 100644 --- a/mysql-test/main/ddl_i18n_koi8r.result +++ b/mysql-test/main/ddl_i18n_koi8r.result @@ -1731,13 +1731,13 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1` /*!40100 DEFAULT CHARACTER USE `mysqltest1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `log` ( `msg` varchar(255) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `c` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; @@ -1811,13 +1811,13 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest2` /*!40100 DEFAULT CHARACTER USE `mysqltest2`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `log` ( `msg` varchar(255) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `c` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; diff --git a/mysql-test/main/ddl_i18n_utf8.result b/mysql-test/main/ddl_i18n_utf8.result index ef1b7e62d40..3cec11850ca 100644 --- a/mysql-test/main/ddl_i18n_utf8.result +++ b/mysql-test/main/ddl_i18n_utf8.result @@ -1731,13 +1731,13 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1` /*!40100 DEFAULT CHARACTER USE `mysqltest1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `log` ( `msg` varchar(255) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `c` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; @@ -1811,13 +1811,13 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest2` /*!40100 DEFAULT CHARACTER USE `mysqltest2`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `log` ( `msg` varchar(255) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `c` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; diff --git a/mysql-test/main/lock_view.result b/mysql-test/main/lock_view.result index cd693032d87..004536d60f7 100644 --- a/mysql-test/main/lock_view.result +++ b/mysql-test/main/lock_view.result @@ -22,7 +22,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1` /*!40100 DEFAULT CHARACTER USE `mysqltest1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -32,7 +32,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest2` /*!40100 DEFAULT CHARACTER USE `mysqltest2`; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v2` AS SELECT 1 AS `a` */; SET character_set_client = @saved_cs_client; @@ -41,27 +41,27 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest3` /*!40100 DEFAULT CHARACTER USE `mysqltest3`; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v3` AS SELECT 1 AS `a` */; SET character_set_client = @saved_cs_client; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v3i` AS SELECT 1 AS `a` */; SET character_set_client = @saved_cs_client; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v3is` AS SELECT 1 AS `schema_name` */; SET character_set_client = @saved_cs_client; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v3nt` AS SELECT 1 AS `1` */; SET character_set_client = @saved_cs_client; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v3ps` AS SELECT 1 AS `user` */; SET character_set_client = @saved_cs_client; @@ -238,7 +238,7 @@ disconnect con1; connection default; /*M!999999\- enable the sandbox mode */ SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v1` AS SELECT 1 AS `id` */; SET character_set_client = @saved_cs_client; diff --git a/mysql-test/main/mysql.result b/mysql-test/main/mysql.result index 1e02cd9f595..42620265567 100644 --- a/mysql-test/main/mysql.result +++ b/mysql-test/main/mysql.result @@ -562,7 +562,7 @@ a1\`b1 CREATE TABLE `a1\``b1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci /*M!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `a1\``b1` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -592,7 +592,7 @@ a1\"b1 CREATE TABLE "a1\""b1" ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci /*M!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE "a1\""b1" ( "a" int(11) DEFAULT NULL ); diff --git a/mysql-test/main/mysqldump-max.result b/mysql-test/main/mysqldump-max.result index 4a2fe09d44d..735fe6374bd 100644 --- a/mysql-test/main/mysqldump-max.result +++ b/mysql-test/main/mysqldump-max.result @@ -95,7 +95,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l USE `test`; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `id` int(8) DEFAULT NULL, `name` varchar(32) DEFAULT NULL @@ -107,7 +107,7 @@ INSERT DELAYED IGNORE INTO `t1` VALUES (1,'first value'),(2,'first value'),(3,'f /*!40000 ALTER TABLE `t1` ENABLE KEYS */; DROP TABLE IF EXISTS `t2`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t2` ( `id` int(8) DEFAULT NULL, `name` varchar(32) DEFAULT NULL @@ -119,7 +119,7 @@ INSERT DELAYED IGNORE INTO `t2` VALUES (1,'first value'),(2,'first value'),(3,'f /*!40000 ALTER TABLE `t2` ENABLE KEYS */; DROP TABLE IF EXISTS `t3`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t3` ( `id` int(8) DEFAULT NULL, `name` varchar(32) DEFAULT NULL @@ -131,7 +131,7 @@ INSERT DELAYED IGNORE INTO `t3` VALUES (1,'first value'),(2,'first value'),(3,'f /*!40000 ALTER TABLE `t3` ENABLE KEYS */; DROP TABLE IF EXISTS `t4`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t4` ( `id` int(8) DEFAULT NULL, `name` varchar(32) DEFAULT NULL @@ -143,7 +143,7 @@ INSERT DELAYED IGNORE INTO `t4` VALUES (1,'first value'),(2,'first value'),(3,'f /*!40000 ALTER TABLE `t4` ENABLE KEYS */; DROP TABLE IF EXISTS `t5`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t5` ( `id` int(8) DEFAULT NULL, `name` varchar(32) DEFAULT NULL @@ -155,7 +155,7 @@ INSERT DELAYED IGNORE INTO `t5` VALUES (1,'first value'),(2,'first value'),(3,'f /*!40000 ALTER TABLE `t5` ENABLE KEYS */; DROP TABLE IF EXISTS `t6`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t6` ( `id` int(8) DEFAULT NULL, `name` varchar(32) DEFAULT NULL @@ -193,7 +193,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l USE `test`; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `id` int(8) DEFAULT NULL, `name` varchar(32) DEFAULT NULL @@ -205,7 +205,7 @@ INSERT DELAYED INTO `t1` VALUES (1,'first value'),(2,'first value'),(3,'first va /*!40000 ALTER TABLE `t1` ENABLE KEYS */; DROP TABLE IF EXISTS `t2`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t2` ( `id` int(8) DEFAULT NULL, `name` varchar(32) DEFAULT NULL @@ -217,7 +217,7 @@ INSERT DELAYED INTO `t2` VALUES (1,'first value'),(2,'first value'),(3,'first va /*!40000 ALTER TABLE `t2` ENABLE KEYS */; DROP TABLE IF EXISTS `t3`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t3` ( `id` int(8) DEFAULT NULL, `name` varchar(32) DEFAULT NULL @@ -229,7 +229,7 @@ INSERT DELAYED INTO `t3` VALUES (1,'first value'),(2,'first value'),(3,'first va /*!40000 ALTER TABLE `t3` ENABLE KEYS */; DROP TABLE IF EXISTS `t4`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t4` ( `id` int(8) DEFAULT NULL, `name` varchar(32) DEFAULT NULL @@ -241,7 +241,7 @@ INSERT DELAYED INTO `t4` VALUES (1,'first value'),(2,'first value'),(3,'first va /*!40000 ALTER TABLE `t4` ENABLE KEYS */; DROP TABLE IF EXISTS `t5`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t5` ( `id` int(8) DEFAULT NULL, `name` varchar(32) DEFAULT NULL @@ -253,7 +253,7 @@ INSERT DELAYED INTO `t5` VALUES (1,'first value'),(2,'first value'),(3,'first va /*!40000 ALTER TABLE `t5` ENABLE KEYS */; DROP TABLE IF EXISTS `t6`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t6` ( `id` int(8) DEFAULT NULL, `name` varchar(32) DEFAULT NULL diff --git a/mysql-test/main/mysqldump-nl.result b/mysql-test/main/mysqldump-nl.result index 56e9c56bae2..03dbc9ea13d 100644 --- a/mysql-test/main/mysqldump-nl.result +++ b/mysql-test/main/mysqldump-nl.result @@ -34,7 +34,7 @@ USE `mysqltest1 -- /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1 1t` ( `foobar @@ -53,7 +53,7 @@ raboof` int(11) DEFAULT NULL -- SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v1 1v` AS SELECT 1 AS `foobar diff --git a/mysql-test/main/mysqldump-timing.result b/mysql-test/main/mysqldump-timing.result index 2ac132412f9..8afb8de6b8c 100644 --- a/mysql-test/main/mysqldump-timing.result +++ b/mysql-test/main/mysqldump-timing.result @@ -21,7 +21,7 @@ timeout without t1 contents expected /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `i` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -45,7 +45,7 @@ This would be a race condition otherwise, but default max_statement_time=0 makes /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `i` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; diff --git a/mysql-test/main/mysqldump-utf8mb4.result b/mysql-test/main/mysqldump-utf8mb4.result index dc2ec06554e..b1a5338c083 100644 --- a/mysql-test/main/mysqldump-utf8mb4.result +++ b/mysql-test/main/mysqldump-utf8mb4.result @@ -46,7 +46,7 @@ Testing text format output /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `point` varchar(10) NOT NULL, `data` varchar(10) DEFAULT NULL, diff --git a/mysql-test/main/mysqldump.result b/mysql-test/main/mysqldump.result index 08725299a38..93e0f9ee89c 100644 --- a/mysql-test/main/mysqldump.result +++ b/mysql-test/main/mysqldump.result @@ -33,7 +33,7 @@ INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890"), ("0987654321098765432109876543210987654321"); /*M!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` decimal(64,20) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -49,7 +49,7 @@ Warnings: Warning 1264 Out of range value for column 'a' at row 1 /*M!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` double DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -71,7 +71,7 @@ ERROR 42S22: Unknown column '1.2345' in 'field list' SET SQL_MODE=@OLD_SQL_MODE; /*M!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` decimal(10,5) DEFAULT NULL, `b` float DEFAULT NULL @@ -80,7 +80,7 @@ CREATE TABLE `t1` ( INSERT INTO `t1` VALUES (1.23450,2.3456),(1.23450,2.3456),(1.23450,2.3456),(1.23450,2.3456),(1.23450,2.3456); /*M!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` decimal(10,5) DEFAULT NULL, `b` float DEFAULT NULL @@ -101,7 +101,7 @@ INSERT INTO `t1` VALUES (1.23450,2.3456),(1.23450,2.3456),(1.23450,2.3456),(1.23 /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` decimal(10,5) DEFAULT NULL, `b` float DEFAULT NULL @@ -131,7 +131,7 @@ UNLOCK TABLES; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` decimal(10,5) DEFAULT NULL, `b` float DEFAULT NULL @@ -214,7 +214,7 @@ INSERT INTO t1 VALUES (_koi8r x'C1C2C3C4C5'), (NULL); /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` varchar(255) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=koi8r COLLATE=koi8r_general_ci; @@ -297,7 +297,7 @@ DROP TABLE t1; create table ```a` (i int); /*M!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE ```a` ( `i` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -321,7 +321,7 @@ create table t1(a int); /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -350,7 +350,7 @@ UNLOCK TABLES; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS "t1"; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE "t1" ( "a" int(11) DEFAULT NULL ); @@ -382,7 +382,7 @@ set global sql_mode='ANSI_QUOTES'; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -411,7 +411,7 @@ UNLOCK TABLES; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS "t1"; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE "t1" ( "a" int(11) DEFAULT NULL ); @@ -447,7 +447,7 @@ insert into t1 values (1),(2),(3); /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -544,7 +544,7 @@ INSERT INTO t1 VALUES (_latin1 ' /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` char(10) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -666,7 +666,7 @@ INSERT INTO t2 VALUES (4),(5),(6); /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t2`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t2` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -708,7 +708,7 @@ INSERT INTO `t1` VALUES (0x602010000280100005E71A); /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `b` blob DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -750,7 +750,7 @@ INSERT INTO t1 VALUES (4),(5),(6); /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -785,7 +785,7 @@ UNLOCK TABLES; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -1155,7 +1155,7 @@ insert into t1 (F_8d3bba7425e7c98c50f52ca1b52d3735) values (1); /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `F_c4ca4238a0b923820dcc509a6f75849b` int(11) DEFAULT NULL, `F_c81e728d9d4c2f636f067f89cc14862c` int(11) DEFAULT NULL, @@ -1531,7 +1531,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l USE `test`; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -1576,14 +1576,14 @@ INSERT INTO t2 VALUES (1), (2); /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `t2`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t2` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -1612,14 +1612,14 @@ CREATE TABLE `t2` ( /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `t2`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t2` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -1807,7 +1807,7 @@ UNLOCK TABLES; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(10) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -1820,7 +1820,7 @@ INSERT INTO `t1` VALUES (NULL),(10),(20); UNLOCK TABLES; DROP TABLE IF EXISTS `t2`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t2` ( `pk` int(11) NOT NULL AUTO_INCREMENT, `a` int(10) DEFAULT NULL, @@ -1926,21 +1926,21 @@ mariadb-dump: Couldn't find table: "non_existing" /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t3`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t3` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `t2`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t2` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -1976,7 +1976,7 @@ mariadb-dump: Got error: 1064: "You have an error in your SQL syntax; check the /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -2013,7 +2013,7 @@ insert into t1 values (0815, 4711, 2006); /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS "t1"; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE "t1" ( "a b" int(11) NOT NULL, "c""d" int(11) NOT NULL, @@ -2048,7 +2048,7 @@ UNLOCK TABLES; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a b` int(11) NOT NULL, `c"d` int(11) NOT NULL, @@ -2103,7 +2103,7 @@ create view v2 as select * from t2 where a like 'a%' with check option; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t2`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t2` ( `a` varchar(30) DEFAULT NULL, KEY `a` (`a`(5)) @@ -2118,7 +2118,7 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `v2`; /*!50001 DROP VIEW IF EXISTS `v2`*/; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v2` AS SELECT 1 AS `a` */; SET character_set_client = @saved_cs_client; @@ -2198,7 +2198,7 @@ create view v1 as select * from t1; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -2211,7 +2211,7 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `v1`; /*!50001 DROP VIEW IF EXISTS `v1`*/; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v1` AS SELECT 1 AS `a` */; SET character_set_client = @saved_cs_client; @@ -2269,7 +2269,7 @@ create view v2 as select * from t2 where a like 'a%' with check option; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t2`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t2` ( `a` varchar(30) DEFAULT NULL, KEY `a` (`a`(5)) @@ -2284,7 +2284,7 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `v2`; /*!50001 DROP VIEW IF EXISTS `v2`*/; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v2` AS SELECT 1 AS `a` */; SET character_set_client = @saved_cs_client; @@ -2335,7 +2335,7 @@ INSERT INTO t1 VALUES ('\''); /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` char(10) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -2382,7 +2382,7 @@ select v3.a from v3, v1 where v1.a=v3.a and v3.b=3 limit 1; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, @@ -2398,7 +2398,7 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `v1`; /*!50001 DROP VIEW IF EXISTS `v1`*/; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v1` AS SELECT 1 AS `a`, 1 AS `b`, @@ -2407,14 +2407,14 @@ SET character_set_client = @saved_cs_client; DROP TABLE IF EXISTS `v2`; /*!50001 DROP VIEW IF EXISTS `v2`*/; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v2` AS SELECT 1 AS `a` */; SET character_set_client = @saved_cs_client; DROP TABLE IF EXISTS `v3`; /*!50001 DROP VIEW IF EXISTS `v3`*/; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v3` AS SELECT 1 AS `a`, 1 AS `b`, @@ -2536,7 +2536,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l USE `test`; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL, `b` bigint(20) DEFAULT NULL @@ -2608,7 +2608,7 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; DROP TABLE IF EXISTS `t2`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t2` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -2666,7 +2666,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l USE `test`; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL, `b` bigint(20) DEFAULT NULL @@ -2680,7 +2680,7 @@ INSERT INTO `t1` VALUES (1,NULL),(2,NULL),(4,NULL),(11,NULL); UNLOCK TABLES; DROP TABLE IF EXISTS `t2`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t2` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -2814,7 +2814,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l USE `test`; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `id` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -2966,7 +2966,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l USE `test`; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `d` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), UNIQUE KEY `d` (`d`) @@ -3004,7 +3004,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l USE `test`; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `d` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), UNIQUE KEY `d` (`d`) @@ -3058,7 +3058,7 @@ a2 /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS "t1 test"; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE "t1 test" ( "a1" int(11) DEFAULT NULL ); @@ -3087,7 +3087,7 @@ DELIMITER ; /*!50003 SET collation_connection = @saved_col_connection */ ; DROP TABLE IF EXISTS "t2 test"; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE "t2 test" ( "a2" int(11) DEFAULT NULL ); @@ -3142,7 +3142,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l USE `test`; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL, `b` varchar(32) DEFAULT NULL, @@ -3158,7 +3158,7 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `v0`; /*!50001 DROP VIEW IF EXISTS `v0`*/; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v0` AS SELECT 1 AS `a`, 1 AS `b`, @@ -3167,7 +3167,7 @@ SET character_set_client = @saved_cs_client; DROP TABLE IF EXISTS `v1`; /*!50001 DROP VIEW IF EXISTS `v1`*/; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v1` AS SELECT 1 AS `a`, 1 AS `b`, @@ -3176,7 +3176,7 @@ SET character_set_client = @saved_cs_client; DROP TABLE IF EXISTS `v2`; /*!50001 DROP VIEW IF EXISTS `v2`*/; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v2` AS SELECT 1 AS `a`, 1 AS `b`, @@ -3268,7 +3268,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l USE `test`; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -3328,7 +3328,7 @@ insert into t1 values ('',''); /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` binary(1) DEFAULT NULL, `b` blob DEFAULT NULL @@ -3364,7 +3364,7 @@ UNLOCK TABLES; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` binary(1) DEFAULT NULL, `b` blob DEFAULT NULL @@ -3549,7 +3549,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqldump_test_db` /*!40100 DEFAULT CH USE `mysqldump_test_db`; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `id` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -3563,7 +3563,7 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `v1`; /*!50001 DROP VIEW IF EXISTS `v1`*/; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v1` AS SELECT 1 AS `id` */; SET character_set_client = @saved_cs_client; @@ -3610,7 +3610,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqldump_tables` /*!40100 DEFAULT CHA USE `mysqldump_tables`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `basetable` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `tag` varchar(64) DEFAULT NULL, @@ -3622,7 +3622,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqldump_views` /*!40100 DEFAULT CHAR USE `mysqldump_views`; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `nasishnasifu` AS SELECT 1 AS `id` */; SET character_set_client = @saved_cs_client; @@ -3758,7 +3758,7 @@ use test; /*M!999999\- enable the sandbox mode */ DROP TABLE IF EXISTS `TABLES`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TEMPORARY TABLE `TABLES` ( `TABLE_CATALOG` varchar(512) NOT NULL, `TABLE_SCHEMA` varchar(64) NOT NULL, @@ -3834,14 +3834,14 @@ CREATE TABLE t1 (a INT) ENGINE=merge UNION=(t2, t3); /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci UNION=(`t2`,`t3`); /*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `t2`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t2` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -3853,7 +3853,7 @@ LOCK TABLES `t2` WRITE; UNLOCK TABLES; DROP TABLE IF EXISTS `t3`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t3` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -3946,7 +3946,7 @@ CREATE TABLE t1 (c1 INT, c2 LONGBLOB); INSERT INTO t1 SET c1=11, c2=REPEAT('q',509); /*M!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `c1` int(11) DEFAULT NULL, `c2` longblob DEFAULT NULL @@ -4034,7 +4034,7 @@ create view db42635.v2 (c) as select * from db42635.t1; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `id` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -4047,7 +4047,7 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `v2`; /*!50001 DROP VIEW IF EXISTS `v2`*/; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v2` AS SELECT 1 AS `c` */; SET character_set_client = @saved_cs_client; @@ -4184,7 +4184,7 @@ INSERT INTO t1 VALUES (3,4), (4,5); /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL @@ -4461,7 +4461,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqldump_test_db` /*!40100 DEFAULT CH USE `mysqldump_test_db`; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `id` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -4475,7 +4475,7 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `v1`; /*!50001 DROP VIEW IF EXISTS `v1`*/; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v1` AS SELECT 1 AS `id` */; SET character_set_client = @saved_cs_client; @@ -4573,7 +4573,7 @@ create table test (a int); /*M!999999\- enable the sandbox mode */ DROP TABLE IF EXISTS `test`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `test` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -4795,7 +4795,7 @@ ALTER DATABASE `test-database` CHARACTER SET latin1 COLLATE latin1_swedish_ci; ALTER DATABASE `test-database` CHARACTER SET utf8 COLLATE utf8_unicode_ci ; /*M!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `test` ( `c1` varchar(10) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; @@ -5286,7 +5286,7 @@ CREATE TABLE t1 (a INT); /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ); @@ -5565,20 +5565,20 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `db1` /*!40100 DEFAULT CHARACTER SET ut USE `db1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `basetable` ( `id` smallint(6) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; INSERT INTO `basetable` VALUES (5),(6); /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `nonunique_table_name` ( `i3` smallint(6) DEFAULT NULL ) ENGINE=MRG_MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci INSERT_METHOD=LAST UNION=(`basetable`); /*!40101 SET character_set_client = @saved_cs_client */; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `nonunique_table_view_name` AS SELECT 1 AS `1` */; SET character_set_client = @saved_cs_client; @@ -5587,7 +5587,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `db2` /*!40100 DEFAULT CHARACTER SET ut USE `db2`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `nonunique_table_name` ( `i1` bigint(20) unsigned NOT NULL AUTO_INCREMENT, UNIQUE KEY `i1` (`i1`) @@ -5595,7 +5595,7 @@ CREATE TABLE `nonunique_table_name` ( /*!40101 SET character_set_client = @saved_cs_client */; INSERT INTO `nonunique_table_name` VALUES (1),(2); /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `nonunique_table_view_name` ( `i2` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci; @@ -5624,7 +5624,7 @@ USE `db2`; /*M!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `nonunique_table_name` ( `i1` bigint(20) unsigned NOT NULL AUTO_INCREMENT, UNIQUE KEY `i1` (`i1`) @@ -5632,7 +5632,7 @@ CREATE TABLE `nonunique_table_name` ( /*!40101 SET character_set_client = @saved_cs_client */; INSERT INTO `nonunique_table_name` VALUES (1),(2); /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `nonunique_table_view_name` ( `i2` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci; @@ -5647,7 +5647,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `db2` /*!40100 DEFAULT CHARACTER SET ut USE `db2`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `nonunique_table_name` ( `i1` bigint(20) unsigned NOT NULL AUTO_INCREMENT, UNIQUE KEY `i1` (`i1`) @@ -5655,7 +5655,7 @@ CREATE TABLE `nonunique_table_name` ( /*!40101 SET character_set_client = @saved_cs_client */; INSERT DELAYED INTO `nonunique_table_name` VALUES (1),(2); /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `nonunique_table_view_name` ( `i2` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci; @@ -5666,21 +5666,21 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `db1` /*!40100 DEFAULT CHARACTER SET ut USE `db1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `basetable` ( `id` smallint(6) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; INSERT DELAYED INTO `basetable` VALUES (5),(6); /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `nonunique_table_name` ( `i3` smallint(6) DEFAULT NULL ) ENGINE=MRG_MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci INSERT_METHOD=LAST UNION=(`basetable`); /*!40101 SET character_set_client = @saved_cs_client */; INSERT INTO `nonunique_table_name` VALUES (5),(6); SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `nonunique_table_view_name` AS SELECT 1 AS `1` */; SET character_set_client = @saved_cs_client; @@ -5827,7 +5827,7 @@ DROP TABLE t1; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE IF NOT EXISTS `general_log` ( `event_time` timestamp(6) NOT NULL DEFAULT current_timestamp(6) ON UPDATE current_timestamp(6), `user_host` mediumtext NOT NULL, @@ -5838,7 +5838,7 @@ CREATE TABLE IF NOT EXISTS `general_log` ( ) ENGINE=CSV DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='General log'; /*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE IF NOT EXISTS `slow_log` ( `start_time` timestamp(6) NOT NULL DEFAULT current_timestamp(6) ON UPDATE current_timestamp(6), `user_host` mediumtext NOT NULL, @@ -5857,7 +5857,7 @@ CREATE TABLE IF NOT EXISTS `slow_log` ( /*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `innodb_index_stats`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `innodb_index_stats` ( `database_name` varchar(64) NOT NULL, `table_name` varchar(199) NOT NULL, @@ -5872,7 +5872,7 @@ CREATE TABLE `innodb_index_stats` ( /*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `innodb_table_stats`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `innodb_table_stats` ( `database_name` varchar(64) NOT NULL, `table_name` varchar(199) NOT NULL, @@ -5884,7 +5884,7 @@ CREATE TABLE `innodb_table_stats` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin STATS_PERSISTENT=0; /*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE IF NOT EXISTS `transaction_registry` ( `transaction_id` bigint(20) unsigned NOT NULL, `commit_id` bigint(20) unsigned NOT NULL, @@ -5923,7 +5923,7 @@ CREATE TABLE IF NOT EXISTS `transaction_registry` ( /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE IF NOT EXISTS `general_log` ( `event_time` timestamp(6) NOT NULL DEFAULT current_timestamp(6) ON UPDATE current_timestamp(6), `user_host` mediumtext NOT NULL, @@ -5934,7 +5934,7 @@ CREATE TABLE IF NOT EXISTS `general_log` ( ) ENGINE=CSV DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='General log'; /*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE IF NOT EXISTS `slow_log` ( `start_time` timestamp(6) NOT NULL DEFAULT current_timestamp(6) ON UPDATE current_timestamp(6), `user_host` mediumtext NOT NULL, @@ -5953,7 +5953,7 @@ CREATE TABLE IF NOT EXISTS `slow_log` ( /*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `innodb_index_stats`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `innodb_index_stats` ( `database_name` varchar(64) NOT NULL, `table_name` varchar(199) NOT NULL, @@ -5973,7 +5973,7 @@ LOCK TABLES `innodb_index_stats` WRITE; UNLOCK TABLES; DROP TABLE IF EXISTS `innodb_table_stats`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `innodb_table_stats` ( `database_name` varchar(64) NOT NULL, `table_name` varchar(199) NOT NULL, @@ -5990,7 +5990,7 @@ LOCK TABLES `innodb_table_stats` WRITE; /*!40000 ALTER TABLE `innodb_table_stats` ENABLE KEYS */; UNLOCK TABLES; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE IF NOT EXISTS `transaction_registry` ( `transaction_id` bigint(20) unsigned NOT NULL, `commit_id` bigint(20) unsigned NOT NULL, @@ -6029,7 +6029,7 @@ CREATE TABLE IF NOT EXISTS `transaction_registry` ( /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE IF NOT EXISTS `general_log` ( `event_time` timestamp(6) NOT NULL DEFAULT current_timestamp(6) ON UPDATE current_timestamp(6), `user_host` mediumtext NOT NULL, @@ -6040,7 +6040,7 @@ CREATE TABLE IF NOT EXISTS `general_log` ( ) ENGINE=CSV DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='General log'; /*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE IF NOT EXISTS `slow_log` ( `start_time` timestamp(6) NOT NULL DEFAULT current_timestamp(6) ON UPDATE current_timestamp(6), `user_host` mediumtext NOT NULL, @@ -6059,7 +6059,7 @@ CREATE TABLE IF NOT EXISTS `slow_log` ( /*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `innodb_index_stats`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `innodb_index_stats` ( `database_name` varchar(64) NOT NULL, `table_name` varchar(199) NOT NULL, @@ -6079,7 +6079,7 @@ LOCK TABLES `innodb_index_stats` WRITE; UNLOCK TABLES; DROP TABLE IF EXISTS `innodb_table_stats`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `innodb_table_stats` ( `database_name` varchar(64) NOT NULL, `table_name` varchar(199) NOT NULL, @@ -6096,7 +6096,7 @@ LOCK TABLES `innodb_table_stats` WRITE; /*!40000 ALTER TABLE `innodb_table_stats` ENABLE KEYS */; UNLOCK TABLES; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE IF NOT EXISTS `transaction_registry` ( `transaction_id` bigint(20) unsigned NOT NULL, `commit_id` bigint(20) unsigned NOT NULL, @@ -6143,7 +6143,7 @@ CREATE TABLE t4(ËÏÌÏÎËÁ1 INT); insert into t4 values(1); /*M!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL, `b` int(11) INVISIBLE DEFAULT NULL @@ -6151,7 +6151,7 @@ CREATE TABLE `t1` ( /*!40101 SET character_set_client = @saved_cs_client */; INSERT INTO `t1` (`a`, `b`) VALUES (1,NULL),(1,2); /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t2` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL @@ -6159,7 +6159,7 @@ CREATE TABLE `t2` ( /*!40101 SET character_set_client = @saved_cs_client */; INSERT INTO `t2` VALUES (1,2),(1,2); /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t3` ( `invisible` int(11) DEFAULT NULL, `a b c & $!@#$%^&*( )` int(11) INVISIBLE DEFAULT 4, @@ -6168,7 +6168,7 @@ CREATE TABLE `t3` ( /*!40101 SET character_set_client = @saved_cs_client */; INSERT INTO `t3` (`invisible`, `a b c & $!@#$%^&*( )`, `ds=~!@ \# $% ^ & * ( ) _ - = +`) VALUES (1,4,5),(5,4,5),(2,4,5),(1,2,3); /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t4` ( `ËÏÌÏÎËÁ1` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -6177,7 +6177,7 @@ INSERT INTO `t4` VALUES (1); #Check side effect on --complete insert /*M!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL, `b` int(11) INVISIBLE DEFAULT NULL @@ -6185,7 +6185,7 @@ CREATE TABLE `t1` ( /*!40101 SET character_set_client = @saved_cs_client */; INSERT INTO `t1` (`a`, `b`) VALUES (1,NULL),(1,2); /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t2` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL @@ -6193,7 +6193,7 @@ CREATE TABLE `t2` ( /*!40101 SET character_set_client = @saved_cs_client */; INSERT INTO `t2` (`a`, `b`) VALUES (1,2),(1,2); /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t3` ( `invisible` int(11) DEFAULT NULL, `a b c & $!@#$%^&*( )` int(11) INVISIBLE DEFAULT 4, @@ -6202,7 +6202,7 @@ CREATE TABLE `t3` ( /*!40101 SET character_set_client = @saved_cs_client */; INSERT INTO `t3` (`invisible`, `a b c & $!@#$%^&*( )`, `ds=~!@ \# $% ^ & * ( ) _ - = +`) VALUES (1,4,5),(5,4,5),(2,4,5),(1,2,3); /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t4` ( `ËÏÌÏÎËÁ1` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -6529,7 +6529,7 @@ update mysql.event set body ='select not_a_value' where db='test' and name='e1'; create table t1 (i int); /*M!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `i` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -6583,7 +6583,7 @@ create table t1 (a int); /*M!999999\- enable the sandbox mode */ DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; diff --git a/mysql-test/main/openssl_1.result b/mysql-test/main/openssl_1.result index bfe79a9df85..b90dc76f401 100644 --- a/mysql-test/main/openssl_1.result +++ b/mysql-test/main/openssl_1.result @@ -91,7 +91,7 @@ INSERT INTO t1 VALUES (1), (2); /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ); @@ -126,7 +126,7 @@ UNLOCK TABLES; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ); @@ -161,7 +161,7 @@ UNLOCK TABLES; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ); diff --git a/mysql-test/main/trigger_wl3253.result b/mysql-test/main/trigger_wl3253.result index 8d4de24d4e0..54cc51a0e58 100644 --- a/mysql-test/main/trigger_wl3253.result +++ b/mysql-test/main/trigger_wl3253.result @@ -312,7 +312,7 @@ CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=2; CREATE TRIGGER tr1_bu BEFORE UPDATE ON t1 FOR EACH ROW SET @a:=3; /*M!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; @@ -375,7 +375,7 @@ CREATE TRIGGER tr1_1_bi BEFORE INSERT ON t1 FOR EACH ROW FOLLOWS tr1_bi SET @a:= # Expected order of triggers in the dump is: tr0_bi, tr1_bi, tr1_1_bi, tr2_i. /*M!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; diff --git a/mysql-test/suite/compat/oracle/r/mysqldump_restore_func_qualified.result b/mysql-test/suite/compat/oracle/r/mysqldump_restore_func_qualified.result index 26468bd2415..c772c2e1eae 100644 --- a/mysql-test/suite/compat/oracle/r/mysqldump_restore_func_qualified.result +++ b/mysql-test/suite/compat/oracle/r/mysqldump_restore_func_qualified.result @@ -26,7 +26,7 @@ LTRIM(now()) AS a0, LPAD(now(),10) AS b0; /*M!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a0` varchar(64) NOT NULL DEFAULT ltrim(current_timestamp()), `a1` varchar(64) GENERATED ALWAYS AS (ltrim(`a0`)) STORED, @@ -35,7 +35,7 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t2` ( `a0` varchar(64) NOT NULL DEFAULT ltrim_oracle(current_timestamp()), `a1` varchar(64) GENERATED ALWAYS AS (ltrim_oracle(`a0`)) STORED, @@ -44,13 +44,13 @@ CREATE TABLE `t2` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v1` AS SELECT 1 AS `a0`, 1 AS `b0` */; SET character_set_client = @saved_cs_client; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v2` AS SELECT 1 AS `a0`, 1 AS `b0` */; diff --git a/mysql-test/suite/federated/federatedx.result b/mysql-test/suite/federated/federatedx.result index 1d757dceb93..7f815c1a61c 100644 --- a/mysql-test/suite/federated/federatedx.result +++ b/mysql-test/suite/federated/federatedx.result @@ -2245,7 +2245,7 @@ CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1'; # Dump table t1 using mysqldump tool /*M!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `id` varchar(20) NOT NULL, PRIMARY KEY (`id`) diff --git a/mysql-test/suite/roles/definer.result b/mysql-test/suite/roles/definer.result index 98cf82fc39b..5939dcf2cec 100644 --- a/mysql-test/suite/roles/definer.result +++ b/mysql-test/suite/roles/definer.result @@ -280,32 +280,32 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l USE `test`; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v1` AS SELECT 1 AS `a+b`, 1 AS `c` */; SET character_set_client = @saved_cs_client; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v2` AS SELECT 1 AS `a+b`, 1 AS `c`, 1 AS `current_role()` */; SET character_set_client = @saved_cs_client; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v3` AS SELECT 1 AS `a+b`, 1 AS `c` */; SET character_set_client = @saved_cs_client; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v4` AS SELECT 1 AS `a+b`, 1 AS `c` */; SET character_set_client = @saved_cs_client; SET @saved_cs_client = @@character_set_client; -SET character_set_client = utf8; +SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v5` AS SELECT 1 AS `a+b`, 1 AS `c` */; @@ -315,7 +315,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1` /*!40100 DEFAULT CHARACTER USE `mysqltest1`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, @@ -324,7 +324,7 @@ CREATE TABLE `t1` ( /*!40101 SET character_set_client = @saved_cs_client */; INSERT INTO `t1` VALUES (1,10,100),(2,20,200); /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t2` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, diff --git a/mysql-test/suite/sql_sequence/mysqldump.result b/mysql-test/suite/sql_sequence/mysqldump.result index e56162a434c..69817b42ec9 100644 --- a/mysql-test/suite/sql_sequence/mysqldump.result +++ b/mysql-test/suite/sql_sequence/mysqldump.result @@ -9,7 +9,7 @@ DO SETVAL(`a1`, 1, 0); CREATE SEQUENCE `x1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=InnoDB; DO SETVAL(`x1`, 1, 0); /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL, KEY `a` (`a`) @@ -23,7 +23,7 @@ DO SETVAL(`a1`, 1, 0); CREATE SEQUENCE `x1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=InnoDB; DO SETVAL(`x1`, 1, 0); /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL, KEY `a` (`a`) @@ -37,7 +37,7 @@ DO SETVAL(`a1`, 1, 0); CREATE SEQUENCE `x1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=InnoDB; DO SETVAL(`x1`, 1, 0); /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL, KEY `a` (`a`) @@ -47,7 +47,7 @@ INSERT INTO `t1` VALUES (1),(2); # dump by tables only tables /*M!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL, KEY `a` (`a`) diff --git a/sql/item.cc b/sql/item.cc index e6e69629fe5..7143bced98b 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3936,7 +3936,7 @@ void Item_string::print(String *str, enum_query_type query_type) } else { - str_value.print(str, system_charset_info); + str_value.print(str, &my_charset_utf8mb4_general_ci); } } else diff --git a/sql/sql_show.cc b/sql/sql_show.cc index dff2a9c73da..7f03debcffb 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1289,7 +1289,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) { Protocol *protocol= thd->protocol; char buff[2048]; - String buffer(buff, sizeof(buff), system_charset_info); + String buffer(buff, sizeof(buff), &my_charset_utf8mb4_general_ci); List field_list; bool error= TRUE; DBUG_ENTER("mysqld_show_create"); @@ -1709,7 +1709,7 @@ static bool get_field_default_value(THD *thd, Field *field, String *def_value, def_value->length(0); if (has_default) { - StringBuffer str(field->charset()); + StringBuffer str(&my_charset_utf8mb4_general_ci); if (field->default_value) { field->default_value->print(&str); @@ -2236,11 +2236,11 @@ int show_create_table_ex(THD *thd, TABLE_LIST *table_list, { packet->append(STRING_WITH_LEN(" INVISIBLE")); } - def_value.set(def_value_buf, sizeof(def_value_buf), system_charset_info); + def_value.set(def_value_buf, sizeof(def_value_buf), &my_charset_utf8mb4_general_ci); if (get_field_default_value(thd, field, &def_value, 1)) { packet->append(STRING_WITH_LEN(" DEFAULT ")); - packet->append(def_value.ptr(), def_value.length(), system_charset_info); + packet->append(def_value.ptr(), def_value.length(), &my_charset_utf8mb4_general_ci); } if (field->vers_update_unversioned()) diff --git a/storage/connect/mysql-test/connect/r/mysql.result b/storage/connect/mysql-test/connect/r/mysql.result index 6e61fe3f4d7..93f68f5aad9 100644 --- a/storage/connect/mysql-test/connect/r/mysql.result +++ b/storage/connect/mysql-test/connect/r/mysql.result @@ -231,7 +231,7 @@ a # Start of mysqldump ------ /*M!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t2` ( `a` int(11) DEFAULT NULL ) ENGINE=CONNECT DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci CONNECTION='mysql://root@localhost:PORT/test/t1' `TABLE_TYPE`='MYSQL'; From b22eacc976d805bdaa8693a938c210082a773b11 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 17 Jan 2025 14:16:41 +0100 Subject: [PATCH 097/213] fix sporadic failures of main.alter_table_online progress updates aren't deterministic, occasionally they can be skipped (if `LOCK_thd_data` is locked). This isn't a problem as such, but breaks tests that wait for a specific value of the progress (and threads waiting for a specific value of the progress, exactly, lock `LOCK_thd_data` which prevents the progress from being updated) In this particular case, though, there is no need to wait for progress = 100, because "Waiting for table metadata lock" happens only at the end of stage = 4 anyway. --- mysql-test/main/alter_table_online.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/main/alter_table_online.test b/mysql-test/main/alter_table_online.test index 7843c90efd1..6416a3e79d1 100644 --- a/mysql-test/main/alter_table_online.test +++ b/mysql-test/main/alter_table_online.test @@ -266,7 +266,7 @@ send alter table t1 add b int NULL, algorithm= copy, lock= none; --connection con2 evalp set @con= $con; -let $wait_condition= select stage = 4 and progress = 100 +let $wait_condition= select stage = 4 and state= "Waiting for table metadata lock" from information_schema.processlist where id = @con; --source include/wait_condition.inc From a69da0c31e97109bba099022acdd393f92fa127f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 23 Dec 2024 21:27:00 +0100 Subject: [PATCH 098/213] MDEV-19761 Before Trigger not processed for Not Null Columns if no explicit value and no DEFAULT it's incorrect to zero out table->triggers->extra_null_bitmap before a statement, because if insert uses an explicit field list and omits a field that has no default value, the field should get NULL implicitly. So extra_null_bitmap should have 1s for all fields that have no defaults * create extra_null_bitmap_init and initialize it as above * copy extra_null_bitmap_init to extra_null_bitmap for inserts * still zero out extra_null_bitmap for updates/deletes where all fields definitely have a value * make not_null_fields_have_null_values() to send ER_NO_DEFAULT_FOR_FIELD for fields with no default and no value, otherwise creation of a trigger with an empty body would change the error message --- .../main/trigger_no_defaults-11698.result | 2 +- .../main/trigger_no_defaults-11698.test | 2 +- mysql-test/main/trigger_null-8605.result | 25 +++++++++ mysql-test/main/trigger_null-8605.test | 25 +++++++++ sql/field.h | 2 +- sql/field_conv.cc | 8 +-- sql/sql_base.cc | 9 +++- sql/sql_delete.cc | 4 +- sql/sql_insert.cc | 26 ++-------- sql/sql_insert.h | 7 +++ sql/sql_load.cc | 9 ++-- sql/sql_trigger.cc | 9 +++- sql/sql_trigger.h | 18 ++++--- sql/sql_update.cc | 4 +- sql/table.cc | 51 ++++++++++--------- 15 files changed, 127 insertions(+), 74 deletions(-) diff --git a/mysql-test/main/trigger_no_defaults-11698.result b/mysql-test/main/trigger_no_defaults-11698.result index 8ce495eaf3a..443bf15bb63 100644 --- a/mysql-test/main/trigger_no_defaults-11698.result +++ b/mysql-test/main/trigger_no_defaults-11698.result @@ -15,10 +15,10 @@ insert t1 (b) values (10); insert t1 (b) values (20); ERROR HY000: Field 'a' doesn't have a default value insert t1 (b) values (30); +ERROR 23000: Column 'a' cannot be null select * from t1; a b 10 10 -0 30 drop table t1; set sql_mode=default; set sql_mode=''; diff --git a/mysql-test/main/trigger_no_defaults-11698.test b/mysql-test/main/trigger_no_defaults-11698.test index c10bec68314..86a7a436ad0 100644 --- a/mysql-test/main/trigger_no_defaults-11698.test +++ b/mysql-test/main/trigger_no_defaults-11698.test @@ -19,7 +19,7 @@ delimiter ;| insert t1 (b) values (10); --error ER_NO_DEFAULT_FOR_FIELD insert t1 (b) values (20); -# arguably the statement below should fail too +--error ER_BAD_NULL_ERROR insert t1 (b) values (30); select * from t1; drop table t1; diff --git a/mysql-test/main/trigger_null-8605.result b/mysql-test/main/trigger_null-8605.result index 10315988708..6480fbf9a7e 100644 --- a/mysql-test/main/trigger_null-8605.result +++ b/mysql-test/main/trigger_null-8605.result @@ -364,3 +364,28 @@ create trigger tr before update on t1 for each row set @a = 1; insert into t1 (pk, i) values (null, null); ERROR 23000: Column 'pk' cannot be null drop table t1; +# +# MDEV-19761 Before Trigger not processed for Not Null Columns if no explicit value and no DEFAULT +# +create table t1( id int, rate int not null); +create trigger test_trigger before insert on t1 for each row +set new.rate=if(new.rate is null,10,new.rate); +insert into t1 (id) values (1); +insert into t1 values (2,3); +select * from t1; +id rate +1 10 +2 3 +create or replace trigger test_trigger before insert on t1 for each row +if new.rate is null then set new.rate = 15; end if; +$$ +insert into t1 (id) values (3); +insert into t1 values (4,5); +select * from t1; +id rate +1 10 +2 3 +3 15 +4 5 +drop table t1; +# End of 10.5 tests diff --git a/mysql-test/main/trigger_null-8605.test b/mysql-test/main/trigger_null-8605.test index 7645b61f5ad..e33f17151bf 100644 --- a/mysql-test/main/trigger_null-8605.test +++ b/mysql-test/main/trigger_null-8605.test @@ -391,3 +391,28 @@ create trigger tr before update on t1 for each row set @a = 1; --error ER_BAD_NULL_ERROR insert into t1 (pk, i) values (null, null); drop table t1; + +--echo # +--echo # MDEV-19761 Before Trigger not processed for Not Null Columns if no explicit value and no DEFAULT +--echo # +create table t1( id int, rate int not null); +create trigger test_trigger before insert on t1 for each row + set new.rate=if(new.rate is null,10,new.rate); + +insert into t1 (id) values (1); +insert into t1 values (2,3); +select * from t1; + +delimiter $$; +create or replace trigger test_trigger before insert on t1 for each row + if new.rate is null then set new.rate = 15; end if; +$$ +delimiter ;$$ + +insert into t1 (id) values (3); +insert into t1 values (4,5); +select * from t1; + +drop table t1; + +--echo # End of 10.5 tests diff --git a/sql/field.h b/sql/field.h index 3894c22e6da..09b9f895273 100644 --- a/sql/field.h +++ b/sql/field.h @@ -5846,7 +5846,7 @@ uint pack_length_to_packflag(uint type); enum_field_types get_blob_type_from_length(ulong length); int set_field_to_null(Field *field); int set_field_to_null_with_conversions(Field *field, bool no_conversions); -int convert_null_to_field_value_or_error(Field *field); +int convert_null_to_field_value_or_error(Field *field, uint err); bool check_expression(Virtual_column_info *vcol, const LEX_CSTRING *name, enum_vcol_info_type type, Alter_info *alter_info= NULL); diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 92e7551c00b..dcbb6b39a31 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -126,7 +126,7 @@ static int set_bad_null_error(Field *field, int err) return 0; case CHECK_FIELD_ERROR_FOR_NULL: if (!field->table->in_use->no_errors) - my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name.str); + my_error(err, MYF(0), field->field_name.str); return -1; } DBUG_ASSERT(0); // impossible @@ -164,7 +164,7 @@ int set_field_to_null(Field *field) If no_conversion was not set, an error message is printed */ -int convert_null_to_field_value_or_error(Field *field) +int convert_null_to_field_value_or_error(Field *field, uint err) { if (field->type() == MYSQL_TYPE_TIMESTAMP) { @@ -179,7 +179,7 @@ int convert_null_to_field_value_or_error(Field *field) field->table->auto_increment_field_not_null= FALSE; return 0; // field is set in fill_record() } - return set_bad_null_error(field, ER_BAD_NULL_ERROR); + return set_bad_null_error(field, err); } /** @@ -216,7 +216,7 @@ set_field_to_null_with_conversions(Field *field, bool no_conversions) if (no_conversions) return -1; - return convert_null_to_field_value_or_error(field); + return convert_null_to_field_value_or_error(field, ER_BAD_NULL_ERROR); } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index aaa86e7bfa0..bb73dcef975 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -8622,7 +8622,6 @@ void switch_to_nullable_trigger_fields(List &items, TABLE *table) while ((item= it++)) item->walk(&Item::switch_to_nullable_fields_processor, 1, field); - table->triggers->reset_extra_null_bitmap(); } } @@ -8676,8 +8675,14 @@ static bool not_null_fields_have_null_values(TABLE *table) swap_variables(uint32, of->flags, ff->flags); if (ff->is_real_null()) { + uint err= ER_BAD_NULL_ERROR; + if (ff->flags & NO_DEFAULT_VALUE_FLAG && !ff->has_explicit_value()) + { + err= ER_NO_DEFAULT_FOR_FIELD; + table->in_use->count_cuted_fields= CHECK_FIELD_WARN; + } ff->set_notnull(); // for next row WHERE condition in UPDATE - if (convert_null_to_field_value_or_error(of) || thd->is_error()) + if (convert_null_to_field_value_or_error(of, err) || thd->is_error()) return true; } } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index fa677feb551..d85a04aa9bb 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -722,8 +722,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, table->mark_columns_needed_for_delete(); } - if ((table->file->ha_table_flags() & HA_CAN_FORCE_BULK_DELETE) && - !table->prepare_triggers_for_delete_stmt_or_event()) + if (!table->prepare_triggers_for_delete_stmt_or_event() && + table->file->ha_table_flags() & HA_CAN_FORCE_BULK_DELETE) will_batch= !table->file->start_bulk_delete(); /* diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index acc841e27f0..2a978640122 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1019,7 +1019,7 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list, INSERT INTO t1 (fields) VALUES ... INSERT INTO t1 VALUES () */ - restore_record(table,s->default_values); // Get empty record + restore_default_record_for_insert(table); table->reset_default_fields(); if (unlikely(fill_record_n_invoke_before_triggers(thd, table, fields, @@ -1048,7 +1048,7 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list, */ if (thd->lex->used_tables || // Column used in values() table->s->visible_fields != table->s->fields) - restore_record(table,s->default_values); // Get empty record + restore_default_record_for_insert(table); else { TABLE_SHARE *share= table->s; @@ -1085,24 +1085,6 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list, } } - /* - with triggers a field can get a value *conditionally*, so we have to - repeat has_no_default_value() check for every row - */ - if (table->triggers && - table->triggers->has_triggers(TRG_EVENT_INSERT, TRG_ACTION_BEFORE)) - { - for (Field **f=table->field ; *f ; f++) - { - if (unlikely(!(*f)->has_explicit_value() && - has_no_default_value(thd, *f, table_list))) - { - error= 1; - goto values_loop_end; - } - } - } - if ((res= table_list->view_check_option(thd, (values_list.elements == 1 ? 0 : @@ -4081,7 +4063,7 @@ select_insert::prepare(List &values, SELECT_LEX_UNIT *u) */ table->file->ha_start_bulk_insert((ha_rows) 0); } - restore_record(table,s->default_values); // Get empty record + restore_default_record_for_insert(table); table->reset_default_fields(); table->next_number_field=table->found_next_number_field; @@ -4226,7 +4208,7 @@ int select_insert::send_data(List &values) originally touched by INSERT ... SELECT, so we have to restore their original values for the next row. */ - restore_record(table, s->default_values); + restore_default_record_for_insert(table); } if (table->next_number_field) { diff --git a/sql/sql_insert.h b/sql/sql_insert.h index 80666a81c50..9aa234b715e 100644 --- a/sql/sql_insert.h +++ b/sql/sql_insert.h @@ -46,6 +46,13 @@ void kill_delayed_threads(void); bool binlog_create_table(THD *thd, TABLE *table, bool replace); bool binlog_drop_table(THD *thd, TABLE *table); +static inline void restore_default_record_for_insert(TABLE *t) +{ + restore_record(t,s->default_values); + if (t->triggers) + t->triggers->default_extra_null_bitmap(); +} + #ifdef EMBEDDED_LIBRARY inline void kill_delayed_threads(void) {} #endif diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 3ccb6f48994..778ee498e41 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -23,7 +23,6 @@ #include "sql_priv.h" #include "unireg.h" #include "sql_load.h" -#include "sql_load.h" #include "sql_cache.h" // query_cache_* #include "sql_base.h" // fill_record_n_invoke_before_triggers #include @@ -1004,8 +1003,7 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, read_info.row_end[0]=0; #endif - restore_record(table, s->default_values); - + restore_default_record_for_insert(table); while ((item= it++)) { Load_data_outvar *dst= item->get_load_data_outvar(); @@ -1118,8 +1116,8 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, thd->progress.max_counter); } } - restore_record(table, s->default_values); + restore_default_record_for_insert(table); while ((item= it++)) { uint length; @@ -1273,8 +1271,7 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, } #endif - restore_record(table, s->default_values); - + restore_default_record_for_insert(table); while ((item= it++)) { /* If this line is to be skipped we don't want to fill field or var */ diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index f35a07347fe..f85faff37ac 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -1297,8 +1297,9 @@ bool Table_triggers_list::prepare_record_accessors(TABLE *table) { int null_bytes= (table->s->fields - table->s->null_fields + 7)/8; - if (!(extra_null_bitmap= (uchar*)alloc_root(&table->mem_root, null_bytes))) + if (!(extra_null_bitmap= (uchar*)alloc_root(&table->mem_root, 2*null_bytes))) return 1; + extra_null_bitmap_init= extra_null_bitmap + null_bytes; if (!(record0_field= (Field **)alloc_root(&table->mem_root, (table->s->fields + 1) * sizeof(Field*)))) @@ -1323,13 +1324,17 @@ bool Table_triggers_list::prepare_record_accessors(TABLE *table) null_ptr++, null_bit= 1; else null_bit*= 2; + if (f->flags & NO_DEFAULT_VALUE_FLAG) + f->set_null(); + else + f->set_notnull(); } else *trg_fld= *fld; } *trg_fld= 0; DBUG_ASSERT(null_ptr <= extra_null_bitmap + null_bytes); - bzero(extra_null_bitmap, null_bytes); + memcpy(extra_null_bitmap_init, extra_null_bitmap, null_bytes); } else { diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h index 101784ee776..685f4d15b3b 100644 --- a/sql/sql_trigger.h +++ b/sql/sql_trigger.h @@ -147,7 +147,7 @@ class Table_triggers_list: public Sql_alloc BEFORE INSERT/UPDATE triggers. */ Field **record0_field; - uchar *extra_null_bitmap; + uchar *extra_null_bitmap, *extra_null_bitmap_init; /** Copy of TABLE::Field array with field pointers set to TABLE::record[1] buffer instead of TABLE::record[0] (used for OLD values in on UPDATE @@ -211,8 +211,8 @@ public: /* End of character ser context. */ Table_triggers_list(TABLE *table_arg) - :record0_field(0), extra_null_bitmap(0), record1_field(0), - trigger_table(table_arg), + :record0_field(0), extra_null_bitmap(0), extra_null_bitmap_init(0), + record1_field(0), trigger_table(table_arg), m_has_unparseable_trigger(false), count(0) { bzero((char *) triggers, sizeof(triggers)); @@ -276,11 +276,15 @@ public: TABLE_LIST *table_list); Field **nullable_fields() { return record0_field; } - void reset_extra_null_bitmap() + void clear_extra_null_bitmap() { - size_t null_bytes= (trigger_table->s->fields - - trigger_table->s->null_fields + 7)/8; - bzero(extra_null_bitmap, null_bytes); + if (size_t null_bytes= extra_null_bitmap_init - extra_null_bitmap) + bzero(extra_null_bitmap, null_bytes); + } + void default_extra_null_bitmap() + { + if (size_t null_bytes= extra_null_bitmap_init - extra_null_bitmap) + memcpy(extra_null_bitmap, extra_null_bitmap_init, null_bytes); } Trigger *find_trigger(const LEX_CSTRING *name, bool remove_from_list); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 9dfb681b119..f2cea510ce7 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -996,8 +996,8 @@ update_begin: goto update_end; } - if ((table->file->ha_table_flags() & HA_CAN_FORCE_BULK_UPDATE) && - !table->prepare_triggers_for_update_stmt_or_event()) + if (!table->prepare_triggers_for_update_stmt_or_event() && + table->file->ha_table_flags() & HA_CAN_FORCE_BULK_UPDATE) will_batch= !table->file->start_bulk_update(); /* diff --git a/sql/table.cc b/sql/table.cc index b18ee64f480..0aad7ae24e1 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -9140,8 +9140,8 @@ void TABLE::prepare_triggers_for_insert_stmt_or_event() { if (triggers) { - if (triggers->has_triggers(TRG_EVENT_DELETE, - TRG_ACTION_AFTER)) + triggers->clear_extra_null_bitmap(); + if (triggers->has_triggers(TRG_EVENT_DELETE, TRG_ACTION_AFTER)) { /* The table has AFTER DELETE triggers that might access to @@ -9150,8 +9150,7 @@ void TABLE::prepare_triggers_for_insert_stmt_or_event() */ (void) file->extra(HA_EXTRA_DELETE_CANNOT_BATCH); } - if (triggers->has_triggers(TRG_EVENT_UPDATE, - TRG_ACTION_AFTER)) + if (triggers->has_triggers(TRG_EVENT_UPDATE, TRG_ACTION_AFTER)) { /* The table has AFTER UPDATE triggers that might access to subject @@ -9166,17 +9165,19 @@ void TABLE::prepare_triggers_for_insert_stmt_or_event() bool TABLE::prepare_triggers_for_delete_stmt_or_event() { - if (triggers && - triggers->has_triggers(TRG_EVENT_DELETE, - TRG_ACTION_AFTER)) + if (triggers) { - /* - The table has AFTER DELETE triggers that might access to subject table - and therefore might need delete to be done immediately. So we turn-off - the batching. - */ - (void) file->extra(HA_EXTRA_DELETE_CANNOT_BATCH); - return TRUE; + triggers->clear_extra_null_bitmap(); + if (triggers->has_triggers(TRG_EVENT_DELETE, TRG_ACTION_AFTER)) + { + /* + The table has AFTER DELETE triggers that might access to subject table + and therefore might need delete to be done immediately. So we turn-off + the batching. + */ + (void) file->extra(HA_EXTRA_DELETE_CANNOT_BATCH); + return TRUE; + } } return FALSE; } @@ -9184,17 +9185,19 @@ bool TABLE::prepare_triggers_for_delete_stmt_or_event() bool TABLE::prepare_triggers_for_update_stmt_or_event() { - if (triggers && - triggers->has_triggers(TRG_EVENT_UPDATE, - TRG_ACTION_AFTER)) + if (triggers) { - /* - The table has AFTER UPDATE triggers that might access to subject - table and therefore might need update to be done immediately. - So we turn-off the batching. - */ - (void) file->extra(HA_EXTRA_UPDATE_CANNOT_BATCH); - return TRUE; + triggers->clear_extra_null_bitmap(); + if (triggers->has_triggers(TRG_EVENT_UPDATE, TRG_ACTION_AFTER)) + { + /* + The table has AFTER UPDATE triggers that might access to subject + table and therefore might need update to be done immediately. + So we turn-off the batching. + */ + (void) file->extra(HA_EXTRA_UPDATE_CANNOT_BATCH); + return TRUE; + } } return FALSE; } From b87c1b06dceaa8f7db7fc900931829aef4421713 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 18 Jan 2025 08:10:49 +0100 Subject: [PATCH 099/213] MDEV-29968 update test results followup for 350cc77fee66 --- mysql-test/suite/s3/mysqldump.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/s3/mysqldump.result b/mysql-test/suite/s3/mysqldump.result index 78d97874c87..47adac57e23 100644 --- a/mysql-test/suite/s3/mysqldump.result +++ b/mysql-test/suite/s3/mysqldump.result @@ -18,7 +18,7 @@ alter table t1 engine=S3; ### /*M!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `pk` int(11) NOT NULL, `a` int(11) DEFAULT NULL, From 653f68784a704179223e1a2d63cebd65fe723ec6 Mon Sep 17 00:00:00 2001 From: Monty Date: Fri, 17 Jan 2025 11:29:01 +0200 Subject: [PATCH 100/213] MDEV-35865 atomic.alter_table times out often The problem was that get_collation_number_internal() loops over all collations for finding a collation based on name. For looking up utf8mb4_0900_ aliases it used 22633 character strings comparisons at startup. Fixed by adding the MariaDB internal collation number in the "0900" alias lookup array. This is fine as collation numbers never changes. Discussed-with: serg@mariadb.com --- include/my_sys.h | 4 +- mysys/charset.c | 14 +++-- strings/ctype-uca.c | 123 +++++++++++++++++++++++--------------------- 3 files changed, 76 insertions(+), 65 deletions(-) diff --git a/include/my_sys.h b/include/my_sys.h index 61401f7e1a3..65409698e7e 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -1121,8 +1121,8 @@ extern my_bool init_compiled_charsets(myf flags); extern void add_compiled_collation(struct charset_info_st *cs); extern void add_compiled_extra_collation(struct charset_info_st *cs); extern my_bool add_alias_for_collation(LEX_CSTRING *collation_name, - LEX_CSTRING *alias, - uint alias_id); + uint collation_id, + LEX_CSTRING *alias, uint alias_id); extern size_t escape_string_for_mysql(CHARSET_INFO *charset_info, char *to, size_t to_length, const char *from, size_t length, diff --git a/mysys/charset.c b/mysys/charset.c index 23f11ad4d61..8918bb1b2ac 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -646,8 +646,8 @@ void add_compiled_extra_collation(struct charset_info_st *cs) corresponding utf8mb4_1400 collation */ -my_bool add_alias_for_collation(LEX_CSTRING *collation_name, LEX_CSTRING *alias, - uint alias_id) +my_bool add_alias_for_collation(LEX_CSTRING *collation_name, uint org_id, + LEX_CSTRING *alias, uint alias_id) { char *coll_name, *comment; struct charset_info_st *new_ci; @@ -655,12 +655,18 @@ my_bool add_alias_for_collation(LEX_CSTRING *collation_name, LEX_CSTRING *alias, MY_CHARSET_LOADER loader; char comment_buff[64+15]; size_t comment_length; - uint org_id= get_collation_number_internal(collation_name->str); - DBUG_ASSERT(org_id); DBUG_ASSERT(all_charsets[org_id]); if (!(org= all_charsets[org_id])) return 1; + + DBUG_ASSERT(!my_strcasecmp(&my_charset_latin1, org->coll_name.str, + collation_name->str)); +#ifdef DEBUG_PRINT_ALIAS + fprintf(stderr, "alias: %s collation: %s org_id: %u\n", + alias->str, collation_name->str, org_id); +#endif + /* We have to init the character set to ensure it is not changed after we copy it. diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c index ebc22047b06..7ba300ba67a 100644 --- a/strings/ctype-uca.c +++ b/strings/ctype-uca.c @@ -39567,6 +39567,8 @@ LEX_CSTRING my_ci_get_collation_name_uca(CHARSET_INFO *cs, /* Add support for MySQL 8.0 utf8mb4_0900_.. collations + + The collation id's where collected from fprintf() in add_alias_for_collation() */ #define mysql_0900_collation_start 255 @@ -39574,74 +39576,78 @@ LEX_CSTRING my_ci_get_collation_name_uca(CHARSET_INFO *cs, struct mysql_0900_to_mariadb_1400_mapping { const char *mysql_col_name, *mariadb_col_name, *case_sensitivity; + uint collation_id; }; struct mysql_0900_to_mariadb_1400_mapping mysql_0900_mapping[]= { /* 255 Ascent insensitive, Case insensitive 'ai_ci' */ - {"", "", "ai_ci"}, - {"de_pb", "german2", "ai_ci"}, - {"is", "icelandic", "ai_ci"}, - {"lv", "latvian", "ai_ci"}, - {"ro", "romanian", "ai_ci"}, - {"sl", "slovenian", "ai_ci"}, - {"pl", "polish", "ai_ci"}, - {"et", "estonian", "ai_ci"}, - {"es", "spanish", "ai_ci"}, - {"sv", "swedish", "ai_ci"}, - {"tr", "turkish", "ai_ci"}, - {"cs", "czech", "ai_ci"}, - {"da", "danish", "ai_ci"}, - {"lt", "lithuanian", "ai_ci"}, - {"sk", "slovak", "ai_ci"}, - {"es_trad", "spanish2", "ai_ci"}, - {"la", "roman", "ai_ci"}, - {"fa", NullS, "ai_ci"}, // Disabled in MySQL - {"eo", "esperanto", "ai_ci"}, - {"hu", "hungarian", "ai_ci"}, - {"hr", "croatian", "ai_ci"}, - {"si", NullS, "ai_ci"}, // Disabled in MySQL - {"vi", "vietnamese", "ai_ci"}, + {"", "", "ai_ci", 2308}, + {"de_pb", "german2", "ai_ci", 2468}, + {"is", "icelandic", "ai_ci", 2316}, + {"lv", "latvian", "ai_ci", 2324}, + {"ro", "romanian", "ai_ci", 2332}, + {"sl", "slovenian", "ai_ci", 2340}, + {"pl", "polish", "ai_ci", 2348}, + {"et", "estonian", "ai_ci", 2356}, + {"es", "spanish", "ai_ci", 2364}, + {"sv", "swedish", "ai_ci", 2372}, + {"tr", "turkish", "ai_ci", 2380}, + {"cs", "czech", "ai_ci", 2388}, + {"da", "danish", "ai_ci", 2396}, + {"lt", "lithuanian", "ai_ci", 2404}, + {"sk", "slovak", "ai_ci", 2412}, + {"es_trad", "spanish2", "ai_ci", 2420}, + {"la", "roman", "ai_ci", 2428}, + {"fa", NullS, "ai_ci", 0}, // Disabled in MySQL + {"eo", "esperanto", "ai_ci", 2444}, + {"hu", "hungarian", "ai_ci", 2452}, + {"hr", "croatian", "ai_ci", 2500}, + {"si", NullS, "ai_ci", 0}, // Disabled in MySQL + {"vi", "vietnamese", "ai_ci", 2492}, /* 278 Ascent sensitive, Case sensitive 'as_cs' */ - {"","", "as_cs"}, - {"de_pb", "german2", "as_cs"}, - {"is", "icelandic", "as_cs"}, - {"lv", "latvian", "as_cs"}, - {"ro", "romanian", "as_cs"}, - {"sl", "slovenian", "as_cs"}, - {"pl", "polish", "as_cs"}, - {"et", "estonian", "as_cs"}, - {"es", "spanish", "as_cs"}, - {"sv", "swedish", "as_cs"}, - {"tr", "turkish", "as_cs"}, - {"cs", "czech", "as_cs"}, - {"da", "danish", "as_cs"}, - {"lt", "lithuanian", "as_cs"}, - {"sk", "slovak", "as_cs"}, - {"es_trad", "spanish2", "as_cs"}, - {"la", "roman", "as_cs"}, - {"fa", NullS, "as_cs"}, // Disabled in MySQL - {"eo", "esperanto", "as_cs"}, - {"hu", "hungarian", "as_cs"}, - {"hr", "croatian", "as_cs"}, - {"si", NullS, "as_cs"}, // Disabled in MySQL - {"vi", "vietnamese", "as_cs"}, + {"","", "as_cs", 2311}, + {"de_pb", "german2", "as_cs", 2471}, + {"is", "icelandic", "as_cs", 2319}, + {"lv", "latvian", "as_cs", 2327}, + {"ro", "romanian", "as_cs", 2335}, + {"sl", "slovenian", "as_cs", 2343}, + {"pl", "polish", "as_cs", 2351}, + {"et", "estonian", "as_cs", 2359}, + {"es", "spanish", "as_cs", 2367}, + {"sv", "swedish", "as_cs", 2375}, + {"tr", "turkish", "as_cs", 2383}, + {"cs", "czech", "as_cs", 2391}, + {"da", "danish", "as_cs", 2399}, + {"lt", "lithuanian", "as_cs", 2407}, + {"sk", "slovak", "as_cs", 2415}, + {"es_trad", "spanish2", "as_cs", 2423}, + {"la", "roman", "as_cs", 2431}, + {"fa", NullS, "as_cs", 0}, // Disabled in MySQL + {"eo", "esperanto", "as_cs", 2447}, + {"hu", "hungarian", "as_cs", 2455}, + {"hr", "croatian", "as_cs", 2503}, + {"si", NullS, "as_cs", 0}, // Disabled in MySQL + {"vi", "vietnamese", "as_cs", 2495}, - {"", NullS, "as_cs"}, // Missing - {"", NullS, "as_cs"}, // Missing - {"_ja_0900_as_cs", NullS, "as_cs"}, // Not supported - {"_ja_0900_as_cs_ks", NullS, "as_cs"}, // Not supported + {"", NullS, "as_cs", 0}, // Missing + {"", NullS, "as_cs", 0}, // Missing + {"_ja_0900_as_cs", NullS, "as_cs", 0}, // Not supported + {"_ja_0900_as_cs_ks", NullS, "as_cs", 0}, // Not supported /* 305 Ascent-sensitive, Case insensitive 'as_ci' */ - {"","", "as_ci"}, - {"ru", NullS, "ai_ci"}, // Not supported - {"ru", NullS, "as_cs"}, // Not supported - {"zh", NullS, "as_cs"}, // Not supported - {NullS, NullS, ""} + {"","", "as_ci", 2310}, + {"ru", NullS, "ai_ci", 0}, // Not supported + {"ru", NullS, "as_cs", 0}, // Not supported + {"zh", NullS, "as_cs", 0}, // Not supported + {NullS, NullS, "", 0} }; +static LEX_CSTRING mysql_utf8_bin= { STRING_WITH_LEN("utf8mb4_0900_bin") }; +static LEX_CSTRING mariadb_utf8_bin= { STRING_WITH_LEN("utf8mb4_bin") }; + /* Map mysql character sets to MariaDB using the same definition but with with the MySQL collation name and id. @@ -39651,8 +39657,6 @@ my_bool mysql_utf8mb4_0900_collation_definitions_add() { uint id= mysql_0900_collation_start; struct mysql_0900_to_mariadb_1400_mapping *map; - LEX_CSTRING mysql_utf8_bin= { STRING_WITH_LEN("utf8mb4_0900_bin") }; - LEX_CSTRING mariadb_utf8_bin= { STRING_WITH_LEN("utf8mb4_bin") }; for (map= mysql_0900_mapping; map->mysql_col_name ; map++, id++) { @@ -39680,12 +39684,13 @@ my_bool mysql_utf8mb4_0900_collation_definitions_add() alias_name.str= alias; alias_name.length= ali_length; - if (add_alias_for_collation(&org_name, &alias_name, id)) + if (add_alias_for_collation(&org_name, map->collation_id, &alias_name, + id)) return 1; } } - if (add_alias_for_collation(&mariadb_utf8_bin, &mysql_utf8_bin, 309)) + if (add_alias_for_collation(&mariadb_utf8_bin, 46, &mysql_utf8_bin, 309)) return 1; return 0; } From 6be42c7276cb342df81e18aa53868623a89abeec Mon Sep 17 00:00:00 2001 From: Monty Date: Fri, 17 Jan 2025 14:43:06 +0200 Subject: [PATCH 101/213] Removed test not related to utf8mb4_0900 from ctype_utf8mb4_0900.test --- mysql-test/main/ctype_utf8mb4_0900.result | 2675 --------------------- mysql-test/main/ctype_utf8mb4_0900.test | 31 - 2 files changed, 2706 deletions(-) diff --git a/mysql-test/main/ctype_utf8mb4_0900.result b/mysql-test/main/ctype_utf8mb4_0900.result index fc2833e2b79..9e85fe6d7dc 100644 --- a/mysql-test/main/ctype_utf8mb4_0900.result +++ b/mysql-test/main/ctype_utf8mb4_0900.result @@ -92,2681 +92,6 @@ utf8mb4_hr_0900_as_cs utf8mb4 298 Yes 8 Alias for utf8mb4_uca1400_croatian_nopa utf8mb4_vi_0900_as_cs utf8mb4 300 Yes 8 Alias for utf8mb4_uca1400_vietnamese_nopad_as_cs utf8mb4_0900_as_ci utf8mb4 305 Yes 8 Alias for utf8mb4_uca1400_nopad_as_ci utf8mb4_0900_bin utf8mb4 309 Yes 1 Alias for utf8mb4_bin -SET NAMES utf8mb4; -CREATE TABLE t1 (c1 CHAR(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin); -insert into t1 values ('A'),('a'); -insert into t1 values ('B'),('b'); -insert into t1 values ('C'),('c'); -insert into t1 values ('D'),('d'); -insert into t1 values ('E'),('e'); -insert into t1 values ('F'),('f'); -insert into t1 values ('G'),('g'); -insert into t1 values ('H'),('h'); -insert into t1 values ('I'),('i'); -insert into t1 values ('J'),('j'); -insert into t1 values ('K'),('k'); -insert into t1 values ('L'),('l'); -insert into t1 values ('M'),('m'); -insert into t1 values ('N'),('n'); -insert into t1 values ('O'),('o'); -insert into t1 values ('P'),('p'); -insert into t1 values ('Q'),('q'); -insert into t1 values ('R'),('r'); -insert into t1 values ('S'),('s'); -insert into t1 values ('T'),('t'); -insert into t1 values ('U'),('u'); -insert into t1 values ('V'),('v'); -insert into t1 values ('W'),('w'); -insert into t1 values ('X'),('x'); -insert into t1 values ('Y'),('y'); -insert into t1 values ('Z'),('z'); -insert into t1 values (_ucs2 0x00e0),(_ucs2 0x00c0); -insert into t1 values (_ucs2 0x00e1),(_ucs2 0x00c1); -insert into t1 values (_ucs2 0x00e2),(_ucs2 0x00c2); -insert into t1 values (_ucs2 0x00e3),(_ucs2 0x00c3); -insert into t1 values (_ucs2 0x00e4),(_ucs2 0x00c4); -insert into t1 values (_ucs2 0x00e5),(_ucs2 0x00c5); -insert into t1 values (_ucs2 0x00e6),(_ucs2 0x00c6); -insert into t1 values (_ucs2 0x00e7),(_ucs2 0x00c7); -insert into t1 values (_ucs2 0x00e8),(_ucs2 0x00c8); -insert into t1 values (_ucs2 0x00e9),(_ucs2 0x00c9); -insert into t1 values (_ucs2 0x00ea),(_ucs2 0x00ca); -insert into t1 values (_ucs2 0x00eb),(_ucs2 0x00cb); -insert into t1 values (_ucs2 0x00ec),(_ucs2 0x00cc); -insert into t1 values (_ucs2 0x00ed),(_ucs2 0x00cd); -insert into t1 values (_ucs2 0x00ee),(_ucs2 0x00ce); -insert into t1 values (_ucs2 0x00ef),(_ucs2 0x00cf); -insert into t1 values (_ucs2 0x00f0),(_ucs2 0x00d0); -insert into t1 values (_ucs2 0x00f1),(_ucs2 0x00d1); -insert into t1 values (_ucs2 0x00f2),(_ucs2 0x00d2); -insert into t1 values (_ucs2 0x00f3),(_ucs2 0x00d3); -insert into t1 values (_ucs2 0x00f4),(_ucs2 0x00d4); -insert into t1 values (_ucs2 0x00f5),(_ucs2 0x00d5); -insert into t1 values (_ucs2 0x00f6),(_ucs2 0x00d6); -insert into t1 values (_ucs2 0x00f7),(_ucs2 0x00d7); -insert into t1 values (_ucs2 0x00f8),(_ucs2 0x00d8); -insert into t1 values (_ucs2 0x00f9),(_ucs2 0x00d9); -insert into t1 values (_ucs2 0x00fa),(_ucs2 0x00da); -insert into t1 values (_ucs2 0x00fb),(_ucs2 0x00db); -insert into t1 values (_ucs2 0x00fc),(_ucs2 0x00dc); -insert into t1 values (_ucs2 0x00fd),(_ucs2 0x00dd); -insert into t1 values (_ucs2 0x00fe),(_ucs2 0x00de); -insert into t1 values (_ucs2 0x00ff),(_ucs2 0x00df); -insert into t1 values (_ucs2 0x0100),(_ucs2 0x0101),(_ucs2 0x0102),(_ucs2 0x0103); -insert into t1 values (_ucs2 0x0104),(_ucs2 0x0105),(_ucs2 0x0106),(_ucs2 0x0107); -insert into t1 values (_ucs2 0x0108),(_ucs2 0x0109),(_ucs2 0x010a),(_ucs2 0x010b); -insert into t1 values (_ucs2 0x010c),(_ucs2 0x010d),(_ucs2 0x010e),(_ucs2 0x010f); -insert into t1 values (_ucs2 0x0110),(_ucs2 0x0111),(_ucs2 0x0112),(_ucs2 0x0113); -insert into t1 values (_ucs2 0x0114),(_ucs2 0x0115),(_ucs2 0x0116),(_ucs2 0x0117); -insert into t1 values (_ucs2 0x0118),(_ucs2 0x0119),(_ucs2 0x011a),(_ucs2 0x011b); -insert into t1 values (_ucs2 0x011c),(_ucs2 0x011d),(_ucs2 0x011e),(_ucs2 0x011f); -insert into t1 values (_ucs2 0x0120),(_ucs2 0x0121),(_ucs2 0x0122),(_ucs2 0x0123); -insert into t1 values (_ucs2 0x0124),(_ucs2 0x0125),(_ucs2 0x0126),(_ucs2 0x0127); -insert into t1 values (_ucs2 0x0128),(_ucs2 0x0129),(_ucs2 0x012a),(_ucs2 0x012b); -insert into t1 values (_ucs2 0x012c),(_ucs2 0x012d),(_ucs2 0x012e),(_ucs2 0x012f); -insert into t1 values (_ucs2 0x0130),(_ucs2 0x0131),(_ucs2 0x0132),(_ucs2 0x0133); -insert into t1 values (_ucs2 0x0134),(_ucs2 0x0135),(_ucs2 0x0136),(_ucs2 0x0137); -insert into t1 values (_ucs2 0x0138),(_ucs2 0x0139),(_ucs2 0x013a),(_ucs2 0x013b); -insert into t1 values (_ucs2 0x013c),(_ucs2 0x013d),(_ucs2 0x013e),(_ucs2 0x013f); -insert into t1 values (_ucs2 0x0140),(_ucs2 0x0141),(_ucs2 0x0142),(_ucs2 0x0143); -insert into t1 values (_ucs2 0x0144),(_ucs2 0x0145),(_ucs2 0x0146),(_ucs2 0x0147); -insert into t1 values (_ucs2 0x0148),(_ucs2 0x0149),(_ucs2 0x014a),(_ucs2 0x014b); -insert into t1 values (_ucs2 0x014c),(_ucs2 0x014d),(_ucs2 0x014e),(_ucs2 0x014f); -insert into t1 values (_ucs2 0x0150),(_ucs2 0x0151),(_ucs2 0x0152),(_ucs2 0x0153); -insert into t1 values (_ucs2 0x0154),(_ucs2 0x0155),(_ucs2 0x0156),(_ucs2 0x0157); -insert into t1 values (_ucs2 0x0158),(_ucs2 0x0159),(_ucs2 0x015a),(_ucs2 0x015b); -insert into t1 values (_ucs2 0x015c),(_ucs2 0x015d),(_ucs2 0x015e),(_ucs2 0x015f); -insert into t1 values (_ucs2 0x0160),(_ucs2 0x0161),(_ucs2 0x0162),(_ucs2 0x0163); -insert into t1 values (_ucs2 0x0164),(_ucs2 0x0165),(_ucs2 0x0166),(_ucs2 0x0167); -insert into t1 values (_ucs2 0x0168),(_ucs2 0x0169),(_ucs2 0x016a),(_ucs2 0x016b); -insert into t1 values (_ucs2 0x016c),(_ucs2 0x016d),(_ucs2 0x016e),(_ucs2 0x016f); -insert into t1 values (_ucs2 0x0170),(_ucs2 0x0171),(_ucs2 0x0172),(_ucs2 0x0173); -insert into t1 values (_ucs2 0x0174),(_ucs2 0x0175),(_ucs2 0x0176),(_ucs2 0x0177); -insert into t1 values (_ucs2 0x0178),(_ucs2 0x0179),(_ucs2 0x017a),(_ucs2 0x017b); -insert into t1 values (_ucs2 0x017c),(_ucs2 0x017d),(_ucs2 0x017e),(_ucs2 0x017f); -insert into t1 values (_ucs2 0x0180),(_ucs2 0x0181),(_ucs2 0x0182),(_ucs2 0x0183); -insert into t1 values (_ucs2 0x0184),(_ucs2 0x0185),(_ucs2 0x0186),(_ucs2 0x0187); -insert into t1 values (_ucs2 0x0188),(_ucs2 0x0189),(_ucs2 0x018a),(_ucs2 0x018b); -insert into t1 values (_ucs2 0x018c),(_ucs2 0x018d),(_ucs2 0x018e),(_ucs2 0x018f); -insert into t1 values (_ucs2 0x0190),(_ucs2 0x0191),(_ucs2 0x0192),(_ucs2 0x0193); -insert into t1 values (_ucs2 0x0194),(_ucs2 0x0195),(_ucs2 0x0196),(_ucs2 0x0197); -insert into t1 values (_ucs2 0x0198),(_ucs2 0x0199),(_ucs2 0x019a),(_ucs2 0x019b); -insert into t1 values (_ucs2 0x019c),(_ucs2 0x019d),(_ucs2 0x019e),(_ucs2 0x019f); -insert into t1 values (_ucs2 0x01a0),(_ucs2 0x01a1),(_ucs2 0x01a2),(_ucs2 0x01a3); -insert into t1 values (_ucs2 0x01a4),(_ucs2 0x01a5),(_ucs2 0x01a6),(_ucs2 0x01a7); -insert into t1 values (_ucs2 0x01a8),(_ucs2 0x01a9),(_ucs2 0x01aa),(_ucs2 0x01ab); -insert into t1 values (_ucs2 0x01ac),(_ucs2 0x01ad),(_ucs2 0x01ae),(_ucs2 0x01af); -insert into t1 values (_ucs2 0x01b0),(_ucs2 0x01b1),(_ucs2 0x01b2),(_ucs2 0x01b3); -insert into t1 values (_ucs2 0x01b4),(_ucs2 0x01b5),(_ucs2 0x01b6),(_ucs2 0x01b7); -insert into t1 values (_ucs2 0x01b8),(_ucs2 0x01b9),(_ucs2 0x01ba),(_ucs2 0x01bb); -insert into t1 values (_ucs2 0x01bc),(_ucs2 0x01bd),(_ucs2 0x01be),(_ucs2 0x01bf); -insert into t1 values (_ucs2 0x01c0),(_ucs2 0x01c1),(_ucs2 0x01c2),(_ucs2 0x01c3); -insert into t1 values (_ucs2 0x01c4),(_ucs2 0x01c5),(_ucs2 0x01c6),(_ucs2 0x01c7); -insert into t1 values (_ucs2 0x01c8),(_ucs2 0x01c9),(_ucs2 0x01ca),(_ucs2 0x01cb); -insert into t1 values (_ucs2 0x01cc),(_ucs2 0x01cd),(_ucs2 0x01ce),(_ucs2 0x01cf); -insert into t1 values (_ucs2 0x01d0),(_ucs2 0x01d1),(_ucs2 0x01d2),(_ucs2 0x01d3); -insert into t1 values (_ucs2 0x01d4),(_ucs2 0x01d5),(_ucs2 0x01d6),(_ucs2 0x01d7); -insert into t1 values (_ucs2 0x01d8),(_ucs2 0x01d9),(_ucs2 0x01da),(_ucs2 0x01db); -insert into t1 values (_ucs2 0x01dc),(_ucs2 0x01dd),(_ucs2 0x01de),(_ucs2 0x01df); -insert into t1 values (_ucs2 0x01e0),(_ucs2 0x01e1),(_ucs2 0x01e2),(_ucs2 0x01e3); -insert into t1 values (_ucs2 0x01e4),(_ucs2 0x01e5),(_ucs2 0x01e6),(_ucs2 0x01e7); -insert into t1 values (_ucs2 0x01e8),(_ucs2 0x01e9),(_ucs2 0x01ea),(_ucs2 0x01eb); -insert into t1 values (_ucs2 0x01ec),(_ucs2 0x01ed),(_ucs2 0x01ee),(_ucs2 0x01ef); -insert into t1 values (_ucs2 0x01f0),(_ucs2 0x01f1),(_ucs2 0x01f2),(_ucs2 0x01f3); -insert into t1 values (_ucs2 0x01f4),(_ucs2 0x01f5),(_ucs2 0x01f6),(_ucs2 0x01f7); -insert into t1 values (_ucs2 0x01f8),(_ucs2 0x01f9),(_ucs2 0x01fa),(_ucs2 0x01fb); -insert into t1 values (_ucs2 0x01fc),(_ucs2 0x01fd),(_ucs2 0x01fe),(_ucs2 0x01ff); -INSERT INTO t1 VALUES (_ucs2 0x1EA0),(_ucs2 0x1EA1),(_ucs2 0x1EA2),(_ucs2 0x1EA3); -INSERT INTO t1 VALUES (_ucs2 0x1EA4),(_ucs2 0x1EA5),(_ucs2 0x1EA6),(_ucs2 0x1EA7); -INSERT INTO t1 VALUES (_ucs2 0x1EA8),(_ucs2 0x1EA9),(_ucs2 0x1EAA),(_ucs2 0x1EAB); -INSERT INTO t1 VALUES (_ucs2 0x1EAC),(_ucs2 0x1EAD),(_ucs2 0x1EAE),(_ucs2 0x1EAF); -INSERT INTO t1 VALUES (_ucs2 0x1EB0),(_ucs2 0x1EB1),(_ucs2 0x1EB2),(_ucs2 0x1EB3); -INSERT INTO t1 VALUES (_ucs2 0x1EB4),(_ucs2 0x1EB5),(_ucs2 0x1EB6),(_ucs2 0x1EB7); -INSERT INTO t1 VALUES (_ucs2 0x1EB8),(_ucs2 0x1EB9),(_ucs2 0x1EBA),(_ucs2 0x1EBB); -INSERT INTO t1 VALUES (_ucs2 0x1EBC),(_ucs2 0x1EBD),(_ucs2 0x1EBE),(_ucs2 0x1EBF); -INSERT INTO t1 VALUES (_ucs2 0x1EC0),(_ucs2 0x1EC1),(_ucs2 0x1EC2),(_ucs2 0x1EC3); -INSERT INTO t1 VALUES (_ucs2 0x1EC4),(_ucs2 0x1EC5),(_ucs2 0x1EC6),(_ucs2 0x1EC7); -INSERT INTO t1 VALUES (_ucs2 0x1EC8),(_ucs2 0x1EC9),(_ucs2 0x1ECA),(_ucs2 0x1ECB); -INSERT INTO t1 VALUES (_ucs2 0x1ECC),(_ucs2 0x1ECD),(_ucs2 0x1ECE),(_ucs2 0x1ECF); -INSERT INTO t1 VALUES (_ucs2 0x1ED0),(_ucs2 0x1ED1),(_ucs2 0x1ED2),(_ucs2 0x1ED3); -INSERT INTO t1 VALUES (_ucs2 0x1ED4),(_ucs2 0x1ED5),(_ucs2 0x1ED6),(_ucs2 0x1ED7); -INSERT INTO t1 VALUES (_ucs2 0x1ED8),(_ucs2 0x1ED9),(_ucs2 0x1EDA),(_ucs2 0x1EDB); -INSERT INTO t1 VALUES (_ucs2 0x1EDC),(_ucs2 0x1EDD),(_ucs2 0x1EDE),(_ucs2 0x1EDF); -INSERT INTO t1 VALUES (_ucs2 0x1EE0),(_ucs2 0x1EE1),(_ucs2 0x1EE2),(_ucs2 0x1EE3); -INSERT INTO t1 VALUES (_ucs2 0x1EE4),(_ucs2 0x1EE5),(_ucs2 0x1EE6),(_ucs2 0x1EE7); -INSERT INTO t1 VALUES (_ucs2 0x1EE8),(_ucs2 0x1EE9),(_ucs2 0x1EEA),(_ucs2 0x1EEB); -INSERT INTO t1 VALUES (_ucs2 0x1EEC),(_ucs2 0x1EED),(_ucs2 0x1EEE),(_ucs2 0x1EEF); -INSERT INTO t1 VALUES (_ucs2 0x1EF0),(_ucs2 0x1EF1); -insert into t1 values ('AA'),('Aa'),('aa'),('aA'); -insert into t1 values ('AE'),('Ae'),('ae'),('aE'); -insert into t1 values ('CH'),('Ch'),('ch'),('cH'); -insert into t1 values ('DZ'),('Dz'),('dz'),('dZ'); -insert into t1 values ('DŽ'),('Dž'),('dž'),('dŽ'); -insert into t1 values ('IJ'),('Ij'),('ij'),('iJ'); -insert into t1 values ('LJ'),('Lj'),('lj'),('lJ'); -insert into t1 values ('LL'),('Ll'),('ll'),('lL'); -insert into t1 values ('NJ'),('Nj'),('nj'),('nJ'); -insert into t1 values ('OE'),('Oe'),('oe'),('oE'); -insert into t1 values ('SS'),('Ss'),('ss'),('sS'); -insert into t1 values ('RR'),('Rr'),('rr'),('rR'); -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_unicode_ci; -GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') -÷ -× -AaÀÁÂÃÄÅàáâãäåĀāĂ㥹ǍǎǞǟǠǡǺǻẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặ -AAAaaAaa -AEAeaEae -ÆæǢǣǼǽ -Bb -ƀ -Ɓ -Ƃƃ -CcÇçĆćĈĉĊċČč -CHChcHch -Ƈƈ -DdĎď -DZDzDŽDždZdzdŽdžDŽDždžDZDzdz -Đđ -Ɖ -Ɗ -Ƌƌ -Ðð -EeÈÉÊËèéêëĒēĔĕĖėĘęĚěẸẹẺẻẼẽẾếỀềỂểỄễỆệ -Ǝǝ -Ə -Ɛ -Ff -Ƒƒ -GgĜĝĞğĠġĢģǦǧǴǵ -Ǥǥ -Ɠ -Ɣ -Ƣƣ -HhĤĥ -ƕǶ -Ħħ -IiÌÍÎÏìíîïĨĩĪīĬĭĮįİǏǐỈỉỊị -IJIjiJijIJij -ı -Ɨ -Ɩ -JjĴĵǰ -KkĶķǨǩ -Ƙƙ -LlĹĺĻļĽľ -Ŀŀ -LJLjlJljLJLjlj -LLLllLll -Łł -ƚ -ƛ -Mm -NnÑñŃńŅņŇňǸǹ -NJNjnJnjNJNjnj -Ɲ -ƞ -Ŋŋ -OoÒÓÔÕÖòóôõöŌōŎŏŐőƠơǑǒǪǫǬǭỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợ -OEOeoEoeŒœ -ØøǾǿ -Ɔ -Ɵ -Pp -Ƥƥ -Qq -ĸ -RrŔŕŖŗŘř -RRRrrRrr -Ʀ -SsŚśŜŝŞşŠšſ -SSSssSssß -Ʃ -ƪ -TtŢţŤť -ƾ -Ŧŧ -ƫ -Ƭƭ -Ʈ -UuÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųƯưǓǔǕǖǗǘǙǚǛǜỤụỦủỨứỪừỬửỮữỰự -Ɯ -Ʊ -Vv -Ʋ -WwŴŵ -Xx -YyÝýÿŶŷŸ -Ƴƴ -ZzŹźŻżŽž -ƍ -Ƶƶ -ƷǮǯ -Ƹƹ -ƺ -Þþ -ƿǷ -ƻ -Ƨƨ -Ƽƽ -Ƅƅ -ʼn -ǀ -ǁ -ǂ -ǃ -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_icelandic_ci; -GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') -÷ -× -AaÀÂÃàâãĀāĂ㥹ǍǎǞǟǠǡǺǻẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặ -AAAaaAaa -AEAeaEae -Áá -ǢǣǼǽ -Bb -ƀ -Ɓ -Ƃƃ -CcÇçĆćĈĉĊċČč -CHChcHch -Ƈƈ -DdĎď -DZDzDŽDždZdzdŽdžDŽDždžDZDzdz -Ðð -Đđ -Ɖ -Ɗ -Ƌƌ -EeÈÊËèêëĒēĔĕĖėĘęĚěẸẹẺẻẼẽẾếỀềỂểỄễỆệ -Éé -Ǝǝ -Ə -Ɛ -Ff -Ƒƒ -GgĜĝĞğĠġĢģǦǧǴǵ -Ǥǥ -Ɠ -Ɣ -Ƣƣ -HhĤĥ -ƕǶ -Ħħ -IiÌÎÏìîïĨĩĪīĬĭĮįİǏǐỈỉỊị -IJIjiJijIJij -Íí -ı -Ɨ -Ɩ -JjĴĵǰ -KkĶķǨǩ -Ƙƙ -LlĹĺĻļĽľ -Ŀŀ -LJLjlJljLJLjlj -LLLllLll -Łł -ƚ -ƛ -Mm -NnÑñŃńŅņŇňǸǹ -NJNjnJnjNJNjnj -Ɲ -ƞ -Ŋŋ -OoÒÔÕòôõŌōŎŏŐőƠơǑǒǪǫǬǭỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợ -OEOeoEoeŒœ -Óó -Ǿǿ -Ɔ -Ɵ -Pp -Ƥƥ -Qq -ĸ -RrŔŕŖŗŘř -RRRrrRrr -Ʀ -SsŚśŜŝŞşŠšſ -SSSssSssß -Ʃ -ƪ -TtŢţŤť -ƾ -Ŧŧ -ƫ -Ƭƭ -Ʈ -UuÙÛÜùûüŨũŪūŬŭŮůŰűŲųƯưǓǔǕǖǗǘǙǚǛǜỤụỦủỨứỪừỬửỮữỰự -Úú -Ɯ -Ʊ -Vv -Ʋ -WwŴŵ -Xx -YyÿŶŷŸ -Ýý -Ƴƴ -ZzŹźŻżŽž -ƍ -Þþ -ÄÆäæ -ÖØöø -Åå -Ƶƶ -ƷǮǯ -Ƹƹ -ƺ -ƿǷ -ƻ -Ƨƨ -Ƽƽ -Ƅƅ -ʼn -ǀ -ǁ -ǂ -ǃ -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_latvian_ci; -GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') -÷ -× -AaÀÁÂÃÄÅàáâãäåĀāĂ㥹ǍǎǞǟǠǡǺǻẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặ -AAAaaAaa -AEAeaEae -ÆæǢǣǼǽ -Bb -ƀ -Ɓ -Ƃƃ -CcÇçĆćĈĉĊċ -CHChcHch -Čč -Ƈƈ -DdĎď -DZDzdZdzDŽDždžDZDzdz -DŽDždŽdž -Đđ -Ɖ -Ɗ -Ƌƌ -Ðð -EeÈÉÊËèéêëĒēĔĕĖėĘęĚěẸẹẺẻẼẽẾếỀềỂểỄễỆệ -Ǝǝ -Ə -Ɛ -Ff -Ƒƒ -GgĜĝĞğĠġǦǧǴǵ -Ģģ -Ǥǥ -Ɠ -Ɣ -Ƣƣ -HhĤĥ -ƕǶ -Ħħ -IiÌÍÎÏìíîïĨĩĪīĬĭĮįİǏǐỈỉỊị -IJIjiJijIJij -Yy -ı -Ɨ -Ɩ -JjĴĵǰ -KkǨǩ -Ķķ -Ƙƙ -LlĹ弾 -Ŀŀ -LJLjlJljLJLjlj -LLLllLll -Ļļ -Łł -ƚ -ƛ -Mm -NnÑñŃńŇňǸǹ -NJNjnJnjNJNjnj -Ņņ -Ɲ -ƞ -Ŋŋ -OoÒÓÔÕÖòóôõöŌōŎŏŐőƠơǑǒǪǫǬǭỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợ -OEOeoEoeŒœ -ØøǾǿ -Ɔ -Ɵ -Pp -Ƥƥ -Qq -ĸ -RrŔŕŘř -RRRrrRrr -Ŗŗ -Ʀ -SsŚśŜŝŞşſ -SSSssSssß -Šš -Ʃ -ƪ -TtŢţŤť -ƾ -Ŧŧ -ƫ -Ƭƭ -Ʈ -UuÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųƯưǓǔǕǖǗǘǙǚǛǜỤụỦủỨứỪừỬửỮữỰự -Ɯ -Ʊ -Vv -Ʋ -WwŴŵ -Xx -ÝýÿŶŷŸ -Ƴƴ -ZzŹźŻż -ƍ -Žž -Ƶƶ -ƷǮǯ -Ƹƹ -ƺ -Þþ -ƿǷ -ƻ -Ƨƨ -Ƽƽ -Ƅƅ -ʼn -ǀ -ǁ -ǂ -ǃ -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_romanian_ci; -GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') -÷ -× -AaÀÁÃÄÅàáãäåĀāĄąǍǎǞǟǠǡǺǻẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặ -AAAaaAaa -AEAeaEae -Ăă -Ââ -ÆæǢǣǼǽ -Bb -ƀ -Ɓ -Ƃƃ -CcÇçĆćĈĉĊċČč -CHChcHch -Ƈƈ -DdĎď -DZDzDŽDždZdzdŽdžDŽDždžDZDzdz -Đđ -Ɖ -Ɗ -Ƌƌ -Ðð -EeÈÉÊËèéêëĒēĔĕĖėĘęĚěẸẹẺẻẼẽẾếỀềỂểỄễỆệ -Ǝǝ -Ə -Ɛ -Ff -Ƒƒ -GgĜĝĞğĠġĢģǦǧǴǵ -Ǥǥ -Ɠ -Ɣ -Ƣƣ -HhĤĥ -ƕǶ -Ħħ -IiÌÍÏìíïĨĩĪīĬĭĮįİǏǐỈỉỊị -IJIjiJijIJij -Îî -ı -Ɨ -Ɩ -JjĴĵǰ -KkĶķǨǩ -Ƙƙ -LlĹĺĻļĽľ -Ŀŀ -LJLjlJljLJLjlj -LLLllLll -Łł -ƚ -ƛ -Mm -NnÑñŃńŅņŇňǸǹ -NJNjnJnjNJNjnj -Ɲ -ƞ -Ŋŋ -OoÒÓÔÕÖòóôõöŌōŎŏŐőƠơǑǒǪǫǬǭỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợ -OEOeoEoeŒœ -ØøǾǿ -Ɔ -Ɵ -Pp -Ƥƥ -Qq -ĸ -RrŔŕŖŗŘř -RRRrrRrr -Ʀ -SsŚśŜŝŠšſ -SSSssSssß -Şş -Ʃ -ƪ -TtŤť -ƾ -Ţţ -Ŧŧ -ƫ -Ƭƭ -Ʈ -UuÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųƯưǓǔǕǖǗǘǙǚǛǜỤụỦủỨứỪừỬửỮữỰự -Ɯ -Ʊ -Vv -Ʋ -WwŴŵ -Xx -YyÝýÿŶŷŸ -Ƴƴ -ZzŹźŻżŽž -ƍ -Ƶƶ -ƷǮǯ -Ƹƹ -ƺ -Þþ -ƿǷ -ƻ -Ƨƨ -Ƽƽ -Ƅƅ -ʼn -ǀ -ǁ -ǂ -ǃ -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_slovenian_ci; -GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') -÷ -× -AaÀÁÂÃÄÅàáâãäåĀāĂ㥹ǍǎǞǟǠǡǺǻẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặ -AAAaaAaa -AEAeaEae -ÆæǢǣǼǽ -Bb -ƀ -Ɓ -Ƃƃ -CcÇçĆćĈĉĊċ -CHChcHch -Čč -Ƈƈ -DdĎď -DZDzdZdzDŽDždžDZDzdz -DŽDždŽdž -Đđ -Ɖ -Ɗ -Ƌƌ -Ðð -EeÈÉÊËèéêëĒēĔĕĖėĘęĚěẸẹẺẻẼẽẾếỀềỂểỄễỆệ -Ǝǝ -Ə -Ɛ -Ff -Ƒƒ -GgĜĝĞğĠġĢģǦǧǴǵ -Ǥǥ -Ɠ -Ɣ -Ƣƣ -HhĤĥ -ƕǶ -Ħħ -IiÌÍÎÏìíîïĨĩĪīĬĭĮįİǏǐỈỉỊị -IJIjiJijIJij -ı -Ɨ -Ɩ -JjĴĵǰ -KkĶķǨǩ -Ƙƙ -LlĹĺĻļĽľ -Ŀŀ -LJLjlJljLJLjlj -LLLllLll -Łł -ƚ -ƛ -Mm -NnÑñŃńŅņŇňǸǹ -NJNjnJnjNJNjnj -Ɲ -ƞ -Ŋŋ -OoÒÓÔÕÖòóôõöŌōŎŏŐőƠơǑǒǪǫǬǭỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợ -OEOeoEoeŒœ -ØøǾǿ -Ɔ -Ɵ -Pp -Ƥƥ -Qq -ĸ -RrŔŕŖŗŘř -RRRrrRrr -Ʀ -SsŚśŜŝŞşſ -SSSssSssß -Šš -Ʃ -ƪ -TtŢţŤť -ƾ -Ŧŧ -ƫ -Ƭƭ -Ʈ -UuÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųƯưǓǔǕǖǗǘǙǚǛǜỤụỦủỨứỪừỬửỮữỰự -Ɯ -Ʊ -Vv -Ʋ -WwŴŵ -Xx -YyÝýÿŶŷŸ -Ƴƴ -ZzŹźŻż -ƍ -Žž -Ƶƶ -ƷǮǯ -Ƹƹ -ƺ -Þþ -ƿǷ -ƻ -Ƨƨ -Ƽƽ -Ƅƅ -ʼn -ǀ -ǁ -ǂ -ǃ -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_polish_ci; -GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') -÷ -× -AaÀÁÂÃÄÅàáâãäåĀāĂăǍǎǞǟǠǡǺǻẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặ -AAAaaAaa -AEAeaEae -Ąą -ÆæǢǣǼǽ -Bb -ƀ -Ɓ -Ƃƃ -CcÇçĈĉĊċČč -CHChcHch -Ćć -Ƈƈ -DdĎď -DZDzDŽDždZdzdŽdžDŽDždžDZDzdz -Đđ -Ɖ -Ɗ -Ƌƌ -Ðð -EeÈÉÊËèéêëĒēĔĕĖėĚěẸẹẺẻẼẽẾếỀềỂểỄễỆệ -Ęę -Ǝǝ -Ə -Ɛ -Ff -Ƒƒ -GgĜĝĞğĠġĢģǦǧǴǵ -Ǥǥ -Ɠ -Ɣ -Ƣƣ -HhĤĥ -ƕǶ -Ħħ -IiÌÍÎÏìíîïĨĩĪīĬĭĮįİǏǐỈỉỊị -IJIjiJijIJij -ı -Ɨ -Ɩ -JjĴĵǰ -KkĶķǨǩ -Ƙƙ -LlĹĺĻļĽľ -Ŀŀ -LJLjlJljLJLjlj -LLLllLll -Łł -ƚ -ƛ -Mm -NnÑñŅņŇňǸǹ -NJNjnJnjNJNjnj -Ńń -Ɲ -ƞ -Ŋŋ -OoÒÔÕÖòôõöŌōŎŏŐőƠơǑǒǪǫǬǭỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợ -OEOeoEoeŒœ -Óó -ØøǾǿ -Ɔ -Ɵ -Pp -Ƥƥ -Qq -ĸ -RrŔŕŖŗŘř -RRRrrRrr -Ʀ -SsŜŝŞşŠšſ -SSSssSssß -Śś -Ʃ -ƪ -TtŢţŤť -ƾ -Ŧŧ -ƫ -Ƭƭ -Ʈ -UuÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųƯưǓǔǕǖǗǘǙǚǛǜỤụỦủỨứỪừỬửỮữỰự -Ɯ -Ʊ -Vv -Ʋ -WwŴŵ -Xx -YyÝýÿŶŷŸ -Ƴƴ -ZzŽž -ƍ -Źź -Żż -Ƶƶ -ƷǮǯ -Ƹƹ -ƺ -Þþ -ƿǷ -ƻ -Ƨƨ -Ƽƽ -Ƅƅ -ʼn -ǀ -ǁ -ǂ -ǃ -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_estonian_ci; -GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') -÷ -× -AaÀÁÂÃÅàáâãåĀāĂ㥹ǍǎǞǟǠǡǺǻẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặ -AAAaaAaa -AEAeaEae -ÆæǢǣǼǽ -Bb -ƀ -Ɓ -Ƃƃ -CcÇçĆćĈĉĊċČč -CHChcHch -Ƈƈ -DdĎď -DZDzdZdz -DŽDždŽdž -DŽDždžDZDzdz -Đđ -Ɖ -Ɗ -Ƌƌ -Ðð -EeÈÉÊËèéêëĒēĔĕĖėĘęĚěẸẹẺẻẼẽẾếỀềỂểỄễỆệ -Ǝǝ -Ə -Ɛ -Ff -Ƒƒ -GgĜĝĞğĠġĢģǦǧǴǵ -Ǥǥ -Ɠ -Ɣ -Ƣƣ -HhĤĥ -ƕǶ -Ħħ -IiÌÍÎÏìíîïĨĩĪīĬĭĮįİǏǐỈỉỊị -IJIjiJijIJij -ı -Ɨ -Ɩ -JjĴĵǰ -KkĶķǨǩ -Ƙƙ -LlĹĺĻļĽľ -Ŀŀ -LJLjlJljLJLjlj -LLLllLll -Łł -ƚ -ƛ -Mm -NnÑñŃńŅņŇňǸǹ -NJNjnJnjNJNjnj -Ɲ -ƞ -Ŋŋ -OoÒÓÔòóôŌōŎŏŐőƠơǑǒǪǫǬǭỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợ -OEOeoEoeŒœ -ØøǾǿ -Ɔ -Ɵ -Pp -Ƥƥ -Qq -ĸ -RrŔŕŖŗŘř -RRRrrRrr -Ʀ -SsŚśŜŝŞşſ -SSSssSssß -Šš -Zz -Žž -Ʃ -ƪ -TtŢţŤť -ƾ -Ŧŧ -ƫ -Ƭƭ -Ʈ -UuÙÚÛùúûŨũŪūŬŭŮůŰűŲųƯưǓǔǕǖǗǘǙǚǛǜỤụỦủỨứỪừỬửỮữỰự -Ɯ -Ʊ -Vv -Ʋ -WwŴŵ -Õõ -Ää -Öö -Üü -Xx -YyÝýÿŶŷŸ -Ƴƴ -ŹźŻż -ƍ -Ƶƶ -ƷǮǯ -Ƹƹ -ƺ -Þþ -ƿǷ -ƻ -Ƨƨ -Ƽƽ -Ƅƅ -ʼn -ǀ -ǁ -ǂ -ǃ -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_spanish_ci; -GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') -÷ -× -AaÀÁÂÃÄÅàáâãäåĀāĂ㥹ǍǎǞǟǠǡǺǻẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặ -AAAaaAaa -AEAeaEae -ÆæǢǣǼǽ -Bb -ƀ -Ɓ -Ƃƃ -CcÇçĆćĈĉĊċČč -CHChcHch -Ƈƈ -DdĎď -DZDzDŽDždZdzdŽdžDŽDždžDZDzdz -Đđ -Ɖ -Ɗ -Ƌƌ -Ðð -EeÈÉÊËèéêëĒēĔĕĖėĘęĚěẸẹẺẻẼẽẾếỀềỂểỄễỆệ -Ǝǝ -Ə -Ɛ -Ff -Ƒƒ -GgĜĝĞğĠġĢģǦǧǴǵ -Ǥǥ -Ɠ -Ɣ -Ƣƣ -HhĤĥ -ƕǶ -Ħħ -IiÌÍÎÏìíîïĨĩĪīĬĭĮįİǏǐỈỉỊị -IJIjiJijIJij -ı -Ɨ -Ɩ -JjĴĵǰ -KkĶķǨǩ -Ƙƙ -LlĹĺĻļĽľ -Ŀŀ -LJLjlJljLJLjlj -LLLllLll -Łł -ƚ -ƛ -Mm -NnŃńŅņŇňǸǹ -NJNjnJnjNJNjnj -Ññ -Ɲ -ƞ -Ŋŋ -OoÒÓÔÕÖòóôõöŌōŎŏŐőƠơǑǒǪǫǬǭỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợ -OEOeoEoeŒœ -ØøǾǿ -Ɔ -Ɵ -Pp -Ƥƥ -Qq -ĸ -RrŔŕŖŗŘř -RRRrrRrr -Ʀ -SsŚśŜŝŞşŠšſ -SSSssSssß -Ʃ -ƪ -TtŢţŤť -ƾ -Ŧŧ -ƫ -Ƭƭ -Ʈ -UuÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųƯưǓǔǕǖǗǘǙǚǛǜỤụỦủỨứỪừỬửỮữỰự -Ɯ -Ʊ -Vv -Ʋ -WwŴŵ -Xx -YyÝýÿŶŷŸ -Ƴƴ -ZzŹźŻżŽž -ƍ -Ƶƶ -ƷǮǯ -Ƹƹ -ƺ -Þþ -ƿǷ -ƻ -Ƨƨ -Ƽƽ -Ƅƅ -ʼn -ǀ -ǁ -ǂ -ǃ -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_swedish_ci; -GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') -÷ -× -AaÀÁÂÃàáâãĀāĂ㥹ǍǎǞǟǠǡǺǻẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặ -AAAaaAaa -AEAeaEae -ǢǣǼǽ -Bb -ƀ -Ɓ -Ƃƃ -CcÇçĆćĈĉĊċČč -CHChcHch -Ƈƈ -DdĎď -DZDzDŽDždZdzdŽdžDŽDždžDZDzdz -Đđ -Ɖ -Ɗ -Ƌƌ -Ðð -EeÈÉÊËèéêëĒēĔĕĖėĘęĚěẸẹẺẻẼẽẾếỀềỂểỄễỆệ -Ǝǝ -Ə -Ɛ -Ff -Ƒƒ -GgĜĝĞğĠġĢģǦǧǴǵ -Ǥǥ -Ɠ -Ɣ -Ƣƣ -HhĤĥ -ƕǶ -Ħħ -IiÌÍÎÏìíîïĨĩĪīĬĭĮįİǏǐỈỉỊị -IJIjiJijIJij -ı -Ɨ -Ɩ -JjĴĵǰ -KkĶķǨǩ -Ƙƙ -LlĹĺĻļĽľ -Ŀŀ -LJLjlJljLJLjlj -LLLllLll -Łł -ƚ -ƛ -Mm -NnÑñŃńŅņŇňǸǹ -NJNjnJnjNJNjnj -Ɲ -ƞ -Ŋŋ -OoÒÓÔÕòóôõŌōŎŏŐőƠơǑǒǪǫǬǭỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợ -OEOeoEoeŒœ -Ǿǿ -Ɔ -Ɵ -Pp -Ƥƥ -Qq -ĸ -RrŔŕŖŗŘř -RRRrrRrr -Ʀ -SsŚśŜŝŞşŠšſ -SSSssSssß -Ʃ -ƪ -TtŢţŤť -ƾ -Ŧŧ -ƫ -Ƭƭ -Ʈ -UuÙÚÛùúûŨũŪūŬŭŮůŰűŲųƯưǓǔǕǖǗǘǙǚǛǜỤụỦủỨứỪừỬửỮữỰự -Ɯ -Ʊ -Vv -Ʋ -WwŴŵ -Xx -YyÜÝüýÿŶŷŸ -Ƴƴ -ZzŹźŻżŽž -ƍ -Åå -ÄÆäæ -ÖØöø -Ƶƶ -ƷǮǯ -Ƹƹ -ƺ -Þþ -ƿǷ -ƻ -Ƨƨ -Ƽƽ -Ƅƅ -ʼn -ǀ -ǁ -ǂ -ǃ -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_turkish_ci; -GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') -÷ -× -AaÀÁÂÃÄÅàáâãäåĀāĂ㥹ǍǎǞǟǠǡǺǻẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặ -AAAaaAaa -AEAeaEae -ÆæǢǣǼǽ -Bb -ƀ -Ɓ -Ƃƃ -CcĆćĈĉĊċČč -CHChcHch -Çç -Ƈƈ -DdĎď -DZDzDŽDždZdzdŽdžDŽDždžDZDzdz -Đđ -Ɖ -Ɗ -Ƌƌ -Ðð -EeÈÉÊËèéêëĒēĔĕĖėĘęĚěẸẹẺẻẼẽẾếỀềỂểỄễỆệ -Ǝǝ -Ə -Ɛ -Ff -Ƒƒ -GgĜĝĠġĢģǦǧǴǵ -Ğğ -Ǥǥ -Ɠ -Ɣ -Ƣƣ -HhĤĥ -Iı -IJIj -ƕǶ -Ħħ -iÌÍÎÏìíîïĨĩĪīĬĭĮįİǏǐỈỉỊị -iJijIJij -Ɨ -Ɩ -JjĴĵǰ -KkĶķǨǩ -Ƙƙ -LlĹĺĻļĽľ -Ŀŀ -LJLjlJljLJLjlj -LLLllLll -Łł -ƚ -ƛ -Mm -NnÑñŃńŅņŇňǸǹ -NJNjnJnjNJNjnj -Ɲ -ƞ -Ŋŋ -OoÒÓÔÕòóôõŌōŎŏŐőƠơǑǒǪǫǬǭỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợ -OEOeoEoeŒœ -Öö -ØøǾǿ -Ɔ -Ɵ -Pp -Ƥƥ -Qq -ĸ -RrŔŕŖŗŘř -RRRrrRrr -Ʀ -SsŚśŜŝŠšſ -SSSssSssß -Şş -Ʃ -ƪ -TtŢţŤť -ƾ -Ŧŧ -ƫ -Ƭƭ -Ʈ -UuÙÚÛùúûŨũŪūŬŭŮůŰűŲųƯưǓǔǕǖǗǘǙǚǛǜỤụỦủỨứỪừỬửỮữỰự -Üü -Ɯ -Ʊ -Vv -Ʋ -WwŴŵ -Xx -YyÝýÿŶŷŸ -Ƴƴ -ZzŹźŻżŽž -ƍ -Ƶƶ -ƷǮǯ -Ƹƹ -ƺ -Þþ -ƿǷ -ƻ -Ƨƨ -Ƽƽ -Ƅƅ -ʼn -ǀ -ǁ -ǂ -ǃ -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_czech_ci; -GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') -÷ -× -AaÀÁÂÃÄÅàáâãäåĀāĂ㥹ǍǎǞǟǠǡǺǻẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặ -AAAaaAaa -AEAeaEae -ÆæǢǣǼǽ -Bb -ƀ -Ɓ -Ƃƃ -CcÇçĆćĈĉĊċ -cH -Čč -Ƈƈ -DdĎď -DZDzdZdzDŽDždžDZDzdz -DŽDždŽdž -Đđ -Ɖ -Ɗ -Ƌƌ -Ðð -EeÈÉÊËèéêëĒēĔĕĖėĘęĚěẸẹẺẻẼẽẾếỀềỂểỄễỆệ -Ǝǝ -Ə -Ɛ -Ff -Ƒƒ -GgĜĝĞğĠġĢģǦǧǴǵ -Ǥǥ -Ɠ -Ɣ -Ƣƣ -HhĤĥ -CHChch -ƕǶ -Ħħ -IiÌÍÎÏìíîïĨĩĪīĬĭĮįİǏǐỈỉỊị -IJIjiJijIJij -ı -Ɨ -Ɩ -JjĴĵǰ -KkĶķǨǩ -Ƙƙ -LlĹĺĻļĽľ -Ŀŀ -LJLjlJljLJLjlj -LLLllLll -Łł -ƚ -ƛ -Mm -NnÑñŃńŅņŇňǸǹ -NJNjnJnjNJNjnj -Ɲ -ƞ -Ŋŋ -OoÒÓÔÕÖòóôõöŌōŎŏŐőƠơǑǒǪǫǬǭỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợ -OEOeoEoeŒœ -ØøǾǿ -Ɔ -Ɵ -Pp -Ƥƥ -Qq -ĸ -RrŔŕŖŗ -RRRrrRrr -Řř -Ʀ -SsŚśŜŝŞşſ -SSSssSssß -Šš -Ʃ -ƪ -TtŢţŤť -ƾ -Ŧŧ -ƫ -Ƭƭ -Ʈ -UuÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųƯưǓǔǕǖǗǘǙǚǛǜỤụỦủỨứỪừỬửỮữỰự -Ɯ -Ʊ -Vv -Ʋ -WwŴŵ -Xx -YyÝýÿŶŷŸ -Ƴƴ -ZzŹźŻż -ƍ -Žž -Ƶƶ -ƷǮǯ -Ƹƹ -ƺ -Þþ -ƿǷ -ƻ -Ƨƨ -Ƽƽ -Ƅƅ -ʼn -ǀ -ǁ -ǂ -ǃ -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_danish_ci; -GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') -÷ -× -AaÀÁÂÃàáâãĀāĂ㥹ǍǎǞǟǠǡǺǻẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặ -aA -AEAeaEae -ǢǣǼǽ -Bb -ƀ -Ɓ -Ƃƃ -CcÇçĆćĈĉĊċČč -CHChcHch -Ƈƈ -DdĎď -DZDzDŽDždZdzdŽdžDŽDždžDZDzdz -Đđ -Ɖ -Ɗ -Ƌƌ -Ðð -EeÈÉÊËèéêëĒēĔĕĖėĘęĚěẸẹẺẻẼẽẾếỀềỂểỄễỆệ -Ǝǝ -Ə -Ɛ -Ff -Ƒƒ -GgĜĝĞğĠġĢģǦǧǴǵ -Ǥǥ -Ɠ -Ɣ -Ƣƣ -HhĤĥ -ƕǶ -Ħħ -IiÌÍÎÏìíîïĨĩĪīĬĭĮįİǏǐỈỉỊị -IJIjiJijIJij -ı -Ɨ -Ɩ -JjĴĵǰ -KkĶķǨǩ -Ƙƙ -LlĹĺĻļĽľ -Ŀŀ -LJLjlJljLJLjlj -LLLllLll -Łł -ƚ -ƛ -Mm -NnÑñŃńŅņŇňǸǹ -NJNjnJnjNJNjnj -Ɲ -ƞ -Ŋŋ -OoÒÓÔÕòóôõŌōŎŏƠơǑǒǪǫǬǭỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợ -OEOeoEoeŒœ -Ǿǿ -Ɔ -Ɵ -Pp -Ƥƥ -Qq -ĸ -RrŔŕŖŗŘř -RRRrrRrr -Ʀ -SsŚśŜŝŞşŠšſ -SSSssSssß -Ʃ -ƪ -TtŢţŤť -ƾ -Ŧŧ -ƫ -Ƭƭ -Ʈ -UuÙÚÛùúûŨũŪūŬŭŮůŲųƯưǓǔǕǖǗǘǙǚǛǜỤụỦủỨứỪừỬửỮữỰự -Ɯ -Ʊ -Vv -Ʋ -WwŴŵ -Xx -YyÜÝüýÿŰűŶŷŸ -Ƴƴ -ZzŹźŻżŽž -ƍ -ÄÆäæ -ÖØöøŐő -AAAaaaÅå -Ƶƶ -ƷǮǯ -Ƹƹ -ƺ -Þþ -ƿǷ -ƻ -Ƨƨ -Ƽƽ -Ƅƅ -ʼn -ǀ -ǁ -ǂ -ǃ -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_lithuanian_ci; -GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') -÷ -× -AaÀÁÂÃÄÅàáâãäåĀāĂ㥹ǍǎǞǟǠǡǺǻẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặ -AAAaaAaa -AEAeaEae -ÆæǢǣǼǽ -Bb -ƀ -Ɓ -Ƃƃ -CCHChcchÇçĆćĈĉĊċ -cH -Čč -Ƈƈ -DdĎď -DZDzdZdzDŽDždžDZDzdz -DŽDždŽdž -Đđ -Ɖ -Ɗ -Ƌƌ -Ðð -EeÈÉÊËèéêëĒēĔĕĖėĘęĚěẸẹẺẻẼẽẾếỀềỂểỄễỆệ -Ǝǝ -Ə -Ɛ -Ff -Ƒƒ -GgĜĝĞğĠġĢģǦǧǴǵ -Ǥǥ -Ɠ -Ɣ -Ƣƣ -HhĤĥ -ƕǶ -Ħħ -IYiyÌÍÎÏìíîïĨĩĪīĬĭĮįİǏǐỈỉỊị -IJIjiJijIJij -ı -Ɨ -Ɩ -JjĴĵǰ -KkĶķǨǩ -Ƙƙ -LlĹĺĻļĽľ -Ŀŀ -LJLjlJljLJLjlj -LLLllLll -Łł -ƚ -ƛ -Mm -NnÑñŃńŅņŇňǸǹ -NJNjnJnjNJNjnj -Ɲ -ƞ -Ŋŋ -OoÒÓÔÕÖòóôõöŌōŎŏŐőƠơǑǒǪǫǬǭỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợ -OEOeoEoeŒœ -ØøǾǿ -Ɔ -Ɵ -Pp -Ƥƥ -Qq -ĸ -RrŔŕŖŗŘř -RRRrrRrr -Ʀ -SsŚśŜŝŞşſ -SSSssSssß -Šš -Ʃ -ƪ -TtŢţŤť -ƾ -Ŧŧ -ƫ -Ƭƭ -Ʈ -UuÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųƯưǓǔǕǖǗǘǙǚǛǜỤụỦủỨứỪừỬửỮữỰự -Ɯ -Ʊ -Vv -Ʋ -WwŴŵ -Xx -ÝýÿŶŷŸ -Ƴƴ -ZzŹźŻż -ƍ -Žž -Ƶƶ -ƷǮǯ -Ƹƹ -ƺ -Þþ -ƿǷ -ƻ -Ƨƨ -Ƽƽ -Ƅƅ -ʼn -ǀ -ǁ -ǂ -ǃ -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_slovak_ci; -GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') -÷ -× -AaÀÁÂÃÅàáâãåĀāĂ㥹ǍǎǞǟǠǡǺǻẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặ -AAAaaAaa -AEAeaEae -Ää -ÆæǢǣǼǽ -Bb -ƀ -Ɓ -Ƃƃ -CcÇçĆćĈĉĊċ -cH -Čč -Ƈƈ -DdĎď -DZDzdZdzDŽDždžDZDzdz -DŽDždŽdž -Đđ -Ɖ -Ɗ -Ƌƌ -Ðð -EeÈÉÊËèéêëĒēĔĕĖėĘęĚěẸẹẺẻẼẽẾếỀềỂểỄễỆệ -Ǝǝ -Ə -Ɛ -Ff -Ƒƒ -GgĜĝĞğĠġĢģǦǧǴǵ -Ǥǥ -Ɠ -Ɣ -Ƣƣ -HhĤĥ -CHChch -ƕǶ -Ħħ -IiÌÍÎÏìíîïĨĩĪīĬĭĮįİǏǐỈỉỊị -IJIjiJijIJij -ı -Ɨ -Ɩ -JjĴĵǰ -KkĶķǨǩ -Ƙƙ -LlĹĺĻļĽľ -Ŀŀ -LJLjlJljLJLjlj -LLLllLll -Łł -ƚ -ƛ -Mm -NnÑñŃńŅņŇňǸǹ -NJNjnJnjNJNjnj -Ɲ -ƞ -Ŋŋ -OoÒÓÕÖòóõöŌōŎŏŐőƠơǑǒǪǫǬǭỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợ -OEOeoEoeŒœ -Ôô -ØøǾǿ -Ɔ -Ɵ -Pp -Ƥƥ -Qq -ĸ -RrŔŕŖŗŘř -RRRrrRrr -Ʀ -SsŚśŜŝŞşſ -SSSssSssß -Šš -Ʃ -ƪ -TtŢţŤť -ƾ -Ŧŧ -ƫ -Ƭƭ -Ʈ -UuÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųƯưǓǔǕǖǗǘǙǚǛǜỤụỦủỨứỪừỬửỮữỰự -Ɯ -Ʊ -Vv -Ʋ -WwŴŵ -Xx -YyÝýÿŶŷŸ -Ƴƴ -ZzŹźŻż -ƍ -Žž -Ƶƶ -ƷǮǯ -Ƹƹ -ƺ -Þþ -ƿǷ -ƻ -Ƨƨ -Ƽƽ -Ƅƅ -ʼn -ǀ -ǁ -ǂ -ǃ -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_spanish2_ci; -GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') -÷ -× -AaÀÁÂÃÄÅàáâãäåĀāĂ㥹ǍǎǞǟǠǡǺǻẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặ -AAAaaAaa -AEAeaEae -ÆæǢǣǼǽ -Bb -ƀ -Ɓ -Ƃƃ -CcÇçĆćĈĉĊċČč -cH -CHChch -Ƈƈ -DdĎď -DZDzDŽDždZdzdŽdžDŽDždžDZDzdz -Đđ -Ɖ -Ɗ -Ƌƌ -Ðð -EeÈÉÊËèéêëĒēĔĕĖėĘęĚěẸẹẺẻẼẽẾếỀềỂểỄễỆệ -Ǝǝ -Ə -Ɛ -Ff -Ƒƒ -GgĜĝĞğĠġĢģǦǧǴǵ -Ǥǥ -Ɠ -Ɣ -Ƣƣ -HhĤĥ -ƕǶ -Ħħ -IiÌÍÎÏìíîïĨĩĪīĬĭĮįİǏǐỈỉỊị -IJIjiJijIJij -ı -Ɨ -Ɩ -JjĴĵǰ -KkĶķǨǩ -Ƙƙ -LlĹĺĻļĽľ -Ŀŀ -LJLjlJljLJLjlj -lL -LLLlll -Łł -ƚ -ƛ -Mm -NnŃńŅņŇňǸǹ -NJNjnJnjNJNjnj -Ññ -Ɲ -ƞ -Ŋŋ -OoÒÓÔÕÖòóôõöŌōŎŏŐőƠơǑǒǪǫǬǭỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợ -OEOeoEoeŒœ -ØøǾǿ -Ɔ -Ɵ -Pp -Ƥƥ -Qq -ĸ -RrŔŕŖŗŘř -RRRrrRrr -Ʀ -SsŚśŜŝŞşŠšſ -SSSssSssß -Ʃ -ƪ -TtŢţŤť -ƾ -Ŧŧ -ƫ -Ƭƭ -Ʈ -UuÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųƯưǓǔǕǖǗǘǙǚǛǜỤụỦủỨứỪừỬửỮữỰự -Ɯ -Ʊ -Vv -Ʋ -WwŴŵ -Xx -YyÝýÿŶŷŸ -Ƴƴ -ZzŹźŻżŽž -ƍ -Ƶƶ -ƷǮǯ -Ƹƹ -ƺ -Þþ -ƿǷ -ƻ -Ƨƨ -Ƽƽ -Ƅƅ -ʼn -ǀ -ǁ -ǂ -ǃ -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_roman_ci; -GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') -÷ -× -AaÀÁÂÃÄÅàáâãäåĀāĂ㥹ǍǎǞǟǠǡǺǻẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặ -AAAaaAaa -AEAeaEae -ÆæǢǣǼǽ -Bb -ƀ -Ɓ -Ƃƃ -CcÇçĆćĈĉĊċČč -CHChcHch -Ƈƈ -DdĎď -DZDzDŽDždZdzdŽdžDŽDždžDZDzdz -Đđ -Ɖ -Ɗ -Ƌƌ -Ðð -EeÈÉÊËèéêëĒēĔĕĖėĘęĚěẸẹẺẻẼẽẾếỀềỂểỄễỆệ -Ǝǝ -Ə -Ɛ -Ff -Ƒƒ -GgĜĝĞğĠġĢģǦǧǴǵ -Ǥǥ -Ɠ -Ɣ -Ƣƣ -HhĤĥ -ƕǶ -Ħħ -IJijÌÍÎÏìíîïĨĩĪīĬĭĮįİǏǐỈỉỊị -IJIjiJij -IJij -ı -Ɨ -Ɩ -Ĵĵǰ -KkĶķǨǩ -Ƙƙ -LlĹĺĻļĽľ -Ŀŀ -LJLjlJlj -LJLjlj -LLLllLll -Łł -ƚ -ƛ -Mm -NnÑñŃńŅņŇňǸǹ -NJNjnJnj -NJNjnj -Ɲ -ƞ -Ŋŋ -OoÒÓÔÕÖòóôõöŌōŎŏŐőƠơǑǒǪǫǬǭỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợ -OEOeoEoeŒœ -ØøǾǿ -Ɔ -Ɵ -Pp -Ƥƥ -Qq -ĸ -RrŔŕŖŗŘř -RRRrrRrr -Ʀ -SsŚśŜŝŞşŠšſ -SSSssSssß -Ʃ -ƪ -TtŢţŤť -ƾ -Ŧŧ -ƫ -Ƭƭ -Ʈ -ÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųƯưǓǔǕǖǗǘǙǚǛǜỤụỦủỨứỪừỬửỮữỰự -Ɯ -Ʊ -UVuv -Ʋ -WwŴŵ -Xx -YyÝýÿŶŷŸ -Ƴƴ -ZzŹźŻżŽž -ƍ -Ƶƶ -ƷǮǯ -Ƹƹ -ƺ -Þþ -ƿǷ -ƻ -Ƨƨ -Ƽƽ -Ƅƅ -ʼn -ǀ -ǁ -ǂ -ǃ -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_esperanto_ci; -GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') -÷ -× -AaÀÁÂÃÄÅàáâãäåĀāĂ㥹ǍǎǞǟǠǡǺǻẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặ -AAAaaAaa -AEAeaEae -ÆæǢǣǼǽ -Bb -ƀ -Ɓ -Ƃƃ -CcÇçĆćĊċČč -CHChcHch -Ĉĉ -Ƈƈ -DdĎď -DZDzDŽDždZdzdŽdžDŽDždžDZDzdz -Đđ -Ɖ -Ɗ -Ƌƌ -Ðð -EeÈÉÊËèéêëĒēĔĕĖėĘęĚěẸẹẺẻẼẽẾếỀềỂểỄễỆệ -Ǝǝ -Ə -Ɛ -Ff -Ƒƒ -GgĞğĠġĢģǦǧǴǵ -Ĝĝ -Ǥǥ -Ɠ -Ɣ -Ƣƣ -Hh -Ĥĥ -ƕǶ -Ħħ -IiÌÍÎÏìíîïĨĩĪīĬĭĮįİǏǐỈỉỊị -IJIjiJijIJij -ı -Ɨ -Ɩ -Jjǰ -Ĵĵ -KkĶķǨǩ -Ƙƙ -LlĹĺĻļĽľ -Ŀŀ -LJLjlJljLJLjlj -LLLllLll -Łł -ƚ -ƛ -Mm -NnÑñŃńŅņŇňǸǹ -NJNjnJnjNJNjnj -Ɲ -ƞ -Ŋŋ -OoÒÓÔÕÖòóôõöŌōŎŏŐőƠơǑǒǪǫǬǭỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợ -OEOeoEoeŒœ -ØøǾǿ -Ɔ -Ɵ -Pp -Ƥƥ -Qq -ĸ -RrŔŕŖŗŘř -RRRrrRrr -Ʀ -SsŚśŞşŠšſ -SSSssSssß -Ŝŝ -Ʃ -ƪ -TtŢţŤť -ƾ -Ŧŧ -ƫ -Ƭƭ -Ʈ -UuÙÚÛÜùúûüŨũŪūŮůŰűŲųƯưǓǔǕǖǗǘǙǚǛǜỤụỦủỨứỪừỬửỮữỰự -Ŭŭ -Ɯ -Ʊ -Vv -Ʋ -WwŴŵ -Xx -YyÝýÿŶŷŸ -Ƴƴ -ZzŹźŻżŽž -ƍ -Ƶƶ -ƷǮǯ -Ƹƹ -ƺ -Þþ -ƿǷ -ƻ -Ƨƨ -Ƽƽ -Ƅƅ -ʼn -ǀ -ǁ -ǂ -ǃ -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_hungarian_ci; -GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') -÷ -× -AaÀÁÂÃÄÅàáâãäåĀāĂ㥹ǍǎǞǟǠǡǺǻẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặ -AAAaaAaa -AEAeaEae -ÆæǢǣǼǽ -Bb -ƀ -Ɓ -Ƃƃ -CcÇçĆćĈĉĊċČč -CHChcHch -Ƈƈ -DdĎď -DZDzDŽDždZdzdŽdžDŽDždžDZDzdz -Đđ -Ɖ -Ɗ -Ƌƌ -Ðð -EeÈÉÊËèéêëĒēĔĕĖėĘęĚěẸẹẺẻẼẽẾếỀềỂểỄễỆệ -Ǝǝ -Ə -Ɛ -Ff -Ƒƒ -GgĜĝĞğĠġĢģǦǧǴǵ -Ǥǥ -Ɠ -Ɣ -Ƣƣ -HhĤĥ -ƕǶ -Ħħ -IiÌÍÎÏìíîïĨĩĪīĬĭĮįİǏǐỈỉỊị -IJIjiJijIJij -ı -Ɨ -Ɩ -JjĴĵǰ -KkĶķǨǩ -Ƙƙ -LlĹĺĻļĽľ -Ŀŀ -LJLjlJljLJLjlj -LLLllLll -Łł -ƚ -ƛ -Mm -NnÑñŃńŅņŇňǸǹ -NJNjnJnjNJNjnj -Ɲ -ƞ -Ŋŋ -OoÒÓÔÕòóôõŌōŎŏƠơǑǒǪǫǬǭỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợ -OEOeoEoeŒœ -ÖöŐő -ØøǾǿ -Ɔ -Ɵ -Pp -Ƥƥ -Qq -ĸ -RrŔŕŖŗŘř -RRRrrRrr -Ʀ -SsŚśŜŝŞşŠšſ -SSSssSssß -Ʃ -ƪ -TtŢţŤť -ƾ -Ŧŧ -ƫ -Ƭƭ -Ʈ -UuÙÚÛùúûŨũŪūŬŭŮůŲųƯưǓǔǕǖǗǘǙǚǛǜỤụỦủỨứỪừỬửỮữỰự -ÜüŰű -Ɯ -Ʊ -Vv -Ʋ -WwŴŵ -Xx -YyÝýÿŶŷŸ -Ƴƴ -ZzŹźŻżŽž -ƍ -Ƶƶ -ƷǮǯ -Ƹƹ -ƺ -Þþ -ƿǷ -ƻ -Ƨƨ -Ƽƽ -Ƅƅ -ʼn -ǀ -ǁ -ǂ -ǃ -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_croatian_mysql561_ci; -GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') -÷ -× -AaÀÁÂÃÄÅàáâãäåĀāĂ㥹ǍǎǞǟǠǡǺǻẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặ -AAAaaAaa -AEAeaEae -ÆæǢǣǼǽ -Bb -ƀ -Ɓ -Ƃƃ -CcÇçĈĉĊċ -CHChcHch -Čč -Ćć -Ƈƈ -DdĎď -DZDzdZdzDZDzdz -DŽDždŽdžDŽDždž -Đđ -Ɖ -Ɗ -Ƌƌ -Ðð -EeÈÉÊËèéêëĒēĔĕĖėĘęĚěẸẹẺẻẼẽẾếỀềỂểỄễỆệ -Ǝǝ -Ə -Ɛ -Ff -Ƒƒ -GgĜĝĞğĠġĢģǦǧǴǵ -Ǥǥ -Ɠ -Ɣ -Ƣƣ -HhĤĥ -ƕǶ -Ħħ -IiÌÍÎÏìíîïĨĩĪīĬĭĮįİǏǐỈỉỊị -IJIjiJijIJij -ı -Ɨ -Ɩ -JjĴĵǰ -KkĶķǨǩ -Ƙƙ -LlĹĺĻļĽľ -Ŀŀ -LLLllLll -LJLjlJljLJLjlj -Łł -ƚ -ƛ -Mm -NnÑñŃńŅņŇňǸǹ -NJNjnJnjNJNjnj -Ɲ -ƞ -Ŋŋ -OoÒÓÔÕÖòóôõöŌōŎŏŐőƠơǑǒǪǫǬǭỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợ -OEOeoEoeŒœ -ØøǾǿ -Ɔ -Ɵ -Pp -Ƥƥ -Qq -ĸ -RrŔŕŖŗŘř -RRRrrRrr -Ʀ -SsŚśŜŝŞşſ -SSSssSssß -Šš -Ʃ -ƪ -TtŢţŤť -ƾ -Ŧŧ -ƫ -Ƭƭ -Ʈ -UuÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųƯưǓǔǕǖǗǘǙǚǛǜỤụỦủỨứỪừỬửỮữỰự -Ɯ -Ʊ -Vv -Ʋ -WwŴŵ -Xx -YyÝýÿŶŷŸ -Ƴƴ -ZzŹźŻż -ƍ -Žž -Ƶƶ -ƷǮǯ -Ƹƹ -ƺ -Þþ -ƿǷ -ƻ -Ƨƨ -Ƽƽ -Ƅƅ -ʼn -ǀ -ǁ -ǂ -ǃ -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_croatian_ci; -GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') -÷ -× -AaÀÁÂÃÄÅàáâãäåĀāĂ㥹ǍǎǞǟǠǡǺǻẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặ -AAAaaAaa -AEAeaEae -ÆæǢǣǼǽ -Bb -ƀ -Ɓ -Ƃƃ -CcÇçĈĉĊċ -CHChcHch -Čč -Ćć -Ƈƈ -DdĎď -DZDzdZdzDZDzdz -dŽ -DŽDždžDŽDždž -Đđ -Ɖ -Ɗ -Ƌƌ -Ðð -EeÈÉÊËèéêëĒēĔĕĖėĘęĚěẸẹẺẻẼẽẾếỀềỂểỄễỆệ -Ǝǝ -Ə -Ɛ -Ff -Ƒƒ -GgĜĝĞğĠġĢģǦǧǴǵ -Ǥǥ -Ɠ -Ɣ -Ƣƣ -HhĤĥ -ƕǶ -Ħħ -IiÌÍÎÏìíîïĨĩĪīĬĭĮįİǏǐỈỉỊị -IJIjiJijIJij -ı -Ɨ -Ɩ -JjĴĵǰ -KkĶķǨǩ -Ƙƙ -LlĹĺĻļĽľ -Ŀŀ -lJ -LLLllLll -LJLjljLJLjlj -Łł -ƚ -ƛ -Mm -NnÑñŃńŅņŇňǸǹ -nJ -NJNjnjNJNjnj -Ɲ -ƞ -Ŋŋ -OoÒÓÔÕÖòóôõöŌōŎŏŐőƠơǑǒǪǫǬǭỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợ -OEOeoEoeŒœ -ØøǾǿ -Ɔ -Ɵ -Pp -Ƥƥ -Qq -ĸ -RrŔŕŖŗŘř -RRRrrRrr -Ʀ -SsŚśŜŝŞşſ -SSSssSssß -Šš -Ʃ -ƪ -TtŢţŤť -ƾ -Ŧŧ -ƫ -Ƭƭ -Ʈ -UuÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųƯưǓǔǕǖǗǘǙǚǛǜỤụỦủỨứỪừỬửỮữỰự -Ɯ -Ʊ -Vv -Ʋ -WwŴŵ -Xx -YyÝýÿŶŷŸ -Ƴƴ -ZzŹźŻż -ƍ -Žž -Ƶƶ -ƷǮǯ -Ƹƹ -ƺ -Þþ -ƿǷ -ƻ -Ƨƨ -Ƽƽ -Ƅƅ -ʼn -ǀ -ǁ -ǂ -ǃ -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_german2_ci; -GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') -÷ -× -AaÀÁÂÃÅàáâãåĀāĂ㥹ǍǎǞǟǠǡǺǻẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặ -AAAaaAaa -AEAeaEaeÄÆäæ -ǢǣǼǽ -Bb -ƀ -Ɓ -Ƃƃ -CcÇçĆćĈĉĊċČč -CHChcHch -Ƈƈ -DdĎď -DZDzDŽDždZdzdŽdžDŽDždžDZDzdz -Đđ -Ɖ -Ɗ -Ƌƌ -Ðð -EeÈÉÊËèéêëĒēĔĕĖėĘęĚěẸẹẺẻẼẽẾếỀềỂểỄễỆệ -Ǝǝ -Ə -Ɛ -Ff -Ƒƒ -GgĜĝĞğĠġĢģǦǧǴǵ -Ǥǥ -Ɠ -Ɣ -Ƣƣ -HhĤĥ -ƕǶ -Ħħ -IiÌÍÎÏìíîïĨĩĪīĬĭĮįİǏǐỈỉỊị -IJIjiJijIJij -ı -Ɨ -Ɩ -JjĴĵǰ -KkĶķǨǩ -Ƙƙ -LlĹĺĻļĽľ -Ŀŀ -LJLjlJljLJLjlj -LLLllLll -Łł -ƚ -ƛ -Mm -NnÑñŃńŅņŇňǸǹ -NJNjnJnjNJNjnj -Ɲ -ƞ -Ŋŋ -OoÒÓÔÕòóôõŌōŎŏŐőƠơǑǒǪǫǬǭỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợ -OEOeoEoeÖöŒœ -ØøǾǿ -Ɔ -Ɵ -Pp -Ƥƥ -Qq -ĸ -RrŔŕŖŗŘř -RRRrrRrr -Ʀ -SsŚśŜŝŞşŠšſ -SSSssSssß -Ʃ -ƪ -TtŢţŤť -ƾ -Ŧŧ -ƫ -Ƭƭ -Ʈ -UuÙÚÛùúûŨũŪūŬŭŮůŰűŲųƯưǓǔǕǖǗǘǙǚǛǜỤụỦủỨứỪừỬửỮữỰự -Üü -Ɯ -Ʊ -Vv -Ʋ -WwŴŵ -Xx -YyÝýÿŶŷŸ -Ƴƴ -ZzŹźŻżŽž -ƍ -Ƶƶ -ƷǮǯ -Ƹƹ -ƺ -Þþ -ƿǷ -ƻ -Ƨƨ -Ƽƽ -Ƅƅ -ʼn -ǀ -ǁ -ǂ -ǃ -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_unicode_520_ci; -GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') -÷ -× -AaÀÁÂÃÄÅàáâãäåĀāĂ㥹ǍǎǞǟǠǡǺǻẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặ -AAAaaAaa -AEAeaEaeÆæǢǣǼǽ -Bb -ƀ -Ɓ -Ƃƃ -CcÇçĆćĈĉĊċČč -CHChcHch -Ƈƈ -DdÐðĎďĐđ -DZDzDŽDždZdzdŽdžDŽDždžDZDzdz -Ɖ -Ɗ -Ƌƌ -EeÈÉÊËèéêëĒēĔĕĖėĘęĚěẸẹẺẻẼẽẾếỀềỂểỄễỆệ -Ǝǝ -Ə -Ɛ -Ff -Ƒƒ -GgĜĝĞğĠġĢģǦǧǴǵ -Ǥǥ -Ɠ -Ɣ -Ƣƣ -HhĤĥĦħ -ƕǶ -IiÌÍÎÏìíîïĨĩĪīĬĭĮįİǏǐỈỉỊị -IJIjiJijIJij -ı -Ɨ -Ɩ -JjĴĵǰ -KkĶķǨǩ -Ƙƙ -LlĹĺĻļĽľĿŀŁł -LJLjlJljLJLjlj -LLLllLll -ƚ -ƛ -Mm -NnÑñŃńŅņŇňǸǹ -NJNjnJnjNJNjnj -Ɲ -ƞ -Ŋŋ -OoÒÓÔÕÖØòóôõöøŌōŎŏŐőƠơǑǒǪǫǬǭǾǿỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợ -OEOeoEoeŒœ -Ɔ -Ɵ -Pp -Ƥƥ -Qq -ĸ -RrŔŕŖŗŘř -RRRrrRrr -Ʀ -SsŚśŜŝŞşŠšſ -SSSssSssß -Ʃ -ƪ -TtŢţŤť -ƾ -Ŧŧ -ƫ -Ƭƭ -Ʈ -UuÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųƯưǓǔǕǖǗǘǙǚǛǜỤụỦủỨứỪừỬửỮữỰự -Ɯ -Ʊ -Vv -Ʋ -WwŴŵ -Xx -YyÝýÿŶŷŸ -Ƴƴ -ZzŹźŻżŽž -ƍ -Ƶƶ -ƷǮǯ -Ƹƹ -ƺ -Þþ -ƿǷ -ƻ -Ƨƨ -Ƽƽ -Ƅƅ -ʼn -ǀ -ǁ -ǂ -ǃ -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_vietnamese_ci; -GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') -÷ -× -AaÀÁÃÄÅàáãäåĀāĄąǍǎǞǟǠǡǺǻẠạẢả -AAAaaAaa -AEAeaEae -ĂăẮắẰằẲẳẴẵẶặ -ÂâẤấẦầẨẩẪẫẬậ -ÆæǢǣǼǽ -Bb -ƀ -Ɓ -Ƃƃ -CcÇçĆćĈĉĊċČč -CHChcHch -Ƈƈ -DdĎď -DZDzDŽDždZdzdŽdžDŽDždžDZDzdz -Đđ -Ɖ -Ɗ -Ƌƌ -Ðð -EeÈÉËèéëĒēĔĕĖėĘęĚěẸẹẺẻẼẽ -ÊêẾếỀềỂểỄễỆệ -Ǝǝ -Ə -Ɛ -Ff -Ƒƒ -GgĜĝĞğĠġĢģǦǧǴǵ -Ǥǥ -Ɠ -Ɣ -Ƣƣ -HhĤĥ -ƕǶ -Ħħ -IiÌÍÎÏìíîïĨĩĪīĬĭĮįİǏǐỈỉỊị -IJIjiJijIJij -ı -Ɨ -Ɩ -JjĴĵǰ -KkĶķǨǩ -Ƙƙ -LlĹĺĻļĽľ -Ŀŀ -LJLjlJljLJLjlj -LLLllLll -Łł -ƚ -ƛ -Mm -NnÑñŃńŅņŇňǸǹ -NJNjnJnjNJNjnj -Ɲ -ƞ -Ŋŋ -OoÒÓÕÖòóõöŌōŎŏŐőǑǒǪǫǬǭỌọỎỏ -OEOeoEoeŒœ -ÔôỐốỒồỔổỖỗỘộ -ƠơỚớỜờỞởỠỡỢợ -ØøǾǿ -Ɔ -Ɵ -Pp -Ƥƥ -Qq -ĸ -RrŔŕŖŗŘř -RRRrrRrr -Ʀ -SsŚśŜŝŞşŠšſ -SSSssSssß -Ʃ -ƪ -TtŢţŤť -ƾ -Ŧŧ -ƫ -Ƭƭ -Ʈ -UuÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųǓǔǕǖǗǘǙǚǛǜỤụỦủ -ƯưỨứỪừỬửỮữỰự -Ɯ -Ʊ -Vv -Ʋ -WwŴŵ -Xx -YyÝýÿŶŷŸ -Ƴƴ -ZzŹźŻżŽž -ƍ -Ƶƶ -ƷǮǯ -Ƹƹ -ƺ -Þþ -ƿǷ -ƻ -Ƨƨ -Ƽƽ -Ƅƅ -ʼn -ǀ -ǁ -ǂ -ǃ -DROP TABLE t1; # # MDEV-20912 Add support for utf8mb4_0900_* collations in MariaDB Server # diff --git a/mysql-test/main/ctype_utf8mb4_0900.test b/mysql-test/main/ctype_utf8mb4_0900.test index 2fd31fab464..8114ab2348f 100644 --- a/mysql-test/main/ctype_utf8mb4_0900.test +++ b/mysql-test/main/ctype_utf8mb4_0900.test @@ -15,37 +15,6 @@ where collation_name like "%0900%" order by collation_name; select * from information_schema.COLLATIONS where collation_name like "%0900%"; -SET NAMES utf8mb4; -CREATE TABLE t1 (c1 CHAR(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin); - ---source include/ctype_unicode_latin.inc - -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_unicode_ci; -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_icelandic_ci; -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_latvian_ci; -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_romanian_ci; -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_slovenian_ci; -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_polish_ci; -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_estonian_ci; -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_spanish_ci; -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_swedish_ci; -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_turkish_ci; -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_czech_ci; -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_danish_ci; -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_lithuanian_ci; -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_slovak_ci; -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_spanish2_ci; -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_roman_ci; -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_esperanto_ci; -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_hungarian_ci; -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_croatian_mysql561_ci; -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_croatian_ci; -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_german2_ci; -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_unicode_520_ci; -SELECT GROUP_CONCAT(c1 ORDER BY c1 SEPARATOR '') FROM t1 GROUP BY c1 COLLATE utf8mb4_vietnamese_ci; - -DROP TABLE t1; - --echo # --echo # MDEV-20912 Add support for utf8mb4_0900_* collations in MariaDB Server --echo # From b1f57a98a8fe1d79e3d1b827501383a19301d6fa Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 18 Jan 2025 15:07:53 +0100 Subject: [PATCH 102/213] cleanup: Alter_table_ctx::Alter_table_ctx() --- sql/sql_alter.cc | 22 ++++------------------ sql/sql_alter.h | 16 ++++++++-------- 2 files changed, 12 insertions(+), 26 deletions(-) diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc index dc98f9c8d93..d8cb7e8f341 100644 --- a/sql/sql_alter.cc +++ b/sql/sql_alter.cc @@ -297,16 +297,8 @@ uint Alter_info::check_vcol_field(Item_field *item) const Alter_table_ctx::Alter_table_ctx() - : implicit_default_value_error_field(NULL), - error_if_not_empty(false), - tables_opened(0), - db(null_clex_str), table_name(null_clex_str), alias(null_clex_str), - new_db(null_clex_str), new_name(null_clex_str), new_alias(null_clex_str), - fk_error_if_delete_row(false), fk_error_id(NULL), - fk_error_table(NULL), modified_primary_key(false) -#ifdef DBUG_ASSERT_EXISTS - , tmp_table(false) -#endif + : db(null_clex_str), table_name(null_clex_str), alias(null_clex_str), + new_db(null_clex_str), new_name(null_clex_str), new_alias(null_clex_str) { } @@ -319,14 +311,8 @@ Alter_table_ctx::Alter_table_ctx(THD *thd, TABLE_LIST *table_list, uint tables_opened_arg, const LEX_CSTRING *new_db_arg, const LEX_CSTRING *new_name_arg) - : implicit_default_value_error_field(NULL), error_if_not_empty(false), - tables_opened(tables_opened_arg), - new_db(*new_db_arg), new_name(*new_name_arg), - fk_error_if_delete_row(false), fk_error_id(NULL), - fk_error_table(NULL), modified_primary_key(false) -#ifdef DBUG_ASSERT_EXISTS - , tmp_table(false) -#endif + : tables_opened(tables_opened_arg), + new_db(*new_db_arg), new_name(*new_name_arg) { /* Assign members db, table_name, new_db and new_name diff --git a/sql/sql_alter.h b/sql/sql_alter.h index 65643eac46f..c5e6cb9ba34 100644 --- a/sql/sql_alter.h +++ b/sql/sql_alter.h @@ -306,9 +306,9 @@ public: void report_implicit_default_value_error(THD *thd, const TABLE_SHARE *) const; public: - Create_field *implicit_default_value_error_field; - bool error_if_not_empty; - uint tables_opened; + Create_field *implicit_default_value_error_field= NULL; + bool error_if_not_empty= false; + uint tables_opened= 0; LEX_CSTRING db; LEX_CSTRING table_name; LEX_CSTRING alias; @@ -322,12 +322,12 @@ public: of table to the new version ER_FK_CANNOT_DELETE_PARENT error should be emitted. */ - bool fk_error_if_delete_row; + bool fk_error_if_delete_row= false; /** Name of foreign key for the above error. */ - const char *fk_error_id; + const char *fk_error_id= NULL; /** Name of table for the above error. */ - const char *fk_error_table; - bool modified_primary_key; + const char *fk_error_table= NULL; + bool modified_primary_key= false; private: char new_filename[FN_REFLEN + 1]; @@ -339,7 +339,7 @@ private: #ifdef DBUG_ASSERT_EXISTS /** Indicates that we are altering temporary table. Used only in asserts. */ - bool tmp_table; + bool tmp_table= false; #endif Alter_table_ctx &operator=(const Alter_table_ctx &rhs); // not implemented From 782c4b94f08ef50f5f86e70c14a601e20ca72f1a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 18 Jan 2025 15:11:12 +0100 Subject: [PATCH 103/213] MDEV-25654 only force HA_KEY_ALG_HASH for fast alter partition not for any ALTER TABLE without ALTER_CHANGE_COLUMN. This fixes galera_sr.MDEV-28971 test followup for 0dcd30197ade --- mysql-test/main/long_unique_bugs.result | 6 ++++++ mysql-test/main/long_unique_bugs.test | 5 +++++ sql/sql_alter.h | 1 + sql/sql_table.cc | 25 +++++++++---------------- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/mysql-test/main/long_unique_bugs.result b/mysql-test/main/long_unique_bugs.result index 1caec209d9f..5ee8b65fbf6 100644 --- a/mysql-test/main/long_unique_bugs.result +++ b/mysql-test/main/long_unique_bugs.result @@ -741,4 +741,10 @@ insert into t1 select seq from seq_1_to_100; alter table t1 add partition (partition p3 values less than (maxvalue)); alter table t1 force; drop table t1; +# veirfy that duplicate has unique is detected +create table t1 (a blob unique); +alter table t1 add constraint constraint_1 unique (a); +Warnings: +Note 1831 Duplicate index `constraint_1`. This is deprecated and will be disallowed in a future release +drop table t1; # End of 10.5 tests diff --git a/mysql-test/main/long_unique_bugs.test b/mysql-test/main/long_unique_bugs.test index 6ad59fe6495..3fbe2a6b777 100644 --- a/mysql-test/main/long_unique_bugs.test +++ b/mysql-test/main/long_unique_bugs.test @@ -721,4 +721,9 @@ alter table t1 force; drop table t1; +--echo # veirfy that duplicate has unique is detected +create table t1 (a blob unique); +alter table t1 add constraint constraint_1 unique (a); +drop table t1; + --echo # End of 10.5 tests diff --git a/sql/sql_alter.h b/sql/sql_alter.h index c5e6cb9ba34..5e7f59650b2 100644 --- a/sql/sql_alter.h +++ b/sql/sql_alter.h @@ -328,6 +328,7 @@ public: /** Name of table for the above error. */ const char *fk_error_table= NULL; bool modified_primary_key= false; + bool fast_alter_partition= false; private: char new_filename[FN_REFLEN + 1]; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 3563c0fa982..aec81d8941e 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -9276,19 +9276,13 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, LEX_CSTRING tmp_name; bzero((char*) &key_create_info, sizeof(key_create_info)); if (key_info->algorithm == HA_KEY_ALG_LONG_HASH) - key_info->algorithm= (alter_info->flags & ALTER_CHANGE_COLUMN) ? - HA_KEY_ALG_UNDEF : HA_KEY_ALG_HASH; + key_info->algorithm= alter_ctx->fast_alter_partition ? + HA_KEY_ALG_HASH : HA_KEY_ALG_UNDEF; /* - This one goes to mysql_prepare_create_table(): - - key_info->algorithm= key->key_create_info.algorithm; - - For HA_KEY_ALG_LONG_HASH if we didn't change ANY column, we pass - HA_KEY_ALG_HASH to ensure mysql_prepare_create_table() does add_hash_field(). - This protects fast alter partition from losing hash properties. - In case of any column changes we drop algorithm to HA_KEY_ALG_UNDEF and - let decide mysql_prepare_create_table() if the hash field is needed - depending on new types. + For fast alter partition we set HA_KEY_ALG_HASH above to make sure it + doesn't lose the hash property. + Otherwise we let mysql_prepare_create_table() decide if the hash field + is needed depending on the (possibly changed) data types. */ key_create_info.algorithm= key_info->algorithm; /* @@ -10317,7 +10311,6 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, TABLE *table, *new_table= nullptr; #ifdef WITH_PARTITION_STORAGE_ENGINE bool partition_changed= false; - bool fast_alter_partition= false; #endif /* Create .FRM for new version of table with a temporary name. @@ -10844,7 +10837,7 @@ do_continue:; Partitioning: part_info is prepared and returned via thd->work_part_info */ if (prep_alter_part_table(thd, table, alter_info, create_info, - &partition_changed, &fast_alter_partition)) + &partition_changed, &alter_ctx.fast_alter_partition)) { DBUG_RETURN(true); } @@ -10879,7 +10872,7 @@ do_continue:; Note, one can run a separate "ALTER TABLE t1 FORCE;" statement before or after the partition change ALTER statement to upgrade data types. */ - if (IF_PARTITIONING(!fast_alter_partition, 1)) + if (!alter_ctx.fast_alter_partition) Create_field::upgrade_data_types(alter_info->create_list); if (create_info->check_fields(thd, alter_info, @@ -10891,7 +10884,7 @@ do_continue:; promote_first_timestamp_column(&alter_info->create_list); #ifdef WITH_PARTITION_STORAGE_ENGINE - if (fast_alter_partition) + if (alter_ctx.fast_alter_partition) { /* ALGORITHM and LOCK clauses are generally not allowed by the From cbb24d9aa5978c1a2d008f9ebf208acd9ee9eaa9 Mon Sep 17 00:00:00 2001 From: ParadoxV5 Date: Thu, 16 Jan 2025 20:57:01 -0700 Subject: [PATCH 104/213] MDEV-35646: Limit `pseudo_thread_id` to `UINT32_MAX` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Although the `my_thread_id` type is 64 bits, binlog format specs limits it to 32 bits in practice. (See also: MDEV-35706) The writable SQL variable `pseudo_thread_id` didn’t realize this though and had a range of `ULONGLONG_MAX` (at least `UINT64_MAX` in C/C++). It consequentially accepted larger values silently, but only the lower 32 bits of whom gets binlogged; this could lead to inconsistency. Reviewed-by: Brandon Nesterenko --- include/my_pthread.h | 7 +++++++ mysql-test/suite/sys_vars/r/sysvars_server_embedded.result | 2 +- .../suite/sys_vars/r/sysvars_server_notembedded.result | 2 +- sql/mysqld.cc | 2 +- sql/sys_vars.cc | 2 +- 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/include/my_pthread.h b/include/my_pthread.h index 10cc2301ea6..519d1be1cb5 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -641,6 +641,13 @@ extern pthread_mutexattr_t my_errorcheck_mutexattr; #endif typedef uint64 my_thread_id; +/** + Long-standing formats (such as the client-server protocol and the binary log) + hard-coded `my_thread_id` to 32 bits in practice. (Though not all + `thread_id`s are typed as such, @ref my_thread_id itself among those.) + @see MDEV-35706 +*/ +#define MY_THREAD_ID_MAX UINT32_MAX extern void my_threadattr_global_init(void); extern my_bool my_thread_global_init(void); diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result index a5a02bfa1bc..cdf6d210933 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result @@ -2877,7 +2877,7 @@ VARIABLE_SCOPE SESSION ONLY VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT This variable is for internal server use NUMERIC_MIN_VALUE 0 -NUMERIC_MAX_VALUE 18446744073709551615 +NUMERIC_MAX_VALUE 4294967295 NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result index 50dd4ae23a3..0af08d00c89 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -3037,7 +3037,7 @@ VARIABLE_SCOPE SESSION ONLY VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT This variable is for internal server use NUMERIC_MIN_VALUE 0 -NUMERIC_MAX_VALUE 18446744073709551615 +NUMERIC_MAX_VALUE 4294967295 NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d6dd8a566af..7a7c1f0491a 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -9770,7 +9770,7 @@ void init_server_psi_keys(void) */ -static my_thread_id thread_id_max= UINT_MAX32; +static my_thread_id thread_id_max= MY_THREAD_ID_MAX; #include #include diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 93298ff7b04..a2058dee224 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1767,7 +1767,7 @@ Sys_pseudo_thread_id( "pseudo_thread_id", "This variable is for internal server use", SESSION_ONLY(pseudo_thread_id), - NO_CMD_LINE, VALID_RANGE(0, ULONGLONG_MAX), DEFAULT(0), + NO_CMD_LINE, VALID_RANGE(0, MY_THREAD_ID_MAX), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD, IN_BINLOG); static bool From 8d6c9ef00112f8eddbcebb4f34902e1023f2a497 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Fri, 20 Dec 2024 14:14:28 +1100 Subject: [PATCH 105/213] MDEV-34925 Fix segv on thd in spider recovery. Create temporary thd whenever needed in spider xa commit / recovery. This prevents crash during recovery. --- .../spider/bugfix/r/mdev_27438.result | 6 +++ .../bugfix/r/mdev_27438_spider_table.result | 25 ++++++++++ .../spider/bugfix/t/mdev_27438.test | 22 ++++++++ .../bugfix/t/mdev_27438_spider_table.test | 38 ++++++++++++++ storage/spider/spd_trx.cc | 50 +++++++++++++------ 5 files changed, 127 insertions(+), 14 deletions(-) create mode 100644 storage/spider/mysql-test/spider/bugfix/r/mdev_27438.result create mode 100644 storage/spider/mysql-test/spider/bugfix/r/mdev_27438_spider_table.result create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_27438.test create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_27438_spider_table.test diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_27438.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_27438.result new file mode 100644 index 00000000000..7a30b0d27db --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_27438.result @@ -0,0 +1,6 @@ +install soname 'ha_spider'; +CREATE TABLE t1 (a INT) ENGINE=Innodb; +SET SESSION debug_dbug="+d,crash_commit_after_log"; +INSERT INTO t1 VALUES (1); +Got one of the listed errors +drop table t1; diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_27438_spider_table.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_27438_spider_table.result new file mode 100644 index 00000000000..a3fc1de5767 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_27438_spider_table.result @@ -0,0 +1,25 @@ +install soname 'ha_spider'; +set spider_same_server_link= 1; +CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +CREATE TABLE t1 (a INT); +create table t2 (a int) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t1"'; +INSERT INTO t2 VALUES (1); +SET SESSION debug_dbug="+d,crash_commit_after_log"; +INSERT INTO t2 VALUES (2); +Got one of the listed errors +call mtr.add_suppression(".*\\[ERROR\\] mariadbd: Table './test/t1' is marked as crashed and should be repaired"); +call mtr.add_suppression(".*\\[Warning\\] Checking table: './test/t1'"); +set spider_same_server_link= 1; +select * from t2; +a +1 +2 +Warnings: +Error 1034 1 client is using or hasn't closed the table properly +Error 1034 Table is fixed +drop server srv; +drop table t1, t2; +Warnings: +Warning 1620 Plugin is busy and will be uninstalled on shutdown diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_27438.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_27438.test new file mode 100644 index 00000000000..44b4e0be912 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27438.test @@ -0,0 +1,22 @@ +--source include/have_debug.inc +# Valgrind does not work well with test that crashes the server +--source include/not_valgrind.inc +install soname 'ha_spider'; +CREATE TABLE t1 (a INT) ENGINE=Innodb; + +# crash the server. +--let $expect_file_name= `select regexp_replace(@@tmpdir, '^.*/','')` +--let $expect_file_name= $MYSQLTEST_VARDIR/tmp/$expect_file_name.expect +--exec echo wait > $expect_file_name +SET SESSION debug_dbug="+d,crash_commit_after_log"; +--error 2006,2013 +INSERT INTO t1 VALUES (1); + +# restart the server +--exec echo restart >> $expect_file_name +--enable_reconnect +--source include/wait_until_connected_again.inc + +drop table t1; +--disable_query_log +--source ../../include/clean_up_spider.inc diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_27438_spider_table.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_27438_spider_table.test new file mode 100644 index 00000000000..dff655141bb --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27438_spider_table.test @@ -0,0 +1,38 @@ +--source include/have_debug.inc +# Valgrind does not work well with test that crashes the server +--source include/not_valgrind.inc + +# Same as spider/bugfix.mdev_27438, but actually using a spider table. +install soname 'ha_spider'; +set spider_same_server_link= 1; +evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); + +CREATE TABLE t1 (a INT); +create table t2 (a int) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t1"'; +INSERT INTO t2 VALUES (1); + +# crash the server. +--let $expect_file_name= `select regexp_replace(@@tmpdir, '^.*/','')` +--let $expect_file_name= $MYSQLTEST_VARDIR/tmp/$expect_file_name.expect +--exec echo wait > $expect_file_name +SET SESSION debug_dbug="+d,crash_commit_after_log"; +--error 2006,2013 +INSERT INTO t2 VALUES (2); + +# restart the server +--exec echo restart >> $expect_file_name +--enable_reconnect +--source include/wait_until_connected_again.inc + +call mtr.add_suppression(".*\\[ERROR\\] mariadbd: Table './test/t1' is marked as crashed and should be repaired"); +call mtr.add_suppression(".*\\[Warning\\] Checking table: './test/t1'"); +set spider_same_server_link= 1; +--disable_ps_protocol +select * from t2; +--enable_ps_protocol +drop server srv; +drop table t1, t2; +--disable_query_log +--source ../../include/clean_up_spider.inc diff --git a/storage/spider/spd_trx.cc b/storage/spider/spd_trx.cc index 6bbf0252619..6a76f03c1b0 100644 --- a/storage/spider/spd_trx.cc +++ b/storage/spider/spd_trx.cc @@ -2598,7 +2598,17 @@ int spider_internal_xa_commit_by_xid( SPIDER_Open_tables_backup open_tables_backup; bool table_xa_opened = FALSE; bool table_xa_member_opened = FALSE; + bool created_tmp_thd = FALSE; DBUG_ENTER("spider_internal_xa_commit_by_xid"); + if (!thd) + { + if (!(thd = spider_create_tmp_thd())) + { + error_num = HA_ERR_OUT_OF_MEM; + goto error; + } + created_tmp_thd= TRUE; + } /* select status @@ -2798,6 +2808,8 @@ xa_delete: goto error; spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE); table_xa_opened = FALSE; + if (created_tmp_thd) + spider_free_tmp_thd(thd); DBUG_RETURN(0); error: @@ -2806,6 +2818,8 @@ error: if (table_xa_member_opened) spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE); error_open_table: + if (created_tmp_thd) + spider_free_tmp_thd(thd); DBUG_RETURN(error_num); } @@ -2830,7 +2844,17 @@ int spider_internal_xa_rollback_by_xid( SPIDER_Open_tables_backup open_tables_backup; bool table_xa_opened = FALSE; bool table_xa_member_opened = FALSE; + bool created_tmp_thd= FALSE; DBUG_ENTER("spider_internal_xa_rollback_by_xid"); + if (!thd) + { + if (!(thd = spider_create_tmp_thd())) + { + error_num = HA_ERR_OUT_OF_MEM; + goto error; + } + created_tmp_thd= TRUE; + } /* select status @@ -3028,6 +3052,8 @@ xa_delete: goto error; spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE); table_xa_opened = FALSE; + if (created_tmp_thd) + spider_free_tmp_thd(thd); DBUG_RETURN(0); error: @@ -3036,6 +3062,8 @@ error: if (table_xa_member_opened) spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE); error_open_table: + if (created_tmp_thd) + spider_free_tmp_thd(thd); DBUG_RETURN(error_num); } @@ -3360,15 +3388,12 @@ int spider_xa_commit_by_xid( DBUG_ENTER("spider_xa_commit_by_xid"); if (!(trx = spider_get_trx(thd, TRUE, &error_num))) - goto error_get_trx; + DBUG_RETURN(error_num); - if ((error_num = spider_internal_xa_commit_by_xid(thd, trx, xid))) - goto error; + error_num = spider_internal_xa_commit_by_xid(thd, trx, xid); - DBUG_RETURN(0); - -error: -error_get_trx: + if (!thd) + spider_free_trx(trx, FALSE); DBUG_RETURN(error_num); } @@ -3382,15 +3407,12 @@ int spider_xa_rollback_by_xid( DBUG_ENTER("spider_xa_rollback_by_xid"); if (!(trx = spider_get_trx(thd, TRUE, &error_num))) - goto error_get_trx; + DBUG_RETURN(error_num); - if ((error_num = spider_internal_xa_rollback_by_xid(thd, trx, xid))) - goto error; + error_num = spider_internal_xa_rollback_by_xid(thd, trx, xid); - DBUG_RETURN(0); - -error: -error_get_trx: + if (!thd) + spider_free_trx(trx, FALSE); DBUG_RETURN(error_num); } From c05e7c4e0eff174a1f2b5e6efd53d80954f9e34b Mon Sep 17 00:00:00 2001 From: Vlad Lesin Date: Wed, 4 Dec 2024 19:56:46 +0300 Subject: [PATCH 106/213] MDEV-35708 lock_rec_get_prev() returns only the first record lock It's supposed that the function gets the previous lock set on a record. But if there are several locks set on a record, it will return only the first one. Continue locks list iteration till the certain lock even if the certain bit in lock bitmap is set. --- storage/innobase/lock/lock0lock.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 94eeef57bd7..4601fb4394d 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -984,13 +984,14 @@ lock_rec_get_prev( ut_ad(!in_lock->is_table()); const page_id_t id{in_lock->un_member.rec_lock.page_id}; hash_cell_t *cell= lock_sys.hash_get(in_lock->type_mode).cell_get(id.fold()); + lock_t *prev_lock= nullptr; for (lock_t *lock= lock_sys_t::get_first(*cell, id); lock != in_lock; lock= lock_rec_get_next_on_page(lock)) if (lock_rec_get_nth_bit(lock, heap_no)) - return lock; + prev_lock= lock; - return nullptr; + return prev_lock; } /*============= FUNCTIONS FOR ANALYZING RECORD LOCK QUEUE ================*/ From 43c36b3c884f2ece37ab9c3475d27027a36fc9af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 15 Jan 2025 09:44:30 +0200 Subject: [PATCH 107/213] MDEV-35852 : ASAN heap-use-after-free in WSREP_DEBUG after INSERT DELAYED Problem was that in case of INSERT DELAYED thd->query() is freed before we call trans_rollback where WSREP_DEBUG could access thd->query() in wsrep_thd_query(). Fix is to reset thd->query() to NULL in delayed_insert destructor after it is freed. There is already null guard at wsrep_thd_query(). Signed-off-by: Julius Goryavsky --- mysql-test/suite/galera/r/MDEV-35852.result | 8 ++++++++ mysql-test/suite/galera/t/MDEV-35852.cnf | 4 ++++ mysql-test/suite/galera/t/MDEV-35852.test | 9 +++++++++ sql/handler.cc | 13 ++++++++----- sql/service_wsrep.cc | 4 +++- sql/sql_insert.cc | 1 + 6 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 mysql-test/suite/galera/r/MDEV-35852.result create mode 100644 mysql-test/suite/galera/t/MDEV-35852.cnf create mode 100644 mysql-test/suite/galera/t/MDEV-35852.test diff --git a/mysql-test/suite/galera/r/MDEV-35852.result b/mysql-test/suite/galera/r/MDEV-35852.result new file mode 100644 index 00000000000..f9d07043cf9 --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-35852.result @@ -0,0 +1,8 @@ +connection node_2; +connection node_1; +CREATE TABLE t (a INT) ENGINE=InnoDB; +INSERT DELAYED INTO t VALUES (); +ERROR HY000: DELAYED option not supported for table 't' +DROP TABLE t; +INSERT DELAYED t1 () VALUES (); +ERROR 42S02: Table 'test.t1' doesn't exist diff --git a/mysql-test/suite/galera/t/MDEV-35852.cnf b/mysql-test/suite/galera/t/MDEV-35852.cnf new file mode 100644 index 00000000000..ebd79612b81 --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-35852.cnf @@ -0,0 +1,4 @@ +!include ../galera_2nodes.cnf + +[mysqld] +wsrep-debug=1 diff --git a/mysql-test/suite/galera/t/MDEV-35852.test b/mysql-test/suite/galera/t/MDEV-35852.test new file mode 100644 index 00000000000..6dce2974dd4 --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-35852.test @@ -0,0 +1,9 @@ +--source include/galera_cluster.inc + +CREATE TABLE t (a INT) ENGINE=InnoDB; +--error ER_DELAYED_NOT_SUPPORTED +INSERT DELAYED INTO t VALUES (); +DROP TABLE t; + +--error ER_NO_SUCH_TABLE +INSERT DELAYED t1 () VALUES (); diff --git a/sql/handler.cc b/sql/handler.cc index 50bcf86f25c..a6e5043a636 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2158,8 +2158,10 @@ int ha_rollback_trans(THD *thd, bool all) my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err); error=1; #ifdef WITH_WSREP - WSREP_WARN("handlerton rollback failed, thd %lld %lld conf %d SQL %s", + WSREP_WARN("handlerton rollback failed, thd %lld %lld " + "conf %d wsrep_err %s SQL %s", thd->thread_id, thd->query_id, thd->wsrep_trx().state(), + wsrep::to_c_string(thd->wsrep_cs().current_error()), thd->query()); #endif /* WITH_WSREP */ } @@ -2172,11 +2174,12 @@ int ha_rollback_trans(THD *thd, bool all) } #ifdef WITH_WSREP - if (thd->is_error()) + if (WSREP(thd) && thd->is_error()) { - WSREP_DEBUG("ha_rollback_trans(%lld, %s) rolled back: %s: %s; is_real %d", - thd->thread_id, all?"TRUE":"FALSE", wsrep_thd_query(thd), - thd->get_stmt_da()->message(), is_real_trans); + WSREP_DEBUG("ha_rollback_trans(%lld, %s) rolled back: msg %s is_real %d wsrep_err %s", + thd->thread_id, all? "TRUE" : "FALSE", + thd->get_stmt_da()->message(), is_real_trans, + wsrep::to_c_string(thd->wsrep_cs().current_error())); } // REPLACE|INSERT INTO ... SELECT uses TOI in consistency check diff --git a/sql/service_wsrep.cc b/sql/service_wsrep.cc index 6aab1bec99b..d1e0260d53c 100644 --- a/sql/service_wsrep.cc +++ b/sql/service_wsrep.cc @@ -1,4 +1,4 @@ -/* Copyright 2018-2024 Codership Oy +/* Copyright 2018-2025 Codership Oy 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 @@ -86,7 +86,9 @@ extern "C" const char *wsrep_thd_query(const THD *thd) return "SET PASSWORD"; /* fallthrough */ default: + { return (thd->query() ? thd->query() : "NULL"); + } } return "NULL"; } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 2a978640122..0182ca0ee1b 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2421,6 +2421,7 @@ public: delayed_insert_threads--; my_free(thd.query()); + thd.reset_query_inner(); thd.security_ctx->user= 0; thd.security_ctx->host= 0; } From d32ec7d48e1c942773da2a1a4d2233d755a8e58e Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Mon, 20 Jan 2025 12:14:46 +0100 Subject: [PATCH 108/213] MDEV-35852 : ASAN heap-use-after-free in WSREP_DEBUG after INSERT DELAYED Post-fix: remove unnecessary warning messages when wrep is not used. --- sql/handler.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index a6e5043a636..979e9315571 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2158,11 +2158,14 @@ int ha_rollback_trans(THD *thd, bool all) my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err); error=1; #ifdef WITH_WSREP - WSREP_WARN("handlerton rollback failed, thd %lld %lld " - "conf %d wsrep_err %s SQL %s", - thd->thread_id, thd->query_id, thd->wsrep_trx().state(), - wsrep::to_c_string(thd->wsrep_cs().current_error()), - thd->query()); + if (WSREP(thd)) + { + WSREP_WARN("handlerton rollback failed, thd %lld %lld " + "conf %d wsrep_err %s SQL %s", + thd->thread_id, thd->query_id, thd->wsrep_trx().state(), + wsrep::to_c_string(thd->wsrep_cs().current_error()), + thd->query()); + } #endif /* WITH_WSREP */ } status_var_increment(thd->status_var.ha_rollback_count); From b056ed6d985cf3b649a3b9f000ad228f543ff894 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 20 Jan 2025 14:07:23 +0100 Subject: [PATCH 109/213] MDEV-35891 mtr, Windows - fix multi-process append for stdout and stderr This backports https://github.com/mysql/mysql-server/commit/e2f685972985, which works around perl issue https://github.com/Perl/perl5/issues/17570 MySQL fix ensures that FILE_APPEND_DATA is used in redirected stdout/stderr open flags, rather than FILE_GENERIC_WRITE. Only this gives lossless append behavior, if multiple processes use the same file. --- .../lib/My/SafeProcess/safe_process_win.cc | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/mysql-test/lib/My/SafeProcess/safe_process_win.cc b/mysql-test/lib/My/SafeProcess/safe_process_win.cc index 8a5bb60a3f5..6e1fd414287 100644 --- a/mysql-test/lib/My/SafeProcess/safe_process_win.cc +++ b/mysql-test/lib/My/SafeProcess/safe_process_win.cc @@ -152,6 +152,24 @@ void handle_signal (int signal) } } +/** + Sets the append flag (FILE_APPEND_DATA) so that the handle inherited by the + child process will be in append mode. + Workaround for perl bug https://github.com/Perl/perl5/issues/17570 +*/ +static void fix_file_append_flag_inheritance(DWORD std_handle) +{ + HANDLE old_handle = GetStdHandle(std_handle); + HANDLE new_handle = ReOpenFile(old_handle, FILE_APPEND_DATA, + FILE_SHARE_WRITE | FILE_SHARE_READ, 0); + if (new_handle != INVALID_HANDLE_VALUE) + { + SetHandleInformation(new_handle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); + SetStdHandle(std_handle, new_handle); + CloseHandle(old_handle); + } +} + int main(int argc, const char** argv ) { @@ -270,6 +288,9 @@ int main(int argc, const char** argv ) SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); + fix_file_append_flag_inheritance(STD_OUTPUT_HANDLE); + fix_file_append_flag_inheritance(STD_ERROR_HANDLE); + #if 0 /* Setup stdin, stdout and stderr redirect */ si.dwFlags= STARTF_USESTDHANDLES; From c1559f261f2e7a95b035e2be8510e4ef47c6cd23 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 20 Jan 2025 19:53:25 +0400 Subject: [PATCH 110/213] MDEV-35688 UBSAN: SUMMARY: UndefinedBehaviorSanitizer: nullptr-with-offset in my_casedn_utf8mb3 The functions MY_CHARSET_HANDLER::caseup() and MY_CHARSET_HANDLER::casedn() in their virtual imlementations do "const char *end= src + srclen" in the very beginning. Therefore src cannot be NULL to avoid "UBSAN: SUMMARY: UndefinedBehaviorSanitizer: nullptr-with-offset". Adding DBUG_ASSERT(src != NULL) into all virtual implementations, to catch this problem in regular Debug builds (without UBSAN). Fixing Master_info_index::get_master_info() to check connection_name->str. If it is NULL then passing empty_clex_str into IdentBufferCasedn instead of *connection_name. --- mysql-test/suite/sys_vars/r/replicate_do_db_basic.result | 6 ++++++ mysql-test/suite/sys_vars/t/replicate_do_db_basic.test | 6 ++++++ sql/rpl_mi.cc | 4 +++- strings/ctype-mb.c | 2 ++ strings/ctype-simple.c | 2 ++ strings/ctype-ucs2.c | 6 ++++++ strings/ctype-ujis.c | 2 ++ strings/ctype-utf8.c | 4 ++++ 8 files changed, 31 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/sys_vars/r/replicate_do_db_basic.result b/mysql-test/suite/sys_vars/r/replicate_do_db_basic.result index 54adf835962..441291401bc 100644 --- a/mysql-test/suite/sys_vars/r/replicate_do_db_basic.result +++ b/mysql-test/suite/sys_vars/r/replicate_do_db_basic.result @@ -43,3 +43,9 @@ SELECT @@GLOBAL.replicate_do_db; # Cleanup. SET @@GLOBAL.replicate_do_db = @save_replicate_do_db; +# +# MDEV-35688 UBSAN: SUMMARY: UndefinedBehaviorSanitizer: nullptr-with-offset in my_casedn_utf8mb3 +# +show variables like 'replicate_do_db'; +Variable_name Value +replicate_do_db diff --git a/mysql-test/suite/sys_vars/t/replicate_do_db_basic.test b/mysql-test/suite/sys_vars/t/replicate_do_db_basic.test index b7004d1938b..5f2074b9c67 100644 --- a/mysql-test/suite/sys_vars/t/replicate_do_db_basic.test +++ b/mysql-test/suite/sys_vars/t/replicate_do_db_basic.test @@ -43,3 +43,9 @@ SELECT @@GLOBAL.replicate_do_db; --echo # Cleanup. SET @@GLOBAL.replicate_do_db = @save_replicate_do_db; + +--echo # +--echo # MDEV-35688 UBSAN: SUMMARY: UndefinedBehaviorSanitizer: nullptr-with-offset in my_casedn_utf8mb3 +--echo # + +show variables like 'replicate_do_db'; diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index a61df1ea11c..7d8b70d5f8e 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -1374,7 +1374,9 @@ Master_info_index::get_master_info(const LEX_CSTRING *connection_name, connection_name->str)); /* Make name lower case for comparison */ - IdentBufferCasedn buff(*connection_name); + IdentBufferCasedn buff(connection_name->str ? + *connection_name : + empty_clex_str); mi= (Master_info*) my_hash_search(&master_info_hash, (const uchar*) buff.ptr(), buff.length()); if (!mi && warning != Sql_condition::WARN_LEVEL_NOTE) diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index 88dd36312ea..404d1c7cd47 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -125,6 +125,7 @@ size_t my_casedn_mb(CHARSET_INFO * cs, const char *src, size_t srclen, char *dst, size_t dstlen) { + DBUG_ASSERT(src != NULL); /* Avoid UBSAN nullptr-with-offset */ DBUG_ASSERT(dstlen >= srclen * cs->cset->casedn_multiply(cs)); DBUG_ASSERT(src != dst || cs->cset->casedn_multiply(cs) == 1); return my_casefold_mb(cs, src, srclen, dst, dstlen, cs->to_lower, 0); @@ -135,6 +136,7 @@ size_t my_caseup_mb(CHARSET_INFO * cs, const char *src, size_t srclen, char *dst, size_t dstlen) { + DBUG_ASSERT(src != NULL); /* Avoid UBSAN nullptr-with-offset */ DBUG_ASSERT(dstlen >= srclen * cs->cset->caseup_multiply(cs)); DBUG_ASSERT(src != dst || cs->cset->caseup_multiply(cs) == 1); return my_casefold_mb(cs, src, srclen, dst, dstlen, cs->to_upper, 1); diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index 1fb8e9c91bb..193d453bd36 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -253,6 +253,7 @@ size_t my_caseup_8bit(CHARSET_INFO * cs, const char *src, size_t srclen, { const char *end= src + srclen; register const uchar *map= cs->to_upper; + DBUG_ASSERT(src != NULL); /* Avoid UBSAN nullptr-with-offset */ DBUG_ASSERT(srclen <= dstlen); for ( ; src != end ; src++) *dst++= (char) map[(uchar) *src]; @@ -265,6 +266,7 @@ size_t my_casedn_8bit(CHARSET_INFO * cs, const char *src, size_t srclen, { const char *end= src + srclen; register const uchar *map=cs->to_lower; + DBUG_ASSERT(src != NULL); /* Avoid UBSAN nullptr-with-offset */ DBUG_ASSERT(srclen <= dstlen); for ( ; src != end ; src++) *dst++= (char) map[(uchar) *src]; diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index 8d275c18bd7..9675731018e 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -1310,6 +1310,7 @@ my_caseup_utf16(CHARSET_INFO *cs, const char *src, size_t srclen, const char *srcend= src + srclen; char *dstend= dst + dstlen; MY_CASEFOLD_INFO *uni_plane= cs->casefold; + DBUG_ASSERT(src != NULL); /* Avoid UBSAN nullptr-with-offset */ DBUG_ASSERT(srclen <= dstlen); while ((src < srcend) && @@ -1368,6 +1369,7 @@ my_casedn_utf16(CHARSET_INFO *cs, const char *src, size_t srclen, const char *srcend= src + srclen; char *dstend= dst + dstlen; MY_CASEFOLD_INFO *uni_plane= cs->casefold; + DBUG_ASSERT(src != NULL); /* Avoid UBSAN nullptr-with-offset */ DBUG_ASSERT(srclen <= dstlen); while ((src < srcend) && @@ -2180,6 +2182,7 @@ my_caseup_utf32(CHARSET_INFO *cs, const char *src, size_t srclen, const char *srcend= src + srclen; char *dstend= dst + dstlen; MY_CASEFOLD_INFO *uni_plane= cs->casefold; + DBUG_ASSERT(src != NULL); /* Avoid UBSAN nullptr-with-offset */ DBUG_ASSERT(srclen <= dstlen); while ((src < srcend) && @@ -2237,6 +2240,7 @@ my_casedn_utf32(CHARSET_INFO *cs, const char *src, size_t srclen, const char *srcend= src + srclen; char *dstend= dst + dstlen; MY_CASEFOLD_INFO *uni_plane= cs->casefold; + DBUG_ASSERT(src != NULL); /* Avoid UBSAN nullptr-with-offset */ DBUG_ASSERT(srclen <= dstlen); while ((res= my_utf32_uni(cs, &wc, (uchar*) src, (uchar*) srcend)) > 0) @@ -3048,6 +3052,7 @@ static size_t my_caseup_ucs2(CHARSET_INFO *cs, const char *src, size_t srclen, const char *srcend= src + srclen; char *dstend= dst + dstlen; MY_CASEFOLD_INFO *uni_plane= cs->casefold; + DBUG_ASSERT(src != NULL); /* Avoid UBSAN nullptr-with-offset */ DBUG_ASSERT(srclen <= dstlen); while ((src < srcend) && @@ -3100,6 +3105,7 @@ static size_t my_casedn_ucs2(CHARSET_INFO *cs, const char *src, size_t srclen, char *dstend= dst + dstlen; MY_CASEFOLD_INFO *uni_plane= cs->casefold; DBUG_ASSERT(srclen <= dstlen); + DBUG_ASSERT(src != NULL); /* Avoid UBSAN nullptr-with-offset */ while ((src < srcend) && (res= my_ucs2_uni(cs, &wc, (uchar*) src, (uchar*) srcend)) > 0) diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c index a5624a8c341..28bd11c1531 100644 --- a/strings/ctype-ujis.c +++ b/strings/ctype-ujis.c @@ -67219,6 +67219,7 @@ size_t my_casedn_ujis(CHARSET_INFO * cs, const char *src, size_t srclen, char *dst, size_t dstlen) { + DBUG_ASSERT(src != NULL); /* Avoid UBSAN nullptr-with-offset */ DBUG_ASSERT(dstlen >= srclen * cs->cset->casedn_multiply(cs)); DBUG_ASSERT(src != dst || cs->cset->casedn_multiply(cs) == 1); return my_casefold_ujis(cs, src, srclen, dst, dstlen, cs->to_lower, 0); @@ -67232,6 +67233,7 @@ size_t my_caseup_ujis(CHARSET_INFO * cs, const char *src, size_t srclen, char *dst, size_t dstlen) { + DBUG_ASSERT(src != NULL); /* Avoid UBSAN nullptr-with-offset */ DBUG_ASSERT(dstlen >= srclen * cs->cset->caseup_multiply(cs)); DBUG_ASSERT(src != dst || cs->cset->caseup_multiply(cs) == 1); return my_casefold_ujis(cs, src, srclen, dst, dstlen, cs->to_upper, 1); diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index b7bdd0e98b0..673ed0839f6 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -676,6 +676,7 @@ static size_t my_caseup_utf8mb3(CHARSET_INFO *cs, const char *srcend= src + srclen; char *dstend= dst + dstlen, *dst0= dst; MY_CASEFOLD_INFO *uni_plane= cs->casefold; + DBUG_ASSERT(src != NULL); /* Avoid UBSAN nullptr-with-offset */ DBUG_ASSERT(src != dst || cs->cset->caseup_multiply(cs) == 1); while ((src < srcend) && @@ -754,6 +755,7 @@ static size_t my_casedn_utf8mb3(CHARSET_INFO *cs, const char *srcend= src + srclen; char *dstend= dst + dstlen, *dst0= dst; MY_CASEFOLD_INFO *uni_plane= cs->casefold; + DBUG_ASSERT(src != NULL); /* Avoid UBSAN nullptr-with-offset */ DBUG_ASSERT(src != dst || cs->cset->casedn_multiply(cs) == 1); while ((src < srcend) && @@ -3124,6 +3126,7 @@ my_caseup_utf8mb4(CHARSET_INFO *cs, const char *src, size_t srclen, const char *srcend= src + srclen; char *dstend= dst + dstlen, *dst0= dst; MY_CASEFOLD_INFO *uni_plane= cs->casefold; + DBUG_ASSERT(src != NULL); /* Avoid UBSAN nullptr-with-offset */ DBUG_ASSERT(src != dst || cs->cset->caseup_multiply(cs) == 1); while ((src < srcend) && @@ -3218,6 +3221,7 @@ my_casedn_utf8mb4(CHARSET_INFO *cs, const char *srcend= src + srclen; char *dstend= dst + dstlen, *dst0= dst; MY_CASEFOLD_INFO *uni_plane= cs->casefold; + DBUG_ASSERT(src != NULL); /* Avoid UBSAN nullptr-with-offset */ DBUG_ASSERT(src != dst || cs->cset->casedn_multiply(cs) == 1); while ((src < srcend) && From 661daf063608d7cbc9f389cd3376934038039c3b Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 20 Jan 2025 18:10:57 +0100 Subject: [PATCH 111/213] MDEV-31298 Assertion `!check_foreigns' failed in trx_mod_table_time_t* trx_t::check_bulk_buffer(dict_table_t*), Assertion `table->skip_alter_undo || !check_unique_secondary' failed in trx_t::check_bulk_buffer unlike CREATE TABLE, CREATE SEQUENCE always causes an implicit commit, even for temporary sequences. --- mysql-test/suite/sql_sequence/temporary.result | 15 +++++++++++++++ mysql-test/suite/sql_sequence/temporary.test | 18 ++++++++++++++++++ sql/sql_parse.cc | 1 - 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/sql_sequence/temporary.result b/mysql-test/suite/sql_sequence/temporary.result index b5c70fd3a50..78ad40c2582 100644 --- a/mysql-test/suite/sql_sequence/temporary.result +++ b/mysql-test/suite/sql_sequence/temporary.result @@ -41,3 +41,18 @@ select nextval(s1); nextval(s1) 2 drop temporary sequence s1; +# End of 10.6 test +# +# MDEV-31298 Assertion `!check_foreigns' failed in trx_mod_table_time_t* trx_t::check_bulk_buffer(dict_table_t*), Assertion `table->skip_alter_undo || !check_unique_secondary' failed in trx_t::check_bulk_buffer +# +set foreign_key_checks=0,unique_checks=0; +create table t1 (c1 char,index (c1)) engine=innodb; +xa start 'a'; +insert into t1 values(); +set foreign_key_checks=1,unique_checks=1; +create temporary sequence f engine=innodb; +ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE state +xa end 'a'; +xa rollback 'a'; +drop table t1; +# End of 10.11 test diff --git a/mysql-test/suite/sql_sequence/temporary.test b/mysql-test/suite/sql_sequence/temporary.test index e57dc693304..cdb50d9ee20 100644 --- a/mysql-test/suite/sql_sequence/temporary.test +++ b/mysql-test/suite/sql_sequence/temporary.test @@ -45,3 +45,21 @@ select nextval(s1); select nextval(s1); drop temporary sequence s1; --enable_ps2_protocol + +--echo # End of 10.6 test + +--echo # +--echo # MDEV-31298 Assertion `!check_foreigns' failed in trx_mod_table_time_t* trx_t::check_bulk_buffer(dict_table_t*), Assertion `table->skip_alter_undo || !check_unique_secondary' failed in trx_t::check_bulk_buffer +--echo # +set foreign_key_checks=0,unique_checks=0; +create table t1 (c1 char,index (c1)) engine=innodb; +xa start 'a'; +insert into t1 values(); +set foreign_key_checks=1,unique_checks=1; +--error ER_XAER_RMFAIL +create temporary sequence f engine=innodb; +xa end 'a'; +xa rollback 'a'; +drop table t1; + +--echo # End of 10.11 test diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 472932cf80c..2b1fe1d9fdf 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -441,7 +441,6 @@ bool stmt_causes_implicit_commit(THD *thd, uint mask) case SQLCOM_DROP_TABLE: case SQLCOM_DROP_SEQUENCE: case SQLCOM_CREATE_TABLE: - case SQLCOM_CREATE_SEQUENCE: /* If CREATE TABLE of non-temporary table and the table is not part if a BEGIN GTID ... COMMIT group, do a implicit commit. From e02e24dff298d295d98d1c962f6e9d574bba5248 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Sun, 15 Dec 2024 23:53:00 +0400 Subject: [PATCH 112/213] MDEV-35338 - Non-copying ALTER does not pad VECTOR column, vector search further does not work Since VECTOR data type is based on VARCHAR, ALTER TABLE expanding VECTOR column was allowed to go with ALGORITHM=INPLACE. However InnoDB sees such columns as VARCHAR and thus it doesn't pad updated columns data to new length. In contrast to ALGORITHM=COPY, which goes with field copy routines. With this patch ALGORITHM=INPLACE is not allowed for VECTOR columns. --- mysql-test/main/vector_innodb.result | 14 ++++++++++++++ mysql-test/main/vector_innodb.test | 11 +++++++++++ storage/innobase/handler/ha_innodb.cc | 4 ++++ 3 files changed, 29 insertions(+) diff --git a/mysql-test/main/vector_innodb.result b/mysql-test/main/vector_innodb.result index 329da2a7159..aeb9f1512ad 100644 --- a/mysql-test/main/vector_innodb.result +++ b/mysql-test/main/vector_innodb.result @@ -227,3 +227,17 @@ connection con1; ERROR 40001: Deadlock found when trying to get lock; try restarting transaction drop table t; disconnect con1; +connection default; +# +# MDEV-35338 - Non-copying ALTER does not pad VECTOR column, +# vector search further does not work +# +create or replace table t (a int, v vector(1) not null, primary key (a)) engine=InnoDB; +insert into t values (1,0x38383838),(2,0x37373737),(3,0x31313131); +alter table t modify v vector(2) not null; +select hex(v) from t order by a; +hex(v) +3838383800000000 +3737373700000000 +3131313100000000 +drop table t; diff --git a/mysql-test/main/vector_innodb.test b/mysql-test/main/vector_innodb.test index 76f196a6c66..be776aa0742 100644 --- a/mysql-test/main/vector_innodb.test +++ b/mysql-test/main/vector_innodb.test @@ -231,3 +231,14 @@ rollback; --reap drop table t; --disconnect con1 +connection default; + +--echo # +--echo # MDEV-35338 - Non-copying ALTER does not pad VECTOR column, +--echo # vector search further does not work +--echo # +create or replace table t (a int, v vector(1) not null, primary key (a)) engine=InnoDB; +insert into t values (1,0x38383838),(2,0x37373737),(3,0x31313131); +alter table t modify v vector(2) not null; +select hex(v) from t order by a; +drop table t; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 0be423e28dc..07de3b09c99 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -119,6 +119,7 @@ simple_thread_local ha_handler_stats *mariadb_stats; #include #include // TT_FOR_UPGRADE +#include "sql_type_vector.h" #define thd_get_trx_isolation(X) ((enum_tx_isolation)thd_tx_isolation(X)) @@ -20763,6 +20764,9 @@ bool ha_innobase::can_convert_blob(const Field_blob *field, bool ha_innobase::can_convert_nocopy(const Field &field, const Column_definition &new_type) const { + if (dynamic_cast(&field)) + return false; + if (const Field_string *tf= dynamic_cast(&field)) return can_convert_string(tf, new_type); From 9171ef3fafdc060beecb9f9cc3ca3c2b525607cf Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Wed, 11 Dec 2024 18:59:39 +1100 Subject: [PATCH 113/213] MDEV-35557 Fix SEGV when reading from ALTERed mysql.servers table Also factor out the json parsing steps into a function. --- mysql-test/main/servers.result | 9 ++++ mysql-test/main/servers.test | 13 ++++++ sql/sql_servers.cc | 75 +++++++++++++++++++--------------- 3 files changed, 63 insertions(+), 34 deletions(-) diff --git a/mysql-test/main/servers.result b/mysql-test/main/servers.result index 00f6e6d3b5d..4e470e39c2f 100644 --- a/mysql-test/main/servers.result +++ b/mysql-test/main/servers.result @@ -83,3 +83,12 @@ create or replace server srv foreign data wrapper mysql options show create server nonexist; ERROR HY000: The foreign server name you are trying to reference does not exist. Data source error: nonexist drop server srv; +# +# MDEV-35557 SIGSEGV in get_server_from_table_to_cache | servers_load, UBSAN null pointer passed as argument 1, which is declared to never be null +# +CREATE SERVER s1 FOREIGN DATA WRAPPER mysql OPTIONS (HOST '127.0.0.1'); +ALTER TABLE mysql.servers ENGINE=InnoDB; +FLUSH PRIVILEGES; +ALTER TABLE mysql.servers ENGINE=Aria; +FLUSH PRIVILEGES; +drop server s1; diff --git a/mysql-test/main/servers.test b/mysql-test/main/servers.test index e824f5ba62c..db0a970c6c0 100644 --- a/mysql-test/main/servers.test +++ b/mysql-test/main/servers.test @@ -83,3 +83,16 @@ create or replace server srv foreign data wrapper mysql options show create server nonexist; drop server srv; + +--echo # +--echo # MDEV-35557 SIGSEGV in get_server_from_table_to_cache | servers_load, UBSAN null pointer passed as argument 1, which is declared to never be null +--echo # + +--source include/have_innodb.inc + +CREATE SERVER s1 FOREIGN DATA WRAPPER mysql OPTIONS (HOST '127.0.0.1'); +ALTER TABLE mysql.servers ENGINE=InnoDB; +FLUSH PRIVILEGES; +ALTER TABLE mysql.servers ENGINE=Aria; +FLUSH PRIVILEGES; +drop server s1; diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc index ac1400057ff..727d45e12ec 100644 --- a/sql/sql_servers.cc +++ b/sql/sql_servers.cc @@ -373,6 +373,45 @@ end: DBUG_RETURN(return_val); } +static bool parse_server_options_json(FOREIGN_SERVER *server, char *ptr) +{ + enum json_types vt; + const char *keyname, *keyname_end, *v; + int v_len, nkey= 0; + engine_option_value *option_list_last; + DBUG_ENTER("parse_server_options_json"); + while ((vt= json_get_object_nkey(ptr, ptr+strlen(ptr), nkey++, + &keyname, &keyname_end, &v, &v_len)) != JSV_NOTHING) + { + if (vt != JSV_STRING) + DBUG_RETURN(TRUE); + /* + We have to make copies here to create "clean" strings and + avoid mutating ptr. + */ + Lex_cstring name= {keyname, keyname_end}, value= {v, v + v_len}, + name_copy= safe_lexcstrdup_root(&mem, name), + value_copy= safe_lexcstrdup_root(&mem, value); + engine_option_value *option= new (&mem) engine_option_value( + engine_option_value::Name(name_copy), + engine_option_value::Value(value_copy), true); + option->link(&server->option_list, &option_list_last); + if (option->value.length) + { + LEX_CSTRING *optval= &option->value; + char *unescaped= (char *) alloca(optval->length); + int len= json_unescape_json(optval->str, optval->str + optval->length, + unescaped, unescaped + optval->length); + if (len < 0) + DBUG_RETURN(TRUE); + DBUG_ASSERT(len <= (int) optval->length); + if (len < (int) optval->length) + strncpy((char *) optval->str, unescaped, len); + optval->length= len; + } + } + DBUG_RETURN(FALSE); +} /* Initialize structures responsible for servers used in federated @@ -435,41 +474,9 @@ get_server_from_table_to_cache(TABLE *table) ptr= get_field(&mem, table->field[8]); server->owner= ptr ? ptr : blank; ptr= get_field(&mem, table->field[9]); - enum json_types vt; - const char *keyname, *keyname_end, *v; - int v_len, nkey= 0; - engine_option_value *option_list_last; server->option_list= NULL; - while ((vt= json_get_object_nkey(ptr, ptr+strlen(ptr), nkey++, - &keyname, &keyname_end, &v, &v_len)) != JSV_NOTHING) - { - if (vt != JSV_STRING) - DBUG_RETURN(TRUE); - /* - We have to make copies here to create "clean" strings and - avoid mutating ptr. - */ - Lex_cstring name= {keyname, keyname_end}, value= {v, v + v_len}, - name_copy= safe_lexcstrdup_root(&mem, name), - value_copy= safe_lexcstrdup_root(&mem, value); - engine_option_value *option= new (&mem) engine_option_value( - engine_option_value::Name(name_copy), - engine_option_value::Value(value_copy), true); - option->link(&server->option_list, &option_list_last); - if (option->value.length) - { - LEX_CSTRING *optval= &option->value; - char *unescaped= (char *) alloca(optval->length); - int len= json_unescape_json(optval->str, optval->str + optval->length, - unescaped, unescaped + optval->length); - if (len < 0) - DBUG_RETURN(TRUE); - DBUG_ASSERT(len <= (int) optval->length); - if (len < (int) optval->length) - strncpy((char *) optval->str, unescaped, len); - optval->length= len; - } - } + if (ptr && parse_server_options_json(server, ptr)) + DBUG_RETURN(TRUE); DBUG_PRINT("info", ("server->server_name %s", server->server_name)); DBUG_PRINT("info", ("server->host %s", server->host)); DBUG_PRINT("info", ("server->db %s", server->db)); From 195dcfec6f09cc4a07991a6ceb90cd7f4e9f3369 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Fri, 17 Jan 2025 08:42:17 +0100 Subject: [PATCH 114/213] MDEV-35793: Server crashes in Item_func_vec_distance_common::get_const_arg The problem was caused by this scenario: The query had both SELECT DISTINCT and ORDER BY. DISTINCT was converted into GROUP BY. Then, vector index was used to resolve the GROUP BY. When join_read_first() initialized vector index scan, it used the ORDER BY clause instead of GROUP BY, which caused a crash. Fixed by making test_if_skip_sort_order() remember which ordering the scan produces in JOIN_TAB::full_index_scan_order, and join_read_first() using that. --- mysql-test/main/vector_innodb.result | 12 ++++++++++++ mysql-test/main/vector_innodb.test | 12 ++++++++++++ sql/sql_select.cc | 10 +++++++--- sql/sql_select.h | 7 +++++++ 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/mysql-test/main/vector_innodb.result b/mysql-test/main/vector_innodb.result index aeb9f1512ad..424873d0efe 100644 --- a/mysql-test/main/vector_innodb.result +++ b/mysql-test/main/vector_innodb.result @@ -241,3 +241,15 @@ hex(v) 3737373700000000 3131313100000000 drop table t; +# +# MDEV-35793: Server crashes in +# Item_func_vec_distance_common::get_const_arg +# +create table t (pk int primary key, v vector(1) not null, vector(v)) engine=innodb; +insert into t values (1,0x31313131),(2,0x32323232); +select distinct vec_distance_euclidean(v, 0x30303030) as d from t order by pk; +d +0.0000000019375161827791346 +0.000000009731407668281116 +drop table t; +# End of 11.7 tests diff --git a/mysql-test/main/vector_innodb.test b/mysql-test/main/vector_innodb.test index be776aa0742..03a91bae33c 100644 --- a/mysql-test/main/vector_innodb.test +++ b/mysql-test/main/vector_innodb.test @@ -242,3 +242,15 @@ insert into t values (1,0x38383838),(2,0x37373737),(3,0x31313131); alter table t modify v vector(2) not null; select hex(v) from t order by a; drop table t; + +--echo # +--echo # MDEV-35793: Server crashes in +--echo # Item_func_vec_distance_common::get_const_arg +--echo # + +create table t (pk int primary key, v vector(1) not null, vector(v)) engine=innodb; +insert into t values (1,0x31313131),(2,0x32323232); # optional, fails either way +select distinct vec_distance_euclidean(v, 0x30303030) as d from t order by pk; +drop table t; + +--echo # End of 11.7 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index f24e1da4b3c..62350b3754f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3683,7 +3683,8 @@ bool JOIN::make_aggr_tables_info() bool is_having_added_as_table_cond= false; DBUG_ENTER("JOIN::make_aggr_tables_info"); - + DBUG_ASSERT(current_ref_ptrs == items0); + sort_and_group_aggr_tab= NULL; if (group_optimized_away) @@ -3790,7 +3791,6 @@ bool JOIN::make_aggr_tables_info() */ init_items_ref_array(); items1= ref_ptr_array_slice(2); - //items1= items0 + all_fields.elements; if (change_to_use_tmp_fields(thd, items1, tmp_fields_list1, tmp_all_fields1, fields_list.elements, all_fields)) @@ -25199,12 +25199,13 @@ join_read_first(JOIN_TAB *tab) tab->read_record.table=table; if (tab->index >= table->s->keys) { - ORDER *order= tab->join->order ? tab->join->order : tab->join->group_list; + ORDER *order= tab->full_index_scan_order; DBUG_ASSERT(tab->index < table->s->total_keys); DBUG_ASSERT(tab->index == table->s->keys); DBUG_ASSERT(tab->sorted); DBUG_ASSERT(order); DBUG_ASSERT(order->next == NULL); + DBUG_ASSERT(order->item[0]->real_item()->type() == Item::FUNC_ITEM); tab->read_record.read_record_func= join_hlindex_read_next; error= tab->table->hlindex_read_first(tab->index, *order->item, tab->join->select_limit); @@ -27110,6 +27111,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, int best_key= -1; bool changed_key= false; THD *thd= tab->join->thd; + ORDER *best_key_order= 0; Json_writer_object trace_wrapper(thd); Json_writer_array trace_arr(thd, "test_if_skip_sort_order"); DBUG_ENTER("test_if_skip_sort_order"); @@ -27342,6 +27344,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, !table->is_clustering_key(best_key))) goto use_filesort; + best_key_order= order; if (select && table->opt_range_keys.is_set(best_key) && best_key != ref_key) { key_map tmp_map; @@ -27441,6 +27444,7 @@ check_reverse_order: join_read_first: join_read_last); tab->type=JT_NEXT; // Read with index_first(), index_next() + tab->full_index_scan_order= best_key_order; /* Currently usage of rowid filters is not supported in InnoDB diff --git a/sql/sql_select.h b/sql/sql_select.h index 8cbc18f1be1..ee14f5a8f01 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -556,6 +556,13 @@ typedef struct st_join_table { /** HAVING condition for checking prior saving a record into tmp table*/ Item *having; + /** + Ordering to be produced when doing full index scan. + Important for vector indexes, set by test_if_skip_sort_order() when it + decides to use full index to produce rows in order. + */ + ORDER *full_index_scan_order; + /** TRUE <=> remove duplicates on this table. */ bool distinct; From 0301ef38b4569c811a0813e49dfe585a7bd66f2b Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Tue, 21 Jan 2025 18:52:33 +0530 Subject: [PATCH 115/213] MDEV-35445 Disable foreign key column nullability check for strict sql mode - MDEV-34392(commit cc810e64d40367208b3f3f35c0277f0c8586a293) adds the check for nullability of foreign key column when foreign key relation is of UPDATE_CASCADE or UPDATE SET NULL. This check makes DDL fail when it violates foreign key nullability. This patch basically does the nullability check for foreign key column only for strict sql mode --- .../r/foreign_sql_mode,COPY,NON-STRICT.rdiff | 57 ++++++++ .../r/foreign_sql_mode,COPY,NOSTRICT.rdiff | 55 ++++++++ .../foreign_sql_mode,INPLACE,NON-STRICT.rdiff | 39 ++++++ .../suite/innodb/r/foreign_sql_mode.result | 65 +++++++++ .../innodb/t/foreign_sql_mode.combinations | 2 + .../suite/innodb/t/foreign_sql_mode.test | 129 ++++++++++++++++++ sql/sql_table.cc | 3 +- storage/innobase/dict/dict0crea.cc | 4 +- storage/innobase/handler/handler0alter.cc | 18 ++- 9 files changed, 364 insertions(+), 8 deletions(-) create mode 100644 mysql-test/suite/innodb/r/foreign_sql_mode,COPY,NON-STRICT.rdiff create mode 100644 mysql-test/suite/innodb/r/foreign_sql_mode,COPY,NOSTRICT.rdiff create mode 100644 mysql-test/suite/innodb/r/foreign_sql_mode,INPLACE,NON-STRICT.rdiff create mode 100644 mysql-test/suite/innodb/r/foreign_sql_mode.result create mode 100644 mysql-test/suite/innodb/t/foreign_sql_mode.combinations create mode 100644 mysql-test/suite/innodb/t/foreign_sql_mode.test diff --git a/mysql-test/suite/innodb/r/foreign_sql_mode,COPY,NON-STRICT.rdiff b/mysql-test/suite/innodb/r/foreign_sql_mode,COPY,NON-STRICT.rdiff new file mode 100644 index 00000000000..66e39ca633e --- /dev/null +++ b/mysql-test/suite/innodb/r/foreign_sql_mode,COPY,NON-STRICT.rdiff @@ -0,0 +1,57 @@ +--- foreign_sql_mode.result ++++ foreign_sql_mode,COPY,NON-STRICT.rdiff +@@ -3,14 +3,14 @@ + CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; + CREATE TABLE t2(f1 INT, FOREIGN KEY(f1) REFERENCES t1(f2) ON UPDATE CASCADE)ENGINE=InnoDB; + ALTER TABLE t2 MODIFY COLUMN f1 INT NOT NULL; +-ERROR HY000: Column 'f1' cannot be NOT NULL: needed in a foreign key constraint 't2_ibfk_1' SET NULL + INSERT INTO t1 VALUES(1, 1); + INSERT INTO t2 VALUES(1); + UPDATE t1 SET f2= NULL; ++ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t1` (`f2`) ON UPDATE CASCADE) + DELETE FROM t2; + SELECT * FROM t1; + f1 f2 +-1 NULL ++1 1 + UPDATE t1 SET f2 = NULL; + SELECT * FROM t1; + f1 f2 +@@ -20,7 +20,7 @@ + CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; + CREATE TABLE t2(f1 INT, f2 INT, FOREIGN KEY(f1) REFERENCES t1(f1) ON UPDATE SET NULL)ENGINE=InnoDB; + ALTER TABLE t2 MODIFY COLUMN f1 INT NOT NULL; +-ERROR HY000: Column 'f1' cannot be NOT NULL: needed in a foreign key constraint 't2_ibfk_1' SET NULL ++ERROR HY000: Error on rename of 'OLD_FILE_NAME' to 'NEW_FILE_NAME' (errno: 150 "Foreign key constraint is incorrectly formed") + INSERT INTO t1 VALUES(1, 1); + INSERT INTO t2 VALUES(1, 1); + UPDATE t1 SET f1= 2; +@@ -32,7 +32,7 @@ + CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; + CREATE TABLE t2(f1 INT, f2 INT, FOREIGN KEY (f2) REFERENCES t1(f2) ON DELETE SET NULL)ENGINE=InnoDB; + ALTER TABLE t2 MODIFY COLUMN f2 INT NOT NULL; +-ERROR HY000: Column 'f2' cannot be NOT NULL: needed in a foreign key constraint 't2_ibfk_1' SET NULL ++ERROR HY000: Error on rename of 'OLD_FILE_NAME' to 'NEW_FILE_NAME' (errno: 150 "Foreign key constraint is incorrectly formed") + DROP TABLE t2, t1; + # modify parent column NULL ON UPDATE CASCADE child column NOT NULL + CREATE TABLE `t#1`(f1 INT, f2 INT NOT NULL, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; +@@ -40,11 +40,10 @@ + FOREIGN KEY(f1) REFERENCES `t#1`(f2) + ON UPDATE CASCADE)ENGINE=InnoDB; + ALTER TABLE `t#1` MODIFY COLUMN f2 INT; +-ERROR HY000: Cannot change column 'f2': used in a foreign key constraint 't#2_ibfk_1' of table 'test.t#2' + INSERT INTO `t#1` VALUES(1, 1); + INSERT INTO `t#2` VALUES(1); + UPDATE `t#1` SET f2= NULL; +-ERROR 23000: Column 'f2' cannot be null ++ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t#2`, CONSTRAINT `t#2_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t#1` (`f2`) ON UPDATE CASCADE) + DELETE FROM `t#2`; + SELECT * FROM `t#1`; + f1 f2 +@@ -60,6 +59,5 @@ + PRIMARY KEY(f1, f2), + FOREIGN KEY(f2, f3) REFERENCES t1(f2, f1) + ON UPDATE CASCADE)ENGINE=InnoDB; +-ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") + DROP TABLE IF EXISTS t2; + DROP TABLE IF EXISTS t1; diff --git a/mysql-test/suite/innodb/r/foreign_sql_mode,COPY,NOSTRICT.rdiff b/mysql-test/suite/innodb/r/foreign_sql_mode,COPY,NOSTRICT.rdiff new file mode 100644 index 00000000000..95df1bfa7d3 --- /dev/null +++ b/mysql-test/suite/innodb/r/foreign_sql_mode,COPY,NOSTRICT.rdiff @@ -0,0 +1,55 @@ +--- foreign_sql_mode.result 2025-01-21 17:23:46.014938931 +0530 ++++ foreign_sql_mode.reject 2025-01-21 17:24:11.783981181 +0530 +@@ -3,20 +3,20 @@ + CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; + CREATE TABLE t2(f1 INT, FOREIGN KEY(f1) REFERENCES t1(f2) ON UPDATE CASCADE)ENGINE=InnoDB; + ALTER TABLE t2 MODIFY COLUMN f1 INT NOT NULL; +-ERROR HY000: Column 'f1' cannot be NOT NULL: needed in a foreign key constraint 't2_ibfk_1' SET NULL + INSERT INTO t1 VALUES(1, 1); + INSERT INTO t2 VALUES(1); + UPDATE t1 SET f2= NULL; ++ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t1` (`f2`) ON UPDATE CASCADE) + DELETE FROM t2; + SELECT * FROM t1; + f1 f2 +-1 NULL ++1 1 + DROP TABLE t2, t1; + # modify child column NOT NULL ON UPDATE SET NULL + CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; + CREATE TABLE t2(f1 INT, f2 INT, FOREIGN KEY(f1) REFERENCES t1(f1) ON UPDATE SET NULL)ENGINE=InnoDB; + ALTER TABLE t2 MODIFY COLUMN f1 INT NOT NULL; +-ERROR HY000: Column 'f1' cannot be NOT NULL: needed in a foreign key constraint 't2_ibfk_1' SET NULL ++ERROR HY000: Error on rename of 'OLD_FILE_NAME' to 'NEW_FILE_NAME' (errno: 150 "Foreign key constraint is incorrectly formed") + INSERT INTO t1 VALUES(1, 1); + INSERT INTO t2 VALUES(1, 1); + UPDATE t1 SET f1= 2; +@@ -28,7 +28,7 @@ + CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; + CREATE TABLE t2(f1 INT, f2 INT, FOREIGN KEY (f2) REFERENCES t1(f2) ON DELETE SET NULL)ENGINE=InnoDB; + ALTER TABLE t2 MODIFY COLUMN f2 INT NOT NULL; +-ERROR HY000: Column 'f2' cannot be NOT NULL: needed in a foreign key constraint 't2_ibfk_1' SET NULL ++ERROR HY000: Error on rename of 'OLD_FILE_NAME' to 'NEW_FILE_NAME' (errno: 150 "Foreign key constraint is incorrectly formed") + DROP TABLE t2, t1; + # modify parent column NULL ON UPDATE CASCADE child column NOT NULL + CREATE TABLE `t#1`(f1 INT, f2 INT NOT NULL, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; +@@ -36,11 +36,10 @@ + FOREIGN KEY(f1) REFERENCES `t#1`(f2) + ON UPDATE CASCADE)ENGINE=InnoDB; + ALTER TABLE `t#1` MODIFY COLUMN f2 INT; +-ERROR HY000: Cannot change column 'f2': used in a foreign key constraint 't#2_ibfk_1' of table 'test.t#2' + INSERT INTO `t#1` VALUES(1, 1); + INSERT INTO `t#2` VALUES(1); + UPDATE `t#1` SET f2= NULL; +-ERROR 23000: Column 'f2' cannot be null ++ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t#2`, CONSTRAINT `t#2_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t#1` (`f2`) ON UPDATE CASCADE) + DELETE FROM `t#2`; + SELECT * FROM `t#1`; + f1 f2 +@@ -56,6 +55,5 @@ + PRIMARY KEY(f1, f2), + FOREIGN KEY(f2, f3) REFERENCES t1(f2, f1) + ON UPDATE CASCADE)ENGINE=InnoDB; +-ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") + DROP TABLE IF EXISTS t2; + DROP TABLE IF EXISTS t1; diff --git a/mysql-test/suite/innodb/r/foreign_sql_mode,INPLACE,NON-STRICT.rdiff b/mysql-test/suite/innodb/r/foreign_sql_mode,INPLACE,NON-STRICT.rdiff new file mode 100644 index 00000000000..8919244e810 --- /dev/null +++ b/mysql-test/suite/innodb/r/foreign_sql_mode,INPLACE,NON-STRICT.rdiff @@ -0,0 +1,39 @@ +--- foreign_sql_mode.result ++++ foreign_sql_mode,INPLACE,NON-STRICT.rdiff +@@ -3,14 +3,14 @@ + CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; + CREATE TABLE t2(f1 INT, FOREIGN KEY(f1) REFERENCES t1(f2) ON UPDATE CASCADE)ENGINE=InnoDB; + ALTER TABLE t2 MODIFY COLUMN f1 INT NOT NULL; +-ERROR HY000: Column 'f1' cannot be NOT NULL: needed in a foreign key constraint 't2_ibfk_1' SET NULL + INSERT INTO t1 VALUES(1, 1); + INSERT INTO t2 VALUES(1); + UPDATE t1 SET f2= NULL; ++ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t1` (`f2`) ON UPDATE CASCADE) + DELETE FROM t2; + SELECT * FROM t1; + f1 f2 +-1 NULL ++1 1 + UPDATE t1 SET f2 = NULL; + SELECT * FROM t1; + f1 f2 +@@ -40,11 +40,10 @@ + FOREIGN KEY(f1) REFERENCES `t#1`(f2) + ON UPDATE CASCADE)ENGINE=InnoDB; + ALTER TABLE `t#1` MODIFY COLUMN f2 INT; +-ERROR HY000: Cannot change column 'f2': used in a foreign key constraint 't#2_ibfk_1' of table 'test.t#2' + INSERT INTO `t#1` VALUES(1, 1); + INSERT INTO `t#2` VALUES(1); + UPDATE `t#1` SET f2= NULL; +-ERROR 23000: Column 'f2' cannot be null ++ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t#2`, CONSTRAINT `t#2_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t#1` (`f2`) ON UPDATE CASCADE) + DELETE FROM `t#2`; + SELECT * FROM `t#1`; + f1 f2 +@@ -60,6 +59,5 @@ + PRIMARY KEY(f1, f2), + FOREIGN KEY(f2, f3) REFERENCES t1(f2, f1) + ON UPDATE CASCADE)ENGINE=InnoDB; +-ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") + DROP TABLE IF EXISTS t2; + DROP TABLE IF EXISTS t1; diff --git a/mysql-test/suite/innodb/r/foreign_sql_mode.result b/mysql-test/suite/innodb/r/foreign_sql_mode.result new file mode 100644 index 00000000000..7044e402745 --- /dev/null +++ b/mysql-test/suite/innodb/r/foreign_sql_mode.result @@ -0,0 +1,65 @@ +call mtr.add_suppression("InnoDB: In ALTER TABLE .* has or is referenced in foreign key constraints which are not compatible with the new table definition."); +# modify child column NOT NULL on UPDATE CASCADE..parent column NULL +CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; +CREATE TABLE t2(f1 INT, FOREIGN KEY(f1) REFERENCES t1(f2) ON UPDATE CASCADE)ENGINE=InnoDB; +ALTER TABLE t2 MODIFY COLUMN f1 INT NOT NULL; +ERROR HY000: Column 'f1' cannot be NOT NULL: needed in a foreign key constraint 't2_ibfk_1' SET NULL +INSERT INTO t1 VALUES(1, 1); +INSERT INTO t2 VALUES(1); +UPDATE t1 SET f2= NULL; +DELETE FROM t2; +SELECT * FROM t1; +f1 f2 +1 NULL +UPDATE t1 SET f2 = NULL; +SELECT * FROM t1; +f1 f2 +1 NULL +DROP TABLE t2, t1; +# modify child column NOT NULL ON UPDATE SET NULL +CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; +CREATE TABLE t2(f1 INT, f2 INT, FOREIGN KEY(f1) REFERENCES t1(f1) ON UPDATE SET NULL)ENGINE=InnoDB; +ALTER TABLE t2 MODIFY COLUMN f1 INT NOT NULL; +ERROR HY000: Column 'f1' cannot be NOT NULL: needed in a foreign key constraint 't2_ibfk_1' SET NULL +INSERT INTO t1 VALUES(1, 1); +INSERT INTO t2 VALUES(1, 1); +UPDATE t1 SET f1= 2; +SELECT * FROM t2; +f1 f2 +NULL 1 +DROP TABLE t2, t1; +# modify child column NOT NULL ON DELETE SET NULL +CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; +CREATE TABLE t2(f1 INT, f2 INT, FOREIGN KEY (f2) REFERENCES t1(f2) ON DELETE SET NULL)ENGINE=InnoDB; +ALTER TABLE t2 MODIFY COLUMN f2 INT NOT NULL; +ERROR HY000: Column 'f2' cannot be NOT NULL: needed in a foreign key constraint 't2_ibfk_1' SET NULL +DROP TABLE t2, t1; +# modify parent column NULL ON UPDATE CASCADE child column NOT NULL +CREATE TABLE `t#1`(f1 INT, f2 INT NOT NULL, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; +CREATE TABLE `t#2`(f1 INT NOT NULL, +FOREIGN KEY(f1) REFERENCES `t#1`(f2) +ON UPDATE CASCADE)ENGINE=InnoDB; +ALTER TABLE `t#1` MODIFY COLUMN f2 INT; +ERROR HY000: Cannot change column 'f2': used in a foreign key constraint 't#2_ibfk_1' of table 'test.t#2' +INSERT INTO `t#1` VALUES(1, 1); +INSERT INTO `t#2` VALUES(1); +UPDATE `t#1` SET f2= NULL; +ERROR 23000: Column 'f2' cannot be null +DELETE FROM `t#2`; +SELECT * FROM `t#1`; +f1 f2 +1 1 +DROP TABLE `t#2`, `t#1`; +CREATE TABLE t1(f1 INT NOT NULL AUTO_INCREMENT, +f2 INT DEFAULT NULL, +PRIMARY KEY(f1), +FOREIGN KEY(f2) REFERENCES t1(f1))ENGINE=InnoDB; +CREATE TABLE t2 (f1 INT NOT NULL, +f2 INT NOT NULL, +f3 INT DEFAULT NULL, +PRIMARY KEY(f1, f2), +FOREIGN KEY(f2, f3) REFERENCES t1(f2, f1) +ON UPDATE CASCADE)ENGINE=InnoDB; +ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") +DROP TABLE IF EXISTS t2; +DROP TABLE IF EXISTS t1; diff --git a/mysql-test/suite/innodb/t/foreign_sql_mode.combinations b/mysql-test/suite/innodb/t/foreign_sql_mode.combinations new file mode 100644 index 00000000000..e84e17b06ac --- /dev/null +++ b/mysql-test/suite/innodb/t/foreign_sql_mode.combinations @@ -0,0 +1,2 @@ +[COPY] +[INPLACE] diff --git a/mysql-test/suite/innodb/t/foreign_sql_mode.test b/mysql-test/suite/innodb/t/foreign_sql_mode.test new file mode 100644 index 00000000000..1569348df07 --- /dev/null +++ b/mysql-test/suite/innodb/t/foreign_sql_mode.test @@ -0,0 +1,129 @@ +--source include/have_innodb.inc +--source alter_sql_mode.inc +call mtr.add_suppression("InnoDB: In ALTER TABLE .* has or is referenced in foreign key constraints which are not compatible with the new table definition."); + +let $combination=`select regexp_replace('$MTR_COMBINATIONS', 'innodb,\|,innodb', '')`; + +let $copy_algo=`select ((strcmp(substring_index('$combination', ",", 1), "COPY") = 0) or (strcmp(substring_index('$combination', ",", -1), "COPY") = 0))`; + +let $inplace_algo=`select ((strcmp(substring_index('$combination', ",", 1), "INPLACE") = 0) or (strcmp(substring_index('$combination', ",", -1), "INPLACE") = 0))`; + +let $algorithm=COPY; +if ($inplace_algo) +{ + let $algorithm=INPLACE; +} +let $sql_mode = `SELECT @@SQL_MODE`; +let $error_code = 0; +if ($sql_mode == "STRICT_TRANS_TABLES") { + let $error_code = ER_FK_COLUMN_NOT_NULL; +} + +--echo # modify child column NOT NULL on UPDATE CASCADE..parent column NULL +CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; +CREATE TABLE t2(f1 INT, FOREIGN KEY(f1) REFERENCES t1(f2) ON UPDATE CASCADE)ENGINE=InnoDB; +replace_result ,ALGORITHM=COPY '' ,ALGORITHM=INPLACE ''; +--error $error_code +eval ALTER TABLE t2 MODIFY COLUMN f1 INT NOT NULL,ALGORITHM=$algorithm; +INSERT INTO t1 VALUES(1, 1); +INSERT INTO t2 VALUES(1); + +let $dml_error_code = ER_ROW_IS_REFERENCED_2; +if ($sql_mode == "STRICT_TRANS_TABLES") +{ + let $dml_error_code = 0; +} + +--error $dml_error_code +UPDATE t1 SET f2= NULL; +DELETE FROM t2; +SELECT * FROM t1; +UPDATE t1 SET f2 = NULL; +SELECT * FROM t1; +DROP TABLE t2, t1; + +let $error_code= ER_ERROR_ON_RENAME; +if ($algorithm == "INPLACE") +{ + let $error_code= ER_FK_COLUMN_NOT_NULL; +} + +if ($sql_mode == "STRICT_TRANS_TABLES") +{ + let $error_code = ER_FK_COLUMN_NOT_NULL; +} + +# Modifying referenced column from NULL to NOT NULL fails when foreign +# clause is ON UPDATE SET NULL or ON DELETE SET NULL irrespective +# of SQL_MODE variable. This is the behaviour even before MDEV-34392 + +--echo # modify child column NOT NULL ON UPDATE SET NULL +CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; +CREATE TABLE t2(f1 INT, f2 INT, FOREIGN KEY(f1) REFERENCES t1(f1) ON UPDATE SET NULL)ENGINE=InnoDB; +replace_result ,ALGORITHM=COPY '' ,ALGORITHM=INPLACE ''; +--replace_regex /Error on rename of '.*' to '.*'/Error on rename of 'OLD_FILE_NAME' to 'NEW_FILE_NAME'/ +--error $error_code +eval ALTER TABLE t2 MODIFY COLUMN f1 INT NOT NULL,ALGORITHM=$algorithm; +INSERT INTO t1 VALUES(1, 1); +INSERT INTO t2 VALUES(1, 1); +UPDATE t1 SET f1= 2; +SELECT * FROM t2; +DROP TABLE t2, t1; + +--echo # modify child column NOT NULL ON DELETE SET NULL +CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; +CREATE TABLE t2(f1 INT, f2 INT, FOREIGN KEY (f2) REFERENCES t1(f2) ON DELETE SET NULL)ENGINE=InnoDB; +replace_result ,ALGORITHM=COPY '' ,ALGORITHM=INPLACE ''; +--replace_regex /Error on rename of '.*' to '.*'/Error on rename of 'OLD_FILE_NAME' to 'NEW_FILE_NAME'/ +--error $error_code +eval ALTER TABLE t2 MODIFY COLUMN f2 INT NOT NULL,ALGORITHM=$algorithm; +DROP TABLE t2, t1; + +if ($sql_mode == "STRICT_TRANS_TABLES") +{ + let $dml_error_code = ER_BAD_NULL_ERROR; +} + +let $error_code= 0; +if ($sql_mode == "STRICT_TRANS_TABLES") +{ + let $error_code = ER_FK_COLUMN_CANNOT_CHANGE_CHILD; +} + +--echo # modify parent column NULL ON UPDATE CASCADE child column NOT NULL +CREATE TABLE `t#1`(f1 INT, f2 INT NOT NULL, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; +CREATE TABLE `t#2`(f1 INT NOT NULL, + FOREIGN KEY(f1) REFERENCES `t#1`(f2) + ON UPDATE CASCADE)ENGINE=InnoDB; +replace_result ,ALGORITHM=COPY '' ,ALGORITHM=INPLACE ''; +--error $error_code +eval ALTER TABLE `t#1` MODIFY COLUMN f2 INT,ALGORITHM=$algorithm; +INSERT INTO `t#1` VALUES(1, 1); +INSERT INTO `t#2` VALUES(1); +--error $dml_error_code +UPDATE `t#1` SET f2= NULL; +DELETE FROM `t#2`; +SELECT * FROM `t#1`; +DROP TABLE `t#2`, `t#1`; + +let $error_code= 0; +if ($sql_mode == "STRICT_TRANS_TABLES") +{ + let $error_code = ER_CANT_CREATE_TABLE; +} + +CREATE TABLE t1(f1 INT NOT NULL AUTO_INCREMENT, + f2 INT DEFAULT NULL, + PRIMARY KEY(f1), + FOREIGN KEY(f2) REFERENCES t1(f1))ENGINE=InnoDB; +--error $error_code +CREATE TABLE t2 (f1 INT NOT NULL, + f2 INT NOT NULL, + f3 INT DEFAULT NULL, + PRIMARY KEY(f1, f2), + FOREIGN KEY(f2, f3) REFERENCES t1(f2, f1) + ON UPDATE CASCADE)ENGINE=InnoDB; +--disable_warnings +DROP TABLE IF EXISTS t2; +--enable_warnings +DROP TABLE IF EXISTS t1; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index aec81d8941e..e906d8a2a62 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -9677,6 +9677,7 @@ fk_check_column_changes(THD *thd, const TABLE *table, *bad_column_name= NULL; enum fk_column_change_type result= FK_COLUMN_NO_CHANGE; + bool strict_mode= thd->is_strict_mode(); while ((column= column_it++)) { @@ -9722,7 +9723,7 @@ fk_check_column_changes(THD *thd, const TABLE *table, goto func_exit; } - if (old_field_not_null != new_field_not_null) + if (strict_mode && old_field_not_null != new_field_not_null) { if (referenced && !new_field_not_null) { diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc index f0e47938178..45a76243f8a 100644 --- a/storage/innobase/dict/dict0crea.cc +++ b/storage/innobase/dict/dict0crea.cc @@ -44,6 +44,7 @@ Created 1/8/1996 Heikki Tuuri #include "dict0priv.h" #include "fts0priv.h" #include "srv0start.h" +#include "ha_innodb.h" /*****************************************************************//** Based on a table object, this function builds the entry to be inserted @@ -1890,6 +1891,7 @@ dict_create_add_foreigns_to_dictionary( error = DB_SUCCESS; + bool strict_mode = thd_is_strict_mode(trx->mysql_thd); for (dict_foreign_set::const_iterator it = local_fk_set.begin(); it != local_fk_set.end(); ++it) { @@ -1897,7 +1899,7 @@ dict_create_add_foreigns_to_dictionary( foreign = *it; ut_ad(foreign->id != NULL); - if (!foreign->check_fk_constraint_valid()) { + if (strict_mode && !foreign->check_fk_constraint_valid()) { error = DB_CANNOT_ADD_CONSTRAINT; } else { error = dict_create_add_foreign_to_dictionary( diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index d30c88414cd..e5824dcdb86 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -4246,13 +4246,15 @@ declared as NOT NULL @param n_drop_fk number of constraints that are being dropped @param col_name modified column name @param new_field_flags Modified field flags +@param strict_mode Whether the sql_mode is strict @retval true Not allowed (will call my_error()) @retval false Allowed */ static bool check_foreigns_nullability(const dict_table_t *user_table, dict_foreign_t **drop_fk, ulint n_drop_fk, - const char *col_name, uint32_t new_field_flags) + const char *col_name, uint32_t new_field_flags, + bool strict_mode) { ut_ad(mutex_own(&dict_sys.mutex)); @@ -4264,7 +4266,7 @@ bool check_foreigns_nullability(const dict_table_t *user_table, if (innobase_dropping_foreign(foreign, drop_fk, n_drop_fk)) continue; - if (foreign->on_update_cascade_null(col_name)) + if (strict_mode && foreign->on_update_cascade_null(col_name)) goto non_null_error; if (foreign->type & (foreign->DELETE_SET_NULL | @@ -4286,7 +4288,7 @@ non_null_error: { for (dict_foreign_t *foreign : user_table->referenced_set) { - if (foreign->on_update_cascade_not_null(col_name)) + if (strict_mode && foreign->on_update_cascade_not_null(col_name)) { char display_name[FN_REFLEN]; const int dblen= int(table_name_t(const_cast(foreign-> @@ -4388,6 +4390,7 @@ column that is being dropped or modified to NOT NULL. @param user_table InnoDB table as it is before the ALTER operation @param drop_fk constraints being dropped @param n_drop_fk number of constraints that are being dropped +@param strict_mode Whether the strict sql_mode is set @retval true Not allowed (will call my_error()) @retval false Allowed */ @@ -4399,7 +4402,8 @@ innobase_check_foreigns( const TABLE* old_table, const dict_table_t* user_table, dict_foreign_t** drop_fk, - ulint n_drop_fk) + ulint n_drop_fk, + bool strict_mode) { for (Field** fp = old_table->field; *fp; fp++) { ut_ad(!(*fp)->real_maybe_null() @@ -4424,7 +4428,8 @@ innobase_check_foreigns( if (check_foreigns_nullability(user_table, drop_fk, n_drop_fk, (*fp)->field_name.str, - it->flags)) { + it->flags, + strict_mode)) { return true; } } @@ -6462,7 +6467,8 @@ prepare_inplace_alter_table_dict( if (new_clustered) { if (innobase_check_foreigns( ha_alter_info, old_table, - user_table, ctx->drop_fk, ctx->num_to_drop_fk)) { + user_table, ctx->drop_fk, ctx->num_to_drop_fk, + thd_is_strict_mode(ctx->trx->mysql_thd))) { new_clustered_failed: DBUG_ASSERT(ctx->trx != ctx->prebuilt->trx); ctx->trx->rollback(); From 91585fff3e2e665cc067b55190c2cc10473f3fd8 Mon Sep 17 00:00:00 2001 From: ParadoxV5 Date: Mon, 16 Dec 2024 19:56:09 -0700 Subject: [PATCH 116/213] MDEV-35665 Potential Buffer Overrun in Gtid_log_event::write() Two-Phase ALTER added a sa_seq_no field, but `Gtid_log_event::write()`'s size calculation doesn't have an addend in its name. This patch resizes the buffer to match `write()`'s code. --- sql/log_event_server.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc index 28e17dc035a..6bd62a77ba3 100644 --- a/sql/log_event_server.cc +++ b/sql/log_event_server.cc @@ -3729,7 +3729,12 @@ Gtid_log_event::peek(const uchar *event_start, size_t event_len, bool Gtid_log_event::write() { - uchar buf[GTID_HEADER_LEN+2+sizeof(XID) + /* flags_extra: */ 1+4]; + uchar buf[GTID_HEADER_LEN+2 + + sizeof(XID) + + 1 // flags_extra: + + 1 // extra_engines + + 8 // sa_seq_no + ]; size_t write_len= 13; int8store(buf, seq_no); From fa74c1a40ff75ab8041103b81ec3fc44ef286de1 Mon Sep 17 00:00:00 2001 From: Monty Date: Tue, 21 Jan 2025 19:19:46 +0200 Subject: [PATCH 117/213] Non partitioned table could be marked as partitioned in ddl.log partion_engine_name was not reset when looping over tables in mysql_rm_table_no_locks. This could cause maria_backup to think that at normal droped table was partitioned. This issue was discovered in 11.8 as part of atomic created and replace and only the fix was backported. --- sql/sql_table.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 59508887e6e..fccdde8a4bc 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1176,7 +1176,6 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, char path[FN_REFLEN + 1]; LEX_CSTRING alias= null_clex_str; LEX_CUSTRING version; - LEX_CSTRING partition_engine_name= {NULL, 0}; StringBuffer<160> unknown_tables(system_charset_info); DDL_LOG_STATE local_ddl_log_state; const char *comment_start; @@ -1263,6 +1262,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, const LEX_CSTRING db= table->db; const LEX_CSTRING table_name= table->table_name; LEX_CSTRING cpath= {0,0}; + LEX_CSTRING partition_engine_name= {NULL, 0}; handlerton *hton= 0; Table_type table_type; size_t path_length= 0; From 068d061454f1146e39b26a9a8c7058d067b36412 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Fri, 3 Jan 2025 17:40:05 +1100 Subject: [PATCH 118/213] MDEV-34813 A simple implementation of ha_partition::compare_key_parts It is not clear that the three Compare_key enums form a hierarchy like alter algorithms do. So on the safe side (in case MDEV-22168 gets implemented without looking at this code) we should return NotEqual if partition engines do not return the same enum value. There's a static merge function that merges these enums, but it is used to merge the Compare_keys of different key parts (horizontally), rather than different partitions (vertically). --- mysql-test/suite/parts/r/alter_table.result | 14 ++++++++++++++ mysql-test/suite/parts/t/alter_table.test | 19 +++++++++++++++++++ sql/ha_partition.cc | 18 ++++++++++++++++++ sql/ha_partition.h | 5 +++++ 4 files changed, 56 insertions(+) diff --git a/mysql-test/suite/parts/r/alter_table.result b/mysql-test/suite/parts/r/alter_table.result index ac8eba12f1b..5f532455219 100644 --- a/mysql-test/suite/parts/r/alter_table.result +++ b/mysql-test/suite/parts/r/alter_table.result @@ -59,4 +59,18 @@ index_name comment PRIMARY i2 disabled drop table t1; +# +# MDEV-34813 ALGORITHM=INSTANT does not work for partitioned tables on indexed column +# +CREATE TABLE `t1` ( +`f1` datetime , +`f2` VARCHAR(2) , +`f3` VARCHAR(200) , +`f4` VARCHAR(100) , +INDEX `i3` (`f4`) ) +PARTITION BY RANGE COLUMNS(`f2`) +(PARTITION `p_01` VALUES LESS THAN ('02') ENGINE = InnoDB, +PARTITION `p_31` VALUES LESS THAN (MAXVALUE) ENGINE = InnoDB); +ALTER online TABLE t1 MODIFY COLUMN `f4` VARCHAR(500) , ALGORITHM=INSTANT, LOCK=NONE; +drop table t1; # End of 10.5 tests diff --git a/mysql-test/suite/parts/t/alter_table.test b/mysql-test/suite/parts/t/alter_table.test index 37adb424d75..00ac3f0265e 100644 --- a/mysql-test/suite/parts/t/alter_table.test +++ b/mysql-test/suite/parts/t/alter_table.test @@ -52,4 +52,23 @@ alter table t1 add partition (partition p4); select index_name, comment from information_schema.statistics where table_schema='test' and table_name='t1'; drop table t1; +--echo # +--echo # MDEV-34813 ALGORITHM=INSTANT does not work for partitioned tables on indexed column +--echo # + +--source include/have_innodb.inc +CREATE TABLE `t1` ( + `f1` datetime , + `f2` VARCHAR(2) , + `f3` VARCHAR(200) , + `f4` VARCHAR(100) , + INDEX `i3` (`f4`) ) + PARTITION BY RANGE COLUMNS(`f2`) + (PARTITION `p_01` VALUES LESS THAN ('02') ENGINE = InnoDB, + PARTITION `p_31` VALUES LESS THAN (MAXVALUE) ENGINE = InnoDB); + +ALTER online TABLE t1 MODIFY COLUMN `f4` VARCHAR(500) , ALGORITHM=INSTANT, LOCK=NONE; + +drop table t1; + --echo # End of 10.5 tests diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 197f4fa51d6..95763eaf477 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -3178,6 +3178,24 @@ err1: DBUG_RETURN(true); } +Compare_keys ha_partition::compare_key_parts( + const Field &old_field, + const Column_definition &new_field, + const KEY_PART_INFO &old_part, + const KEY_PART_INFO &new_part) const +{ + Compare_keys res= m_file[0]->compare_key_parts(old_field, new_field, + old_part, new_part); + /* + Partitions have the same storage engine (until MDEV-22168) so the + calls should all return the same value for now. + */ + for (uint i= 1; i < m_tot_parts; i++) + if (res != m_file[i]->compare_key_parts(old_field, new_field, + old_part, new_part)) + return Compare_keys::NotEqual; + return res; +} /** Setup m_engine_array diff --git a/sql/ha_partition.h b/sql/ha_partition.h index b0321578d30..b8524dd15fb 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -481,6 +481,11 @@ public: m_part_info= part_info; m_is_sub_partitioned= part_info->is_sub_partitioned(); } + Compare_keys compare_key_parts( + const Field &old_field, + const Column_definition &new_field, + const KEY_PART_INFO &old_part, + const KEY_PART_INFO &new_part) const override; void return_record_by_parent() override; From 7358cbe6277da9ce749d179b01a2d46a5c699bd9 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Fri, 17 Jan 2025 18:15:04 +1100 Subject: [PATCH 119/213] MDEV-28526 Spider: remove conn_kind member variables The conn_kind, which stands for "connection kind", is no longer useful because the HandlerSocket support is deleted and Spider now has only one connection kind, SPIDER_CONN_KIND_MYSQL. Remove conn_kind and related code. Signed-off-by: Yuchen Pei Reviewed-by: Nayuta Yanagisawa --- storage/spider/ha_spider.cc | 44 +++++++------------------------ storage/spider/ha_spider.h | 8 ++---- storage/spider/spd_conn.cc | 37 ++++++++++---------------- storage/spider/spd_conn.h | 3 --- storage/spider/spd_copy_tables.cc | 9 +++---- storage/spider/spd_db_conn.cc | 14 +++++----- storage/spider/spd_db_conn.h | 3 +-- storage/spider/spd_db_include.h | 2 -- storage/spider/spd_db_mysql.cc | 4 +-- storage/spider/spd_direct_sql.cc | 2 -- storage/spider/spd_include.h | 1 - storage/spider/spd_ping_table.cc | 8 +++--- storage/spider/spd_table.cc | 32 +++++++--------------- storage/spider/spd_trx.cc | 36 +++++++++---------------- storage/spider/spd_trx.h | 6 +---- 15 files changed, 65 insertions(+), 144 deletions(-) diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc index 8aff2858c3a..54a2fd110f3 100644 --- a/storage/spider/ha_spider.cc +++ b/storage/spider/ha_spider.cc @@ -209,7 +209,6 @@ int ha_spider::open( DBUG_PRINT("info",("spider this=%p", this)); dup_key_idx = (uint) -1; - conn_kinds = SPIDER_CONN_KIND_MYSQL; #ifdef WITH_PARTITION_STORAGE_ENGINE table->file->get_no_parts("", &part_num); if (part_num) @@ -639,22 +638,7 @@ int ha_spider::check_access_kind_for_connection( int error_num, roop_count; DBUG_ENTER("ha_spider::check_access_kind_for_connection"); DBUG_PRINT("info",("spider this=%p", this)); - conn_kinds = 0; - switch (wide_handler->sql_command) - { - case SQLCOM_UPDATE: - case SQLCOM_UPDATE_MULTI: - case SQLCOM_DELETE: - case SQLCOM_DELETE_MULTI: - default: - conn_kinds |= SPIDER_CONN_KIND_MYSQL; - for (roop_count = 0; roop_count < (int) share->link_count; roop_count++) - { - conn_kind[roop_count] = SPIDER_CONN_KIND_MYSQL; - } - break; - } - if ((error_num = spider_check_trx_and_get_conn(thd, this, TRUE))) + if ((error_num= spider_check_trx_and_get_conn(thd, this))) { DBUG_RETURN(error_num); } @@ -980,7 +964,7 @@ int ha_spider::external_lock( } } - if ((error_num= spider_check_trx_and_get_conn(thd, this, FALSE))) + if ((error_num= spider_check_trx_and_get_conn(thd, this))) DBUG_RETURN(error_num); if (!partition_handler || !partition_handler->handlers) { @@ -1113,8 +1097,6 @@ int ha_spider::reset() if (check_error_mode(error_num2)) error_num = error_num2; } - - conn_kind[roop_count] = SPIDER_CONN_KIND_MYSQL; } result_list.bulk_update_mode = 0; result_list.bulk_update_size = 0; @@ -1140,7 +1122,6 @@ int ha_spider::reset() result_list.use_union = FALSE; result_list.use_both_key = FALSE; pt_clone_last_searcher = NULL; - conn_kinds = SPIDER_CONN_KIND_MYSQL; use_index_merge = FALSE; init_rnd_handler = FALSE; #ifdef HA_MRR_USE_DEFAULT_IMPL @@ -5232,7 +5213,7 @@ int ha_spider::rnd_next( DBUG_RETURN(error_num); use_pre_call = FALSE; } - if ((error_num= spider_check_trx_and_get_conn(ha_thd(), this, FALSE))) + if ((error_num= spider_check_trx_and_get_conn(ha_thd(), this))) DBUG_RETURN(error_num); DBUG_RETURN(rnd_next_internal(buf)); } @@ -5797,8 +5778,7 @@ int ha_spider::info( pthread_mutex_lock(&share->sts_mutex); if (difftime(tmp_time, share->sts_get_time) >= sts_interval) { - if ((error_num = spider_check_trx_and_get_conn(ha_thd(), this, - FALSE))) + if ((error_num= spider_check_trx_and_get_conn(ha_thd(), this))) { pthread_mutex_unlock(&share->sts_mutex); if (!share->sts_init) @@ -6361,7 +6341,7 @@ int ha_spider::check_crd() } if (crd_mode == 3) crd_mode = 1; - if ((error_num = spider_check_trx_and_get_conn(ha_thd(), this, FALSE))) + if ((error_num= spider_check_trx_and_get_conn(ha_thd(), this))) { DBUG_RETURN(check_error_mode(error_num)); } @@ -7748,7 +7728,7 @@ int ha_spider::truncate() DBUG_RETURN(ER_SPIDER_READ_ONLY_NUM); } wide_handler->sql_command = SQLCOM_TRUNCATE; - if ((error_num = spider_check_trx_and_get_conn(thd, this, FALSE))) + if ((error_num= spider_check_trx_and_get_conn(thd, this))) { DBUG_RETURN(error_num); } @@ -9334,13 +9314,11 @@ int ha_spider::drop_tmp_tables() } bool ha_spider::handler_opened( - int link_idx, - uint tgt_conn_kind + int link_idx ) { DBUG_ENTER("ha_spider::handler_opened"); DBUG_PRINT("info",("spider this=%p", this)); DBUG_PRINT("info",("spider link_idx=%d", link_idx)); - DBUG_PRINT("info",("spider tgt_conn_kind=%u", tgt_conn_kind)); if ( spider_bit_is_set(m_handler_opened, link_idx) ) { @@ -9361,8 +9339,7 @@ void ha_spider::set_handler_opened( } void ha_spider::clear_handler_opened( - int link_idx, - uint tgt_conn_kind + int link_idx ) { DBUG_ENTER("ha_spider::clear_handler_opened"); DBUG_PRINT("info",("spider this=%p", this)); @@ -9381,7 +9358,7 @@ int ha_spider::close_opened_handler( if (spider_bit_is_set(m_handler_opened, link_idx)) { if ((error_num = spider_db_close_handler(this, - conns[link_idx], link_idx, SPIDER_CONN_KIND_MYSQL)) + conns[link_idx], link_idx)) ) { error_num= spider_maybe_ping_1(this, link_idx, error_num); } @@ -11568,8 +11545,7 @@ int ha_spider::append_lock_tables_list() if (!(wide_handler->trx = spider_get_trx(ha_thd(), TRUE, &error_num))) DBUG_RETURN(error_num); - if ((error_num = spider_check_trx_and_get_conn(wide_handler->trx->thd, this, - FALSE))) + if ((error_num = spider_check_trx_and_get_conn(wide_handler->trx->thd, this))) { DBUG_RETURN(error_num); } diff --git a/storage/spider/ha_spider.h b/storage/spider/ha_spider.h index 34fad7eee96..d794bfa0cc4 100644 --- a/storage/spider/ha_spider.h +++ b/storage/spider/ha_spider.h @@ -62,8 +62,6 @@ public: uint sql_kinds; uint *sql_kind; ulonglong *connection_ids; - uint conn_kinds; - uint *conn_kind; char *conn_keys_first_ptr; char **conn_keys; SPIDER_CONN **conns; @@ -632,15 +630,13 @@ public: int check_ha_range_eof(); int drop_tmp_tables(); bool handler_opened( - int link_idx, - uint tgt_conn_kind + int link_idx ); void set_handler_opened( int link_idx ); void clear_handler_opened( - int link_idx, - uint tgt_conn_kind + int link_idx ); int close_opened_handler( int link_idx, diff --git a/storage/spider/spd_conn.cc b/storage/spider/spd_conn.cc index 2faeba56b23..e37df5027bd 100644 --- a/storage/spider/spd_conn.cc +++ b/storage/spider/spd_conn.cc @@ -112,7 +112,6 @@ const uchar *spider_conn_get_key( auto conn= static_cast(conn_); DBUG_ENTER("spider_conn_get_key"); *length = conn->conn_key_length; - DBUG_PRINT("info",("spider conn_kind=%u", conn->conn_kind)); #ifdef DBUG_TRACE spider_print_keys(conn->conn_key, conn->conn_key_length); #endif @@ -402,7 +401,6 @@ SPIDER_CONN *spider_create_conn( ha_spider *spider, int link_idx, int base_link_idx, - uint conn_kind, int *error_num ) { int *need_mon; @@ -556,7 +554,6 @@ SPIDER_CONN *spider_create_conn( conn->semi_trx_isolation_chk = FALSE; conn->semi_trx_chk = FALSE; conn->link_idx = base_link_idx; - conn->conn_kind = conn_kind; conn->conn_need_mon = need_mon; if (spider) conn->need_mon = &spider->need_mons[base_link_idx]; @@ -643,13 +640,11 @@ SPIDER_CONN *spider_get_conn( ha_spider *spider, bool another, bool thd_chg, - uint conn_kind, int *error_num ) { SPIDER_CONN *conn = NULL; int base_link_idx = link_idx; DBUG_ENTER("spider_get_conn"); - DBUG_PRINT("info",("spider conn_kind=%u", conn_kind)); if (spider) link_idx = spider->conn_link_idx[base_link_idx]; @@ -688,7 +683,8 @@ SPIDER_CONN *spider_get_conn( pthread_mutex_unlock(&spider_conn_mutex); if (spider_param_max_connections()) { /* enable connection pool */ - conn = spider_get_conn_from_idle_connection(share, link_idx, conn_key, spider, conn_kind, base_link_idx, error_num); + conn= spider_get_conn_from_idle_connection( + share, link_idx, conn_key, spider, base_link_idx, error_num); /* failed get conn, goto error */ if (!conn) goto error; @@ -697,8 +693,8 @@ SPIDER_CONN *spider_get_conn( else { /* did not enable conncetion pool , create_conn */ DBUG_PRINT("info",("spider create new conn")); - if (!(conn = spider_create_conn(share, spider, link_idx, - base_link_idx, conn_kind, error_num))) + if (!(conn= spider_create_conn(share, spider, link_idx, + base_link_idx, error_num))) goto error; *conn->conn_key = *conn_key; if (spider) @@ -722,8 +718,8 @@ SPIDER_CONN *spider_get_conn( } else { DBUG_PRINT("info",("spider create new conn")); /* conn_recycle_strict = 0 and conn_recycle_mode = 0 or 2 */ - if (!(conn = spider_create_conn(share, spider, link_idx, base_link_idx, - conn_kind, error_num))) + if (!(conn= spider_create_conn(share, spider, link_idx, base_link_idx, + error_num))) goto error; *conn->conn_key = *conn_key; if (spider) @@ -872,8 +868,7 @@ int spider_check_and_get_casual_read_conn( '0' + spider->result_list.casual_read[link_idx]; if (!(spider->conns[link_idx]= spider_get_conn( spider->share, link_idx, spider->conn_keys[link_idx], - spider->wide_handler->trx, spider, FALSE, TRUE, - SPIDER_CONN_KIND_MYSQL, &error_num))) + spider->wide_handler->trx, spider, FALSE, TRUE, &error_num))) { *spider->conn_keys[link_idx] = first_byte_bak; DBUG_RETURN(error_num); @@ -3023,9 +3018,8 @@ void *spider_bg_sts_action( if (!conns[spider.search_link_idx]) { spider_get_conn(share, spider.search_link_idx, - share->conn_keys[spider.search_link_idx], - trx, &spider, FALSE, FALSE, SPIDER_CONN_KIND_MYSQL, - &error_num); + share->conn_keys[spider.search_link_idx], trx, + &spider, FALSE, FALSE, &error_num); conns[spider.search_link_idx]->error_mode = 0; spider.search_link_idx = -1; } @@ -3298,9 +3292,8 @@ void *spider_bg_crd_action( if (!conns[spider.search_link_idx]) { spider_get_conn(share, spider.search_link_idx, - share->conn_keys[spider.search_link_idx], - trx, &spider, FALSE, FALSE, SPIDER_CONN_KIND_MYSQL, - &error_num); + share->conn_keys[spider.search_link_idx], trx, + &spider, FALSE, FALSE, &error_num); conns[spider.search_link_idx]->error_mode = 0; spider.search_link_idx = -1; } @@ -3854,8 +3847,6 @@ bool spider_conn_use_handler( spider->share->use_handlers[link_idx]); DBUG_ENTER("spider_conn_use_handler"); DBUG_PRINT("info",("spider use_handler=%d", use_handler)); - DBUG_PRINT("info",("spider spider->conn_kind[link_idx]=%u", - spider->conn_kind[link_idx])); if (spider->do_direct_update) { spider->sql_kinds |= SPIDER_SQL_KIND_SQL; @@ -3921,7 +3912,7 @@ bool spider_conn_need_open_handler( ) { DBUG_ENTER("spider_conn_need_open_handler"); DBUG_PRINT("info",("spider spider=%p", spider)); - if (spider->handler_opened(link_idx, spider->conn_kind[link_idx])) + if (spider->handler_opened(link_idx)) { DBUG_PRINT("info",("spider HA already opened")); DBUG_RETURN(FALSE); @@ -3934,7 +3925,6 @@ SPIDER_CONN* spider_get_conn_from_idle_connection( int link_idx, char *conn_key, ha_spider *spider, - uint conn_kind, int base_link_idx, int *error_num ) @@ -4022,7 +4012,8 @@ SPIDER_CONN* spider_get_conn_from_idle_connection( if (ip_port_conn) pthread_mutex_unlock(&ip_port_conn->mutex); DBUG_PRINT("info",("spider create new conn")); - if (!(conn = spider_create_conn(share, spider, link_idx, base_link_idx, conn_kind, error_num))) + if (!(conn= spider_create_conn(share, spider, link_idx, base_link_idx, + error_num))) DBUG_RETURN(conn); *conn->conn_key = *conn_key; if (spider) diff --git a/storage/spider/spd_conn.h b/storage/spider/spd_conn.h index ba02178a608..ba3ca0ab62c 100644 --- a/storage/spider/spd_conn.h +++ b/storage/spider/spd_conn.h @@ -124,7 +124,6 @@ SPIDER_CONN *spider_create_conn( ha_spider *spider, int link_id, int base_link_id, - uint conn_kind, int *error_num ); @@ -136,7 +135,6 @@ SPIDER_CONN *spider_get_conn( ha_spider *spider, bool another, bool thd_chg, - uint conn_kind, int *error_num ); @@ -451,7 +449,6 @@ SPIDER_CONN* spider_get_conn_from_idle_connection int link_idx, char *conn_key, ha_spider *spider, - uint conn_kind, int base_link_idx, int *error_num ); diff --git a/storage/spider/spd_copy_tables.cc b/storage/spider/spd_copy_tables.cc index d9cf32b3923..0ea7b0dcf0c 100644 --- a/storage/spider/spd_copy_tables.cc +++ b/storage/spider/spd_copy_tables.cc @@ -501,11 +501,10 @@ int spider_udf_get_copy_tgt_conns( while (table_conn) { share = table_conn->share; - if ( - !(table_conn->conn = spider_get_conn( - share, 0, share->conn_keys[0], trx, NULL, FALSE, FALSE, - SPIDER_CONN_KIND_MYSQL, &error_num)) - ) { + if (!(table_conn->conn= + spider_get_conn(share, 0, share->conn_keys[0], trx, NULL, + FALSE, FALSE, &error_num))) + { my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), share->server_names[0]); DBUG_RETURN(ER_CONNECT_TO_FOREIGN_DATA_SOURCE); } diff --git a/storage/spider/spd_db_conn.cc b/storage/spider/spd_db_conn.cc index 72489a1777e..1c1aa308e82 100644 --- a/storage/spider/spd_db_conn.cc +++ b/storage/spider/spd_db_conn.cc @@ -73,7 +73,7 @@ int spider_db_connect( THD* thd = current_thd; longlong connect_retry_interval; DBUG_ENTER("spider_db_connect"); - DBUG_ASSERT(conn->conn_kind != SPIDER_CONN_KIND_MYSQL || conn->need_mon); + DBUG_ASSERT(conn->need_mon); DBUG_PRINT("info",("spider link_idx=%d", link_idx)); DBUG_PRINT("info",("spider conn=%p", conn)); @@ -221,7 +221,6 @@ void spider_db_disconnect( ) { DBUG_ENTER("spider_db_disconnect"); DBUG_PRINT("info",("spider conn=%p", conn)); - DBUG_PRINT("info",("spider conn->conn_kind=%u", conn->conn_kind)); if (conn->db_conn->is_connected()) { conn->db_conn->disconnect(); @@ -10361,9 +10360,9 @@ int spider_db_open_handler( spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id]; DBUG_ENTER("spider_db_open_handler"); spider_lock_before_query(conn, &spider->need_mons[link_idx]); - if (!spider->handler_opened(link_idx, conn->conn_kind)) + if (!spider->handler_opened(link_idx)) *handler_id_ptr = conn->opened_handlers; - if (!spider->handler_opened(link_idx, conn->conn_kind)) + if (!spider->handler_opened(link_idx)) my_sprintf(spider->m_handler_cid[link_idx], (spider->m_handler_cid[link_idx], SPIDER_SQL_HANDLER_CID_FORMAT, @@ -10388,7 +10387,7 @@ int spider_db_open_handler( goto error; } dbton_hdl->reset_sql(SPIDER_SQL_TYPE_HANDLER); - if (!spider->handler_opened(link_idx, conn->conn_kind)) + if (!spider->handler_opened(link_idx)) { if ((error_num = dbton_hdl->insert_opened_handler(conn, link_idx))) goto error; @@ -10405,15 +10404,14 @@ error: int spider_db_close_handler( ha_spider *spider, SPIDER_CONN *conn, - int link_idx, - uint tgt_conn_kind + int link_idx ) { int error_num= 0; spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id]; DBUG_ENTER("spider_db_close_handler"); DBUG_PRINT("info",("spider conn=%p", conn)); spider_lock_before_query(conn, &spider->need_mons[link_idx]); - if (spider->handler_opened(link_idx, tgt_conn_kind)) + if (spider->handler_opened(link_idx)) { dbton_hdl->reset_sql(SPIDER_SQL_TYPE_HANDLER); if ((error_num = dbton_hdl->append_close_handler_part( diff --git a/storage/spider/spd_db_conn.h b/storage/spider/spd_db_conn.h index 6e94e2d1517..b9e06e3f219 100644 --- a/storage/spider/spd_db_conn.h +++ b/storage/spider/spd_db_conn.h @@ -1175,8 +1175,7 @@ int spider_db_open_handler( int spider_db_close_handler( ha_spider *spider, SPIDER_CONN *conn, - int link_idx, - uint tgt_conn_kind + int link_idx ); diff --git a/storage/spider/spd_db_include.h b/storage/spider/spd_db_include.h index 430cd8479be..bcb16ab391b 100644 --- a/storage/spider/spd_db_include.h +++ b/storage/spider/spd_db_include.h @@ -174,8 +174,6 @@ typedef st_spider_result SPIDER_RESULT; #define SPIDER_SQL_LOP_CHK_PRM_PRF_STR "spider_lc_" #define SPIDER_SQL_LOP_CHK_PRM_PRF_LEN (sizeof(SPIDER_SQL_LOP_CHK_PRM_PRF_STR) - 1) -#define SPIDER_CONN_KIND_MYSQL (1 << 0) - #define SPIDER_SQL_KIND_SQL (1 << 0) #define SPIDER_SQL_KIND_HANDLER (1 << 1) diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index 5fd215de341..b0c56b0376a 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -3193,7 +3193,7 @@ void spider_db_mbase::reset_opened_handler() { tmp_spider = (*tmp_link_for_hash)->spider; tmp_link_idx = (*tmp_link_for_hash)->link_idx; - tmp_spider->clear_handler_opened(tmp_link_idx, conn->conn_kind); + tmp_spider->clear_handler_opened(tmp_link_idx); } DBUG_VOID_RETURN; } @@ -7377,7 +7377,7 @@ int spider_mbase_share::discover_table_structure( int *need_mon= &need_mon_deref; if (!(conn = spider_get_conn( spider_share, 0, spider_share->conn_keys[roop_count], trx, NULL, FALSE, - FALSE, SPIDER_CONN_KIND_MYSQL, &error_num)) + FALSE, &error_num)) ) { DBUG_RETURN(error_num); } diff --git a/storage/spider/spd_direct_sql.cc b/storage/spider/spd_direct_sql.cc index 5aabb5c07fc..f0661bdd4c0 100644 --- a/storage/spider/spd_direct_sql.cc +++ b/storage/spider/spd_direct_sql.cc @@ -416,7 +416,6 @@ SPIDER_CONN *spider_udf_direct_sql_create_conn( conn->semi_trx_isolation = -2; conn->semi_trx_isolation_chk = FALSE; conn->semi_trx_chk = FALSE; - conn->conn_kind = SPIDER_CONN_KIND_MYSQL; if (mysql_mutex_init(spd_key_mutex_mta_conn, &conn->mta_conn_mutex, MY_MUTEX_INIT_FAST)) @@ -561,7 +560,6 @@ SPIDER_CONN *spider_udf_direct_sql_get_conn( conn->queued_ping = FALSE; DBUG_PRINT("info",("spider conn=%p", conn)); - DBUG_PRINT("info",("spider conn->conn_kind=%u", conn->conn_kind)); DBUG_RETURN(conn); error: diff --git a/storage/spider/spd_include.h b/storage/spider/spd_include.h index bb3dc92ed3a..17877040358 100644 --- a/storage/spider/spd_include.h +++ b/storage/spider/spd_include.h @@ -589,7 +589,6 @@ typedef struct st_spider_conn_loop_check SPIDER_CONN_LOOP_CHECK; /* database connection */ typedef struct st_spider_conn { - uint conn_kind; char *conn_key; uint conn_key_length; my_hash_value_type conn_key_hash_value; diff --git a/storage/spider/spd_ping_table.cc b/storage/spider/spd_ping_table.cc index 8e4f8a2214b..68254a636e5 100644 --- a/storage/spider/spd_ping_table.cc +++ b/storage/spider/spd_ping_table.cc @@ -648,11 +648,9 @@ SPIDER_CONN *spider_get_ping_table_tgt_conn( ) { SPIDER_CONN *conn; DBUG_ENTER("spider_get_ping_table_tgt_conn"); - if ( - !(conn = spider_get_conn( - share, 0, share->conn_keys[0], trx, NULL, FALSE, FALSE, - SPIDER_CONN_KIND_MYSQL, error_num)) - ) { + if (!(conn= spider_get_conn(share, 0, share->conn_keys[0], trx, NULL, FALSE, + FALSE, error_num))) + { my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), share->server_names[0]); *error_num = ER_CONNECT_TO_FOREIGN_DATA_SOURCE; diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc index 9a4924c42d1..5aa49cbc327 100644 --- a/storage/spider/spd_table.cc +++ b/storage/spider/spd_table.cc @@ -4517,7 +4517,6 @@ SPIDER_SHARE *spider_get_share( &spider->conn_can_fo, sizeof(uchar) * share->link_bitmap_size, &spider->sql_kind, sizeof(uint) * share->link_count, &spider->connection_ids, sizeof(ulonglong) * share->link_count, - &spider->conn_kind, sizeof(uint) * share->link_count, &spider->db_request_id, sizeof(ulonglong) * share->link_count, &spider->db_request_phase, sizeof(uchar) * share->link_bitmap_size, &spider->m_handler_opened, sizeof(uchar) * share->link_bitmap_size, @@ -4558,7 +4557,6 @@ SPIDER_SHARE *spider_get_share( tmp_cid += SPIDER_SQL_HANDLER_CID_LEN + 1; result_list->upd_tmp_tbl_prms[roop_count].init(); result_list->upd_tmp_tbl_prms[roop_count].field_count = 1; - spider->conn_kind[roop_count] = SPIDER_CONN_KIND_MYSQL; } spider_trx_set_link_idx_for_all(spider); @@ -4613,7 +4611,6 @@ SPIDER_SHARE *spider_get_share( !(spider->conns[roop_count] = spider_get_conn(share, roop_count, spider->conn_keys[roop_count], spider->wide_handler->trx, spider, FALSE, TRUE, - SPIDER_CONN_KIND_MYSQL, error_num)) ) { if ( @@ -4993,7 +4990,6 @@ SPIDER_SHARE *spider_get_share( &spider->conn_can_fo, sizeof(uchar) * share->link_bitmap_size, &spider->sql_kind, sizeof(uint) * share->link_count, &spider->connection_ids, sizeof(ulonglong) * share->link_count, - &spider->conn_kind, sizeof(uint) * share->link_count, &spider->db_request_id, sizeof(ulonglong) * share->link_count, &spider->db_request_phase, sizeof(uchar) * share->link_bitmap_size, &spider->m_handler_opened, sizeof(uchar) * share->link_bitmap_size, @@ -5031,7 +5027,6 @@ SPIDER_SHARE *spider_get_share( tmp_cid += SPIDER_SQL_HANDLER_CID_LEN + 1; result_list->upd_tmp_tbl_prms[roop_count].init(); result_list->upd_tmp_tbl_prms[roop_count].field_count = 1; - spider->conn_kind[roop_count] = SPIDER_CONN_KIND_MYSQL; } spider_trx_set_link_idx_for_all(spider); @@ -5083,7 +5078,6 @@ SPIDER_SHARE *spider_get_share( !(spider->conns[roop_count] = spider_get_conn(share, roop_count, spider->conn_keys[roop_count], spider->wide_handler->trx, spider, FALSE, TRUE, - SPIDER_CONN_KIND_MYSQL, error_num)) ) { if ( @@ -5703,11 +5697,9 @@ int spider_open_all_tables( } /* create conn */ - if ( - !(conn = spider_get_conn( - &tmp_share, 0, tmp_share.conn_keys[0], trx, NULL, FALSE, FALSE, - SPIDER_CONN_KIND_MYSQL, &error_num)) - ) { + if (!(conn= spider_get_conn(&tmp_share, 0, tmp_share.conn_keys[0], trx, + NULL, FALSE, FALSE, &error_num))) + { spider_sys_index_end(table_tables); spider_close_sys_table(thd, table_tables, &open_tables_backup, TRUE); @@ -5801,11 +5793,9 @@ int spider_open_all_tables( } /* create another conn */ - if ( - (!(conn = spider_get_conn( - &tmp_share, 0, tmp_share.conn_keys[0], trx, spider, TRUE, FALSE, - SPIDER_CONN_KIND_MYSQL, &error_num))) - ) { + if ((!(conn= spider_get_conn(&tmp_share, 0, tmp_share.conn_keys[0], trx, + spider, TRUE, FALSE, &error_num)))) + { spider_free_tmp_dbton_handler(spider); spider_free(trx, share, MYF(0)); delete spider; @@ -8850,9 +8840,8 @@ void *spider_table_bg_sts_action( if (!conns[spider->search_link_idx]) { spider_get_conn(share, spider->search_link_idx, - share->conn_keys[spider->search_link_idx], - trx, spider, FALSE, FALSE, SPIDER_CONN_KIND_MYSQL, - &error_num); + share->conn_keys[spider->search_link_idx], trx, + spider, FALSE, FALSE, &error_num); if (conns[spider->search_link_idx]) { conns[spider->search_link_idx]->error_mode = 0; @@ -9003,9 +8992,8 @@ void *spider_table_bg_crd_action( if (!conns[spider->search_link_idx]) { spider_get_conn(share, spider->search_link_idx, - share->conn_keys[spider->search_link_idx], - trx, spider, FALSE, FALSE, SPIDER_CONN_KIND_MYSQL, - &error_num); + share->conn_keys[spider->search_link_idx], trx, + spider, FALSE, FALSE, &error_num); if (conns[spider->search_link_idx]) { conns[spider->search_link_idx]->error_mode = 0; diff --git a/storage/spider/spd_trx.cc b/storage/spider/spd_trx.cc index 105cf7b744b..af690e7ff5f 100644 --- a/storage/spider/spd_trx.cc +++ b/storage/spider/spd_trx.cc @@ -2673,13 +2673,11 @@ int spider_internal_xa_commit_by_xid( goto error; } - if ( - !(conn = spider_get_conn( - &tmp_share, 0, tmp_share.conn_keys[0], trx, NULL, FALSE, FALSE, - SPIDER_CONN_KIND_MYSQL, &error_num)) && - (force_commit == 0 || - (force_commit == 1 && error_num != ER_XAER_NOTA)) - ) { + if (!(conn= spider_get_conn(&tmp_share, 0, tmp_share.conn_keys[0], trx, + NULL, FALSE, FALSE, &error_num)) && + (force_commit == 0 || + (force_commit == 1 && error_num != ER_XAER_NOTA))) + { spider_sys_index_end(table_xa_member); spider_free_tmp_share_alloc(&tmp_share); free_root(&mem_root, MYF(0)); @@ -2903,13 +2901,11 @@ int spider_internal_xa_rollback_by_xid( goto error; } - if ( - !(conn = spider_get_conn( - &tmp_share, 0, tmp_share.conn_keys[0], trx, NULL, FALSE, FALSE, - SPIDER_CONN_KIND_MYSQL, &error_num)) && - (force_commit == 0 || - (force_commit == 1 && error_num != ER_XAER_NOTA)) - ) { + if (!(conn= spider_get_conn(&tmp_share, 0, tmp_share.conn_keys[0], trx, + NULL, FALSE, FALSE, &error_num)) && + (force_commit == 0 || + (force_commit == 1 && error_num != ER_XAER_NOTA))) + { spider_sys_index_end(table_xa_member); spider_free_tmp_share_alloc(&tmp_share); free_root(&mem_root, MYF(0)); @@ -3409,8 +3405,7 @@ int spider_end_trx( int spider_check_trx_and_get_conn( THD *thd, - ha_spider *spider, - bool use_conn_kind + ha_spider *spider ) { int error_num, roop_count, search_link_idx; SPIDER_TRX *trx; @@ -3500,7 +3495,7 @@ int spider_check_trx_and_get_conn( *spider->conn_keys[0] = first_byte; for (roop_count = 0; roop_count < (int) share->link_count; roop_count++) { - if (!spider->handler_opened(roop_count, SPIDER_CONN_KIND_MYSQL)) + if (!spider->handler_opened(roop_count)) spider->conns[roop_count] = NULL; } bool search_link_idx_is_checked = FALSE; @@ -3513,12 +3508,9 @@ int spider_check_trx_and_get_conn( spider->conn_link_idx, roop_count, share->link_count, SPIDER_LINK_STATUS_RECOVERY) ) { - uint tgt_conn_kind = (use_conn_kind ? spider->conn_kind[roop_count] : - SPIDER_CONN_KIND_MYSQL); if (roop_count == spider->search_link_idx) search_link_idx_is_checked = TRUE; if ( - tgt_conn_kind == SPIDER_CONN_KIND_MYSQL && !spider->conns[roop_count] ) { *spider->conn_keys[roop_count] = first_byte; @@ -3527,8 +3519,6 @@ int spider_check_trx_and_get_conn( spider_get_conn(share, roop_count, spider->conn_keys[roop_count], trx, spider, FALSE, TRUE, - use_conn_kind ? spider->conn_kind[roop_count] : - SPIDER_CONN_KIND_MYSQL, &error_num)) ) { if ( @@ -3607,8 +3597,6 @@ int spider_check_trx_and_get_conn( spider_get_conn(share, roop_count, spider->conn_keys[roop_count], trx, spider, FALSE, TRUE, - use_conn_kind ? spider->conn_kind[roop_count] : - SPIDER_CONN_KIND_MYSQL, &error_num)) ) { if ( diff --git a/storage/spider/spd_trx.h b/storage/spider/spd_trx.h index 2055a49717e..93b03fcec21 100644 --- a/storage/spider/spd_trx.h +++ b/storage/spider/spd_trx.h @@ -227,11 +227,7 @@ int spider_end_trx( SPIDER_CONN *conn ); -int spider_check_trx_and_get_conn( - THD *thd, - ha_spider *spider, - bool use_conn_kind -); +int spider_check_trx_and_get_conn(THD *thd, ha_spider *spider); THD *spider_create_tmp_thd(); From 402b1374a7e0333969564c814679a1e1f8356b21 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Mon, 20 Jan 2025 13:41:53 +1100 Subject: [PATCH 120/213] MDEV-34849 Spider: do not change the first byte of a connection key Each spider connection is identified with a connection key, which is an encoding of the backend parameters. The first byte of the key is by default 0, and in rare circumstances it is changed to a different value: when semi_table_lock is set to 1; and when using casual read. When this happens, often a new connection is created with the new key. Neither case is useful: the description of semi_table_lock has nothing to do with creation of new connections and the parameter itself was deprecated for 10.7+ (MDEV-28829) and marked for deletion (MDEV-28830); while new threads created by non-zero spider_casual_read causes only threads to be idle, thus not achieving any gain, see MDEV-26151, and the param has also been deprecated in 11.5+ (MDEV-31789). The relevant code adds unnecessary complexity to the spider code. This change does not reduce parallelism, because already when bgs mode is on a background thread is created per partition, and there is no evidence spider creates multiple threads for one partition. If the needs of such cases arise it will be a separate issue. --- storage/spider/ha_spider.cc | 3 --- storage/spider/spd_conn.cc | 5 ----- storage/spider/spd_table.cc | 19 ------------------- storage/spider/spd_trx.cc | 22 +--------------------- 4 files changed, 1 insertion(+), 48 deletions(-) diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc index 54a2fd110f3..0089b1fa0f6 100644 --- a/storage/spider/ha_spider.cc +++ b/storage/spider/ha_spider.cc @@ -1006,9 +1006,6 @@ int ha_spider::reset() THD *thd = ha_thd(); SPIDER_TRX *tmp_trx, *trx_bak; SPIDER_CONDITION *tmp_cond; -/* - char first_byte, first_byte_bak; -*/ backup_error_status(); DBUG_ENTER("ha_spider::reset"); DBUG_PRINT("info",("spider this=%p", this)); diff --git a/storage/spider/spd_conn.cc b/storage/spider/spd_conn.cc index e37df5027bd..5019e5ece11 100644 --- a/storage/spider/spd_conn.cc +++ b/storage/spider/spd_conn.cc @@ -863,17 +863,12 @@ int spider_check_and_get_casual_read_conn( if (conn->casual_read_current_id > 63) conn->casual_read_current_id = 2; } - char first_byte_bak = *spider->conn_keys[link_idx]; - *spider->conn_keys[link_idx] = - '0' + spider->result_list.casual_read[link_idx]; if (!(spider->conns[link_idx]= spider_get_conn( spider->share, link_idx, spider->conn_keys[link_idx], spider->wide_handler->trx, spider, FALSE, TRUE, &error_num))) { - *spider->conn_keys[link_idx] = first_byte_bak; DBUG_RETURN(error_num); } - *spider->conn_keys[link_idx] = first_byte_bak; spider->conns[link_idx]->casual_read_base_conn = conn; spider_check_and_set_autocommit(thd, spider->conns[link_idx], NULL); DBUG_RETURN(0); diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc index 5aa49cbc327..347a3074325 100644 --- a/storage/spider/spd_table.cc +++ b/storage/spider/spd_table.cc @@ -4227,8 +4227,6 @@ SPIDER_SHARE *spider_get_share( #ifdef WITH_PARTITION_STORAGE_ENGINE int crd_sync; #endif - char first_byte; - int semi_table_lock_conn; int search_link_idx; uint sql_command = thd_sql_command(thd); SPIDER_Open_tables_backup open_tables_backup; @@ -4425,13 +4423,6 @@ SPIDER_SHARE *spider_get_share( pthread_mutex_unlock(&share->mutex); } - semi_table_lock_conn = spider_param_semi_table_lock_connection(thd, - share->semi_table_lock_conn); - if (semi_table_lock_conn) - first_byte = '0' + - spider_param_semi_table_lock(thd, share->semi_table_lock); - else - first_byte = '0'; if (!(spider->wide_handler->trx = spider_get_trx(thd, TRUE, error_num))) { @@ -4551,7 +4542,6 @@ SPIDER_SHARE *spider_get_share( for (roop_count = 0; roop_count < (int) share->link_count; roop_count++) { spider->conn_keys[roop_count] = tmp_name; - *tmp_name = first_byte; tmp_name += share->conn_keys_lengths[roop_count] + 1; spider->m_handler_cid[roop_count] = tmp_cid; tmp_cid += SPIDER_SQL_HANDLER_CID_LEN + 1; @@ -4909,14 +4899,6 @@ SPIDER_SHARE *spider_get_share( pthread_mutex_unlock(&share->mutex); } - semi_table_lock_conn = spider_param_semi_table_lock_connection(thd, - share->semi_table_lock_conn); - if (semi_table_lock_conn) - first_byte = '0' + - spider_param_semi_table_lock(thd, share->semi_table_lock); - else - first_byte = '0'; - spider->share = share; if (!(spider->wide_handler->trx = spider_get_trx(thd, TRUE, error_num))) { @@ -5021,7 +5003,6 @@ SPIDER_SHARE *spider_get_share( for (roop_count = 0; roop_count < (int) share->link_count; roop_count++) { spider->conn_keys[roop_count] = tmp_name; - *tmp_name = first_byte; tmp_name += share->conn_keys_lengths[roop_count] + 1; spider->m_handler_cid[roop_count] = tmp_cid; tmp_cid += SPIDER_SQL_HANDLER_CID_LEN + 1; diff --git a/storage/spider/spd_trx.cc b/storage/spider/spd_trx.cc index af690e7ff5f..e46b8cc289a 100644 --- a/storage/spider/spd_trx.cc +++ b/storage/spider/spd_trx.cc @@ -3411,9 +3411,6 @@ int spider_check_trx_and_get_conn( SPIDER_TRX *trx; SPIDER_SHARE *share = spider->share; SPIDER_CONN *conn; - char first_byte, first_byte_bak; - int semi_table_lock_conn = spider_param_semi_table_lock_connection(thd, - share->semi_table_lock_conn); DBUG_ENTER("spider_check_trx_and_get_conn"); if (!(trx = spider_get_trx(thd, TRUE, &error_num))) { @@ -3428,28 +3425,15 @@ int spider_check_trx_and_get_conn( if (!trx_ha || trx_ha->wait_for_reusing) spider_trx_set_link_idx_for_all(spider); - - if (semi_table_lock_conn) - first_byte = '0' + - spider_param_semi_table_lock(thd, share->semi_table_lock); - else - first_byte = '0'; - DBUG_PRINT("info",("spider semi_table_lock_conn = %d", - semi_table_lock_conn)); - DBUG_PRINT("info",("spider semi_table_lock = %d", - spider_param_semi_table_lock(thd, share->semi_table_lock))); - DBUG_PRINT("info",("spider first_byte = %d", first_byte)); if ( !trx_ha || trx_ha->wait_for_reusing || trx->spider_thread_id != spider->spider_thread_id || trx->trx_conn_adjustment != spider->trx_conn_adjustment || - first_byte != *spider->conn_keys[0] || share->link_statuses[spider->conn_link_idx[spider->search_link_idx]] == SPIDER_LINK_STATUS_NG ) { - DBUG_PRINT("info",(first_byte != *spider->conn_keys[0] ? - "spider change conn type" : trx != spider->wide_handler->trx ? + DBUG_PRINT("info",(trx != spider->wide_handler->trx ? "spider change thd" : "spider next trx")); spider->wide_handler->trx = trx; spider->trx_conn_adjustment = trx->trx_conn_adjustment; @@ -3491,8 +3475,6 @@ int spider_check_trx_and_get_conn( } spider->spider_thread_id = trx->spider_thread_id; - first_byte_bak = *spider->conn_keys[0]; - *spider->conn_keys[0] = first_byte; for (roop_count = 0; roop_count < (int) share->link_count; roop_count++) { if (!spider->handler_opened(roop_count)) @@ -3513,7 +3495,6 @@ int spider_check_trx_and_get_conn( if ( !spider->conns[roop_count] ) { - *spider->conn_keys[roop_count] = first_byte; if ( !(conn = spider_get_conn(share, roop_count, @@ -3543,7 +3524,6 @@ int spider_check_trx_and_get_conn( ); } DBUG_PRINT("info",("spider get conn error")); - *spider->conn_keys[0] = first_byte_bak; spider->spider_thread_id = 0; DBUG_RETURN(error_num); } From e3c768dc8a2de78aa0c096ea1d821c7d801eed44 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Tue, 21 Jan 2025 10:41:20 +1100 Subject: [PATCH 121/213] MDEV-34849 Clean up spider_check_trx_and_get_conn() Factoring out parts and documentation. Does not change the logic of the code. --- storage/spider/spd_conn.cc | 6 - storage/spider/spd_include.h | 17 +- storage/spider/spd_trx.cc | 361 ++++++++++++++++------------------- 3 files changed, 176 insertions(+), 208 deletions(-) diff --git a/storage/spider/spd_conn.cc b/storage/spider/spd_conn.cc index 5019e5ece11..9f2624b4bc7 100644 --- a/storage/spider/spd_conn.cc +++ b/storage/spider/spd_conn.cc @@ -2995,12 +2995,6 @@ void *spider_bg_sts_action( if (spider.search_link_idx < 0) { spider_trx_set_link_idx_for_all(&spider); -/* - spider.search_link_idx = spider_conn_next_link_idx( - thd, share->link_statuses, share->access_balances, - spider.conn_link_idx, spider.search_link_idx, share->link_count, - SPIDER_LINK_STATUS_OK); -*/ spider.search_link_idx = spider_conn_first_link_idx(thd, share->link_statuses, share->access_balances, spider.conn_link_idx, share->link_count, SPIDER_LINK_STATUS_OK); diff --git a/storage/spider/spd_include.h b/storage/spider/spd_include.h index 17877040358..47373a7fea5 100644 --- a/storage/spider/spd_include.h +++ b/storage/spider/spd_include.h @@ -939,6 +939,10 @@ typedef struct st_spider_transaction uint trx_ha_reuse_count; XID_STATE internal_xid_state; SPIDER_CONN *join_trx_top; + /* + Assigned from the global variable `spider_thread_id', which + starts from 1 and increments + */ ulonglong spider_thread_id; ulonglong trx_conn_adjustment; uint locked_connections; @@ -1079,10 +1083,6 @@ typedef struct st_spider_share MEM_ROOT mem_root; -/* - volatile bool auto_increment_init; - volatile ulonglong auto_increment_lclval; -*/ ha_statistics stat; longlong static_records_for_status; @@ -1570,7 +1570,14 @@ typedef struct st_spider_trx_ha */ uint *conn_link_idx; uchar *conn_can_fo; - /* TODO: document */ + /* + TODO: better documentation of this field. + + By assigning true to wait_for_reusing, in + spider_check_trx_and_get_conn the fields of the spider handler + will be updated using the trx, as well as some other small + behavioural differences there. + */ bool wait_for_reusing; } SPIDER_TRX_HA; diff --git a/storage/spider/spd_trx.cc b/storage/spider/spd_trx.cc index e46b8cc289a..290b1fb1127 100644 --- a/storage/spider/spd_trx.cc +++ b/storage/spider/spd_trx.cc @@ -48,6 +48,10 @@ extern struct charset_info_st *spd_charset_utf8mb3_bin; extern handlerton *spider_hton_ptr; extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE]; pthread_mutex_t spider_thread_id_mutex; +/* + Starts from 1 and increment by 1 whenever a new SPIDER_TRX is + created. +*/ ulonglong spider_thread_id; #ifdef HAVE_PSI_INTERFACE @@ -3188,6 +3192,12 @@ int spider_rollback( conn->db_conn->reset_lock_table_hash(); } + /* + We do (almost) nothing if the following two conditions are both met: + + * This is just the end of a statement, not an explicit rollback. + * The autocommit is OFF or we are in an explicit transaction. + */ if (all || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { if (trx->trx_start) @@ -3403,14 +3413,160 @@ int spider_end_trx( DBUG_RETURN(error_num); } +/* + Report a table error. + + The error_msg requires two format params, db name and table name. +*/ +static int spider_report_table_error(ha_spider *spider, + int error_num, const char *error_msg) +{ + TABLE *table = spider->get_table(); + TABLE_SHARE *table_share = table->s; + char *db = (char *) my_alloca( + table_share->db.length + 1 + table_share->table_name.length + 1); + if (!db) + { + my_error(HA_ERR_OUT_OF_MEM, MYF(0)); + return HA_ERR_OUT_OF_MEM; + } + char *table_name = db + table_share->db.length + 1; + memcpy(db, table_share->db.str, table_share->db.length); + db[table_share->db.length] = '\0'; + memcpy(table_name, table_share->table_name.str, + table_share->table_name.length); + table_name[table_share->table_name.length] = '\0'; + my_printf_error(error_num, error_msg, MYF(0), db, table_name); + my_afree(db); + return error_num; +} + +/* Only called from spider_check_trx_and_get_conn. */ +static int spider_trx_update(THD *thd, ha_spider *spider, SPIDER_TRX *trx) +{ + int search_link_idx, roop_count; + SPIDER_SHARE *share = spider->share; + DBUG_ENTER("spider_trx_update"); + DBUG_PRINT("info", ("spider next trx")); + spider->trx_conn_adjustment = trx->trx_conn_adjustment; + if ( + spider->spider_thread_id != trx->spider_thread_id || + spider->search_link_query_id != thd->query_id + ) { + search_link_idx = spider_conn_first_link_idx(thd, + share->link_statuses, share->access_balances, spider->conn_link_idx, + share->link_count, SPIDER_LINK_STATUS_OK); + if (search_link_idx == -1) + DBUG_RETURN(spider_report_table_error(spider, + ER_SPIDER_ALL_LINKS_FAILED_NUM, + ER_SPIDER_ALL_LINKS_FAILED_STR)); + else if (search_link_idx == -2) + { + my_error(HA_ERR_OUT_OF_MEM, MYF(0)); + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + } + spider->search_link_idx = search_link_idx; + spider->search_link_query_id = thd->query_id; + } + spider->spider_thread_id = trx->spider_thread_id; + + for (roop_count = 0; roop_count < (int) share->link_count; roop_count++) + { + if (!spider->handler_opened(roop_count)) + spider->conns[roop_count] = NULL; + } + DBUG_RETURN(0); +} + +/* + Only called from spider_check_trx_and_get_conn + + TODO: this function comes from a refactoring, and the from_if param + is true iff the call is from the "if" branch, for lack of a better + name. This needs to be further understood and explained or removed + accordingly. +*/ +static int spider_trx_get_conn(ha_spider *spider, SPIDER_TRX *trx, + bool from_if) +{ + int roop_count, error_num; + bool search_link_idx_is_checked = FALSE; + SPIDER_CONN *conn; + SPIDER_SHARE *share = spider->share; + DBUG_ENTER("spider_trx_get_conn"); + for ( + roop_count = spider_conn_link_idx_next(share->link_statuses, + spider->conn_link_idx, -1, share->link_count, + SPIDER_LINK_STATUS_RECOVERY); + roop_count < (int) share->link_count; + roop_count = spider_conn_link_idx_next(share->link_statuses, + spider->conn_link_idx, roop_count, share->link_count, + SPIDER_LINK_STATUS_RECOVERY) + ) { + if (roop_count == spider->search_link_idx) + search_link_idx_is_checked = TRUE; + if ((conn= spider->conns[roop_count])) + { + /* TODO: do we need the check for !from_if here? */ + if (!from_if) + conn->error_mode&= spider->error_mode; + } + else if (!(conn = + spider_get_conn(share, roop_count, + spider->conn_keys[roop_count], trx, + spider, FALSE, TRUE, + &error_num))) + { + if ( + share->monitoring_kind[roop_count] && + spider->need_mons[roop_count] + ) { + error_num = spider_ping_table_mon_from_table( + trx, + trx->thd, + share, + roop_count, + (uint32) share->monitoring_sid[roop_count], + share->table_name, + share->table_name_length, + spider->conn_link_idx[roop_count], + NULL, + 0, + share->monitoring_kind[roop_count], + share->monitoring_limit[roop_count], + share->monitoring_flag[roop_count], + TRUE + ); + } + DBUG_PRINT("info",("spider get conn error")); + /* + Flag for another update (trx->spider_thread_id is at least + 1, causing the next check spider->spider_thread_id != + trx->spider_thread_id to return true). + + TODO: do we need the check for from_if here? + */ + if (from_if) + spider->spider_thread_id = 0; + DBUG_RETURN(error_num); + } + else + conn->error_mode &= spider->error_mode; + } + if (!search_link_idx_is_checked) + DBUG_RETURN(spider_report_table_error(spider, + ER_SPIDER_LINK_MON_JUST_NG_NUM, + ER_SPIDER_LINK_MON_JUST_NG_STR)); + DBUG_RETURN(0); +} + int spider_check_trx_and_get_conn( THD *thd, ha_spider *spider ) { - int error_num, roop_count, search_link_idx; + int error_num; SPIDER_TRX *trx; SPIDER_SHARE *share = spider->share; - SPIDER_CONN *conn; DBUG_ENTER("spider_check_trx_and_get_conn"); if (!(trx = spider_get_trx(thd, TRUE, &error_num))) { @@ -3433,202 +3589,13 @@ int spider_check_trx_and_get_conn( share->link_statuses[spider->conn_link_idx[spider->search_link_idx]] == SPIDER_LINK_STATUS_NG ) { - DBUG_PRINT("info",(trx != spider->wide_handler->trx ? - "spider change thd" : "spider next trx")); - spider->wide_handler->trx = trx; - spider->trx_conn_adjustment = trx->trx_conn_adjustment; - if ( - spider->spider_thread_id != trx->spider_thread_id || - spider->search_link_query_id != thd->query_id - ) { - search_link_idx = spider_conn_first_link_idx(thd, - share->link_statuses, share->access_balances, spider->conn_link_idx, - share->link_count, SPIDER_LINK_STATUS_OK); - if (search_link_idx == -1) - { - TABLE *table = spider->get_table(); - TABLE_SHARE *table_share = table->s; - char *db = (char *) my_alloca( - table_share->db.length + 1 + table_share->table_name.length + 1); - if (!db) - { - my_error(HA_ERR_OUT_OF_MEM, MYF(0)); - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - char *table_name = db + table_share->db.length + 1; - memcpy(db, table_share->db.str, table_share->db.length); - db[table_share->db.length] = '\0'; - memcpy(table_name, table_share->table_name.str, - table_share->table_name.length); - table_name[table_share->table_name.length] = '\0'; - my_printf_error(ER_SPIDER_ALL_LINKS_FAILED_NUM, - ER_SPIDER_ALL_LINKS_FAILED_STR, MYF(0), db, table_name); - my_afree(db); - DBUG_RETURN(ER_SPIDER_ALL_LINKS_FAILED_NUM); - } else if (search_link_idx == -2) - { - my_error(HA_ERR_OUT_OF_MEM, MYF(0)); - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - spider->search_link_idx = search_link_idx; - spider->search_link_query_id = thd->query_id; - } - spider->spider_thread_id = trx->spider_thread_id; - - for (roop_count = 0; roop_count < (int) share->link_count; roop_count++) - { - if (!spider->handler_opened(roop_count)) - spider->conns[roop_count] = NULL; - } - bool search_link_idx_is_checked = FALSE; - for ( - roop_count = spider_conn_link_idx_next(share->link_statuses, - spider->conn_link_idx, -1, share->link_count, - SPIDER_LINK_STATUS_RECOVERY); - roop_count < (int) share->link_count; - roop_count = spider_conn_link_idx_next(share->link_statuses, - spider->conn_link_idx, roop_count, share->link_count, - SPIDER_LINK_STATUS_RECOVERY) - ) { - if (roop_count == spider->search_link_idx) - search_link_idx_is_checked = TRUE; - if ( - !spider->conns[roop_count] - ) { - if ( - !(conn = - spider_get_conn(share, roop_count, - spider->conn_keys[roop_count], trx, - spider, FALSE, TRUE, - &error_num)) - ) { - if ( - share->monitoring_kind[roop_count] && - spider->need_mons[roop_count] - ) { - error_num = spider_ping_table_mon_from_table( - trx, - trx->thd, - share, - roop_count, - (uint32) share->monitoring_sid[roop_count], - share->table_name, - share->table_name_length, - spider->conn_link_idx[roop_count], - NULL, - 0, - share->monitoring_kind[roop_count], - share->monitoring_limit[roop_count], - share->monitoring_flag[roop_count], - TRUE - ); - } - DBUG_PRINT("info",("spider get conn error")); - spider->spider_thread_id = 0; - DBUG_RETURN(error_num); - } - conn->error_mode &= spider->error_mode; - } - } - if (!search_link_idx_is_checked) - { - TABLE *table = spider->get_table(); - TABLE_SHARE *table_share = table->s; - char *db = (char *) my_alloca( - table_share->db.length + 1 + table_share->table_name.length + 1); - if (!db) - { - my_error(HA_ERR_OUT_OF_MEM, MYF(0)); - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - char *table_name = db + table_share->db.length + 1; - memcpy(db, table_share->db.str, table_share->db.length); - db[table_share->db.length] = '\0'; - memcpy(table_name, table_share->table_name.str, - table_share->table_name.length); - table_name[table_share->table_name.length] = '\0'; - my_printf_error(ER_SPIDER_LINK_MON_JUST_NG_NUM, - ER_SPIDER_LINK_MON_JUST_NG_STR, MYF(0), db, table_name); - my_afree(db); - DBUG_RETURN(ER_SPIDER_LINK_MON_JUST_NG_NUM); - } - } else { - DBUG_PRINT("info",("spider link_status = %ld", - share->link_statuses[spider->conn_link_idx[spider->search_link_idx]])); - bool search_link_idx_is_checked = FALSE; - for ( - roop_count = spider_conn_link_idx_next(share->link_statuses, - spider->conn_link_idx, -1, share->link_count, - SPIDER_LINK_STATUS_RECOVERY); - roop_count < (int) share->link_count; - roop_count = spider_conn_link_idx_next(share->link_statuses, - spider->conn_link_idx, roop_count, share->link_count, - SPIDER_LINK_STATUS_RECOVERY) - ) { - if (roop_count == spider->search_link_idx) - search_link_idx_is_checked = TRUE; - conn = spider->conns[roop_count]; - - if (!conn) - { - DBUG_PRINT("info",("spider get conn %d", roop_count)); - if ( - !(conn = - spider_get_conn(share, roop_count, - spider->conn_keys[roop_count], trx, - spider, FALSE, TRUE, - &error_num)) - ) { - if ( - share->monitoring_kind[roop_count] && - spider->need_mons[roop_count] - ) { - error_num = spider_ping_table_mon_from_table( - trx, - trx->thd, - share, - roop_count, - (uint32) share->monitoring_sid[roop_count], - share->table_name, - share->table_name_length, - spider->conn_link_idx[roop_count], - NULL, - 0, - share->monitoring_kind[roop_count], - share->monitoring_limit[roop_count], - share->monitoring_flag[roop_count], - TRUE - ); - } - DBUG_PRINT("info",("spider get conn error")); - DBUG_RETURN(error_num); - } - } - conn->error_mode &= spider->error_mode; - } - if (!search_link_idx_is_checked) - { - TABLE *table = spider->get_table(); - TABLE_SHARE *table_share = table->s; - char *db = (char *) my_alloca( - table_share->db.length + 1 + table_share->table_name.length + 1); - if (!db) - { - my_error(HA_ERR_OUT_OF_MEM, MYF(0)); - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - char *table_name = db + table_share->db.length + 1; - memcpy(db, table_share->db.str, table_share->db.length); - db[table_share->db.length] = '\0'; - memcpy(table_name, table_share->table_name.str, - table_share->table_name.length); - table_name[table_share->table_name.length] = '\0'; - my_printf_error(ER_SPIDER_LINK_MON_JUST_NG_NUM, - ER_SPIDER_LINK_MON_JUST_NG_STR, MYF(0), db, table_name); - my_afree(db); - DBUG_RETURN(ER_SPIDER_LINK_MON_JUST_NG_NUM); - } + if ((error_num= spider_trx_update(thd, spider, trx))) + DBUG_RETURN(error_num); + if ((error_num= spider_trx_get_conn(spider, trx, true))) + DBUG_RETURN(error_num); } + else if ((error_num= spider_trx_get_conn(spider, trx, false))) + DBUG_RETURN(error_num); spider->set_first_link_idx(); DBUG_RETURN(spider_create_trx_ha(trx, spider, trx_ha)); } From 1f306d395d00df158702d35b3338ccfe8663744e Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Mon, 20 Jan 2025 17:50:29 +1100 Subject: [PATCH 122/213] MDEV-34849 Spider: update conn->queue_connect_share when needed Update conn->queue_connect_share in spider_check_trx_and_get_conn to avoid use-after-free. There are two branches in spider_check_trx_and_get_conn, often called at the beginning of a spider DML, depending on whether an update of various spider fields is needed. If it is determined to be needed, the updating may NULL the connections associated with the spider handler, which subsequently causes a call to spider_get_conn() which updates conn->queued_connect_share with the SPIDER_SHARE associated with the spider handler. We make it so that conn->queued_connect_share is updated regardless of the branch it enters, so that it will not be a stale and potentially already freed one. --- .../spider/bugfix/r/mdev_34849.result | 24 +++++++++ .../spider/bugfix/t/mdev_34849.test | 52 +++++++++++++++++++ storage/spider/spd_trx.cc | 2 + 3 files changed, 78 insertions(+) create mode 100644 storage/spider/mysql-test/spider/bugfix/r/mdev_34849.result create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_34849.test diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_34849.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_34849.result new file mode 100644 index 00000000000..9433dd7f679 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_34849.result @@ -0,0 +1,24 @@ +# +# MDEV-34849 SIGSEGV in server_mysql_real_connect, spider_db_connect, __strcmp_evex and __strnlen_evex, ASAN heap-use-after-free in spider_db_connect on INSERT +# +INSTALL SONAME 'ha_spider'; +CREATE TABLE t1 (c INT) ENGINE=Spider; +CREATE TABLE t2 (c INT) ENGINE=Spider; +SELECT * FROM t2; +ERROR HY000: Unable to connect to foreign data source: localhost +set @old_table_open_cache=@@global.table_open_cache; +SET GLOBAL table_open_cache=0; +Warnings: +Warning 1292 Truncated incorrect table_open_cache value: '0' +set autocommit=0; +/* 1 */ INSERT INTO t1 VALUES (0); +ERROR HY000: Unable to connect to foreign data source: localhost +/* 2 */ INSERT INTO t2 VALUES (0); +ERROR HY000: Unable to connect to foreign data source: localhost +set global spider_connect_error_interval=0; +/* 3 */ INSERT INTO t1 VALUES (0); +ERROR HY000: Unable to connect to foreign data source: localhost +drop table t1, t2; +set global table_open_cache=@old_table_open_cache; +Warnings: +Warning 1620 Plugin is busy and will be uninstalled on shutdown diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_34849.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_34849.test new file mode 100644 index 00000000000..4890abf4c7d --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_34849.test @@ -0,0 +1,52 @@ +--echo # +--echo # MDEV-34849 SIGSEGV in server_mysql_real_connect, spider_db_connect, __strcmp_evex and __strnlen_evex, ASAN heap-use-after-free in spider_db_connect on INSERT +--echo # + +INSTALL SONAME 'ha_spider'; + +CREATE TABLE t1 (c INT) ENGINE=Spider; +CREATE TABLE t2 (c INT) ENGINE=Spider; + +# So that t2 is inserted into spider_init_error_tables and in INSERT +# INTO t2 we go into failure mode in spider_get_share() +--error 1429 +SELECT * FROM t2; + +# Resets the table cache so that the next two queries will call +# ha_spider::open() on t1 and t2 respectively +set @old_table_open_cache=@@global.table_open_cache; +SET GLOBAL table_open_cache=0; + +# This causes trx_ha->wait_for_reusing to remain false during the +# (non-)rollback at the end of the first INSERT INTO t1 statement, so +# that the second INSERT INTO t1 enters the branch in +# spider_check_trx_and_get_conn() that does not update spider fields +# including NULLing its associated connections. +set autocommit=0; + +# Misses the table cache when opening the table. Spider then opens the +# table so that the next INSERT INTO t1 causes a table cache hit and +# skips the call to open table with spider +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +/* 1 */ INSERT INTO t1 VALUES (0); + +# Spider opens the table and creates a t2 share, assigns it to +# conn->queued_connect_share, and frees the t2 share on failure +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +/* 2 */ INSERT INTO t2 VALUES (0); + +# So that the final INSERT INTO t1 will decide not to return the same +# error in spider_db_connect(), and move onto using the freed share +set global spider_connect_error_interval=0; + +# Skips call to ha_spider::open(), so it does not create a t1 share +# nor reassign it to conn->queued_connect_share, causing it to remain +# the freed t2 share, and using the share results in segv +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +/* 3 */ INSERT INTO t1 VALUES (0); + +drop table t1, t2; + +set global table_open_cache=@old_table_open_cache; +--disable_query_log +--source ../../include/clean_up_spider.inc diff --git a/storage/spider/spd_trx.cc b/storage/spider/spd_trx.cc index 290b1fb1127..c52c781af8a 100644 --- a/storage/spider/spd_trx.cc +++ b/storage/spider/spd_trx.cc @@ -3510,6 +3510,8 @@ static int spider_trx_get_conn(ha_spider *spider, SPIDER_TRX *trx, /* TODO: do we need the check for !from_if here? */ if (!from_if) conn->error_mode&= spider->error_mode; + if (conn->queued_connect) + conn->queued_connect_share= share; } else if (!(conn = spider_get_conn(share, roop_count, From aef6f35989fb1c7710b93ce1472732cade6fae63 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 22 Jan 2025 10:53:44 +0400 Subject: [PATCH 123/213] MDEV-35549 UBSAN: runtime error: applying zero offset to null pointer on XA RECOVER With UBSAN builds the function my_string_repertoire_8bit() failed on "runtime error: applying zero offset to null pointer" when NULL wad passed as the str parameter. Fix: test str for NULL, and return MY_REPERTOIRE_ASCII if str is NULL. MTR: This problem made MTR tests - main.xa_sync - innodb.xa_debug - main.xa fail with the nullptr-with-offset UNSAN error. After this commit these tests do not fail anymore. This commit does not need any new MTR tests. --- strings/ctype.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/strings/ctype.c b/strings/ctype.c index ccc59a20fe8..eba1827e19a 100644 --- a/strings/ctype.c +++ b/strings/ctype.c @@ -842,6 +842,8 @@ my_string_repertoire_8bit(CHARSET_INFO *cs, const char *str, size_t length) const char *strend; if ((cs->state & MY_CS_NONASCII) && length > 0) return MY_REPERTOIRE_UNICODE30; + if (!str) // Avoid UBSAN nullptr-with-offset + return MY_REPERTOIRE_ASCII; for (strend= str + length; str < strend; str++) { if (((uchar) *str) > 0x7F) From b730abda097c98b5dda982666c8ab6447d80b686 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Fri, 8 Nov 2024 18:41:05 +0400 Subject: [PATCH 124/213] MDEV-33285 - Assertion `m_table' failed in ha_perfschema::rnd_end on CHECKSUM TABLE CHECKSUM TABLE causes variety of crashes when killed. This bug it not specific to PERFORMANCE_SCHEMA. Removed duplicate handler::ha_rnd_end() call. --- mysql-test/main/kill_debug.result | 26 ++++++++++++++++++++++ mysql-test/main/kill_debug.test | 36 +++++++++++++++++++++++++++++++ sql/handler.cc | 5 ++++- sql/sql_table.cc | 3 ++- 4 files changed, 68 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/kill_debug.result b/mysql-test/main/kill_debug.result index 061e7602383..40047ef7eb7 100644 --- a/mysql-test/main/kill_debug.result +++ b/mysql-test/main/kill_debug.result @@ -237,3 +237,29 @@ kill $id; set debug_sync='now SIGNAL go3'; drop table t1; set debug_sync='reset'; +# +# MDEV-33285 - Assertion `m_table' failed in ha_perfschema::rnd_end on +# CHECKSUM TABLE +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES(1); +SET debug_sync='mysql_checksum_table_after_calculate_checksum SIGNAL parked WAIT_FOR go'; +CHECKSUM TABLE t1; +connect con1, localhost, root; +connection con1; +SET debug_sync='now WAIT_FOR parked'; +KILL QUERY id; +SET debug_sync='now SIGNAL go'; +connection default; +ERROR 70100: Query execution was interrupted +SET debug_sync='mysql_checksum_table_before_calculate_checksum SIGNAL parked WAIT_FOR go'; +CHECKSUM TABLE t1; +connection con1; +SET debug_sync='now WAIT_FOR parked'; +KILL QUERY id; +SET debug_sync='now SIGNAL go'; +connection default; +ERROR 70100: Query execution was interrupted +DROP TABLE t1; +disconnect con1; +SET debug_sync='RESET'; diff --git a/mysql-test/main/kill_debug.test b/mysql-test/main/kill_debug.test index 32a764004e3..0285fb48bd2 100644 --- a/mysql-test/main/kill_debug.test +++ b/mysql-test/main/kill_debug.test @@ -316,3 +316,39 @@ evalp kill $id; set debug_sync='now SIGNAL go3'; drop table t1; set debug_sync='reset'; + + +--echo # +--echo # MDEV-33285 - Assertion `m_table' failed in ha_perfschema::rnd_end on +--echo # CHECKSUM TABLE +--echo # +let $id= `select connection_id()`; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES(1); +SET debug_sync='mysql_checksum_table_after_calculate_checksum SIGNAL parked WAIT_FOR go'; +send CHECKSUM TABLE t1; + +connect con1, localhost, root; +connection con1; +SET debug_sync='now WAIT_FOR parked'; +replace_result $id id; +eval KILL QUERY $id; +SET debug_sync='now SIGNAL go'; +connection default; +error ER_QUERY_INTERRUPTED; +reap; + +SET debug_sync='mysql_checksum_table_before_calculate_checksum SIGNAL parked WAIT_FOR go'; +send CHECKSUM TABLE t1; +connection con1; +SET debug_sync='now WAIT_FOR parked'; +replace_result $id id; +eval KILL QUERY $id; +SET debug_sync='now SIGNAL go'; + +connection default; +error ER_QUERY_INTERRUPTED; +reap; +DROP TABLE t1; +disconnect con1; +SET debug_sync='RESET'; diff --git a/sql/handler.cc b/sql/handler.cc index 979e9315571..c3aa1c64906 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -5584,7 +5584,10 @@ int handler::calculate_checksum() for (;;) { if (thd->killed) - return HA_ERR_ABORTED_BY_USER; + { + error= HA_ERR_ABORTED_BY_USER; + break; + } ha_checksum row_crc= 0; error= ha_rnd_next(table->record[0]); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index e906d8a2a62..2162850172b 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -12237,14 +12237,15 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, protocol->store_null(); else { + DEBUG_SYNC(thd, "mysql_checksum_table_before_calculate_checksum"); int error= t->file->calculate_checksum(); + DEBUG_SYNC(thd, "mysql_checksum_table_after_calculate_checksum"); if (thd->killed) { /* we've been killed; let handler clean up, and remove the partial current row from the recordset (embedded lib) */ - t->file->ha_rnd_end(); thd->protocol->remove_last_row(); goto err; } From 82310f926b7c6547f25dd80e4edf3f38b22913e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 22 Jan 2025 17:22:07 +0200 Subject: [PATCH 125/213] MDEV-29182 Assertion fld->field_no < table->n_v_def failed on cascade row_ins_cascade_calc_update_vec(): Skip any virtual columns in the update vector of the parent table. Based on mysql/mysql-server@0ac176453bfef7fb1fdfa70af74618c32910181c Reviewed by: Debarun Banerjee --- mysql-test/suite/innodb/r/foreign_key.result | 17 +++++++++++++++++ mysql-test/suite/innodb/t/foreign_key.test | 15 +++++++++++++++ storage/innobase/row/row0ins.cc | 4 +++- 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result index 6fbea6883bf..7bb5c4ed5d6 100644 --- a/mysql-test/suite/innodb/r/foreign_key.result +++ b/mysql-test/suite/innodb/r/foreign_key.result @@ -1022,4 +1022,21 @@ t2 CREATE TABLE `t2` ( CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci drop tables t2, t1; +# +# MDEV-29182 Assertion fld->field_no < table->n_v_def failed on cascade +# +CREATE TABLE t1(a INT PRIMARY KEY, b VARCHAR(3), c INT AS (LENGTH(b)) VIRTUAL, +INDEX(c)) ENGINE=InnoDB; +CREATE TABLE t2(a INT REFERENCES t1(a) ON UPDATE CASCADE, +b INT GENERATED ALWAYS AS(a) VIRTUAL, INDEX(b)) ENGINE=InnoDB; +INSERT INTO t1 SET a=1,b='fu'; +INSERT INTO t2 SET a=1; +UPDATE t1 SET a=2,b='bar'; +SELECT * FROM t1; +a b c +2 bar 3 +SELECT * FROM t2; +a b +2 2 +DROP TABLE t2,t1; # End of 10.5 tests diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test index 5b72dd4096a..3b97fa0e588 100644 --- a/mysql-test/suite/innodb/t/foreign_key.test +++ b/mysql-test/suite/innodb/t/foreign_key.test @@ -1063,6 +1063,21 @@ alter table t2 add foreign key(a) references t1; show create table t2; drop tables t2, t1; + +--echo # +--echo # MDEV-29182 Assertion fld->field_no < table->n_v_def failed on cascade +--echo # +CREATE TABLE t1(a INT PRIMARY KEY, b VARCHAR(3), c INT AS (LENGTH(b)) VIRTUAL, + INDEX(c)) ENGINE=InnoDB; +CREATE TABLE t2(a INT REFERENCES t1(a) ON UPDATE CASCADE, + b INT GENERATED ALWAYS AS(a) VIRTUAL, INDEX(b)) ENGINE=InnoDB; +INSERT INTO t1 SET a=1,b='fu'; +INSERT INTO t2 SET a=1; +UPDATE t1 SET a=2,b='bar'; +SELECT * FROM t1; +SELECT * FROM t2; +DROP TABLE t2,t1; + --echo # End of 10.5 tests --source include/wait_until_count_sessions.inc diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index ca43e9045e1..59a2ebd6830 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -479,7 +479,9 @@ row_ins_cascade_calc_update_vec( const upd_field_t* parent_ufield = &parent_update->fields[j]; - if (parent_ufield->field_no == parent_field_no) { + if (parent_ufield->field_no == parent_field_no + && !(parent_ufield->new_val.type.prtype + & DATA_VIRTUAL)) { ulint min_size; const dict_col_t* col; From b214ca72191eb9194a8131e3ff1c92cfb6ece81f Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Thu, 23 Jan 2025 11:29:52 +0100 Subject: [PATCH 126/213] MDEV-35090 (Item_func_current_user) Assertion `typeid(*copy) == typeid(*this)' failed in Item_func_or_sum::do_build_clone Added missing do_get_copy of Item_func_current_user. --- mysql-test/main/view.result | 11 +++++++++++ mysql-test/main/view.test | 13 +++++++++++++ sql/item_strfunc.h | 2 ++ 3 files changed, 26 insertions(+) diff --git a/mysql-test/main/view.result b/mysql-test/main/view.result index 3d3efd041c3..1686a6c0026 100644 --- a/mysql-test/main/view.result +++ b/mysql-test/main/view.result @@ -6990,4 +6990,15 @@ View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 AS `1` from `t1` union (select 1 AS `1` from DUAL where 1 group by 1 having 1 for update) latin1 latin1_swedish_ci DROP VIEW v1; DROP TABLE t1; +# +# MDEV-35090: (Item_func_current_user) Assertion +# `typeid(*copy) == typeid(*this)' failed in +# Item_func_or_sum::do_build_clone +# +CREATE VIEW v AS SELECT 1; +SELECT * FROM v WHERE UpdateXML('N/A','/a',CURRENT_USER()); +1 +Warnings: +Warning 1292 Truncated incorrect INTEGER value: 'N/A' +DROP VIEW v; # End of 10.5 tests diff --git a/mysql-test/main/view.test b/mysql-test/main/view.test index 20aaba8e52a..3c6117c0e36 100644 --- a/mysql-test/main/view.test +++ b/mysql-test/main/view.test @@ -6755,4 +6755,17 @@ SHOW CREATE VIEW v1; DROP VIEW v1; DROP TABLE t1; +--echo # +--echo # MDEV-35090: (Item_func_current_user) Assertion +--echo # `typeid(*copy) == typeid(*this)' failed in +--echo # Item_func_or_sum::do_build_clone +--echo # + +CREATE VIEW v AS SELECT 1; + +SELECT * FROM v WHERE UpdateXML('N/A','/a',CURRENT_USER()); + +# Cleanup +DROP VIEW v; + --echo # End of 10.5 tests diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index e40eed1adf2..24c19b2914a 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -1029,6 +1029,8 @@ public: return mark_unsupported_function(fully_qualified_func_name(), arg, VCOL_SESSION_FUNC); } + Item *do_get_copy(THD *thd) const override + { return get_item_copy(thd, this); } }; From 136e866119779668736a4d52ae3301e1f6e3eff2 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Thu, 23 Jan 2025 00:03:04 +0100 Subject: [PATCH 127/213] Update WolfSSL to the latest release 5.7.6 Workaround build bugs with preprocessor flags du-jour 1. OPENSSL_ALL does not work anymore (error in ssl.h) nor WOLFSSL_MYSQL_COMPATIBLE, would work, when building library. 2. OPENSSL_EXTRA has to be used instead of OPENSSL_ALL now. WOLFSSL_MYSQL_COMPATIBLE needs to be used to workaround their conflicting definition of protocol_version, which is used in server code. 3. -D_CRT_USE_CONFORMING_ANNEX_K_TIME to force C11-correct definition of gmtime_s on Windows, set some other flags WOLFSSL_MYSQL_COMPATIBLE was previously defining 4. Use HAVE_EMPTY_AGGREGATES=0 to workaround build error on clang (error: struct has size 0 in C, size 1 in C++ [-Werror,-Wextern-c-compat] WOLF_AGG_DUMMY_MEMBER;) --- extra/wolfssl/CMakeLists.txt | 2 ++ extra/wolfssl/user_settings.h.in | 17 ++++++++++++++++- extra/wolfssl/wolfssl | 2 +- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/extra/wolfssl/CMakeLists.txt b/extra/wolfssl/CMakeLists.txt index e3f8da21f76..85fb06bd128 100644 --- a/extra/wolfssl/CMakeLists.txt +++ b/extra/wolfssl/CMakeLists.txt @@ -130,6 +130,8 @@ if(MSVC) if(CMAKE_C_COMPILER_ID MATCHES Clang) target_compile_options(wolfssl PRIVATE $<$:-Wno-incompatible-function-pointer-types>) endif() + target_compile_definitions(wolfssl PRIVATE + _CRT_USE_CONFORMING_ANNEX_K_TIME HAVE_GMTIME_S WOLFSSL_HAVE_MIN WOLFSSL_HAVE_MAX) endif() CONFIGURE_FILE(user_settings.h.in user_settings.h) diff --git a/extra/wolfssl/user_settings.h.in b/extra/wolfssl/user_settings.h.in index 489118b33b4..92e92d04e4a 100644 --- a/extra/wolfssl/user_settings.h.in +++ b/extra/wolfssl/user_settings.h.in @@ -3,7 +3,21 @@ #define HAVE_CRL #define WOLFSSL_HAVE_ERROR_QUEUE + +/* + Workaround bug in 5.7.6 + WOLFSSL_MYSQL_COMPATIBLE breaks building wolfssl + + But it is needed to avoid redefinition of protocol_version + when its public header ssl.h is included +*/ +#ifndef BUILDING_WOLFSSL #define WOLFSSL_MYSQL_COMPATIBLE +#endif + +#define SP_INT_BITS 8192 +#define HAVE_EMPTY_AGGREGATES 0 + #define HAVE_ECC #define ECC_TIMING_RESISTANT #define HAVE_HASHDRBG @@ -24,7 +38,8 @@ #define HAVE_THREAD_LS #define WOLFSSL_AES_COUNTER #define NO_WOLFSSL_STUB -#define OPENSSL_ALL +// #define OPENSSL_ALL +#define OPENSSL_EXTRA #define WOLFSSL_ALLOW_TLSV10 #define NO_OLD_TIMEVAL_NAME #define HAVE_SECURE_RENEGOTIATION diff --git a/extra/wolfssl/wolfssl b/extra/wolfssl/wolfssl index 00e42151ca0..239b85c8043 160000 --- a/extra/wolfssl/wolfssl +++ b/extra/wolfssl/wolfssl @@ -1 +1 @@ -Subproject commit 00e42151ca061463ba6a95adb2290f678cbca472 +Subproject commit 239b85c80438bf60d9a5b9e0ebe9ff097a760d0d From d4da659b432f47fcbc86ff446f72ce42fc535dfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 23 Jan 2025 14:38:08 +0200 Subject: [PATCH 128/213] MDEV-35854: Simplify dict_get_referenced_table() innodb_convert_name(): Convert a schema or table name to my_charset_filename compatible format. dict_table_lookup(): Replaces dict_get_referenced_table(). Make the callers responsible for invoking innodb_convert_name(). innobase_casedn_str(): Remove. Let us invoke my_casedn_str() directly. dict_table_rename_in_cache(): Do not duplicate a call to dict_mem_foreign_table_name_lookup_set(). innobase_convert_to_filename_charset(): Defined static in the only compilation unit that needs it. dict_scan_id(): Remove the constant parameters table_id=FALSE, accept_also_dot=TRUE. Invoke strconvert() directly. innobase_convert_from_id(): Remove; only called from dict_scan_id(). innobase_convert_from_table_id(): Remove (dead code). table_name_t::dblen(), table_name_t::basename(): In non-debug builds, tolerate names that may miss a '/' separator. Reviewed by: Debarun Banerjee --- mysql-test/suite/innodb/r/foreign_key.result | 24 ++ mysql-test/suite/innodb/t/foreign_key.test | 17 ++ storage/innobase/dict/dict0dict.cc | 163 +++---------- storage/innobase/dict/dict0mem.cc | 8 +- storage/innobase/handler/ha_innodb.cc | 243 ++++++++++--------- storage/innobase/handler/handler0alter.cc | 17 +- storage/innobase/include/dict0dict.h | 16 -- storage/innobase/include/dict0mem.h | 2 +- storage/innobase/include/dict0types.h | 14 +- storage/innobase/include/ha_prototypes.h | 63 ++--- storage/innobase/row/row0mysql.cc | 2 +- 11 files changed, 245 insertions(+), 324 deletions(-) diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result index 80a0afb8d06..0404ab81c61 100644 --- a/mysql-test/suite/innodb/r/foreign_key.result +++ b/mysql-test/suite/innodb/r/foreign_key.result @@ -1118,5 +1118,29 @@ test.binaries check status OK test.collections check status OK disconnect con1; DROP TABLE binaries, collections; +CREATE SCHEMA `#mysql50##mysql50#d-b`; +CREATE TABLE `#mysql50##mysql50#d-b`.t1 (a INT PRIMARY KEY, b INT UNIQUE) engine=InnoDB; +USE `#mysql50##mysql50#d-b`; +CREATE TABLE t2 (a INT PRIMARY KEY, b INT UNIQUE REFERENCES t1(b)) ENGINE=InnoDB; +SET STATEMENT foreign_key_checks=0 FOR +ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1(a); +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(11) NOT NULL, + `b` int(11) DEFAULT NULL, + PRIMARY KEY (`a`), + UNIQUE KEY `b` (`b`), + CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t1` (`b`), + CONSTRAINT `t2_ibfk_2` FOREIGN KEY (`a`) REFERENCES `t1` (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t1 SET a=1; +INSERT INTO t2 SET a=1; +DELETE FROM t1; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`#mysql50#d-b`.`t2`, CONSTRAINT `t2_ibfk_2` FOREIGN KEY (`a`) REFERENCES `t1` (`a`)) +DELETE FROM t2; +DELETE FROM t1; +DROP DATABASE `#mysql50##mysql50#d-b`; +USE test; # End of 10.6 tests SET GLOBAL innodb_stats_persistent = @save_stats_persistent; diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test index 506cca3245c..e31320ee810 100644 --- a/mysql-test/suite/innodb/t/foreign_key.test +++ b/mysql-test/suite/innodb/t/foreign_key.test @@ -4,6 +4,7 @@ --disable_query_log call mtr.add_suppression("InnoDB: Transaction was aborted due to "); +call mtr.add_suppression("Invalid \\(old\\?\\) table or database name '#mysql50#d-b'"); --enable_query_log SET GLOBAL innodb_stats_persistent = 0; @@ -1188,6 +1189,22 @@ CHECK TABLE binaries, collections EXTENDED; # Cleanup DROP TABLE binaries, collections; +CREATE SCHEMA `#mysql50##mysql50#d-b`; +CREATE TABLE `#mysql50##mysql50#d-b`.t1 (a INT PRIMARY KEY, b INT UNIQUE) engine=InnoDB; +USE `#mysql50##mysql50#d-b`; +CREATE TABLE t2 (a INT PRIMARY KEY, b INT UNIQUE REFERENCES t1(b)) ENGINE=InnoDB; +SET STATEMENT foreign_key_checks=0 FOR +ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1(a); +SHOW CREATE TABLE t2; +INSERT INTO t1 SET a=1; +INSERT INTO t2 SET a=1; +--error ER_ROW_IS_REFERENCED_2 +DELETE FROM t1; +DELETE FROM t2; +DELETE FROM t1; +DROP DATABASE `#mysql50##mysql50#d-b`; +USE test; + --echo # End of 10.6 tests SET GLOBAL innodb_stats_persistent = @save_stats_persistent; diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index d97e26f7fca..dd0b4c714bf 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -1467,6 +1467,26 @@ dict_table_t::rename_tablespace(span new_name, bool replace) const return err; } +/********************************************************************** +Converts an identifier from my_charset_filename to UTF-8 charset. +@return result string length, as returned by strconvert() */ +static +uint +innobase_convert_to_filename_charset( +/*=================================*/ + char* to, /* out: converted identifier */ + const char* from, /* in: identifier to convert */ + ulint len) /* in: length of 'to', in bytes */ +{ + uint errors; + CHARSET_INFO* cs_to = &my_charset_filename; + CHARSET_INFO* cs_from = system_charset_info; + + return(static_cast(strconvert( + cs_from, from, uint(strlen(from)), + cs_to, to, static_cast(len), &errors))); +} + /**********************************************************************//** Renames a table object. @return TRUE if success */ @@ -1599,19 +1619,20 @@ dict_table_rename_in_cache( foreign->referenced_table->referenced_set.erase(foreign); } - if (strlen(foreign->foreign_table_name) - < strlen(table->name.m_name)) { + const bool do_alloc = strlen(foreign->foreign_table_name) + < strlen(table->name.m_name); + + if (do_alloc) { /* Allocate a longer name buffer; TODO: store buf len to save memory */ foreign->foreign_table_name = mem_heap_strdup( foreign->heap, table->name.m_name); - dict_mem_foreign_table_name_lookup_set(foreign, TRUE); } else { strcpy(foreign->foreign_table_name, table->name.m_name); - dict_mem_foreign_table_name_lookup_set(foreign, FALSE); } + dict_mem_foreign_table_name_lookup_set(foreign, do_alloc); if (strchr(foreign->id, '/')) { /* This is a >= 4.0.18 format id */ @@ -3105,20 +3126,13 @@ dict_scan_id( mem_heap_t* heap, /*!< in: heap where to allocate the id (NULL=id will not be allocated, but it will point to string near ptr) */ - const char** id, /*!< out,own: the id; NULL if no id was + const char** id) /*!< out,own: the id; NULL if no id was scannable */ - ibool table_id,/*!< in: TRUE=convert the allocated id - as a table name; FALSE=convert to UTF-8 */ - ibool accept_also_dot) - /*!< in: TRUE if also a dot can appear in a - non-quoted id; in a quoted id it can appear - always */ { char quote = '\0'; ulint len = 0; const char* s; char* str; - char* dst; *id = NULL; @@ -3154,7 +3168,6 @@ dict_scan_id( } } else { while (!my_isspace(cs, *ptr) && *ptr != '(' && *ptr != ')' - && (accept_also_dot || *ptr != '.') && *ptr != ',' && *ptr != '\0') { ptr++; @@ -3188,125 +3201,15 @@ dict_scan_id( str = mem_heap_strdupl(heap, s, len); } - if (!table_id) { -convert_id: - /* Convert the identifier from connection character set - to UTF-8. */ - len = 3 * len + 1; - *id = dst = static_cast(mem_heap_alloc(heap, len)); - - innobase_convert_from_id(cs, dst, str, len); - } else if (!strncmp(str, srv_mysql50_table_name_prefix, - sizeof(srv_mysql50_table_name_prefix) - 1)) { - /* This is a pre-5.1 table name - containing chars other than [A-Za-z0-9]. - Discard the prefix and use raw UTF-8 encoding. */ - str += sizeof(srv_mysql50_table_name_prefix) - 1; - len -= sizeof(srv_mysql50_table_name_prefix) - 1; - goto convert_id; - } else { - /* Encode using filename-safe characters. */ - len = 5 * len + 1; - *id = dst = static_cast(mem_heap_alloc(heap, len)); - - innobase_convert_from_table_id(cs, dst, str, len); - } - + ulint dstlen = 3 * len + 1; + char *dst = static_cast(mem_heap_alloc(heap, dstlen)); + *id = dst; + uint errors; + strconvert(cs, str, uint(len), system_charset_info, dst, + uint(dstlen), &errors); return(ptr); } -/*********************************************************************//** -Open a table from its database and table name, this is currently used by -foreign constraint parser to get the referenced table. -@return complete table name with database and table name, allocated from -heap memory passed in */ -char* -dict_get_referenced_table( - const char* name, /*!< in: foreign key table name */ - const char* database_name, /*!< in: table db name */ - ulint database_name_len, /*!< in: db name length */ - const char* table_name, /*!< in: table name */ - ulint table_name_len, /*!< in: table name length */ - dict_table_t** table, /*!< out: table object or NULL */ - mem_heap_t* heap, /*!< in/out: heap memory */ - CHARSET_INFO* from_cs) /*!< in: table name charset */ -{ - char* ref; - char db_name[MAX_DATABASE_NAME_LEN]; - char tbl_name[MAX_TABLE_NAME_LEN]; - CHARSET_INFO* to_cs = &my_charset_filename; - uint errors; - ut_ad(database_name || name); - ut_ad(table_name); - - if (!strncmp(table_name, srv_mysql50_table_name_prefix, - sizeof(srv_mysql50_table_name_prefix) - 1)) { - /* This is a pre-5.1 table name - containing chars other than [A-Za-z0-9]. - Discard the prefix and use raw UTF-8 encoding. */ - table_name += sizeof(srv_mysql50_table_name_prefix) - 1; - table_name_len -= sizeof(srv_mysql50_table_name_prefix) - 1; - - to_cs = system_charset_info; - } - - table_name_len = strconvert(from_cs, table_name, table_name_len, to_cs, - tbl_name, MAX_TABLE_NAME_LEN, &errors); - table_name = tbl_name; - - if (database_name) { - to_cs = &my_charset_filename; - if (!strncmp(database_name, srv_mysql50_table_name_prefix, - sizeof(srv_mysql50_table_name_prefix) - 1)) { - database_name - += sizeof(srv_mysql50_table_name_prefix) - 1; - database_name_len - -= sizeof(srv_mysql50_table_name_prefix) - 1; - to_cs = system_charset_info; - } - - database_name_len = strconvert( - from_cs, database_name, database_name_len, to_cs, - db_name, MAX_DATABASE_NAME_LEN, &errors); - database_name = db_name; - } else { - /* Use the database name of the foreign key table */ - - database_name = name; - database_name_len = dict_get_db_name_len(name); - } - - /* Copy database_name, '/', table_name, '\0' */ - const size_t len = database_name_len + table_name_len + 1; - ref = static_cast(mem_heap_alloc(heap, len + 1)); - memcpy(ref, database_name, database_name_len); - ref[database_name_len] = '/'; - memcpy(ref + database_name_len + 1, table_name, table_name_len + 1); - - /* Values; 0 = Store and compare as given; case sensitive - 1 = Store and compare in lower; case insensitive - 2 = Store as given, compare in lower; case semi-sensitive */ - if (lower_case_table_names == 2) { - innobase_casedn_str(ref); - *table = dict_sys.load_table({ref, len}); - memcpy(ref, database_name, database_name_len); - ref[database_name_len] = '/'; - memcpy(ref + database_name_len + 1, table_name, table_name_len + 1); - - } else { -#ifndef _WIN32 - if (lower_case_table_names == 1) { - innobase_casedn_str(ref); - } -#else - innobase_casedn_str(ref); -#endif /* !_WIN32 */ - *table = dict_sys.load_table({ref, len}); - } - - return(ref); -} - /*********************************************************************//** Removes MySQL comments from an SQL string. A comment is either (a) '#' to the end of the line, @@ -3563,7 +3466,7 @@ loop: } } - ptr = dict_scan_id(cs, ptr, heap, &id, FALSE, TRUE); + ptr = dict_scan_id(cs, ptr, heap, &id); if (id == NULL) { diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc index 9de43abbb17..5aeb5d51728 100644 --- a/storage/innobase/dict/dict0mem.cc +++ b/storage/innobase/dict/dict0mem.cc @@ -816,7 +816,7 @@ void dict_mem_foreign_table_name_lookup_set( /*===================================*/ dict_foreign_t* foreign, /*!< in/out: foreign struct */ - ibool do_alloc) /*!< in: is an alloc needed */ + bool do_alloc) /*!< in: is an alloc needed */ { if (lower_case_table_names == 2) { if (do_alloc) { @@ -830,7 +830,8 @@ dict_mem_foreign_table_name_lookup_set( } strcpy(foreign->foreign_table_name_lookup, foreign->foreign_table_name); - innobase_casedn_str(foreign->foreign_table_name_lookup); + my_casedn_str(system_charset_info, + foreign->foreign_table_name_lookup); } else { foreign->foreign_table_name_lookup = foreign->foreign_table_name; @@ -860,7 +861,8 @@ dict_mem_referenced_table_name_lookup_set( } strcpy(foreign->referenced_table_name_lookup, foreign->referenced_table_name); - innobase_casedn_str(foreign->referenced_table_name_lookup); + my_casedn_str(system_charset_info, + foreign->referenced_table_name_lookup); } else { foreign->referenced_table_name_lookup = foreign->referenced_table_name; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 31c4f525adf..3229cb67241 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1320,9 +1320,7 @@ static void innodb_drop_database(handlerton*, char *path) namebuf[len] = '/'; namebuf[len + 1] = '\0'; -#ifdef _WIN32 - innobase_casedn_str(namebuf); -#endif /* _WIN32 */ + IF_WIN(my_casedn_str(system_charset_info, namebuf),); THD * const thd= current_thd; trx_t *trx= innobase_trx_allocate(thd); @@ -2435,21 +2433,6 @@ dtype_get_mblen( } } -/******************************************************************//** -Converts an identifier to a table name. */ -void -innobase_convert_from_table_id( -/*===========================*/ - CHARSET_INFO* cs, /*!< in: the 'from' character set */ - char* to, /*!< out: converted identifier */ - const char* from, /*!< in: identifier to convert */ - ulint len) /*!< in: length of 'to', in bytes */ -{ - uint errors; - - strconvert(cs, from, FN_REFLEN, &my_charset_filename, to, (uint) len, &errors); -} - /********************************************************************** Check if the length of the identifier exceeds the maximum allowed. return true when length of identifier is too long. */ @@ -2474,21 +2457,6 @@ innobase_check_identifier_length( DBUG_RETURN(false); } -/******************************************************************//** -Converts an identifier to UTF-8. */ -void -innobase_convert_from_id( -/*=====================*/ - CHARSET_INFO* cs, /*!< in: the 'from' character set */ - char* to, /*!< out: converted identifier */ - const char* from, /*!< in: identifier to convert */ - ulint len) /*!< in: length of 'to', in bytes */ -{ - uint errors; - - strconvert(cs, from, FN_REFLEN, system_charset_info, to, (uint) len, &errors); -} - /******************************************************************//** Compares NUL-terminated UTF-8 strings case insensitively. @return 0 if a=b, <0 if a1 if a>b */ @@ -2537,16 +2505,6 @@ innobase_basename( return((name) ? name : "null"); } -/******************************************************************//** -Makes all characters in a NUL-terminated UTF-8 string lower case. */ -void -innobase_casedn_str( -/*================*/ - char* a) /*!< in/out: string to put in lower case */ -{ - my_casedn_str(system_charset_info, a); -} - /** Determines the current SQL statement. Thread unsafe, can only be called from the thread owning the THD. @param[in] thd MySQL thread handle @@ -3683,13 +3641,13 @@ innobase_format_name( ulint buflen, /*!< in: length of buf, in bytes */ const char* name) /*!< in: table name to format */ { - const char* bufend; + char* bufend; bufend = innobase_convert_name(buf, buflen, name, strlen(name), NULL); ut_ad((ulint) (bufend - buf) < buflen); - buf[bufend - buf] = '\0'; + *bufend = '\0'; } /**********************************************************************//** @@ -5386,7 +5344,7 @@ normalize_table_name_c_low( memcpy(norm_name + db_len + 1, name_ptr, name_len + 1); if (set_lower_case) { - innobase_casedn_str(norm_name); + my_casedn_str(system_charset_info, norm_name); } } @@ -6261,7 +6219,7 @@ ha_innobase::open_dict_table( case name, including the partition separator "P" */ strcpy(par_case_name, norm_name); - innobase_casedn_str(par_case_name); + my_casedn_str(system_charset_info, par_case_name); #else /* On Windows platfrom, check whether there exists table name in @@ -12389,6 +12347,73 @@ public: const char* str() { return buf; } }; +/** Construct an InnoDB table name from a schema and table name. +@param table_name buffer InnoDB table name being constructed +@param db schema name +@param name table name +@return table_name filled in */ +static char *copy_name(char *table_name, LEX_CSTRING db, LEX_CSTRING name) + noexcept +{ + memcpy(table_name, db.str, db.length); + table_name[db.length] = '/'; + memcpy(table_name + db.length + 1, name.str, name.length + 1); + return table_name; +} + +char *dict_table_lookup(LEX_CSTRING db, LEX_CSTRING name, + dict_table_t **table, mem_heap_t *heap) noexcept +{ + const size_t len= db.length + name.length + 1; + char *ref= static_cast(mem_heap_alloc(heap, len + 1)); + copy_name(ref, db, name); + + switch (lower_case_table_names) { + case 2: /* store as given, compare in lower case */ + my_casedn_str(system_charset_info, ref); + *table= dict_sys.load_table({ref, len}); + return copy_name(ref, db, name); + case 0: /* store and compare as given; case sensitive */ +#ifndef _WIN32 /* On Windows, InnoDB treats 0 as lower_case_table_names=1 */ + break; +#endif + case 1: /* store and compare in lower case */ + my_casedn_str(system_charset_info, ref); + } + + *table = dict_sys.load_table({ref, len}); + return ref; +} + +/** Convert a schema or table name to InnoDB (and file system) format. +@param cs source character set +@param name name encoded in cs +@param buf output buffer (MAX_TABLE_NAME_LEN + 1 bytes) +@return the converted string (within buf) */ +LEX_CSTRING innodb_convert_name(CHARSET_INFO *cs, LEX_CSTRING name, char *buf) + noexcept +{ + CHARSET_INFO *to_cs= &my_charset_filename; + if (!strncmp(name.str, srv_mysql50_table_name_prefix, + sizeof srv_mysql50_table_name_prefix - 1)) + { + /* Before MySQL 5.1 introduced my_charset_filename, schema and + table names were stored in the file system as specified by the + user, hopefully in ASCII encoding, but it could also be in ISO + 8859-1 or UTF-8. Such schema or table names are distinguished by + the #mysql50# prefix. + + Let us discard that prefix and convert the name to UTF-8 + (system_charset_info). */ + name.str+= sizeof srv_mysql50_table_name_prefix - 1; + name.length-= sizeof srv_mysql50_table_name_prefix - 1; + to_cs= system_charset_info; + } + uint errors; + return LEX_CSTRING{buf, strconvert(cs, name.str, name.length, to_cs, + buf, MAX_TABLE_NAME_LEN, &errors)}; +} + /** Create InnoDB foreign keys from MySQL alter_info. Collect all dict_foreign_t items into local_fk_set and then add into system table. @return DB_SUCCESS or specific error code */ @@ -12404,6 +12429,9 @@ create_table_info_t::create_foreign_keys() const char* ref_column_names[MAX_COLS_PER_FK]; char create_name[MAX_DATABASE_NAME_LEN + 1 + MAX_TABLE_NAME_LEN + 1]; + char db_name[MAX_DATABASE_NAME_LEN + 1]; + char t_name[MAX_TABLE_NAME_LEN + 1]; + static_assert(MAX_TABLE_NAME_LEN == MAX_DATABASE_NAME_LEN, ""); dict_index_t* index = NULL; fkerr_t index_error = FK_SUCCESS; dict_index_t* err_index = NULL; @@ -12411,59 +12439,57 @@ create_table_info_t::create_foreign_keys() const bool tmp_table = m_flags2 & DICT_TF2_TEMPORARY; const CHARSET_INFO* cs = thd_charset(m_thd); const char* operation = "Create "; - const char* name = m_table_name; enum_sql_command sqlcom = enum_sql_command(thd_sql_command(m_thd)); + LEX_CSTRING name= {m_table_name, strlen(m_table_name)}; if (sqlcom == SQLCOM_ALTER_TABLE) { - dict_table_t* table_to_alter; mem_heap_t* heap = mem_heap_create(10000); - ulint highest_id_so_far; - char* n = dict_get_referenced_table( - name, LEX_STRING_WITH_LEN(m_form->s->db), - LEX_STRING_WITH_LEN(m_form->s->table_name), - &table_to_alter, heap, cs); + LEX_CSTRING t{innodb_convert_name(cs, m_form->s->table_name, + t_name)}; + LEX_CSTRING d{innodb_convert_name(cs, m_form->s->db, db_name)}; + dict_table_t* alter_table; + char* n = dict_table_lookup(d, t, &alter_table, heap); /* Starting from 4.0.18 and 4.1.2, we generate foreign key id's in the format databasename/tablename_ibfk_[number], where [number] is local to the table; look for the highest [number] - for table_to_alter, so that we can assign to new constraints + for alter_table, so that we can assign to new constraints higher numbers. */ /* If we are altering a temporary table, the table name after ALTER TABLE does not correspond to the internal table name, and - table_to_alter is NULL. TODO: should we fix this somehow? */ + alter_table=nullptr. But, we do not support FOREIGN KEY + constraints for temporary tables. */ - if (table_to_alter) { - n = table_to_alter->name.m_name; - highest_id_so_far = dict_table_get_highest_foreign_id( - table_to_alter); - } else { - highest_id_so_far = 0; + if (alter_table) { + n = alter_table->name.m_name; + number = 1 + dict_table_get_highest_foreign_id( + alter_table); } char* bufend = innobase_convert_name( create_name, sizeof create_name, n, strlen(n), m_thd); - create_name[bufend - create_name] = '\0'; - number = highest_id_so_far + 1; + *bufend = '\0'; mem_heap_free(heap); operation = "Alter "; - } else if (strstr(name, "#P#") || strstr(name, "#p#")) { + } else if (strstr(m_table_name, "#P#") + || strstr(m_table_name, "#p#")) { /* Partitioned table */ create_name[0] = '\0'; } else { char* bufend = innobase_convert_name(create_name, sizeof create_name, - name, - strlen(name), m_thd); - create_name[bufend - create_name] = '\0'; + LEX_STRING_WITH_LEN(name), + m_thd); + *bufend = '\0'; } Alter_info* alter_info = m_create_info->alter_info; ut_ad(alter_info); List_iterator_fast key_it(alter_info->key_list); - dict_table_t* table = dict_sys.find_table({name,strlen(name)}); + dict_table_t* table = dict_sys.find_table({name.str, name.length}); if (!table) { ib_foreign_warn(m_trx, DB_CANNOT_ADD_CONSTRAINT, create_name, "%s table %s foreign key constraint" @@ -12510,27 +12536,27 @@ create_table_info_t::create_foreign_keys() col->field_name.length); success = find_col(table, column_names + i); if (!success) { - key_text k(fk); ib_foreign_warn( m_trx, DB_CANNOT_ADD_CONSTRAINT, create_name, "%s table %s foreign key %s constraint" " failed. Column %s was not found.", - operation, create_name, k.str(), + operation, create_name, + key_text(fk).str(), column_names[i]); dict_foreign_free(foreign); return (DB_CANNOT_ADD_CONSTRAINT); } ++i; if (i >= MAX_COLS_PER_FK) { - key_text k(fk); ib_foreign_warn( m_trx, DB_CANNOT_ADD_CONSTRAINT, create_name, "%s table %s foreign key %s constraint" " failed. Too many columns: %u (%u " "allowed).", - operation, create_name, k.str(), i, + operation, create_name, + key_text(fk).str(), i, MAX_COLS_PER_FK); dict_foreign_free(foreign); return (DB_CANNOT_ADD_CONSTRAINT); @@ -12542,9 +12568,9 @@ create_table_info_t::create_foreign_keys() &index_error, &err_col, &err_index); if (!index) { - key_text k(fk); foreign_push_index_error(m_trx, operation, create_name, - k.str(), column_names, + key_text(fk).str(), + column_names, index_error, err_col, err_index, table); dict_foreign_free(foreign); @@ -12610,14 +12636,12 @@ create_table_info_t::create_foreign_keys() memcpy(foreign->foreign_col_names, column_names, i * sizeof(void*)); - foreign->referenced_table_name = dict_get_referenced_table( - name, LEX_STRING_WITH_LEN(fk->ref_db), - LEX_STRING_WITH_LEN(fk->ref_table), - &foreign->referenced_table, foreign->heap, cs); - - if (!foreign->referenced_table_name) { - return (DB_OUT_OF_MEMORY); - } + LEX_CSTRING t{innodb_convert_name(cs, fk->ref_table, t_name)}; + LEX_CSTRING d = fk->ref_db.str + ? innodb_convert_name(cs, fk->ref_db, db_name) + : LEX_CSTRING{table->name.m_name, table->name.dblen()}; + foreign->referenced_table_name = dict_table_lookup( + d, t, &foreign->referenced_table, foreign->heap); if (!foreign->referenced_table && m_trx->check_foreigns) { char buf[MAX_TABLE_NAME_LEN + 1] = ""; @@ -12627,15 +12651,15 @@ create_table_info_t::create_foreign_keys() buf, MAX_TABLE_NAME_LEN, foreign->referenced_table_name, strlen(foreign->referenced_table_name), m_thd); - buf[bufend - buf] = '\0'; - key_text k(fk); + *bufend = '\0'; ib_foreign_warn(m_trx, DB_CANNOT_ADD_CONSTRAINT, create_name, "%s table %s with foreign key %s " "constraint failed. Referenced table " "%s not found in the data dictionary.", - operation, create_name, k.str(), buf); - return (DB_CANNOT_ADD_CONSTRAINT); + operation, create_name, + key_text(fk).str(), buf); + return DB_CANNOT_ADD_CONSTRAINT; } /* Don't allow foreign keys on partitioned tables yet. */ @@ -12658,7 +12682,6 @@ create_table_info_t::create_foreign_keys() success = find_col(foreign->referenced_table, ref_column_names + j); if (!success) { - key_text k(fk); ib_foreign_warn( m_trx, DB_CANNOT_ADD_CONSTRAINT, @@ -12667,9 +12690,9 @@ create_table_info_t::create_foreign_keys() "constraint failed. " "Column %s was not found.", operation, create_name, - k.str(), ref_column_names[j]); - - return (DB_CANNOT_ADD_CONSTRAINT); + key_text(fk).str(), + ref_column_names[j]); + return DB_CANNOT_ADD_CONSTRAINT; } } ++j; @@ -12689,16 +12712,15 @@ create_table_info_t::create_foreign_keys() &err_index); if (!index) { - key_text k(fk); foreign_push_index_error( - m_trx, operation, create_name, k.str(), + m_trx, operation, create_name, + key_text(fk).str(), column_names, index_error, err_col, err_index, foreign->referenced_table); - - return (DB_CANNOT_ADD_CONSTRAINT); + return DB_CANNOT_ADD_CONSTRAINT; } } else { - ut_a(m_trx->check_foreigns == FALSE); + ut_a(!m_trx->check_foreigns); index = NULL; } @@ -12735,7 +12757,6 @@ create_table_info_t::create_foreign_keys() NULL if the column is not allowed to be NULL! */ - key_text k(fk); ib_foreign_warn( m_trx, DB_CANNOT_ADD_CONSTRAINT, @@ -12746,9 +12767,9 @@ create_table_info_t::create_foreign_keys() "but column '%s' is defined as " "NOT NULL.", operation, create_name, - k.str(), col_name); + key_text(fk).str(), col_name); - return (DB_CANNOT_ADD_CONSTRAINT); + return DB_CANNOT_ADD_CONSTRAINT; } } } @@ -13596,7 +13617,7 @@ int ha_innobase::delete_table(const char *name) if (!table && lower_case_table_names == 1 && is_partition(norm_name)) { IF_WIN(normalize_table_name_c_low(norm_name, name, false), - innobase_casedn_str(norm_name)); + my_casedn_str(system_charset_info, norm_name)); table= dict_sys.load_table(n, DICT_ERR_IGNORE_DROP); } #endif @@ -13903,7 +13924,8 @@ static dberr_t innobase_rename_table(trx_t *trx, const char *from, case name, including the partition separator "P" */ strcpy(par_case_name, norm_from); - innobase_casedn_str(par_case_name); + my_casedn_str(system_charset_info, + par_case_name); #else /* On Windows platfrom, check whether there exists table name in @@ -20924,25 +20946,6 @@ const char* SET_TRANSACTION_MSG = const char* INNODB_PARAMETERS_MSG = "Please refer to https://mariadb.com/kb/en/library/innodb-system-variables/"; -/********************************************************************** -Converts an identifier from my_charset_filename to UTF-8 charset. -@return result string length, as returned by strconvert() */ -uint -innobase_convert_to_filename_charset( -/*=================================*/ - char* to, /* out: converted identifier */ - const char* from, /* in: identifier to convert */ - ulint len) /* in: length of 'to', in bytes */ -{ - uint errors; - CHARSET_INFO* cs_to = &my_charset_filename; - CHARSET_INFO* cs_from = system_charset_info; - - return(static_cast(strconvert( - cs_from, from, uint(strlen(from)), - cs_to, to, static_cast(len), &errors))); -} - /********************************************************************** Converts an identifier from my_charset_filename to UTF-8 charset. @return result string length, as returned by strconvert() */ diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index ff427297375..afcff2f3ea1 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -30,6 +30,7 @@ Smart ALTER TABLE #include #include #include +#include /* Include necessary InnoDB headers */ #include "btr0sea.h" @@ -3231,6 +3232,9 @@ innobase_get_foreign_key_info( ulint num_fk = 0; Alter_info* alter_info = ha_alter_info->alter_info; const CHARSET_INFO* cs = thd_charset(trx->mysql_thd); + char db_name[MAX_DATABASE_NAME_LEN + 1]; + char t_name[MAX_TABLE_NAME_LEN + 1]; + static_assert(MAX_TABLE_NAME_LEN == MAX_DATABASE_NAME_LEN, ""); DBUG_ENTER("innobase_get_foreign_key_info"); @@ -3295,14 +3299,15 @@ innobase_get_foreign_key_info( add_fk[num_fk] = dict_mem_foreign_create(); + LEX_CSTRING t = innodb_convert_name(cs, fk_key->ref_table, + t_name); + LEX_CSTRING d = fk_key->ref_db.str + ? innodb_convert_name(cs, fk_key->ref_db, db_name) + : LEX_CSTRING{table->name.m_name, table->name.dblen()}; dict_sys.lock(SRW_LOCK_CALL); - referenced_table_name = dict_get_referenced_table( - table->name.m_name, - LEX_STRING_WITH_LEN(fk_key->ref_db), - LEX_STRING_WITH_LEN(fk_key->ref_table), - &referenced_table, - add_fk[num_fk]->heap, cs); + referenced_table_name = dict_table_lookup( + d, t, &referenced_table, add_fk[num_fk]->heap); /* Test the case when referenced_table failed to open, if trx->check_foreigns is not set, we should diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 0197a790faa..519e1c5bd10 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -55,22 +55,6 @@ inline size_t dict_get_db_name_len(const char *name) } -/*********************************************************************//** -Open a table from its database and table name, this is currently used by -foreign constraint parser to get the referenced table. -@return complete table name with database and table name, allocated from -heap memory passed in */ -char* -dict_get_referenced_table( -/*======================*/ - const char* name, /*!< in: foreign key table name */ - const char* database_name, /*!< in: table db name */ - ulint database_name_len,/*!< in: db name length */ - const char* table_name, /*!< in: table name */ - ulint table_name_len, /*!< in: table name length */ - dict_table_t** table, /*!< out: table object or NULL */ - mem_heap_t* heap, /*!< in: heap memory */ - CHARSET_INFO* from_cs); /*!< in: table name charset */ /*********************************************************************//** Frees a foreign key struct. */ void diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 609aaf951ca..3b1ae66d861 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -431,7 +431,7 @@ void dict_mem_foreign_table_name_lookup_set( /*===================================*/ dict_foreign_t* foreign, /*!< in/out: foreign struct */ - ibool do_alloc); /*!< in: is an alloc needed */ + bool do_alloc); /*!< in: is an alloc needed */ /**********************************************************************//** Sets the referenced_table_name_lookup pointer based on the value of diff --git a/storage/innobase/include/dict0types.h b/storage/innobase/include/dict0types.h index ec50e8cd951..85eed8d416c 100644 --- a/storage/innobase/include/dict0types.h +++ b/storage/innobase/include/dict0types.h @@ -110,7 +110,7 @@ struct table_name_t table_name_t(char* name) : m_name(name) {} /** @return the end of the schema name */ - const char* dbend() const + const char* dbend() const noexcept { const char* sep = strchr(m_name, '/'); ut_ad(sep); @@ -118,11 +118,19 @@ struct table_name_t } /** @return the length of the schema name, in bytes */ - size_t dblen() const { return size_t(dbend() - m_name); } + size_t dblen() const noexcept + { + const char *end= dbend(); + return UNIV_LIKELY(end != nullptr) ? size_t(end - m_name) : 0; + } /** Determine the filename-safe encoded table name. @return the filename-safe encoded table name */ - const char* basename() const { return dbend() + 1; } + const char* basename() const noexcept + { + const char *end= dbend(); + return UNIV_LIKELY(end != nullptr) ? end + 1 : nullptr; + } /** The start of the table basename suffix for partitioned tables */ static const char part_suffix[4]; diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h index 96ce0cfe783..098986febdf 100644 --- a/storage/innobase/include/ha_prototypes.h +++ b/storage/innobase/include/ha_prototypes.h @@ -40,6 +40,8 @@ class Field; struct dict_table_t; struct dict_foreign_t; struct table_name_t; +struct mem_block_info_t; +typedef struct mem_block_info_t mem_heap_t; // JAN: TODO missing features: #undef MYSQL_FT_INIT_EXT @@ -156,33 +158,6 @@ const char* innobase_basename( const char* path_name); -/******************************************************************//** -Converts an identifier to a table name. */ -void -innobase_convert_from_table_id( -/*===========================*/ - CHARSET_INFO* cs, /*!< in: the 'from' character set */ - char* to, /*!< out: converted identifier */ - const char* from, /*!< in: identifier to convert */ - ulint len); /*!< in: length of 'to', in bytes; should - be at least 5 * strlen(to) + 1 */ -/******************************************************************//** -Converts an identifier to UTF-8. */ -void -innobase_convert_from_id( -/*=====================*/ - CHARSET_INFO* cs, /*!< in: the 'from' character set */ - char* to, /*!< out: converted identifier */ - const char* from, /*!< in: identifier to convert */ - ulint len); /*!< in: length of 'to', in bytes; - should be at least 3 * strlen(to) + 1 */ -/******************************************************************//** -Makes all characters in a NUL-terminated UTF-8 string lower case. */ -void -innobase_casedn_str( -/*================*/ - char* a); /*!< in/out: string to put in lower case */ - #ifdef WITH_WSREP ulint wsrep_innobase_mysql_sort(int mysql_type, uint charset_number, unsigned char* str, ulint str_length, @@ -370,15 +345,6 @@ innobase_next_autoinc( MY_ATTRIBUTE((pure, warn_unused_result)); /********************************************************************** -Converts an identifier from my_charset_filename to UTF-8 charset. */ -uint -innobase_convert_to_system_charset( -/*===============================*/ - char* to, /* out: converted identifier */ - const char* from, /* in: identifier to convert */ - ulint len, /* in: length of 'to', in bytes */ - uint* errors); /* out: error return */ -/********************************************************************** Check if the length of the identifier exceeds the maximum allowed. The input to this function is an identifier in charset my_charset_filename. return true when length of identifier is too long. */ @@ -398,14 +364,13 @@ innobase_convert_to_system_charset( ulint len, /* in: length of 'to', in bytes */ uint* errors); /* out: error return */ -/********************************************************************** -Converts an identifier from my_charset_filename to UTF-8 charset. */ -uint -innobase_convert_to_filename_charset( -/*=================================*/ - char* to, /* out: converted identifier */ - const char* from, /* in: identifier to convert */ - ulint len); /* in: length of 'to', in bytes */ +/** Convert a schema or table name to InnoDB (and file system) format. +@param cs source character set +@param name name encoded in cs +@param buf output buffer (MAX_TABLE_NAME_LEN + 1 bytes) +@return the converted string (within buf) */ +LEX_CSTRING innodb_convert_name(CHARSET_INFO *cs, LEX_CSTRING name, char *buf) + noexcept; /** Report that a table cannot be decrypted. @param thd connection context @@ -460,6 +425,16 @@ void destroy_background_thd(MYSQL_THD thd); void innobase_reset_background_thd(MYSQL_THD); +/** Open a table based on a database and table name. +@param db schema name +@param name table name within the schema +@param table table +@param heap memory heap for allocating a converted name +@return InnoDB format table name with database and table name, +allocated from heap */ +char *dict_table_lookup(LEX_CSTRING db, LEX_CSTRING name, + dict_table_t **table, mem_heap_t *heap) noexcept; + #ifdef WITH_WSREP /** Append table-level exclusive key. @param thd MySQL thread handle diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index ac5e08d4498..ac11ea56ad0 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -2608,7 +2608,7 @@ row_rename_table_for_mysql( memcpy(par_case_name, old_name, strlen(old_name)); par_case_name[strlen(old_name)] = 0; - innobase_casedn_str(par_case_name); + my_casedn_str(system_charset_info, par_case_name); #else /* On Windows platfrom, check whether there exists table name in From 2543be69423b8a6582a4d2fa688d969359f8de3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 23 Jan 2025 14:38:35 +0200 Subject: [PATCH 129/213] MDEV-35854: Clarify row_rename_table_for_mysql() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit enum rename_fk: Replaces the "bool use_fk" parameter of row_rename_table_for_mysql() and innobase_rename_table(): RENAME_IGNORE_FK: Replaces use_fk=false when the operation cannot involve any FOREIGN KEY constraints, that is, it is a partitioned table or an internal table for FULLTEXT INDEX. RENAME_REBUILD: Replaces use_fk=false when the table may contain FOREIGN KEY constraints, which must not be modified in the data dictionary tables SYS_FOREIGN and SYS_FOREIGN_COLS. RENAME_ALTER_COPY: Replaces use_fk=true. This is only specified in ha_innobase::rename_table(), which may be invoked as part of ALTER TABLE…ALGORITHM=COPY, but also during RENAME TABLE. An alternative value RENAME_FK could be useful to specify in ha_innobase::rename_table() when it is executed as part of CREATE OR REPLACE TABLE, which currently is not an atomic operation. Reviewed by: Debarun Banerjee --- storage/innobase/fts/fts0fts.cc | 4 ++-- storage/innobase/handler/ha_innodb.cc | 15 +++++++++------ storage/innobase/handler/handler0alter.cc | 6 ++++-- storage/innobase/include/row0mysql.h | 11 ++++++++++- storage/innobase/row/row0mysql.cc | 15 ++++++++------- 5 files changed, 33 insertions(+), 18 deletions(-) diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index df2cb568d4d..83ae2827230 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -1392,7 +1392,7 @@ static dberr_t fts_drop_table(trx_t *trx, const char *table_name, bool rename) char *tmp= dict_mem_create_temporary_tablename(heap, table->name.m_name, table->id); dberr_t err= row_rename_table_for_mysql(table->name.m_name, tmp, trx, - false); + RENAME_IGNORE_FK); mem_heap_free(heap); if (err != DB_SUCCESS) { @@ -1450,7 +1450,7 @@ fts_rename_one_aux_table( fts_table_new_name[table_new_name_len] = 0; return row_rename_table_for_mysql( - fts_table_old_name, fts_table_new_name, trx, false); + fts_table_old_name, fts_table_new_name, trx, RENAME_IGNORE_FK); } /****************************************************************//** diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 3229cb67241..4dd7a9405dd 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -13889,10 +13889,10 @@ err_exit: @param[in,out] trx InnoDB data dictionary transaction @param[in] from old table name @param[in] to new table name -@param[in] use_fk whether to enforce FOREIGN KEY +@param[in] fk how to handle FOREIGN KEY @return DB_SUCCESS or error code */ static dberr_t innobase_rename_table(trx_t *trx, const char *from, - const char *to, bool use_fk) + const char *to, rename_fk fk) { dberr_t error; char norm_to[FN_REFLEN]; @@ -13910,7 +13910,7 @@ static dberr_t innobase_rename_table(trx_t *trx, const char *from, ut_ad(trx->will_lock); - error = row_rename_table_for_mysql(norm_from, norm_to, trx, use_fk); + error = row_rename_table_for_mysql(norm_from, norm_to, trx, fk); if (error != DB_SUCCESS) { if (error == DB_TABLE_NOT_FOUND @@ -13936,7 +13936,8 @@ static dberr_t innobase_rename_table(trx_t *trx, const char *from, #endif /* _WIN32 */ trx_start_if_not_started(trx, true); error = row_rename_table_for_mysql( - par_case_name, norm_to, trx, false); + par_case_name, norm_to, trx, + RENAME_IGNORE_FK); } } @@ -14132,7 +14133,8 @@ int ha_innobase::truncate() if (error == DB_SUCCESS) { - error= innobase_rename_table(trx, ib_table->name.m_name, temp_name, false); + error= innobase_rename_table(trx, ib_table->name.m_name, temp_name, + RENAME_REBUILD); if (error == DB_SUCCESS) error= trx->drop_table(*ib_table); } @@ -14330,7 +14332,8 @@ ha_innobase::rename_table( row_mysql_lock_data_dictionary(trx); if (error == DB_SUCCESS) { - error = innobase_rename_table(trx, from, to, true); + error = innobase_rename_table(trx, from, to, + RENAME_ALTER_COPY); } DEBUG_SYNC(thd, "after_innobase_rename_table"); diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index afcff2f3ea1..a967259a2ab 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -10414,10 +10414,12 @@ commit_try_rebuild( char* old_name= mem_heap_strdup(ctx->heap, user_table->name.m_name); dberr_t error = row_rename_table_for_mysql(user_table->name.m_name, - ctx->tmp_name, trx, false); + ctx->tmp_name, trx, + RENAME_REBUILD); if (error == DB_SUCCESS) { error = row_rename_table_for_mysql( - rebuilt_table->name.m_name, old_name, trx, false); + rebuilt_table->name.m_name, old_name, trx, + RENAME_REBUILD); if (error == DB_SUCCESS) { /* The statistics for the surviving indexes will be re-inserted in alter_stats_rebuild(). */ diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 8cbeed7d297..63858f25f02 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -370,6 +370,15 @@ row_import_tablespace_for_mysql( row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL */ MY_ATTRIBUTE((nonnull, warn_unused_result)); +enum rename_fk { + /** ignore FOREIGN KEY constraints */ + RENAME_IGNORE_FK= 0, + /** Rename a table as part of a native table-rebuilding DDL operation */ + RENAME_REBUILD, + /** Rename as part of ALTER TABLE...ALGORITHM=COPY */ + RENAME_ALTER_COPY +}; + /*********************************************************************//** Renames a table for MySQL. @return error code or DB_SUCCESS */ @@ -379,7 +388,7 @@ row_rename_table_for_mysql( const char* old_name, /*!< in: old table name */ const char* new_name, /*!< in: new table name */ trx_t* trx, /*!< in/out: transaction */ - bool use_fk) /*!< in: whether to parse and enforce + rename_fk fk) /*!< in: how to handle FOREIGN KEY constraints */ MY_ATTRIBUTE((nonnull, warn_unused_result)); diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index ac11ea56ad0..c72e71bf047 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -2554,7 +2554,7 @@ row_rename_table_for_mysql( const char* old_name, /*!< in: old table name */ const char* new_name, /*!< in: new table name */ trx_t* trx, /*!< in/out: transaction */ - bool use_fk) /*!< in: whether to parse and enforce + rename_fk fk) /*!< in: how to handle FOREIGN KEY constraints */ { dict_table_t* table = NULL; @@ -2579,6 +2579,8 @@ 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); + ut_ad(fk != RENAME_IGNORE_FK || !new_is_tmp); + table = dict_table_open_on_name(old_name, true, DICT_ERR_IGNORE_FK_NOKEY); @@ -2638,10 +2640,9 @@ row_rename_table_for_mysql( << TROUBLESHOOTING_MSG; goto funct_exit; - - } else if (use_fk && !old_is_tmp && new_is_tmp) { - /* MySQL is doing an ALTER TABLE command and it renames the - original table to a temporary table name. We want to preserve + } else if (fk == RENAME_ALTER_COPY && !old_is_tmp && new_is_tmp) { + /* Non-native ALTER TABLE is renaming the + original table to a temporary name. We want to preserve the original foreign key constraint definitions despite the name change. An exception is those constraints for which the ALTER TABLE contained DROP FOREIGN KEY .*/ @@ -2685,7 +2686,7 @@ row_rename_table_for_mysql( goto rollback_and_exit; } - if (!new_is_tmp) { + if (/* fk == RENAME_IGNORE_FK || */ !new_is_tmp) { /* Rename all constraints. */ char new_table_name[MAX_TABLE_NAME_LEN + 1]; char old_table_utf8[MAX_TABLE_NAME_LEN + 1]; @@ -2859,7 +2860,7 @@ row_rename_table_for_mysql( err = dict_load_foreigns( new_name, nullptr, trx->id, !old_is_tmp || trx->check_foreigns, - use_fk + fk == RENAME_ALTER_COPY ? DICT_ERR_IGNORE_NONE : DICT_ERR_IGNORE_FK_NOKEY, fk_tables); From 24c903394712beb5394eff36846c425065488de0 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 22 Jan 2025 17:14:33 +0400 Subject: [PATCH 130/213] MDEV-35538 UBSAN: nullptr-with-offset: runtime error: applying zero offset to null pointer in check_rules and in init_weight_level Rewriting loops in check_rules() and init_weight_level() in the way to avoid UBSAN nullptr-with-offset error. No MTR test are needed - the reported failures disappeared from "mtr" output when running an UBSAN compiled build. --- strings/ctype-uca.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c index a79a0764840..cb86a2b0c6f 100644 --- a/strings/ctype-uca.c +++ b/strings/ctype-uca.c @@ -33867,9 +33867,10 @@ check_rules(MY_CHARSET_LOADER *loader, const MY_COLL_RULES *rules, const MY_UCA_WEIGHT_LEVEL *dst, const MY_UCA_WEIGHT_LEVEL *src) { - const MY_COLL_RULE *r, *rlast; - for (r= rules->rule, rlast= rules->rule + rules->nrules; r < rlast; r++) + size_t i; + for (i= 0; i < rules->nrules; i++) { + const MY_COLL_RULE *r= &rules->rule[i]; if (r->curr[0] > dst->maxchar) { my_snprintf(loader->error, sizeof(loader->error), @@ -34492,7 +34493,6 @@ init_weight_level(MY_CHARSET_LOADER *loader, CHARSET_INFO *cs, MY_COLL_RULES *rules, MY_UCA_WEIGHT_LEVEL *dst, const MY_UCA_WEIGHT_LEVEL *src) { - MY_COLL_RULE *r, *rlast; int ncontractions= 0; size_t i, npages= (src->maxchar + 1) / 256; @@ -34517,8 +34517,9 @@ init_weight_level(MY_CHARSET_LOADER *loader, CHARSET_INFO *cs, Mark pages that will be otherwriten as NULL. We'll allocate their own memory. */ - for (r= rules->rule, rlast= rules->rule + rules->nrules; r < rlast; r++) + for (i= 0; i < rules->nrules; i++) { + const MY_COLL_RULE *r= &rules->rule[i]; if (!r->curr[1]) /* If not a contraction */ { uint pagec= (r->curr[0] >> 8); @@ -34564,9 +34565,9 @@ init_weight_level(MY_CHARSET_LOADER *loader, CHARSET_INFO *cs, Now iterate through the rules, overwrite weights for the characters that appear in the rules, and put all contractions into contraction list. */ - for (r= rules->rule; r < rlast; r++) + for (i= 0; i < rules->nrules; i++) { - if (apply_one_rule(loader, rules, r, dst)) + if (apply_one_rule(loader, rules, &rules->rule[i], dst)) return TRUE; } From 3a6af458e6149657c1e135af821a23a7c15c68f1 Mon Sep 17 00:00:00 2001 From: Vlad Lesin Date: Thu, 10 Oct 2024 15:43:36 +0300 Subject: [PATCH 131/213] MDEV-34877 Port "Bug #11745929 Change lock priority so that the transaction holding S-lock gets X-lock first" fix from MySQL to MariaDB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit implements mysql/mysql-server@7037a0bdc83196755a3bf3e935cfb3c0127715d5 functionality. If some transaction 't' requests not-gap X-lock 'Xt' on record 'r', and locks list of the record 'r' contains not-gap granted S-lock 'St' of transaction 't', followed by not-gap waiting locks WB={Wb1, Wb2, ..., Wbn} conflicting with 'Xt', and 'Xt' does not conflict with any other lock, located in the list after 'St', then grant 'Xt'. Note that insert-intention locks are also gap locks. If some transaction 't' holds not-gap lock 'Lt' on record 'r', and some other transactions have not-gap continuous waiting locks sequence L(B)={L(b1), L(b2), ..., L(bn)} following L(t) in the list of locks for the record 'r', and transaction 't' requests not-gap, what means also not insert intention, as ii-locks are also gap locks, X-lock conflicting with any lock in L(B), then grant the. MySQL's commit contains the following explanation of why insert-intention locks must not overtake a waiting ordinary or gap locks: "It is important that this decission rule doesn't allow INSERT_INTENTION locks to overtake WAITING locks on gaps (`S`, `S|GAP`, `X`, `X|GAP`), as inserting a record into a gap would split such WAITING lock, violating the invariant that each transaction can have at most single WAITING lock at any time." I would add to the explanation the following. Suppose we have trx 1 which holds ordinary X-lock on some record. And trx 2 executes "DELETE FROM t" or "SELECT * FOR UPDATE" in RR(see lock_delete_updated.test and MDEV-27992), i.e. it creates waiting ordinary X-lock on the same record. And then trx 1 wants to insert some record just before the locked record. It requests insert-intention lock, and if the lock overtakes trx 2 lock, there will be phantom records for trx 2 in RR. lock_delete_updated.test shows how "DELETE" allows to insert some records in already scanned gap and misses some records to delete. The current implementation differs from MySQL implementation. There are two key differences: 1. Lock queue ordering. In MySQL all waiting locks precede all granted locks. A new waiting lock is added to the head of the queue, a new granted lock is added to the end of the queue, if some waiting lock is granted, it's moved to the end of the queue. In MariaDB any new lock is added to the end of the queue and waiting lock does not change its position in the queue where the lock is granted. The rule is that blocking lock must be located before blocked lock in lock queue. We maintain the rule with inserting bypassing lock just before bypassed one. 2. MySQL implementation uses some object(locksys::Trx_locks_cache) which can be passed to consecutive calls to rec_lock_has_to_wait() for the same trx and heap_no to cache the result of checking if trx has a granted lock which is blocking the waiting lock(see locksys::Trx_locks_cache::has_granted_blocker()). The current implementation does not use such object, because it looks for such granted lock on the level of lock_rec_other_has_conflicting() and lock_rec_has_to_wait_in_queue(). I.e. there is no need in additional lock queue iteration in locksys::Trx_locks_cache::has_granted_blocker(), as we already iterate it in lock_rec_other_has_conflicting() and lock_rec_has_to_wait_in_queue(). During the testing the following case was found. Suppose we have delete-marked record and going to do inplace insert into that delete-marked record. Usually we don't create explicit lock if there are no conlicting with not gap X-lock locks(see lock_clust_rec_modify_check_and_lock(), btr_cur_update_in_place()). The implicit lock will be converted to explicit one by demand. That can happen during INSERT, the not-gap S-lock can be acquired on searching for duplicates(see row_ins_duplicate_error_in_clust()), and, if delete-marked record is found, inplace insert(see btr_cur_upd_rec_in_place()) modifies the record, what is treated as implicit lock. But there can be a case when some transaction trx1 holds not-gap S-lock, another transaction trx2 creates waiting X-lock, and then trx2 tries to do inplace insert. Before the fix the waiting X-lock of trx2 would be conflicting lock, and trx1 would try to create explicit X-lock, what would cause deadlock, and one of the transactions whould be rolled back. But after the fix, trx2 waiting X-lock is not treated as conflicting with trx1 X-lock anymore, as trx1 already holds S-lock. If we don't create explicit lock, then some other transaction trx3 can create it during implicit to explicit lock conversion and place it at the end of the queue. So there can be the following locks order in the queue: S1(granted) X2(waiting) X1(granted) The above queue is not valid, because all granted trx1 locks must be placed before waiting trx2 lock. Besides, lock_rec_release_try() can remove S(granted, trx1) lock and grant X lock to trx 2, and there can be two granted X-locks on the same record: X2(granted) X1(granted) Taking into account that lock_rec_release_try() can release cell and lock_sys latches leaving some locks unreleased, the queue validation function can fail in any unexpected place. It can be fixed with two ways: 1) Place explicit X(granted, trx1) lock before X(waiting, trx2) lock during implicit to explicit lock conversion. This option is implemented in MySQL, as granted lock is always placed at the top of locks queue, and waiting locks are placed at the bottom of the queue. MariaDB does not do this, and implementing this variant would require conflicting locks search before converting implicit to explicit lock, what, in turns, would require cell and/or lock_sys latch acquiring. 2) Create and place X(granted, trx1) lock before X(waiting, trx2) during inplace INSERT, i.e. when lock_rec_lock() is invoked from lock_clust_rec_modify_check_and_lock() or lock_sec_rec_modify_check_and_lock(), if X(waiting, trx2) is bypassed. Such a way we don't need in additional conflicting locks search, as they are searched anyway in lock_rec_low(). This fix implements the second variant(see the changes around c_lock_info.insert_after in lock_rec_lock). I.e. if some record was delete-marked and we do inplace insert in such a record, and some lock for bypass was found, create explicit lock to avoid conflicting lock search on each implicit to explicit lock conversion. We can remove it if MDEV-35624 is implemented. lock_rec_other_has_conflicting(), lock_rec_has_to_wait_in_queue(): search locks to bypass along with conflicting locks searching in the same loop. The result is returned in conflicting_lock_info object. There can be several locks to bypass, only the first one is returned to limit lock_rec_find_similar_on_page() with the first bypassed lock to preserve "blocking before blocked" invariant. conflicting_lock_info also contains a pointer to the lock, after which we can insert bypassing lock. This lock precedes bypassed one. Bypassing lock can be next-key lock, and the following cases are possible: 1. S1(not-gap, granted) II2(granted) X3(waiting for S1), When new X1(ordinary) lock is acquired, there will be the following locks queue: S1(not-gap, granted) II2(granted) X1(ordinary, granted) X3(waiting for S1) If we had inserted new X1 lock just after S1, and S1 had been released on transaction commit or rollback, we would have the following sequence in the locks queue: X1(ordinary, granted) II2(granted) X3(waiting for X1) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This is not a real issue as II lock once granted can be ignored but it could possibly hit some assert(taking into account that lock_release_try() can release lock_sys latch, and other threads can acquire the latch and validate lock queue) as it breaks our design constraint that any granted lock in the queue should not conflict with locks ahead in the queue. But lock_rec_queue_validate() does not check the above constraint. We place new bypassing lock just before bypassed one, but there still can be the case when lock bitmap is used instead of creating new lock object(see lock_rec_add_to_queue() and lock_rec_find_similar_on_page()), and the lock, which owns the bitmap, can precede II2(granted). We can either disable lock_rec_find_similar_on_page() space optimization for bypassing locks or treat "X1(ordinary, granted) II2(granted)" sequence as valid. As we don't currently have the function which would fail on the above sequence, let treat it as valid for the case, when lock_release() execution is in process. 2. S1(ordinary, granted) II2(waiting for S1) X3(waiting for S1) When new X1(ordinary) lock is acquired, there will be the following locks queue: S1(ordinary, granted) II2(waiting for S1) X1(ordinary, granted) X3(waiting for S1). After S1 releasing there will be: II2(granted) X1(ordinary, granted) X3(waiting for X1) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The above queue is valid because ordinary lock does not conflict with II-lock(see lock_rec_has_to_wait()). lock_rec_create_low(): insert new lock to the position which lock_rec_other_has_conflicting(), lock_rec_has_to_wait_in_queue() returned if the lock is bypassing. lock_rec_find_similar_on_page(): add ability to limit similiar lock search with the certain lock to preserve "blocking before blocked" invariant for all bypassed locks. lock_rec_add_to_queue(): don't treat bypassed locks as waiting ones to let lock bitmap reusing for bypassing locks. lock_rec_lock(): fix inplace insert case, explained above. lock_rec_dequeue_from_page(), lock_rec_rebuild_waiting_queue(): move bypassing lock to the correct place to preserve "blocking before blocked" invariant. Reviewed by: Debarun Banerjee, Marko Mäkelä. --- .../r/avoid_deadlock_with_blocked.result | 198 +++++++ .../innodb/t/avoid_deadlock_with_blocked.test | 228 ++++++++ storage/innobase/include/hash0hash.h | 20 +- storage/innobase/include/lock0lock.h | 43 +- storage/innobase/include/lock0lock.inl | 25 - storage/innobase/include/lock0priv.h | 9 +- storage/innobase/include/lock0priv.inl | 18 +- storage/innobase/include/lock0types.h | 34 +- storage/innobase/lock/lock0lock.cc | 487 +++++++++++++----- storage/innobase/lock/lock0prdt.cc | 28 +- 10 files changed, 877 insertions(+), 213 deletions(-) create mode 100644 mysql-test/suite/innodb/r/avoid_deadlock_with_blocked.result create mode 100644 mysql-test/suite/innodb/t/avoid_deadlock_with_blocked.test diff --git a/mysql-test/suite/innodb/r/avoid_deadlock_with_blocked.result b/mysql-test/suite/innodb/r/avoid_deadlock_with_blocked.result new file mode 100644 index 00000000000..4e0cca42898 --- /dev/null +++ b/mysql-test/suite/innodb/r/avoid_deadlock_with_blocked.result @@ -0,0 +1,198 @@ +connect stop_purge,localhost,root; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connect con1,localhost,root,,; +connect con2,localhost,root,,; +connect con3,localhost,root,,; +connection default; +CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=0; +INSERT INTO t1 (id) VALUES (1); +# Simplest scenario: +# , +# , , +# Before MDEV-34877: +# , , +# After MDEV-34877: +# , , +# Expected: instead of deadlocking, the con1's request should ingore con2's +connection con1; +BEGIN; +SELECT * FROM t1 LOCK IN SHARE MODE; +id +1 +connection con2; +BEGIN; +SET DEBUG_SYNC = 'lock_wait_before_suspend SIGNAL con2_will_wait'; +SELECT * FROM t1 FOR UPDATE; +connection con1; +SET DEBUG_SYNC = 'now WAIT_FOR con2_will_wait'; +SELECT * FROM t1 FOR UPDATE; +id +1 +COMMIT; +connection con2; +id +1 +COMMIT; +# The scenario when we bypass X<-S pair: +# , +# , , +# , , +# , , , +connection con1; +BEGIN; +SELECT * FROM t1 LOCK IN SHARE MODE; +id +1 +connection con2; +BEGIN; +SET DEBUG_SYNC = 'lock_wait_before_suspend SIGNAL con2_will_wait'; +SELECT * FROM t1 FOR UPDATE; +connection con3; +SET DEBUG_SYNC = 'now WAIT_FOR con2_will_wait'; +BEGIN; +SET DEBUG_SYNC = 'lock_wait_before_suspend SIGNAL con3_will_wait'; +SELECT * FROM t1 LOCK IN SHARE MODE;; +connection con1; +SET DEBUG_SYNC = 'now WAIT_FOR con3_will_wait'; +SELECT * FROM t1 FOR UPDATE; +id +1 +COMMIT; +connection con2; +id +1 +COMMIT; +connection con3; +id +1 +COMMIT; +# A variant of the above scenario: +# , +# , , +# , , +# Expected: a deadlock, as INSERT INTENTION should not overtake locks on gap, to not slice them +connection con1; +BEGIN; +SELECT * FROM t1 WHERE id=1 FOR UPDATE; +id +1 +connection con2; +BEGIN; +SET DEBUG_SYNC = 'lock_wait_start SIGNAL con2_will_wait'; +SELECT * FROM t1 LOCK IN SHARE MODE; +connection con1; +SET DEBUG_SYNC = 'now WAIT_FOR con2_will_wait'; +INSERT INTO t1 VALUES (0); +ROLLBACK; +connection con2; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +COMMIT; +# More complicated scenario: +# , +# , , +# , , +# , , , +# , , +# Expected: a deadlock, as INSERT INTENTION should not overtake locks on gap, to not slice them +connection con1; +BEGIN; +SELECT * FROM t1 LOCK IN SHARE MODE; +id +1 +connection con2; +BEGIN; +SELECT * FROM t1 WHERE id=1 LOCK IN SHARE MODE; +id +1 +connection con3; +SET DEBUG_SYNC = 'lock_wait_before_suspend SIGNAL con3_will_wait'; +SELECT * FROM t1 FOR UPDATE; +connection con1; +SET DEBUG_SYNC = 'now WAIT_FOR con3_will_wait'; +SET DEBUG_SYNC = 'lock_wait_start SIGNAL con1_will_wait'; +INSERT INTO t1 VALUES (0); +connection con2; +SET DEBUG_SYNC = 'now WAIT_FOR con1_will_wait'; +COMMIT; +connection con1; +ROLLBACK; +connection con3; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +# More complicated scenario. +# , +# , , +# , , +# , , , +# Before MDEV-34877: +# , , +# After MDEV-34877: +# , , +connection con1; +BEGIN; +SELECT * FROM t1 LOCK IN SHARE MODE; +id +1 +connection con2; +BEGIN; +SELECT * FROM t1 WHERE id=1 LOCK IN SHARE MODE; +id +1 +connection default; +connection con3; +SET DEBUG_SYNC = 'lock_wait_before_suspend SIGNAL con3_will_wait'; +SELECT * FROM t1 FOR UPDATE; +connection con1; +SET DEBUG_SYNC = 'now WAIT_FOR con3_will_wait'; +SET DEBUG_SYNC = 'lock_wait_before_suspend SIGNAL con1_will_wait'; +SELECT * FROM t1 WHERE id=1 FOR UPDATE; +connection con2; +SET DEBUG_SYNC = 'now WAIT_FOR con1_will_wait'; +COMMIT; +connection con1; +id +1 +COMMIT; +connection con3; +id +1 +COMMIT; +# A secenario, where con1 has to bypass two transactions: +# +# +# +# Before MDEV-34877: +# +# After MDEV-34877: +# +connection con1; +BEGIN; +SELECT * FROM t1 LOCK IN SHARE MODE; +id +1 +connection con2; +SET DEBUG_SYNC = 'lock_wait_before_suspend SIGNAL con2_will_wait'; +SELECT * FROM t1 FOR UPDATE; +connection con3; +SET DEBUG_SYNC = 'now WAIT_FOR con2_will_wait'; +SET DEBUG_SYNC = 'lock_wait_before_suspend SIGNAL con3_will_wait'; +SELECT * FROM t1 FOR UPDATE; +connection con1; +SET DEBUG_SYNC = 'now WAIT_FOR con3_will_wait'; +SELECT * FROM t1 WHERE id=1 FOR UPDATE; +id +1 +COMMIT; +connection con2; +id +1 +COMMIT; +connection con3; +id +1 +COMMIT; +connection default; +disconnect con1; +disconnect con2; +disconnect con3; +disconnect stop_purge; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/avoid_deadlock_with_blocked.test b/mysql-test/suite/innodb/t/avoid_deadlock_with_blocked.test new file mode 100644 index 00000000000..aa55b1ba008 --- /dev/null +++ b/mysql-test/suite/innodb/t/avoid_deadlock_with_blocked.test @@ -0,0 +1,228 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/count_sessions.inc + +--disable_query_log +call mtr.add_suppression("InnoDB: Transaction was aborted due to "); +--enable_query_log + +connect stop_purge,localhost,root; +START TRANSACTION WITH CONSISTENT SNAPSHOT; + +--connect (con1,localhost,root,,) +--connect (con2,localhost,root,,) +--connect (con3,localhost,root,,) + +--connection default +CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=0; +INSERT INTO t1 (id) VALUES (1); + +--echo # Simplest scenario: +--echo # , +--echo # , , +--echo # Before MDEV-34877: +--echo # , , +--echo # After MDEV-34877: +--echo # , , +--echo # Expected: instead of deadlocking, the con1's request should ingore con2's + +--connection con1 + BEGIN; + SELECT * FROM t1 LOCK IN SHARE MODE; + +--connection con2 + BEGIN; + SET DEBUG_SYNC = 'lock_wait_before_suspend SIGNAL con2_will_wait'; + --send SELECT * FROM t1 FOR UPDATE + +--connection con1 + SET DEBUG_SYNC = 'now WAIT_FOR con2_will_wait'; + SELECT * FROM t1 FOR UPDATE; + COMMIT; + +--connection con2 + --reap + COMMIT; + +--echo # The scenario when we bypass X<-S pair: +--echo # , +--echo # , , +--echo # , , +--echo # , , , + +--connection con1 + BEGIN; + SELECT * FROM t1 LOCK IN SHARE MODE; + +--connection con2 + BEGIN; + SET DEBUG_SYNC = 'lock_wait_before_suspend SIGNAL con2_will_wait'; + --send SELECT * FROM t1 FOR UPDATE + +--connection con3 + SET DEBUG_SYNC = 'now WAIT_FOR con2_will_wait'; + BEGIN; + SET DEBUG_SYNC = 'lock_wait_before_suspend SIGNAL con3_will_wait'; + --send SELECT * FROM t1 LOCK IN SHARE MODE; + +--connection con1 + SET DEBUG_SYNC = 'now WAIT_FOR con3_will_wait'; + SELECT * FROM t1 FOR UPDATE; + COMMIT; + +--connection con2 + --reap + COMMIT; + +--connection con3 + --reap + COMMIT; + +# +--echo # A variant of the above scenario: +--echo # , +--echo # , , +--echo # , , +--echo # Expected: a deadlock, as INSERT INTENTION should not overtake locks on gap, to not slice them +--connection con1 + BEGIN; + SELECT * FROM t1 WHERE id=1 FOR UPDATE; + +--connection con2 + BEGIN; + SET DEBUG_SYNC = 'lock_wait_start SIGNAL con2_will_wait'; + --send SELECT * FROM t1 LOCK IN SHARE MODE + +--connection con1 + SET DEBUG_SYNC = 'now WAIT_FOR con2_will_wait'; + INSERT INTO t1 VALUES (0); + ROLLBACK; + +--connection con2 + --error ER_LOCK_DEADLOCK + --reap + COMMIT; + +--echo # More complicated scenario: +--echo # , +--echo # , , +--echo # , , +--echo # , , , +--echo # , , +--echo # Expected: a deadlock, as INSERT INTENTION should not overtake locks on gap, to not slice them + +--connection con1 + BEGIN; + SELECT * FROM t1 LOCK IN SHARE MODE; + +--connection con2 + BEGIN; + SELECT * FROM t1 WHERE id=1 LOCK IN SHARE MODE; + +--connection con3 + SET DEBUG_SYNC = 'lock_wait_before_suspend SIGNAL con3_will_wait'; + --send SELECT * FROM t1 FOR UPDATE + +--connection con1 + SET DEBUG_SYNC = 'now WAIT_FOR con3_will_wait'; + SET DEBUG_SYNC = 'lock_wait_start SIGNAL con1_will_wait'; + --send INSERT INTO t1 VALUES (0) + +--connection con2 + SET DEBUG_SYNC = 'now WAIT_FOR con1_will_wait'; + COMMIT; + +--connection con1 + --reap + ROLLBACK; + +--connection con3 + --error ER_LOCK_DEADLOCK + --reap + +--echo # More complicated scenario. +--echo # , +--echo # , , +--echo # , , +--echo # , , , +--echo # Before MDEV-34877: +--echo # , , +--echo # After MDEV-34877: +--echo # , , + + +--connection con1 + BEGIN; + SELECT * FROM t1 LOCK IN SHARE MODE; + +--connection con2 + BEGIN; + SELECT * FROM t1 WHERE id=1 LOCK IN SHARE MODE; + +--connection default + +--connection con3 + SET DEBUG_SYNC = 'lock_wait_before_suspend SIGNAL con3_will_wait'; + --send SELECT * FROM t1 FOR UPDATE + +--connection con1 + SET DEBUG_SYNC = 'now WAIT_FOR con3_will_wait'; + SET DEBUG_SYNC = 'lock_wait_before_suspend SIGNAL con1_will_wait'; + --send SELECT * FROM t1 WHERE id=1 FOR UPDATE + +--connection con2 + SET DEBUG_SYNC = 'now WAIT_FOR con1_will_wait'; + COMMIT; + +--connection con1 + --reap + COMMIT; + +--connection con3 + --reap + COMMIT; + +--echo # A secenario, where con1 has to bypass two transactions: +--echo # +--echo # +--echo # +--echo # Before MDEV-34877: +--echo # +--echo # After MDEV-34877: +--echo # +--connection con1 + BEGIN; + SELECT * FROM t1 LOCK IN SHARE MODE; + +--connection con2 + SET DEBUG_SYNC = 'lock_wait_before_suspend SIGNAL con2_will_wait'; + --send SELECT * FROM t1 FOR UPDATE + +--connection con3 + SET DEBUG_SYNC = 'now WAIT_FOR con2_will_wait'; + SET DEBUG_SYNC = 'lock_wait_before_suspend SIGNAL con3_will_wait'; + --send SELECT * FROM t1 FOR UPDATE + +--connection con1 + SET DEBUG_SYNC = 'now WAIT_FOR con3_will_wait'; + SELECT * FROM t1 WHERE id=1 FOR UPDATE; + COMMIT; + +--connection con2 + --reap + COMMIT; + +--connection con3 + --reap + COMMIT; + +--connection default +--disconnect con1 +--disconnect con2 +--disconnect con3 +--disconnect stop_purge + +DROP TABLE t1; + +--source include/wait_until_count_sessions.inc diff --git a/storage/innobase/include/hash0hash.h b/storage/innobase/include/hash0hash.h index 4d45c0bf772..4fc21a90f1f 100644 --- a/storage/innobase/include/hash0hash.h +++ b/storage/innobase/include/hash0hash.h @@ -107,10 +107,28 @@ public: @param element the being-removed element @param next the next-element pointer in T */ template - void remove(T &element, T *T::*next) noexcept + void remove(const T &element, T *T::*next) noexcept { remove(search(next, [&element](const T *p){return p==&element;}), next); } + + /** Insert an element after another. + @tparam T type of the element + @param after the element after which to insert + @param insert the being-inserted element + @param next the next-element pointer in T */ + template void insert_after(T &after, T &insert, T *T::*next) + { +#ifdef UNIV_DEBUG + for (const T *c= static_cast(node); c; c= c->*next) + if (c == &after) + goto found; + ut_error; + found: +#endif + insert.*next= after.*next; + after.*next= &insert; + } }; /** Hash table with singly-linked overflow lists */ diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index 9da6f1680cd..fb79a82a808 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -52,6 +52,20 @@ namespace Deadlock enum report { REPORT_OFF, REPORT_BASIC, REPORT_FULL }; } +/** Conflicting lock info */ +struct conflicting_lock_info { + /** Conflicting lock */ + const lock_t *conflicting; + /** If some lock was bypassed, points to the lock after which bypassing + lock must be inserted into linked list of locks for the certain cell of + record locks hash table. */ + lock_t *insert_after; + /** First bypassed lock */ + ut_d(const lock_t *bypassed;) +}; + +extern const conflicting_lock_info null_c_lock_info; + /*********************************************************************//** Gets the heap_no of the smallest user record on a page. @return heap_no of smallest user record, or PAGE_HEAP_NO_SUPREMUM */ @@ -1144,25 +1158,6 @@ struct TMTrxGuard #endif }; -/*********************************************************************//** -Creates a new record lock and inserts it to the lock queue. Does NOT check -for deadlocks or lock compatibility! -@return created lock */ -UNIV_INLINE -lock_t* -lock_rec_create( -/*============*/ - lock_t* c_lock, /*!< conflicting lock */ - unsigned type_mode,/*!< in: lock mode and wait flag */ - const buf_block_t* block, /*!< in: buffer block containing - the record */ - ulint heap_no,/*!< in: heap number of the record */ - dict_index_t* index, /*!< in: index of record */ - trx_t* trx, /*!< in,out: transaction */ - bool caller_owns_trx_mutex); - /*!< in: true if caller owns - trx mutex */ - /** Remove a record lock request, waiting or granted, on a discarded page @param in_lock lock object @param cell hash table cell containing in_lock */ @@ -1170,7 +1165,7 @@ void lock_rec_discard(lock_t *in_lock, hash_cell_t &cell) noexcept; /** Create a new record lock and inserts it to the lock queue, without checking for deadlocks or conflicts. -@param[in] c_lock conflicting lock, or NULL +@param c_lock_info conflicting lock info @param[in] type_mode lock mode and wait flag @param[in] page_id index page number @param[in] page R-tree index page, or NULL @@ -1180,8 +1175,8 @@ without checking for deadlocks or conflicts. @param[in] holds_trx_mutex whether the caller holds trx->mutex @return created lock */ lock_t* -lock_rec_create_low( - lock_t* c_lock, +lock_rec_create( + const conflicting_lock_info &c_lock_info, unsigned type_mode, const page_id_t page_id, const page_t* page, @@ -1192,7 +1187,7 @@ lock_rec_create_low( /** Enqueue a waiting request for a lock which cannot be granted immediately. Check for deadlocks. -@param[in] c_lock conflicting lock +@param c_lock_info conflicting lock info @param[in] type_mode the requested lock mode (LOCK_S or LOCK_X) possibly ORed with LOCK_GAP or LOCK_REC_NOT_GAP, ORed with @@ -1210,7 +1205,7 @@ Check for deadlocks. @retval DB_DEADLOCK if this transaction was chosen as the victim */ dberr_t lock_rec_enqueue_waiting( - lock_t* c_lock, + const conflicting_lock_info &c_lock_info, unsigned type_mode, const page_id_t id, const page_t* page, diff --git a/storage/innobase/include/lock0lock.inl b/storage/innobase/include/lock0lock.inl index 1b9255ffb3e..37db4062e8c 100644 --- a/storage/innobase/include/lock0lock.inl +++ b/storage/innobase/include/lock0lock.inl @@ -51,28 +51,3 @@ lock_get_min_heap_no( FALSE))); } } - -/*********************************************************************//** -Creates a new record lock and inserts it to the lock queue. Does NOT check -for deadlocks or lock compatibility! -@return created lock */ -UNIV_INLINE -lock_t* -lock_rec_create( -/*============*/ - lock_t* c_lock, /*!< conflicting lock */ - unsigned type_mode,/*!< in: lock mode and wait flag */ - const buf_block_t* block, /*!< in: buffer block containing - the record */ - ulint heap_no,/*!< in: heap number of the record */ - dict_index_t* index, /*!< in: index of record */ - trx_t* trx, /*!< in,out: transaction */ - bool caller_owns_trx_mutex) - /*!< in: TRUE if caller owns - trx mutex */ -{ - return lock_rec_create_low( - c_lock, - type_mode, block->page.id(), block->page.frame, heap_no, - index, trx, caller_owns_trx_mutex); -} diff --git a/storage/innobase/include/lock0priv.h b/storage/innobase/include/lock0priv.h index e8a4cdd5240..14f0a6e0903 100644 --- a/storage/innobase/include/lock0priv.h +++ b/storage/innobase/include/lock0priv.h @@ -497,14 +497,11 @@ inline byte lock_rec_reset_nth_bit(lock_t* lock, ulint i) return(bit); } -/*********************************************************************//** -Gets the first or next record lock on a page. +/** Gets the first or next record lock on a page. +@param lock a record lock @return next lock, NULL if none exists */ UNIV_INLINE -lock_t* -lock_rec_get_next_on_page( -/*======================*/ - lock_t* lock); /*!< in: a record lock */ +lock_t *lock_rec_get_next_on_page(const lock_t *lock); /*********************************************************************//** Gets the next explicit lock request on a record. diff --git a/storage/innobase/include/lock0priv.inl b/storage/innobase/include/lock0priv.inl index 3c8ec01367b..27f12bc552d 100644 --- a/storage/innobase/include/lock0priv.inl +++ b/storage/innobase/include/lock0priv.inl @@ -101,14 +101,11 @@ lock_rec_set_nth_bit( lock->trx->lock.set_nth_bit_calls++; } -/*********************************************************************//** -Gets the first or next record lock on a page. +/** Gets the first or next record lock on a page. +@param lock a record lock @return next lock, NULL if none exists */ UNIV_INLINE -lock_t* -lock_rec_get_next_on_page( -/*======================*/ - lock_t* lock) /*!< in: a record lock */ +lock_t *lock_rec_get_next_on_page(const lock_t *lock) { return const_cast(lock_rec_get_next_on_page_const(lock)); } @@ -167,14 +164,11 @@ lock_rec_get_nth_bit( return(1 & *b >> (i % 8)); } -/*********************************************************************//** -Gets the first or next record lock on a page. +/** Gets the first or next record lock on a page. +@param lock a record lock @return next lock, NULL if none exists */ UNIV_INLINE -const lock_t* -lock_rec_get_next_on_page_const( -/*============================*/ - const lock_t* lock) /*!< in: a record lock */ +const lock_t *lock_rec_get_next_on_page_const(const lock_t *lock) { ut_ad(!lock->is_table()); diff --git a/storage/innobase/include/lock0types.h b/storage/innobase/include/lock0types.h index 0d00b4b360d..da235fb06a0 100644 --- a/storage/innobase/include/lock0types.h +++ b/storage/innobase/include/lock0types.h @@ -232,11 +232,43 @@ struct ib_lock_t return(static_cast(type_mode & LOCK_MODE_MASK)); } - bool is_rec_granted_exclusive_not_gap() const + static bool is_rec_exclusive_not_gap(unsigned type_mode) { + ut_ad(!(type_mode & LOCK_TABLE)); return (type_mode & (LOCK_MODE_MASK | LOCK_GAP)) == LOCK_X; } + bool is_rec_exclusive_not_gap() const + { + return is_rec_exclusive_not_gap(type_mode); + } + + bool is_waiting_not_gap() const + { + return (type_mode & (LOCK_WAIT | LOCK_GAP)) == LOCK_WAIT; + } + + /** Checks if a lock can be bypassed. + @param has_s_lock_or_stronger if caller's transaction already holds + not gap and not insert intention S-lock + or stronger for the same heap_no as the + current lock + @return true if the lock can be bypassed, false otherwise */ + bool can_be_bypassed(bool has_s_lock_or_stronger) const noexcept + { + ut_ad(!is_table()); + /* We don't neet do check supremum bit in the lock's bitmap here, + because the function is always called after checking for + bypass_mode, which already contains check for supremum. */ + ut_ad(!is_insert_intention() || is_gap()); + /* We don't need to check + trx->lock.wait_trx == blocking_trx && mode() == LOCK_X + condition here because there can be the following case: + S1 X2(waits for S1) S3(waits for X2), + bypassing X1 must not conflict with S3. */ + return has_s_lock_or_stronger && is_waiting_not_gap(); + } + /** Print the lock object into the given output stream. @param[in,out] out the output stream @return the given output stream. */ diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index ed9d6d2db02..6545d38817a 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -56,6 +56,8 @@ Created 5/7/1996 Heikki Tuuri #include #endif /* WITH_WSREP */ +const conflicting_lock_info null_c_lock_info{nullptr, nullptr, ut_d(nullptr)}; + /** The value of innodb_deadlock_detect */ my_bool innodb_deadlock_detect; /** The value of innodb_deadlock_report */ @@ -1159,12 +1161,23 @@ func_exit: lock= lock_rec_get_next(heap_no, lock); do { + /* TODO: Conflicting locks can be only before the waiting lock, + consider the following optimization: + if (lock == wait_lock) + break; */ /* This is similar case as above except here we have record-locks instead of table locks. See details from comment above. */ if (lock->trx->mysql_thd && wsrep_will_BF_abort(lock, trx)) { + /* There can't be bypassed locks because: + 1. The transaction can't be blocked by lock to bypass because + lock_rec_other_has_conflicting() does not treat such lock as + conflicting. + 2. The lock is placed before bypassed lock in + lock_rec_create_low(). + TODO: add debug check here */ victims.emplace(lock->trx); } } while ((lock= lock_rec_get_next(heap_no, lock))); @@ -1200,8 +1213,22 @@ func_exit: } #endif /* WITH_WSREP */ -/*********************************************************************//** -Checks if some other transaction has a conflicting explicit lock request +static inline bool lock_rec_can_be_bypassing(const trx_t *trx, + const lock_t *lock) +{ + ut_ad(!lock->is_insert_intention() || lock->is_gap()); + static_assert(int{LOCK_S} == 2, ""); + static_assert(int{LOCK_X} == 3, ""); + /* The below is an optimization of the following: + return lock->trx == trx && !(lock->type_mode & (LOCK_WAIT | LOCK_GAP)) && + lock_mode_stronger_or_eq(lock->mode(), LOCK_S); + The bitwise & with LOCK_MODE_MASK - 1 will map both LOCK_X and LOCK_S to + LOCK_S, which we are comparing to. */ + return lock->trx == trx && + (lock->type_mode & (LOCK_WAIT | LOCK_GAP | (LOCK_MODE_MASK - 1))) == LOCK_S; +} + +/** Checks if some other transaction has a conflicting explicit lock request in the queue, so that we have to wait. @param[in] mode LOCK_S or LOCK_X, possibly ORed to LOCK_GAP or LOC_REC_NOT_GAP, LOCK_INSERT_INTENTION @@ -1209,23 +1236,48 @@ LOCK_INSERT_INTENTION @param[in] id page identifier @param[in] heap_no heap number of the record @param[in] trx our transaction -@return conflicting lock and the flag which indicated if conflicting locks -which wait for the current transaction were ignored */ -static lock_t *lock_rec_other_has_conflicting(unsigned mode, - const hash_cell_t &cell, - const page_id_t id, - ulint heap_no, const trx_t *trx) +@return conflicting lock, lock after which new lock should be inserted +in lock queue in the case when the conflicting lock must be bypassed and +bypassed lock */ +static conflicting_lock_info +lock_rec_other_has_conflicting(unsigned mode, const hash_cell_t &cell, + const page_id_t id, ulint heap_no, + const trx_t *trx) noexcept { - bool is_supremum = (heap_no == PAGE_HEAP_NO_SUPREMUM); + const bool is_supremum= (heap_no == PAGE_HEAP_NO_SUPREMUM); + ut_ad(!(mode & LOCK_INSERT_INTENTION) || (mode & LOCK_GAP) || is_supremum); + const bool bypass_mode= + !is_supremum && lock_t::is_rec_exclusive_not_gap(mode); + bool has_s_lock_or_stronger= false; + const lock_t *insert_after= nullptr; + ut_d(const lock_t *bypassed= nullptr;) + const lock_t *prev_lock= nullptr; - for (lock_t* lock = lock_sys_t::get_first(cell, id, heap_no); - lock; lock = lock_rec_get_next(heap_no, lock)) { - if (lock_rec_has_to_wait(trx, mode, lock, is_supremum)) { - return(lock); - } - } + for (lock_t *lock= lock_sys_t::get_first(cell, id, heap_no); lock; + lock= lock_rec_get_next(heap_no, lock)) + { + if (bypass_mode && lock_rec_can_be_bypassing(trx, lock)) + { + has_s_lock_or_stronger= true; + } + else if (lock_rec_has_to_wait(trx, mode, lock, is_supremum)) + { + if (!bypass_mode || !lock->can_be_bypassed(has_s_lock_or_stronger)) + return {lock, nullptr, ut_d(nullptr)}; + /* Store the first lock to bypass to invoke + lock_rec_find_similar_on_page() only for the locks which precede all + bypassed locks. */ + ut_d(if (!bypassed) bypassed= lock;) + /* There can be several locks to bypass, insert bypassing lock just + before the first bypassed lock. */ + if (!insert_after) + insert_after= prev_lock; + continue; + } + prev_lock= lock; + } - return(NULL); + return {nullptr, const_cast(insert_after), ut_d(bypassed)}; } /*********************************************************************//** @@ -1294,6 +1346,69 @@ lock_number_of_tables_locked( /*============== RECORD LOCK CREATION AND QUEUE MANAGEMENT =============*/ +#ifdef UNIV_DEBUG +/** Validates the correctness of locks bypassing in lock queue on a single +record, i.e. there must not be the following sequence: + (trx1 S) (trx2 X) (trx3 X) (trx1 X) +If bypassing works correctly, where must be the following sequence instead of +the above: + (trx1 S) (trx1 X) (trx2 X) (trx3 X) +Note the above locks are record or next-key locks. +If wrong sequence is found, the function will crash with failed assertion. +@param checked_lock the lock up to which the queue to check +@param heap_no heap_no of the queue to check */ +static void lock_rec_queue_validate_bypass(const lock_t *checked_lock, + ulint heap_no) +{ + /* "do_lock_reverse_page_reorganize" causes lock queue reversing during page + reorganizing, which causes validation failure. Skip the validation for such + case. */ + DBUG_EXECUTE_IF("do_lock_reverse_page_reorganize", return;); + if (!checked_lock || checked_lock->is_waiting()) + return; + page_id_t page_id= checked_lock->un_member.rec_lock.page_id; + hash_cell_t *cell= lock_sys.rec_hash.cell_get(page_id.fold()); + auto mode= checked_lock->type_mode; + const trx_t *trx= checked_lock->trx; + const bool is_supremum= (heap_no == PAGE_HEAP_NO_SUPREMUM); + ut_ad(!(mode & LOCK_INSERT_INTENTION) || (mode & LOCK_GAP) || is_supremum); + if (is_supremum || !lock_t::is_rec_exclusive_not_gap(mode)) + return; + const lock_t *has_s_lock_or_stronger= nullptr; + const lock_t *bypassed= nullptr; + + for (lock_t *lock= lock_sys_t::get_first(*cell, page_id, heap_no); lock; + lock= lock_rec_get_next(heap_no, lock)) + { + if (lock_rec_can_be_bypassing(trx, lock)) + { + ut_ad(!bypassed || lock != checked_lock); + has_s_lock_or_stronger= lock; + continue; + } + if (lock_rec_has_to_wait(trx, mode, lock, is_supremum)) + { + if (!lock->can_be_bypassed(has_s_lock_or_stronger)) + return; + bypassed= lock; + } + ut_ad(lock != checked_lock || !bypassed); + if (lock == checked_lock) + return; + } +} + +/** Validates the correctness of locks bypassing in lock queue for each set bit +in the lock bitmap. If wrong sequence is found, the function will crash with +failed assertion. +@param lock the lock which bitmap to be checked */ +static void lock_rec_queue_validate_bypass(const lock_t *lock) { + for (ulint i= 0; i < lock_rec_get_n_bits(lock); ++i) + if (lock_rec_get_nth_bit(lock, i)) + lock_rec_queue_validate_bypass(lock, i); +} +#endif + /** Reset the wait status of a lock. @param[in,out] lock lock that was possibly being waited for */ static void lock_reset_lock_and_trx_wait(lock_t *lock) @@ -1308,6 +1423,10 @@ static void lock_reset_lock_and_trx_wait(lock_t *lock) trx->lock.wait_lock= nullptr; trx->lock.wait_trx= nullptr; lock->type_mode&= ~LOCK_WAIT; +#ifdef UNIV_DEBUG + if (!lock->is_table()) + lock_rec_queue_validate_bypass(lock); +#endif } #ifdef UNIV_DEBUG @@ -1325,7 +1444,7 @@ static void check_trx_state(const trx_t *trx) /** Create a new record lock and inserts it to the lock queue, without checking for deadlocks or conflicts. -@param[in] c_lock conflicting lock +@param[in] c_lock_info conflicting lock info @param[in] type_mode lock mode and wait flag @param[in] page_id index page number @param[in] page R-tree index page, or NULL @@ -1335,8 +1454,8 @@ without checking for deadlocks or conflicts. @param[in] holds_trx_mutex whether the caller holds trx->mutex @return created lock */ lock_t* -lock_rec_create_low( - lock_t* c_lock, +lock_rec_create( + const conflicting_lock_info &c_lock_info, unsigned type_mode, const page_id_t page_id, const page_t* page, @@ -1354,6 +1473,8 @@ lock_rec_create_low( ut_ad(!(type_mode & LOCK_TABLE)); ut_ad(trx->state != TRX_STATE_NOT_STARTED); ut_ad(!trx->is_autocommit_non_locking()); + ut_ad(c_lock_info.insert_after ? !(type_mode & LOCK_WAIT) : + !c_lock_info.bypassed); /* If rec is the supremum record, then we reset the gap and LOCK_REC_NOT_GAP bits, as all locks on the supremum are @@ -1424,23 +1545,30 @@ lock_rec_create_low( } else { /* Predicate lock always on INFIMUM (0) */ lock->un_member.rec_lock.n_bits = 8; - } + } lock_rec_bitmap_reset(lock); lock_rec_set_nth_bit(lock, heap_no); index->table->n_rec_locks++; ut_ad(index->table->get_ref_count() || !index->table->can_be_evicted); const auto lock_hash = &lock_sys.hash_get(type_mode); - lock_hash->cell_get(page_id.fold())->append(*lock, &lock_t::hash); + hash_cell_t& cell = *lock_hash->cell_get(page_id.fold()); + if (UNIV_LIKELY(!c_lock_info.insert_after)) + cell.append(*lock, &lock_t::hash); + else + cell.insert_after(*c_lock_info.insert_after, *lock, + &lock_t::hash); if (type_mode & LOCK_WAIT) { if (trx->lock.wait_trx) { - ut_ad(!c_lock || trx->lock.wait_trx == c_lock->trx); + ut_ad(!c_lock_info.conflicting + || trx->lock.wait_trx + == c_lock_info.conflicting->trx); ut_ad(trx->lock.wait_lock); ut_ad((*trx->lock.wait_lock).trx == trx); } else { - ut_ad(c_lock); - trx->lock.wait_trx = c_lock->trx; + ut_ad(c_lock_info.conflicting); + trx->lock.wait_trx = c_lock_info.conflicting->trx; ut_ad(!trx->lock.wait_lock); } trx->lock.wait_lock = lock; @@ -1451,12 +1579,13 @@ lock_rec_create_low( } MONITOR_INC(MONITOR_RECLOCK_CREATED); MONITOR_INC(MONITOR_NUM_RECLOCK); - + ut_d(lock_rec_queue_validate_bypass(lock, heap_no)); return lock; } /** Enqueue a waiting request for a lock which cannot be granted immediately. Check for deadlocks. +@param c_lock_info conflicting lock info @param[in] type_mode the requested lock mode (LOCK_S or LOCK_X) possibly ORed with LOCK_GAP or LOCK_REC_NOT_GAP, ORed with @@ -1474,7 +1603,7 @@ Check for deadlocks. @retval DB_DEADLOCK if this transaction was chosen as the victim */ dberr_t lock_rec_enqueue_waiting( - lock_t* c_lock, + const conflicting_lock_info &c_lock_info, unsigned type_mode, const page_id_t id, const page_t* page, @@ -1506,8 +1635,8 @@ lock_rec_enqueue_waiting( /* 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( - c_lock, + lock_t* lock = lock_rec_create( + c_lock_info, type_mode | LOCK_WAIT, id, page, heap_no, index, trx, true); if (prdt && type_mode & LOCK_PREDICATE) { @@ -1525,18 +1654,20 @@ lock_rec_enqueue_waiting( return DB_LOCK_WAIT; } -/*********************************************************************//** -Looks for a suitable type record lock struct by the same trx on the same page. -This can be used to save space when a new record lock should be set on a page: -no new struct is needed, if a suitable old is found. +/** Looks for a suitable type record lock struct by the same trx on the same +page. This can be used to save space when a new record lock should be set on a +page: no new struct is needed, if a suitable old is found. +@param type_mode lock type_mode field +@param heap_no heap number of the record +@param lock lock_sys.get_first() +@param last_lock the lock up to which to find +@param trx the transaction which lock we are looking for @return lock or NULL */ -static inline -lock_t* -lock_rec_find_similar_on_page( - ulint type_mode, /*!< in: lock type_mode field */ - ulint heap_no, /*!< in: heap number of the record */ - lock_t* lock, /*!< in: lock_sys.get_first() */ - const trx_t* trx) /*!< in: transaction */ +static inline lock_t *lock_rec_find_similar_on_page(ulint type_mode, + ulint heap_no, + const lock_t *lock, + const lock_t *last_lock, + const trx_t *trx) { lock_sys.rec_hash.assert_locked(lock->un_member.rec_lock.page_id); DBUG_EXECUTE_IF("innodb_skip_lock_bitmap", { @@ -1546,14 +1677,14 @@ lock_rec_find_similar_on_page( }); for (/* No op */; - lock != NULL; + lock != last_lock; lock = lock_rec_get_next_on_page(lock)) { if (lock->trx == trx && lock->type_mode == type_mode && lock_rec_get_n_bits(lock) > heap_no) { - return(lock); + return const_cast(lock); } } @@ -1576,7 +1707,8 @@ which does NOT check for deadlocks or lock compatibility! @param[in,out] trx transaction @param[in] caller_owns_trx_mutex TRUE if caller owns the transaction mutex */ TRANSACTIONAL_TARGET -static void lock_rec_add_to_queue(unsigned type_mode, const hash_cell_t &cell, +static void lock_rec_add_to_queue(const conflicting_lock_info &c_lock_info, + unsigned type_mode, const hash_cell_t &cell, const page_id_t id, const page_t *page, ulint heap_no, dict_index_t *index, trx_t *trx, bool caller_owns_trx_mutex) @@ -1623,8 +1755,8 @@ static void lock_rec_add_to_queue(unsigned type_mode, const hash_cell_t &cell, all locks on the supremum are automatically of the gap type, and we try to avoid unnecessary memory consumption of a new record lock struct for a gap type lock */ - - if (heap_no == PAGE_HEAP_NO_SUPREMUM) { + const bool is_supremum = heap_no == PAGE_HEAP_NO_SUPREMUM; + if (is_supremum) { ut_ad(!(type_mode & LOCK_REC_NOT_GAP)); /* There should never be LOCK_REC_NOT_GAP on a supremum @@ -1634,23 +1766,47 @@ static void lock_rec_add_to_queue(unsigned type_mode, const hash_cell_t &cell, } if (type_mode & LOCK_WAIT) { - goto create; } else if (lock_t *first_lock = lock_sys_t::get_first(cell, id)) { + ut_ad(!(type_mode & LOCK_INSERT_INTENTION) + || (type_mode & LOCK_GAP) || is_supremum); + const bool bypass_mode = !is_supremum + && lock_t::is_rec_exclusive_not_gap(type_mode); + bool has_s_lock_or_stronger = false; for (lock_t* lock = first_lock;;) { - if (lock->is_waiting() - && lock_rec_get_nth_bit(lock, heap_no)) { - goto create; + if (!lock_rec_get_nth_bit(lock, heap_no)) + goto cont; + ut_ad(!lock->is_insert_intention() || lock->is_gap() + || is_supremum); + if (bypass_mode && lock_rec_can_be_bypassing(trx, lock)) + { + has_s_lock_or_stronger= true; } + /* There can be several locks suited for bypassing, + skip them all, the below condition is optimization of + lock->is_waiting() + && (!bypass_mode || !lock->can_be_bypassed( + has_s_lock_or_stronger)) + so we don't have to check lock's 'waiting' flag twice.*/ + else if (lock->is_waiting() + && (!bypass_mode || !has_s_lock_or_stronger + || !lock->is_gap())) + goto create; +cont: if (!(lock = lock_rec_get_next_on_page(lock))) { break; } } + const lock_t *bypassed = c_lock_info.insert_after + ? lock_rec_get_next(heap_no, c_lock_info.insert_after) + : nullptr; + ut_ad(bypassed == c_lock_info.bypassed); /* Look for a similar record lock on the same page: if one is found and there are no waiting lock requests, we can just set the bit */ if (lock_t* lock = lock_rec_find_similar_on_page( - type_mode, heap_no, first_lock, trx)) { + type_mode, heap_no, first_lock, + bypassed, trx)) { trx_t* lock_trx = lock->trx; if (caller_owns_trx_mutex) { trx->mutex_unlock(); @@ -1663,6 +1819,7 @@ static void lock_rec_add_to_queue(unsigned type_mode, const hash_cell_t &cell, if (caller_owns_trx_mutex) { trx->mutex_lock(); } + ut_d(lock_rec_queue_validate_bypass(lock)); return; } } @@ -1672,9 +1829,9 @@ create: because we should be moving an existing waiting lock request. */ ut_ad(!(type_mode & LOCK_WAIT) || trx->lock.wait_trx); - lock_rec_create_low(nullptr, - type_mode, id, page, heap_no, index, trx, - caller_owns_trx_mutex); + lock_rec_create(c_lock_info, + type_mode, id, page, heap_no, index, trx, + caller_owns_trx_mutex); } /** A helper function for lock_rec_lock_slow(), which grants a Next Key Lock @@ -1713,12 +1870,13 @@ static void lock_reuse_for_next_key_lock(const lock_t *held_lock, that GAP Locks do not conflict with anything. Therefore a GAP Lock could be granted to us right now if we've requested: */ mode|= LOCK_GAP; - ut_ad(nullptr == - lock_rec_other_has_conflicting(mode, cell, id, heap_no, trx)); + ut_ad(nullptr == lock_rec_other_has_conflicting(mode, cell, id, heap_no, trx) + .conflicting); /* It might be the case we already have one, so we first check that. */ if (lock_rec_has_expl(mode, cell, id, heap_no, trx) == nullptr) - lock_rec_add_to_queue(mode, cell, id, page, heap_no, index, trx, true); + lock_rec_add_to_queue(null_c_lock_info, mode, cell, id, page, heap_no, + index, trx, true); } @@ -1806,21 +1964,26 @@ lock_rec_lock( /* Do nothing if the trx already has a strong enough lock on rec */ if (!held_lock) { - if (lock_t *c_lock= lock_rec_other_has_conflicting(mode, g.cell(), id, - heap_no, trx)) + conflicting_lock_info c_lock_info= + lock_rec_other_has_conflicting(mode, g.cell(), id, heap_no, trx); + if (c_lock_info.conflicting) /* If another transaction has a non-gap conflicting request in the queue, as this transaction does not have a lock strong enough already granted on the record, we have to wait. */ - err= lock_rec_enqueue_waiting(c_lock, mode, id, block->page.frame, - heap_no, index, thr, nullptr); - else if (!impl) + err= lock_rec_enqueue_waiting(c_lock_info, mode, id, + block->page.frame, heap_no, index, thr, + nullptr); + /* If some lock was bypassed, we need to create explicit lock to avoid + conflicting lock search on every try to convert implicit to explicit + lock. */ + else if (!impl || c_lock_info.insert_after) { /* Set the requested lock on the record. */ - lock_rec_add_to_queue(mode, g.cell(), id, block->page.frame, heap_no, - index, trx, true); + lock_rec_add_to_queue(c_lock_info, mode, g.cell(), id, + block->page.frame, heap_no, index, trx, true); err= DB_SUCCESS_LOCKED_REC; } } @@ -1853,46 +2016,74 @@ lock_rec_lock( /* Simplified and faster path for the most common cases */ if (!impl) - lock_rec_create_low(nullptr, mode, id, block->page.frame, heap_no, index, - trx, false); + lock_rec_create(null_c_lock_info, mode, id, block->page.frame, heap_no, + index, trx, false); return DB_SUCCESS_LOCKED_REC; } -/*********************************************************************//** -Checks if a waiting record lock request still has to wait in a queue. -@return lock that is causing the wait */ -static -const lock_t* +/** Checks if a waiting record lock request still has to wait in a queue. +@param cell record locks hash table cell for waiting lock +@param wait_lock waiting lock +@return lock that is causing the wait, lock after which new lock should be +inserted in lock queue in the case when the lock that is causing the wait must +be bypassed and bypassed lock itself */ +static conflicting_lock_info lock_rec_has_to_wait_in_queue(const hash_cell_t &cell, const lock_t *wait_lock) { - const lock_t* lock; - ulint heap_no; - ulint bit_mask; - ulint bit_offset; + const lock_t *lock; + ulint heap_no; + ulint bit_mask; + ulint bit_offset; - ut_ad(wait_lock->is_waiting()); - ut_ad(!wait_lock->is_table()); + ut_ad(wait_lock->is_waiting()); + ut_ad(!wait_lock->is_table()); - heap_no = lock_rec_find_set_bit(wait_lock); + heap_no= lock_rec_find_set_bit(wait_lock); + const bool is_supremum= (heap_no == PAGE_HEAP_NO_SUPREMUM); + ut_ad(!(wait_lock->is_insert_intention()) || + (wait_lock->is_gap()) || is_supremum); + const bool bypass_mode= + !is_supremum && wait_lock->is_rec_exclusive_not_gap(); + bool has_s_lock_or_stronger= false; + const lock_t *insert_after= nullptr; + ut_d(const lock_t *bypassed= nullptr); - bit_offset = heap_no / 8; - bit_mask = static_cast(1) << (heap_no % 8); + bit_offset= heap_no / 8; + bit_mask= static_cast(1) << (heap_no % 8); - for (lock = lock_sys_t::get_first( - cell, wait_lock->un_member.rec_lock.page_id); - lock != wait_lock; - lock = lock_rec_get_next_on_page_const(lock)) { - const byte* p = (const byte*) &lock[1]; - - if (heap_no < lock_rec_get_n_bits(lock) - && (p[bit_offset] & bit_mask) - && lock_has_to_wait(wait_lock, lock)) { - return(lock); - } - } - - return(NULL); + const trx_t *trx= wait_lock->trx; + const lock_t *prev_lock= nullptr; + /* We can't use lock_sys_t::get_first(cell, id, heap_no) here as in + lock_rec_other_has_conflicting() because we iterate locks only till + wait_lock */ + for (lock= + lock_sys_t::get_first(cell, wait_lock->un_member.rec_lock.page_id); + lock != wait_lock; lock= lock_rec_get_next_on_page_const(lock)) + { + const byte *p= (const byte *) &lock[1]; + if (heap_no >= lock_rec_get_n_bits(lock) || !(p[bit_offset] & bit_mask)) + continue; + if (bypass_mode && lock_rec_can_be_bypassing(trx, lock)) + { + has_s_lock_or_stronger= true; + } + else if (lock_has_to_wait(wait_lock, lock)) + { + if (!bypass_mode || !lock->can_be_bypassed(has_s_lock_or_stronger)) + return {lock, nullptr, ut_d(nullptr)}; + /* Store only the first lock to bypass. */ + ut_d(if (!bypassed) + bypassed= lock;) + /* There can be several locks to bypass, insert bypassing lock just + before the first bypassed lock. */ + if (!insert_after) + insert_after= prev_lock; + continue; + } + prev_lock= lock; + } + return {nullptr, const_cast(insert_after), ut_d(bypassed)}; } /** Note that a record lock wait started */ @@ -2375,13 +2566,15 @@ static void lock_rec_dequeue_from_page(lock_t *in_lock, bool owns_wait_mutex) grant locks if there are no conflicting locks ahead. Stop at the first X lock that is waiting or has been granted. */ - for (lock_t* lock = lock_sys_t::get_first(cell, page_id); - lock != NULL; - lock = lock_rec_get_next_on_page(lock)) { - - if (!lock->is_waiting()) { + for (lock_t* lock = lock_sys_t::get_first(cell, page_id), *next; + lock != NULL; lock= next) { + /* Store pointer to the next element, because if some lock is + bypassed, the pointer to the next lock in the current lock + object will be changed, as the current lock will change + its position in lock queue. */ + next= lock_rec_get_next_on_page(lock); + if (!lock->is_waiting()) continue; - } if (!owns_wait_mutex) { mysql_mutex_lock(&lock_sys.wait_mutex); @@ -2390,10 +2583,10 @@ static void lock_rec_dequeue_from_page(lock_t *in_lock, bool owns_wait_mutex) ut_ad(lock->trx->lock.wait_trx); ut_ad(lock->trx->lock.wait_lock); - - if (const lock_t* c = lock_rec_has_to_wait_in_queue( - cell, lock)) { - trx_t* c_trx = c->trx; + conflicting_lock_info c_lock_info= + lock_rec_has_to_wait_in_queue(cell, lock); + if (c_lock_info.conflicting) { + trx_t* c_trx = c_lock_info.conflicting->trx; lock->trx->lock.wait_trx = c_trx; if (c_trx->lock.wait_trx && innodb_deadlock_detect @@ -2401,6 +2594,12 @@ static void lock_rec_dequeue_from_page(lock_t *in_lock, bool owns_wait_mutex) Deadlock::to_be_checked = true; } } else { + if (UNIV_UNLIKELY(c_lock_info.insert_after != nullptr)) + { + cell.remove(*lock, &lock_t::hash); + cell.insert_after(*c_lock_info.insert_after, + *lock, &lock_t::hash); + } /* Grant the lock */ ut_ad(lock->trx != in_lock->trx); lock_grant(lock); @@ -2551,9 +2750,9 @@ lock_rec_inherit_to_gap(hash_cell_t &heir_cell, const page_id_t heir, ((!from_split || !lock->is_record_not_gap()) && lock->mode() != (lock_trx->duplicates ? LOCK_S : LOCK_X)))) { - lock_rec_add_to_queue(LOCK_GAP | lock->mode(), heir_cell, heir, - heir_page, heir_heap_no, lock->index, lock_trx, - false); + lock_rec_add_to_queue(null_c_lock_info, LOCK_GAP | lock->mode(), + heir_cell, heir, heir_page, heir_heap_no, + lock->index, lock_trx, false); } } } @@ -2583,7 +2782,7 @@ lock_rec_inherit_to_gap_if_gap_lock( !lock->is_insert_intention() && (heap_no == PAGE_HEAP_NO_SUPREMUM || !lock->is_record_not_gap()) && !lock_table_has(lock->trx, lock->index->table, LOCK_X)) - lock_rec_add_to_queue(LOCK_GAP | lock->mode(), + lock_rec_add_to_queue(null_c_lock_info, LOCK_GAP | lock->mode(), g.cell(), id, block->page.frame, heir_heap_no, lock->index, lock->trx, false); } @@ -2629,15 +2828,19 @@ lock_rec_move( /* Note that we FIRST reset the bit, and then set the lock: the function works also if donator_id == receiver_id */ - lock_rec_add_to_queue(type_mode, receiver_cell, - receiver_id, receiver.page.frame, - receiver_heap_no, + lock_rec_add_to_queue(null_c_lock_info, type_mode, + receiver_cell, receiver_id, + receiver.page.frame, receiver_heap_no, lock->index, lock_trx, true); lock_trx->mutex_unlock(); } ut_ad(!lock_sys_t::get_first(donator_cell, donator_id, donator_heap_no)); + ut_d(lock_rec_queue_validate_bypass(lock_sys_t::get_first( + receiver_cell, + receiver_id, receiver_heap_no), + receiver_heap_no)); } /** Move all the granted locks to the front of the given lock list. @@ -2796,8 +2999,9 @@ lock_move_reorganize_page( /* NOTE that the old lock bitmap could be too small for the new heap number! */ - lock_rec_add_to_queue(lock->type_mode, cell, id, block->page.frame, - new_heap_no, lock->index, lock_trx, true); + lock_rec_add_to_queue(null_c_lock_info, lock->type_mode, cell, id, + block->page.frame, new_heap_no, lock->index, + lock_trx, true); } lock_trx->mutex_unlock(); @@ -2939,9 +3143,9 @@ lock_move_rec_list_end( lock->type_mode&= ~LOCK_WAIT; } - lock_rec_add_to_queue(type_mode, g.cell2(), new_id, - new_page, - rec2_heap_no, lock->index, lock_trx, true); + lock_rec_add_to_queue(null_c_lock_info, type_mode, g.cell2(), new_id, + new_page, rec2_heap_no, lock->index, lock_trx, + true); } lock_trx->mutex_unlock(); @@ -3062,7 +3266,7 @@ lock_move_rec_list_start( lock->type_mode&= ~LOCK_WAIT; } - lock_rec_add_to_queue(type_mode, g.cell2(), new_id, + lock_rec_add_to_queue(null_c_lock_info, type_mode, g.cell2(), new_id, new_block->page.frame, rec2_heap_no, lock->index, lock_trx, true); } @@ -3156,7 +3360,7 @@ lock_rtr_move_rec_list( lock->type_mode&= ~LOCK_WAIT; } - lock_rec_add_to_queue(type_mode, g.cell2(), new_id, + lock_rec_add_to_queue(null_c_lock_info, type_mode, g.cell2(), new_id, new_block->page.frame, rec2_heap_no, lock->index, lock_trx, true); @@ -4253,19 +4457,30 @@ static void lock_rec_rebuild_waiting_queue( { lock_sys.assert_locked(cell); - for (lock_t *lock= first_lock; lock != NULL; - lock= lock_rec_get_next(heap_no, lock)) + for (lock_t *lock= first_lock, *next; lock != NULL; lock= next) { + /* Store pointer to the next element, because if some lock is + bypassed, the pointer to the next lock in the current lock + object will be changed, as the current lock will change + its position in lock queue. */ + next= lock_rec_get_next(heap_no, lock); if (!lock->is_waiting()) continue; mysql_mutex_lock(&lock_sys.wait_mutex); ut_ad(lock->trx->lock.wait_trx); ut_ad(lock->trx->lock.wait_lock); - if (const lock_t *c= lock_rec_has_to_wait_in_queue(cell, lock)) - lock->trx->lock.wait_trx= c->trx; + conflicting_lock_info c_lock_info= + lock_rec_has_to_wait_in_queue(cell, lock); + if (c_lock_info.conflicting) + lock->trx->lock.wait_trx= c_lock_info.conflicting->trx; else { + if (c_lock_info.insert_after) + { + cell.remove(*lock, &lock_t::hash); + cell.insert_after(*c_lock_info.insert_after, *lock, &lock_t::hash); + } /* Grant the lock */ ut_ad(trx != lock->trx); lock_grant(lock); @@ -4696,8 +4911,10 @@ reiterate: { ut_ad(!lock->index->table->is_temporary()); bool supremum_bit= lock_rec_get_nth_bit(lock, PAGE_HEAP_NO_SUPREMUM); + /* if XA is being prepared, it must not own waiting locks */ + ut_ad(!lock->is_waiting()); bool rec_granted_exclusive_not_gap= - lock->is_rec_granted_exclusive_not_gap(); + lock->is_rec_exclusive_not_gap(); if (UNIV_UNLIKELY(lock->type_mode & (LOCK_PREDICATE | LOCK_PRDT_PAGE))) continue; /* SPATIAL INDEX locking is broken. */ const auto fold = lock->un_member.rec_lock.page_id.fold(); @@ -4870,7 +5087,9 @@ reiterate: if (!lock->is_table()) { ut_ad(!lock->index->table->is_temporary()); - if (!lock->is_rec_granted_exclusive_not_gap()) + /* if XA is being prepared, it must not own waiting locks */ + ut_ad(!lock->is_waiting()); + if (!lock->is_rec_exclusive_not_gap()) lock_rec_dequeue_from_page(lock, false); else if (UNIV_UNLIKELY(lock->type_mode & (LOCK_PREDICATE | LOCK_PRDT_PAGE))) @@ -5432,7 +5651,8 @@ lock_rec_queue_validate( ut_ad(trx_state_eq(lock->trx, TRX_STATE_COMMITTED_IN_MEMORY) || !lock->is_waiting() - || lock_rec_has_to_wait_in_queue(cell, lock)); + || lock_rec_has_to_wait_in_queue(cell, lock). + conflicting); lock->trx->mutex_unlock(); } @@ -5524,7 +5744,8 @@ func_exit: if (lock->is_waiting()) { ut_a(lock->is_gap() - || lock_rec_has_to_wait_in_queue(cell, lock)); + || lock_rec_has_to_wait_in_queue(cell, lock). + conflicting); } else if (!lock->is_gap()) { const lock_mode mode = lock->mode() == LOCK_S ? LOCK_X : LOCK_S; @@ -5830,13 +6051,16 @@ lock_rec_insert_check_and_lock( on the successor, which produced an unnecessary deadlock. */ const unsigned type_mode= LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION; - if (lock_t *c_lock= lock_rec_other_has_conflicting(type_mode, - g.cell(), id, - heap_no, trx)) + conflicting_lock_info c_lock_info= lock_rec_other_has_conflicting( + type_mode, g.cell(), id, heap_no, trx); + /* Insert intention locks must not bypass any other lock. */ + ut_ad(!c_lock_info.insert_after && !c_lock_info.bypassed); + if (c_lock_info.conflicting) { trx->mutex_lock(); - err= lock_rec_enqueue_waiting(c_lock, type_mode, id, block->page.frame, - heap_no, index, thr, nullptr); + err= lock_rec_enqueue_waiting(c_lock_info, type_mode, id, + block->page.frame, heap_no, index, thr, + nullptr); trx->mutex_unlock(); } } @@ -5905,8 +6129,9 @@ static trx_t *lock_rec_convert_impl_to_expl_for_trx(trx_t *trx, if (!trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY) && !lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, g.cell(), id, heap_no, trx)) - lock_rec_add_to_queue(LOCK_X | LOCK_REC_NOT_GAP, g.cell(), id, - page_align(rec), heap_no, index, trx, true); + lock_rec_add_to_queue(null_c_lock_info, LOCK_X | LOCK_REC_NOT_GAP, + g.cell(), id, page_align(rec), heap_no, index, + trx, true); } trx->release_reference(); diff --git a/storage/innobase/lock/lock0prdt.cc b/storage/innobase/lock/lock0prdt.cc index 3ea05ddb741..12b2a990f8c 100644 --- a/storage/innobase/lock/lock0prdt.cc +++ b/storage/innobase/lock/lock0prdt.cc @@ -470,8 +470,9 @@ create: because we should be moving an existing waiting lock request. */ ut_ad(!(type_mode & LOCK_WAIT) || trx->lock.wait_trx); - lock_t* lock = lock_rec_create(nullptr, - type_mode, block, PRDT_HEAPNO, index, + lock_t* lock = lock_rec_create(null_c_lock_info, + type_mode, block->page.id(), + block->page.frame, PRDT_HEAPNO, index, trx, caller_owns_trx_mutex); if (lock->type_mode & LOCK_PREDICATE) { @@ -533,8 +534,9 @@ lock_prdt_insert_check_and_lock( trx->mutex_lock(); /* Allocate MBR on the lock heap */ lock_init_prdt_from_mbr(prdt, mbr, 0, trx->lock.lock_heap); - err= lock_rec_enqueue_waiting(c_lock, mode, id, block->page.frame, - PRDT_HEAPNO, index, thr, prdt); + err= lock_rec_enqueue_waiting({c_lock, nullptr, ut_d(nullptr)}, mode, id, + block->page.frame, PRDT_HEAPNO, index, + thr, prdt); trx->mutex_unlock(); } } @@ -734,10 +736,10 @@ lock_prdt_lock( lock_t* lock = lock_sys_t::get_first(g.cell(), id); if (lock == NULL) { - lock = lock_rec_create( - NULL, - prdt_mode, block, PRDT_HEAPNO, - index, trx, FALSE); + lock = lock_rec_create(null_c_lock_info, + prdt_mode, block->page.id(), + block->page.frame, PRDT_HEAPNO, index, + trx, FALSE); status = LOCK_REC_SUCCESS_CREATED; } else { @@ -759,7 +761,8 @@ lock_prdt_lock( prdt_mode, g.cell(), id, prdt, trx)) { err = lock_rec_enqueue_waiting( - wait_for, prdt_mode, id, + {wait_for, nullptr, ut_d(nullptr)}, + prdt_mode, id, block->page.frame, PRDT_HEAPNO, index, thr, prdt); } else { @@ -826,10 +829,9 @@ lock_place_prdt_page_lock( } if (lock == NULL) { - lock = lock_rec_create_low( - NULL, - mode, page_id, NULL, PRDT_HEAPNO, - index, trx, FALSE); + lock = lock_rec_create(null_c_lock_info, + mode, page_id, NULL, PRDT_HEAPNO, + index, trx, FALSE); #ifdef PRDT_DIAG printf("GIS_DIAGNOSTIC: page lock %d\n", (int) page_no); From 77ea99a4b5f0b275e1531419ef134da6237cb95a Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Thu, 23 Jan 2025 13:48:00 -0800 Subject: [PATCH 132/213] MDEV-35869 Wrong result using degenerated subquery with window function This bug affected queries containing degenerated single-value subqueries with window functions. The bug led mostly to wrong results for such queries. A subquery is called degenerated if it is of the form (SELECT ...). For degenerated subqueries of the form (SELECT ) the transformation (SELECT ) => usually is applied. However if contains set functions or window functions such rewriting is not valid for an obvious reason. The code before this patch erroneously applied the transformation when contained window functions and did not contain set functions. Approved by Rex Johnston --- mysql-test/main/win.result | 23 +++++++++++++++++++ mysql-test/main/win.test | 12 ++++++++++ .../encryption/r/tempfiles_encrypted.result | 23 +++++++++++++++++++ sql/item_subselect.cc | 1 + 4 files changed, 59 insertions(+) diff --git a/mysql-test/main/win.result b/mysql-test/main/win.result index f3b719d0a18..76d89340679 100644 --- a/mysql-test/main/win.result +++ b/mysql-test/main/win.result @@ -4601,4 +4601,27 @@ w2_total w1_total u 200 200 2 DROP VIEW v1; DROP TABLE t1; +# +# MDEV-35869: degenerated subquery with window function +# +CREATE TABLE t1 (a int DEFAULT 10); +INSERT INTO t1 VALUES (7), (2), (3); +SELECT * FROM t1 WHERE (SELECT AVG(3)) > 2; +a +7 +2 +3 +SELECT * FROM t1 WHERE (SELECT AVG(3) OVER ()) > 2; +a +7 +2 +3 +INSERT INTO t1 VALUES((SELECT avg(4) OVER ())); +SELECT * FROM t1; +a +7 +2 +3 +4 +DROP TABLE t1; # End of 10.5 tests diff --git a/mysql-test/main/win.test b/mysql-test/main/win.test index 5722cedab81..e80b55da089 100644 --- a/mysql-test/main/win.test +++ b/mysql-test/main/win.test @@ -3001,4 +3001,16 @@ eval $q3; DROP VIEW v1; DROP TABLE t1; +--echo # +--echo # MDEV-35869: degenerated subquery with window function +--echo # + +CREATE TABLE t1 (a int DEFAULT 10); +INSERT INTO t1 VALUES (7), (2), (3); +SELECT * FROM t1 WHERE (SELECT AVG(3)) > 2; +SELECT * FROM t1 WHERE (SELECT AVG(3) OVER ()) > 2; +INSERT INTO t1 VALUES((SELECT avg(4) OVER ())); +SELECT * FROM t1; +DROP TABLE t1; + --echo # End of 10.5 tests diff --git a/mysql-test/suite/encryption/r/tempfiles_encrypted.result b/mysql-test/suite/encryption/r/tempfiles_encrypted.result index e233c8fa3ef..aa66f01bc1e 100644 --- a/mysql-test/suite/encryption/r/tempfiles_encrypted.result +++ b/mysql-test/suite/encryption/r/tempfiles_encrypted.result @@ -4607,6 +4607,29 @@ w2_total w1_total u 200 200 2 DROP VIEW v1; DROP TABLE t1; +# +# MDEV-35869: degenerated subquery with window function +# +CREATE TABLE t1 (a int DEFAULT 10); +INSERT INTO t1 VALUES (7), (2), (3); +SELECT * FROM t1 WHERE (SELECT AVG(3)) > 2; +a +7 +2 +3 +SELECT * FROM t1 WHERE (SELECT AVG(3) OVER ()) > 2; +a +7 +2 +3 +INSERT INTO t1 VALUES((SELECT avg(4) OVER ())); +SELECT * FROM t1; +a +7 +2 +3 +4 +DROP TABLE t1; # End of 10.5 tests # # MDEV-23867: select crash in compute_window_func diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 8da808ca3a0..05e98071947 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1215,6 +1215,7 @@ Item_singlerow_subselect::select_transformer(JOIN *join) !select_lex->table_list.elements && select_lex->item_list.elements == 1 && !select_lex->item_list.head()->with_sum_func() && + !select_lex->item_list.head()->with_window_func && /* We can't change name of Item_field or Item_ref, because it will prevent its correct resolving, but we should save name of From d261fa5c70372bcee79bbb57cfeab0de13265e44 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 8 Nov 2024 13:51:34 +0400 Subject: [PATCH 133/213] MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify Also fixes: MDEV-32190 Index corruption with unique key and nopad collation (without DESC or HASH keys) MDEV-28328 Assertion failures in btr0cur.cc upon INSERT or in row0sel.cc afterwards The code in strings/strcoll.inl when comparing an empty string to a string like 0x0001050001 did not take into account that the leftmost weight in the latter can be zero, while there are some more weights can follow the zero weight. Rewriting the code to treat the shorter string as smaller than a longer string. --- mysql-test/main/ctype_big5.result | 9 +++ mysql-test/main/ctype_big5.test | 7 +++ mysql-test/main/ctype_cp932.result | 9 +++ mysql-test/main/ctype_cp932.test | 7 +++ mysql-test/main/ctype_eucjpms.result | 9 +++ mysql-test/main/ctype_eucjpms.test | 7 +++ mysql-test/main/ctype_euckr.result | 9 +++ mysql-test/main/ctype_euckr.test | 7 +++ mysql-test/main/ctype_gb2312.result | 9 +++ mysql-test/main/ctype_gb2312.test | 7 +++ mysql-test/main/ctype_gbk.result | 9 +++ mysql-test/main/ctype_gbk.test | 7 +++ mysql-test/main/ctype_sjis.result | 9 +++ mysql-test/main/ctype_sjis.test | 7 +++ mysql-test/main/ctype_sjis_innodb.result | 23 ++++++++ mysql-test/main/ctype_sjis_innodb.test | 62 +++++++++++++++++++++ mysql-test/main/ctype_ucs.result | 9 +++ mysql-test/main/ctype_ucs.test | 7 +++ mysql-test/main/ctype_ujis.result | 15 +++++ mysql-test/main/ctype_ujis.test | 15 +++++ mysql-test/main/ctype_utf8.result | 9 +++ mysql-test/main/ctype_utf8.test | 6 ++ mysql-test/main/ctype_utf8mb3_innodb.result | 39 +++++++++++++ mysql-test/main/ctype_utf8mb3_innodb.test | 39 +++++++++++++ strings/strcoll.inl | 6 +- 25 files changed, 340 insertions(+), 2 deletions(-) create mode 100644 mysql-test/main/ctype_sjis_innodb.result create mode 100644 mysql-test/main/ctype_sjis_innodb.test create mode 100644 mysql-test/main/ctype_utf8mb3_innodb.result create mode 100644 mysql-test/main/ctype_utf8mb3_innodb.test diff --git a/mysql-test/main/ctype_big5.result b/mysql-test/main/ctype_big5.result index a89f8a75dc0..c26758e2063 100644 --- a/mysql-test/main/ctype_big5.result +++ b/mysql-test/main/ctype_big5.result @@ -5445,5 +5445,14 @@ EXECUTE IMMEDIATE CONCAT('a.', @seq, ':=1'); ERROR HY000: Invalid big5 character string: '\xA3\xC0' SET sql_mode=DEFAULT; # +# MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify +# +select strcmp(_big5'' collate big5_chinese_nopad_ci, _big5 0x0001050001) as c1; +c1 +-1 +select strcmp(_big5'' collate big5_nopad_bin, _big5 0x0001050001) as c1; +c1 +-1 +# # End of 10.5 tests # diff --git a/mysql-test/main/ctype_big5.test b/mysql-test/main/ctype_big5.test index 4b6203a2577..917a3c02a1a 100644 --- a/mysql-test/main/ctype_big5.test +++ b/mysql-test/main/ctype_big5.test @@ -290,6 +290,13 @@ SET NAMES big5; SET @seq=_big5 0xA3C0; --source include/ctype_ident_sys.inc +--echo # +--echo # MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify +--echo # + +select strcmp(_big5'' collate big5_chinese_nopad_ci, _big5 0x0001050001) as c1; +select strcmp(_big5'' collate big5_nopad_bin, _big5 0x0001050001) as c1; + --echo # --echo # End of 10.5 tests --echo # diff --git a/mysql-test/main/ctype_cp932.result b/mysql-test/main/ctype_cp932.result index ed222c997da..4b6eda1bc86 100644 --- a/mysql-test/main/ctype_cp932.result +++ b/mysql-test/main/ctype_cp932.result @@ -653,5 +653,14 @@ EXECUTE IMMEDIATE CONCAT('a.', @seq, ':=1'); ERROR HY000: Invalid cp932 character string: '\x81' SET sql_mode=DEFAULT; # +# MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify +# +select strcmp(_cp932'' collate cp932_japanese_nopad_ci, _cp932 0x0001050001) as c1; +c1 +-1 +select strcmp(_cp932'' collate cp932_nopad_bin, _cp932 0x0001050001) as c1; +c1 +-1 +# # End of 10.5 tests # diff --git a/mysql-test/main/ctype_cp932.test b/mysql-test/main/ctype_cp932.test index 0f5ff437d33..b4e33f517ca 100644 --- a/mysql-test/main/ctype_cp932.test +++ b/mysql-test/main/ctype_cp932.test @@ -61,6 +61,13 @@ SET NAMES cp932; SET @seq=_cp932 0x81AD; --source include/ctype_ident_sys.inc +--echo # +--echo # MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify +--echo # + +select strcmp(_cp932'' collate cp932_japanese_nopad_ci, _cp932 0x0001050001) as c1; +select strcmp(_cp932'' collate cp932_nopad_bin, _cp932 0x0001050001) as c1; + --echo # --echo # End of 10.5 tests --echo # diff --git a/mysql-test/main/ctype_eucjpms.result b/mysql-test/main/ctype_eucjpms.result index b886e340671..5f81ec1a76b 100644 --- a/mysql-test/main/ctype_eucjpms.result +++ b/mysql-test/main/ctype_eucjpms.result @@ -34547,5 +34547,14 @@ EXECUTE IMMEDIATE CONCAT('a.', @seq, ':=1'); ERROR HY000: Invalid eucjpms character string: '\x8F\xA1\xA1' SET sql_mode=DEFAULT; # +# MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify +# +select strcmp(_eucjpms'' collate eucjpms_japanese_nopad_ci, _eucjpms 0x0001050001) as c1; +c1 +-1 +select strcmp(_eucjpms'' collate eucjpms_nopad_bin, _eucjpms 0x0001050001) as c1; +c1 +-1 +# # End of 10.5 tests # diff --git a/mysql-test/main/ctype_eucjpms.test b/mysql-test/main/ctype_eucjpms.test index 0d002f769a8..aebb9e10930 100644 --- a/mysql-test/main/ctype_eucjpms.test +++ b/mysql-test/main/ctype_eucjpms.test @@ -612,6 +612,13 @@ SET NAMES eucjpms; SET @seq=_eucjpms 0x8FA1A1; --source include/ctype_ident_sys.inc +--echo # +--echo # MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify +--echo # + +select strcmp(_eucjpms'' collate eucjpms_japanese_nopad_ci, _eucjpms 0x0001050001) as c1; +select strcmp(_eucjpms'' collate eucjpms_nopad_bin, _eucjpms 0x0001050001) as c1; + --echo # --echo # End of 10.5 tests --echo # diff --git a/mysql-test/main/ctype_euckr.result b/mysql-test/main/ctype_euckr.result index e7f02603786..cd72ffbab7c 100644 --- a/mysql-test/main/ctype_euckr.result +++ b/mysql-test/main/ctype_euckr.result @@ -26065,5 +26065,14 @@ EXECUTE IMMEDIATE CONCAT('a.', @seq, ':=1'); ERROR HY000: Invalid euckr character string: '\xA2\xE8' SET sql_mode=DEFAULT; # +# MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify +# +select strcmp(_euckr'' collate euckr_korean_nopad_ci, _euckr 0x0001050001) as c1; +c1 +-1 +select strcmp(_euckr'' collate euckr_nopad_bin, _euckr 0x0001050001) as c1; +c1 +-1 +# # End of 10.5 tests # diff --git a/mysql-test/main/ctype_euckr.test b/mysql-test/main/ctype_euckr.test index 1154047fdb0..2196c5d3717 100644 --- a/mysql-test/main/ctype_euckr.test +++ b/mysql-test/main/ctype_euckr.test @@ -241,6 +241,13 @@ SET NAMES euckr; SET @seq=_euckr 0xA2E8; --source include/ctype_ident_sys.inc +--echo # +--echo # MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify +--echo # + +select strcmp(_euckr'' collate euckr_korean_nopad_ci, _euckr 0x0001050001) as c1; +select strcmp(_euckr'' collate euckr_nopad_bin, _euckr 0x0001050001) as c1; + --echo # --echo # End of 10.5 tests --echo # diff --git a/mysql-test/main/ctype_gb2312.result b/mysql-test/main/ctype_gb2312.result index f0bbb48621d..136471d4f25 100644 --- a/mysql-test/main/ctype_gb2312.result +++ b/mysql-test/main/ctype_gb2312.result @@ -5135,5 +5135,14 @@ EXECUTE IMMEDIATE CONCAT('a.', @seq, ':=1'); ERROR HY000: Invalid gb2312 character string: '\xA2\xA1' SET sql_mode=DEFAULT; # +# MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify +# +select strcmp(_gb2312'' collate gb2312_chinese_nopad_ci, _gb2312 0x0001050001) as c1; +c1 +-1 +select strcmp(_gb2312'' collate gb2312_nopad_bin, _gb2312 0x0001050001) as c1; +c1 +-1 +# # End of 10.5 tests # diff --git a/mysql-test/main/ctype_gb2312.test b/mysql-test/main/ctype_gb2312.test index b9147fdc420..15b69e00ea2 100644 --- a/mysql-test/main/ctype_gb2312.test +++ b/mysql-test/main/ctype_gb2312.test @@ -199,6 +199,13 @@ SET NAMES gb2312; SET @seq=_gb2312 0xA2A1; --source include/ctype_ident_sys.inc +--echo # +--echo # MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify +--echo # + +select strcmp(_gb2312'' collate gb2312_chinese_nopad_ci, _gb2312 0x0001050001) as c1; +select strcmp(_gb2312'' collate gb2312_nopad_bin, _gb2312 0x0001050001) as c1; + --echo # --echo # End of 10.5 tests --echo # diff --git a/mysql-test/main/ctype_gbk.result b/mysql-test/main/ctype_gbk.result index cbf396e69ba..a1610969d73 100644 --- a/mysql-test/main/ctype_gbk.result +++ b/mysql-test/main/ctype_gbk.result @@ -6603,5 +6603,14 @@ EXECUTE IMMEDIATE CONCAT('a.', @seq, ':=1'); ERROR HY000: Invalid gbk character string: '\xAA\xA1' SET sql_mode=DEFAULT; # +# MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify +# +select strcmp(_gbk'' collate gbk_chinese_nopad_ci, _gbk 0x0001050001); +strcmp(_gbk'' collate gbk_chinese_nopad_ci, _gbk 0x0001050001) +-1 +select strcmp(_gbk'' collate gbk_nopad_bin, _gbk 0x0001050001); +strcmp(_gbk'' collate gbk_nopad_bin, _gbk 0x0001050001) +-1 +# # End of 10.5 tests # diff --git a/mysql-test/main/ctype_gbk.test b/mysql-test/main/ctype_gbk.test index 9f6f6672952..8043e233e07 100644 --- a/mysql-test/main/ctype_gbk.test +++ b/mysql-test/main/ctype_gbk.test @@ -500,6 +500,13 @@ SET NAMES gbk; SET @seq=_gbk 0xAAA1; --source include/ctype_ident_sys.inc +--echo # +--echo # MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify +--echo # + +select strcmp(_gbk'' collate gbk_chinese_nopad_ci, _gbk 0x0001050001); +select strcmp(_gbk'' collate gbk_nopad_bin, _gbk 0x0001050001); + --echo # --echo # End of 10.5 tests --echo # diff --git a/mysql-test/main/ctype_sjis.result b/mysql-test/main/ctype_sjis.result index f93a0b8be60..e6797950403 100644 --- a/mysql-test/main/ctype_sjis.result +++ b/mysql-test/main/ctype_sjis.result @@ -19389,5 +19389,14 @@ EXECUTE IMMEDIATE CONCAT('a.', @seq, ':=1'); ERROR HY000: Invalid sjis character string: '_x81' SET sql_mode=DEFAULT; # +# MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify +# +select strcmp(_sjis'' collate sjis_japanese_nopad_ci, _sjis 0x0001050001) as c1; +c1 +-1 +select strcmp(_sjis'' collate sjis_nopad_bin, _sjis 0x0001050001) as c1; +c1 +-1 +# # End of 10.5 tests # diff --git a/mysql-test/main/ctype_sjis.test b/mysql-test/main/ctype_sjis.test index 951571ef523..83e12c85bda 100644 --- a/mysql-test/main/ctype_sjis.test +++ b/mysql-test/main/ctype_sjis.test @@ -328,6 +328,13 @@ SET NAMES sjis; SET @seq=_sjis 0x81AD; --source include/ctype_ident_sys.inc +--echo # +--echo # MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify +--echo # + +select strcmp(_sjis'' collate sjis_japanese_nopad_ci, _sjis 0x0001050001) as c1; +select strcmp(_sjis'' collate sjis_nopad_bin, _sjis 0x0001050001) as c1; + --echo # --echo # End of 10.5 tests --echo # diff --git a/mysql-test/main/ctype_sjis_innodb.result b/mysql-test/main/ctype_sjis_innodb.result new file mode 100644 index 00000000000..6252848c8bb --- /dev/null +++ b/mysql-test/main/ctype_sjis_innodb.result @@ -0,0 +1,23 @@ +# Start of 10.5 tests +# +# MDEV-28328 Assertion failures in btr0cur.cc upon INSERT or in row0sel.cc afterwards +# +SET NAMES utf8mb3; +CREATE TABLE t ( +a year(4) DEFAULT NULL, +b varbinary(2545) DEFAULT '', +c mediumtext COLLATE sjis_japanese_nopad_ci NOT NULL, +d decimal(7,7) DEFAULT NULL, +e char(219) COLLATE sjis_japanese_nopad_ci DEFAULT '', +f bigint(25) DEFAULT 0, +g bigint(20) DEFAULT NULL, +h datetime(1) DEFAULT '1900-01-01 00:00:00.0', +PRIMARY KEY (c(25),e) +) ENGINE=InnoDB DEFAULT CHARSET=sjis COLLATE=sjis_japanese_nopad_ci; +INSERT IGNORE INTO t VALUES ... a mixture of non-ASCII and binary content +SELECT * FROM t /*output suppressed, just make sure it does not crash*/; +CHECK TABLE t; +Table Op Msg_type Msg_text +test.t check status OK +DROP TABLE t; +# End of 10.5 tests diff --git a/mysql-test/main/ctype_sjis_innodb.test b/mysql-test/main/ctype_sjis_innodb.test new file mode 100644 index 00000000000..80f3b4fec0a --- /dev/null +++ b/mysql-test/main/ctype_sjis_innodb.test @@ -0,0 +1,62 @@ +--source include/have_sjis.inc +--source include/have_innodb.inc + +--echo # Start of 10.5 tests + +--echo # +--echo # MDEV-28328 Assertion failures in btr0cur.cc upon INSERT or in row0sel.cc afterwards +--echo # + +SET NAMES utf8mb3; + +CREATE TABLE t ( + a year(4) DEFAULT NULL, + b varbinary(2545) DEFAULT '', + c mediumtext COLLATE sjis_japanese_nopad_ci NOT NULL, + d decimal(7,7) DEFAULT NULL, + e char(219) COLLATE sjis_japanese_nopad_ci DEFAULT '', + f bigint(25) DEFAULT 0, + g bigint(20) DEFAULT NULL, + h datetime(1) DEFAULT '1900-01-01 00:00:00.0', + PRIMARY KEY (c(25),e) +) ENGINE=InnoDB DEFAULT CHARSET=sjis COLLATE=sjis_japanese_nopad_ci; + +--echo INSERT IGNORE INTO t VALUES ... a mixture of non-ASCII and binary content + +--disable_query_log +INSERT IGNORE INTO t VALUES +(NULL,'tsls','ce License窶? is a trademark of MariaDB Corporation Ab.\n\nParameters\n\nLicensor: MariaDB Corporation Ab\nLicensed Work: MariaDB MaxScale (TM) v.2.3.20\n The Licensed Work is (c) 2020 MariaDB Corporation Ab\nAdditional Use Grant: You may use the Licensed Work when your application\n uses the Licensed Work with a total of less than three\n server instances for any purpose.\n\nChange Date: 2024-06-02\n\nChange License: Version 2 or later of the GNU General Public License as\n published by the Free Software Foundation.\n\nFor information about alternative licensing arrangements for the Software,\nplease visit: https://mariadb.com/products/mariadb-enterprise\n\nNotice\n\nThe Business Source License (this document, or the 窶廰icense窶?) is not an Open\nSource license. However, the Licensed Work will eventually be made available\nunder an Open Source License, as stated in this License.\n\nFor more information on the use of the Business Source License for MariaDB\nproducts, please visit the MariaDB Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-mariadb.\n\nFor more information on the use of the Business Source License generally,\nplease visit the Adopting and Developing Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-adopting.\n\n-----------------------------------------------------------------------------\n\nBusiness Source License 1.1\n\nTerms\n\nThe Licensor hereby grants you the right to copy, modify, create derivative\nworks, redistribute, and make non-production use of the Licensed Work. The\nLicensor may make an Additional Use Grant, above, permitting limited\nproduction use.\n\nEffective on the Change Date, or the fourth anniversary of the first publicly\navailable distribution of a specific version of the Licensed Work under this\nLicense, whichever comes first, the Licensor hereby grants you rights under\nthe terms of the Change License, and the rights granted in the paragraph\nabove terminate.\n\nIf your use of the Licensed Work does not comply with the requirements\ncurrently in effect as described in this License, you must purchase a\ncommercial license from the Licensor, its affiliated entities, or authorized\nresellers, or you must refrain from using the Licensed Work.\n\nAll copies of the original and modified Licensed Work, and derivative works\nof the Licensed Work, are subject to this License. This License applies\nseparately for each version of the Licensed Work and the Change Date may vary\nfor each version of the Licensed Work released by Licensor.\n\nYou must conspicuously display this License on each original or modified copy\nof the Licensed Work. If you receive the Licensed Work in original or\nmodified form from a third party, the terms and conditions set forth in this\nLicense apply to your use of that work.\n\nAny use of the Licensed Work in violation of this License will automatically\nterminate your rights under this License for the current and all other\nversions of the Licensed Work.\n\nThis License does not grant you any right in any trademark or logo of\nLicensor or its affiliates (provged that you may use a trademark or logo of\nLicensor as expressly required by this License).\n\nTO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVgED ON\nAN 窶廣S IS窶? BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\nEXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\nTITLE.\n\nMariaDB hereby grants you permission to use this License窶冱 text to license\nyour works, and to refer to it using the trademark 窶廝usiness Source License窶?,\nas long as you comply with the Covenants of Licensor below.\n\nCovenants of Licensor\n\nIn consgeration of the right to use this License窶冱 text and the 窶廝usiness\nSource License窶? name and trademark, Licensor covenants to MariaDB, and to all\nother recipients of the licensed work to be provged by Licensor:\n\n1. To specify as the Change License the GPL Version 2.0 or any later version,\n or a license that is compatible with GPL Version 2.0 or a later version,\n where 窶彡ompatible窶? means that software provged under the Change License can\n be included in a program with software provged under GPL Version 2.0 or a\n later version. Licensor may specify additional Change Licenses without\n limitation.\n\n2. To either: (a) specify an additional grant of rights to use that does not\n impose any additional restriction on the right granted in this License, as\n the Additional Use Grant; or (b) insert the text 窶廸one窶?.\n\n3. To specify a Change Date.\n\n4. Not to modify this License in any other way.\nLicense text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved.\n窶廝usiness Source License窶? is a trademark of MariaDB Corporation Ab.\n\nParameters\n\nLicensor: MariaDB Corporation Ab\nLicensed Work: MariaDB MaxScale (TM) v.2.3.20\n The Licensed Work is (c) 2020 MariaDB Corporation Ab\nAdditional Use Grant: You may use the Licensed Work when your application\n uses the Licensed Work with a total of less than three\n server instances for any purpose.\n\nChange Date: 2024-06-02\n\nChange License: Version 2 or later of the GNU General Public License as\n published by the Free Software Foundation.\n\nFor information about alternative licensing arrangements for the Software,\nplease visit: https://mariadb.com/products/mariadb-enterprise\n\nNotice\n\nThe Business Source License (this document, or the 窶廰icense窶?) is not an Open\nSource license. However, the Licensed Work will eventually be made available\nunder an Open Source License, as stated in this License.\n\nFor more information on the use of the Business Source License for MariaDB\nproducts, please visit the MariaDB Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-mariadb.\n\nFor more information on the use of the Business Source License generally,\nplease visit the Adopting and Developing Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-adopting.\n\n-----------------------------------------------------------------------------\n\nBusiness Source License 1.1\n\nTerms\n\nThe Licensor hereby grants you the right to copy, modify, create derivative\nworks, redistribute, and make non-production use of the Licensed Work. The\nLicensor may make an Additional Use Grant, above, permitting limited\nproduction use.\n\nEffective on the Change Date, or the fourth anniversary of the first publicly\navailable distribution of a specific version of the Licensed Work under this\nLicense, whichever comes first, the Licensor hereby grants you rights under\nthe terms of the Change License, and the rights granted in the paragraph\nabove terminate.\n\nIf your use of the Licensed Work does not comply with the requirements\ncurrently in effect as described in this License, you must purchase a\ncommercial license from the Licensor, its affiliated entities, or authorized\nresellers, or you must refrain from using the Licensed Work.\n\nAll copies of the original and modified Licensed Work, and derivative works\nof the Licensed Work, are subject to this License. This License applies\nseparately for each version of the Licensed Work and the Change Date may vary\nfor each version of the Licensed Work released by Licensor.\n\nYou must conspicuously display this License on each original or modified copy\nof the Licensed Work. If you receive the Licensed Work in original or\nmodified form from a third party, the terms and conditions set forth in this\nLicense apply to your use of that work.\n\nAny use of the Licensed Work in violation of this License will automatically\nterminate your rights under this License for the current and all other\nversions of the Licensed Work.\n\nThis License does not grant you any right in any trademark or logo of\nLicensor or its affiliates (provged that you may use a trademark or logo of\nLicensor as expressly required by this License).\n\nTO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVgED ON\nAN 窶廣S IS窶? BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\nEXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\nTITLE.\n\nMariaDB hereby grants you permission to use this License窶冱 text to license\nyour works, and to refer to it using the trademark 窶廝usiness Source License窶?,\nas long as you comply with the Covenants of Licensor below.\n\nCovenants of Licensor\n\nIn consgeration of the right to use this License窶冱 text and the 窶廝usiness\nSource License窶? name and trademark, Licensor covenants to MariaDB, and to all\nother recipients of the licensed work to be provged by Licensor:\n\n1. To specify as the Change License the GPL Version 2.0 or any later version,\n or a license that is compatible with GPL Version 2.0 or a later version,\n where 窶彡ompatible窶? means that software provged under the Change License can\n be included in a program with software provged under GPL Version 2.0 or a\n later version. Licensor may specify additional Change Licenses without\n limitation.\n\n2. To either: (a) specify an additional grant of rights to use that does not\n impose any additional restriction on the right granted in this License, as\n the Additional Use Grant; or (b) insert the text 窶廸one窶?.\n\n3. To specify a Change Date.\n\n4. Not to modify this License in any other way.\nLicense text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved.\n窶廝usiness Source License窶? is a trademark of MariaDB Corporation Ab.\n\nParameters\n\nLicensor: MariaDB Corporation Ab\nLicensed Work: MariaDB MaxScale (TM) v.2.3.20\n The Licensed Work is (c) 2020 MariaDB Corporation Ab\nAdditional Use Grant: You may use the Licensed Work when your application\n uses the Licensed Work with a total of less than three\n server instances for any purpose.\n\nChange Date: 2024-06-02\n\nChange License: Version 2 or later of the GNU General Public License as\n published by the Free Software Foundation.\n\nFor information about alternative licensing arrangements for the Software,\nplease visit: https://mariadb.com/products/mariadb-enterprise\n\nNotice\n\nThe Business Source License (this document, or the 窶廰icense窶?) is not an Open\nSource license. However, the Licensed Work will eventually be made available\nunder an Open Source License, as stated in this License.\n\nFor more information on the use of the Business Source License for MariaDB\nproducts, please visit the MariaDB Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-mariadb.\n\nFor more information on the use of the Business Source License generally,\nplease visit the Adopting and Developing Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-adopting.\n\n-----------------------------------------------------------------------------\n\nBusiness Source License 1.1\n\nTerms\n\nThe Licensor hereby grants you the right to copy, modify, create derivative\nworks, redistribute, and make non-production use of the Licensed Work. The\nLicensor may make an Additional Use Grant, above, permitting limited\nproduction use.\n\nEffective on the Change Date, or the fourth anniversary of the first publicly\navailable distribution of a specific version of the Licensed Work under this\nLicense, whichever comes first, the Licensor hereby grants you rights under\nthe terms of the Change License, and the rights granted in the paragraph\nabove terminate.\n\nIf your use of the Licensed Work does not comply with the requirements\ncurrently in effect as described in this License, you must purchase a\ncommercial license from the Licensor, its affiliated entities, or authorized\nresellers, or you must refrain from using the Licensed Work.\n\nAll copies of the original and modified Licensed Work, and derivative works\nof the Licensed Work, are subject to this License. This License applies\nseparately for each version of the Licensed Work and the Change Date may vary\nfor each version of the Licensed Work released by Licensor.\n\nYou must conspicuously display this License on each original or modified copy\nof the Licensed Work. If you receive the Licensed Work in original or\nmodified form from a third party, the terms and conditions set forth in this\nLicense apply to your use of that work.\n\nAny use of the Licensed Work in violation of this License will automatically\nterminate your rights under this License for the current and all other\nversions of the Licensed Work.\n\nThis License does not grant you any right in any trademark or logo of\nLicensor or its affiliates (provged that you may use a trademark or logo of\nLicensor as expressly required by this License).\n\nTO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVgED ON\nAN 窶廣S IS窶? BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\nEXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\nTITLE.\n\nMariaDB hereby grants you permission to use this License窶冱 text to license\nyour works, and to refer to it using the trademark 窶廝usiness Source License窶?,\nas long as you comply with the Covenants of Licensor below.\n\nCovenants of Licensor\n\nIn consgeration of the right to use this License窶冱 text and the 窶廝usiness\nSource License窶? name and trademark, Licensor covenants to MariaDB, and to all\nother recipients of the licensed work to be provged by Licensor:\n\n1. To specify as the Change License the GPL Version 2.0 or any later version,\n or a license that is compatible with GPL Version 2.0 or a later version,\n where 窶彡ompatible窶? means that software provged under the Change License can\n be included in a program with software provged under GPL Version 2.0 or a\n later version. Licensor may specify additional Change Licenses without\n limitation.\n\n2. To either: (a) specify an additional grant of rights to use that does not\n impose any additional restriction on the right granted in this License, as\n the Additional Use Grant; or (b) insert the text 窶廸one窶?.\n\n3. To specify a Change Date.\n\n4. Not to modify this License in any other way.\nLicense text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved.\n窶廝usiness Source License窶? is a trademark of MariaDB Corporation Ab.\n\nParameters\n\nLicensor: MariaDB Corporation Ab\nLicensed Work: MariaDB MaxScale (TM) v.2.3.20\n The Licensed Work is (c) 2020 MariaDB Corporation Ab\nAdditional Use Grant: You may use the Licensed Work when your application\n uses the Licensed Work with a total of less than three\n server instances for any purpose.\n\nChange Date: 2024-06-02\n\nChange License: Version 2 or later of the GNU General Public License as\n published by the Free Software Foundation.\n\nFor information about alternative licensing arrangements for the Software,\nplease visit: https://mariadb.com/products/mariadb-enterprise\n\nNotice\n\nThe Business Source License (this document, or the 窶廰icense窶?) is not an Open\nSource license. However, the Licensed Work will eventually be made available\nunder an Open Source License, as stated in this License.\n\nFor more information on the use of the Business Source License for MariaDB\nproducts, please visit the MariaDB Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-mariadb.\n\nFor more information on the use of the Business Source License generally,\nplease visit the Adopting and Developing Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-adopting.\n\n-----------------------------------------------------------------------------\n\nBusiness Source License 1.1\n\nTerms\n\nThe Licensor hereby grants you the right to copy, modify, create derivative\nworks, redistribute, and make non-production use of the Licensed Work. The\nLicensor may make an Additional Use Grant, above, permitting limited\nproduction use.\n\nEffective on the Change Date, or the fourth anniversary of the first publicly\navailable distribution of a specific version of the Licensed Work under this\nLicense, whichever comes first, the Licensor hereby grants you rights under\nthe terms of the Change License, and the rights granted in the paragraph\nabove terminate.\n\nIf your use of the Licensed Work does not comply with the requirements\ncurrently in effect as described in this License, you must purchase a\ncommercial license from the Licensor, its affiliated entities, or authorized\nresellers, or you must refrain from using the Licensed Work.\n\nAll copies of the original and modified Licensed Work, and derivative works\nof the Licensed Work, are subject to this License. This License applies\nseparately for each version of the Licensed Work and the Change Date may vary\nfor each version of the Licensed Work released by Licensor.\n\nYou must conspicuously display this License on each original or modified copy\nof the Licensed Work. If you receive the Licensed Work in original or\nmodified form from a third party, the terms and conditions set forth in this\nLicense apply to your use of that work.\n\nAny use of the Licensed Work in violation of this License will automatically\nterminate your rights under this License for the current and all other\nversions of the Licensed Work.\n\nThis License does not grant you any right in any trademark or logo of\nLicensor or its affiliates (provged that you may use a trademark or logo of\nLicensor as expressly required by this License).\n\nTO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVgED ON\nAN 窶廣S IS窶? BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\nEXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\nTITLE.\n\nMariaDB hereby grants you permission to use this License窶冱 text to license\nyour works, and to refer to it using the trademark 窶廝usiness Source License窶?,\nas long as you comply with the Covenants of Licensor below.\n\nCovenants of Licensor\n\nIn consgeration of the right to use this License窶冱 text and the 窶廝usiness\nSource License窶? name and trademark, Licensor covenants to MariaDB, and to all\nother recipients of the licensed work to be provged by Licensor:\n\n1. To specify as the Change License the GPL Version 2.0 or any later version,\n or a license that is compatible with GPL Version 2.0 or a later version,\n where 窶彡ompatible窶? means that software provged under the Change License can\n be included in a program with software provged under GPL Version 2.0 or a\n later version. Licensor may specify additional Change Licenses without\n limitation.\n\n2. To either: (a) specify an additional grant of rights to use that does not\n impose any additional restriction on the right granted in this License, as\n the Additional Use Grant; or (b) insert the text 窶廸one窶?.\n\n3. To specify a Change Date.\n\n4. Not to modify this License in any other way.\nLicense text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved.\n窶廝usiness Source License窶? is a trademark of MariaDB Corporation Ab.\n\nParameters\n\nLicensor: MariaDB Corporation Ab\nLicensed Work: MariaDB MaxScale (TM) v.2.3.20\n The Licensed Work is (c) 2020 MariaDB Corporation Ab\nAdditional Use Grant: You may use the Licensed Work when your application\n uses the Licensed Work with a total of less than three\n server instances for any purpose.\n\nChange Date: 2024-06-02\n\nChange License: Version 2 or later of the GNU General Public License as\n published by the Free Software Foundation.\n\nFor information about alternative licensing arrangements for the Software,\nplease visit: https://mariadb.com/products/mariadb-enterprise\n\nNotice\n\nThe Business Source License (this document, or the 窶廰icense窶?) is not an Open\nSource license. However, the Licensed Work will eventually be made available\nunder an Open Source License, as stated in this License.\n\nFor more information on the use of the Business Source License for MariaDB\nproducts, please visit the MariaDB Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-mariadb.\n\nFor more information on the use of the Business Source License generally,\nplease visit the Adopting and Developing Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-adopting.\n\n-----------------------------------------------------------------------------\n\nBusiness Source License 1.1\n\nTerms\n\nThe Licensor hereby grants you the right to copy, modify, create derivative\nworks, redistribute, and make non-production use of the Licensed Work. The\nLicensor may make an Additional Use Grant, above, permitting limited\nproduction use.\n\nEffective on the Change Date, or the fourth anniversary of the first publicly\navailable distribution of a specific version of the Licensed Work under this\nLicense, whichever comes first, the Licensor hereby grants you rights under\nthe terms of the Change License, and the rights granted in the paragraph\nabove terminate.\n\nIf your use of the Licensed Work does not comply with the requirements\ncurrently in effect as described in this License, you must purchase a\ncommercial license from the Licensor, its affiliated entities, or authorized\nresellers, or you must refrain from using the Licensed Work.\n\nAll copies of the original and modified Licensed Work, and derivative works\nof the Licensed Work, are subject to this License. This License applies\nseparately for each version of the Licensed Work and the Change Date may vary\nfor each version of the Licensed Work released by Licensor.\n\nYou must conspicuously display this License on each original or modified copy\nof the Licensed Work. If you receive the Licensed Work in original or\nmodified form from a third party, the terms and conditions set forth in this\nLicense apply to your use of that work.\n\nAny use of the Licensed Work in violation of this License will automatically\nterminate your rights under this License for the current and all other\nversions of the Licensed Work.\n\nThis License does not grant you any right in any trademark or logo of\nLicensor or its affiliates (provged that you may use a trademark or logo of\nLicensor as expressly required by this License).\n\nTO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVgED ON\nAN 窶廣S IS窶? BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\nEXPRESS OR IMPLIED, INCLUDING (WITHO',NULL,'g',0,4,'1979-03-20 13:59:42.0'), +(1972,'j','? y瘢?5ロ ~-イワ?\r?WC @ヤ ?ソ?=ウr!Iラ.%梓?菓キ?dIT9%Nロc*1i?ヌ我オ4ァ?)5慴ト?/rUGCキ|刈ヘY5レ嬶?ー;源ヨ ゚ケ,V敝|*9モV@、2ユ修^僵!雫ヲ笵?^jオ゚?#Vc@1%Bト?Lo_*ヲワFン? ィ?5cー;站kJaイ?亀メ?~$筧?\0Yy ケ%?SテンTzuナQ ミ{?$ヤ??? v\n叮エ6?飛?ロ轣.ッ}Pヒ「貼ホ_0操瞽オヲU5&[1i杷bメ8;クロ?ェクa??\0-\ru?>ァァ9ンkミ??禮Pウ?ネ^=Y?{rRB~ミ;?}?\r.{)墮??#ト稽悲」??稷ァィ゚$O釶ッレ}OSカ枝?G?}ヲツ+?1,゙&栖、ォマ?@W?ヨ?廣?ケィ閊瑳\rN?X怎?\0゚・0・、?*ス2}諡?ラOカ鉉+fqJ?オ\\銓ミad?)カh?チヤミ私cT?X??yN ォヘ>+クcV\n[ヤ4Qネ?゚d? ?$@ノ.羃ホU?{\"<ヨムノターV・z?gP?(\Z>C努#lィ?甫Q0豢4=3\\ヌZ!?カ+oe$t B{梳惡欧裲ノタ?輾?4ニェ墨]+恷痊lEテ;ソ們狄カ0イアゥ?7ホQォ濶lニ> ・jKアゥ?ヒ?J茲X髄F9ト|?ヲナT禝ア・w?8YァB絃ヲィAZ?>?8[gvI、ェツ」濘豼ヘ斥-クX?・EI82K!?UリdぬB推?*??9ャtク芍e亂\0v。」奎??N?夜Vユ 1ワ??\0ケXBoヲ\\D冊膨)5・M@テ?B?1テM?ハー?6メ黔2ゥoA?ク轄??ヨ\0E0ッ゚オA?R吃ZU?sミauニ?+?ホ?ヤ\0h?8:?/T?\rトョ珥Wf粕oカjjv?楽鉄p?.8ゥ・|ー*儺フ*捕蝮CXメョ. bメsレ・@ネu档?ヨ&%#^ヌゥ?\0孑ケmサ8?ュエ錺?灯 r???ヘナ?(タァ\"wョミ?%ルkーニ\rVWjネk?癜ハ6mイ2。Iオモフト、J=キァ??hx。 ラケテOャウ*? ァd銖c#!?0?sミ?%v?9メ$\0?K詢}エ??VT?u\'ヌ ??$?\rソ皺.。d?!脛ネ?2& 暹?6譁Zル^k ラ優エiヤア?\0?<エキ存旗叫aエキトフ??\0頂 ワ、ー。o家?\0鍄??&f?$―?コメX?6Qロ[rlソv??ヘュ・?>YrJフ8.チ{差?Fツ?vイツ?/シァ???\0Ur」?$ロゥ??\06穢ト^オワ?*/\Z?タi\n^亥クァ繧#沓yオ聶?\07c簸?。>莪)竟ト?#ソrr&HT?<△wcヤ廸IExAミ?ヲニー?∈?; U\0Qセリラィ\nエ\\Fi\rj篳?ク?g?:死bR婉 \'トト難?祺J?e\0\n?ウス1逓dリセ?-\\メ??カク bnoJ?9<;?%w{%モs番?循 サ村夢?ェUS?8Pマ紅ト匆逐3祗ルEア、? d家答ケYNヘ?6*?イラm>ミョ\\NAF斟ルmネ昨*フルウaWfヘ?vlルアWcケキJ縱bョヘ?XナVfナ&Nリ?*?ウbョヘ?6*?ウbュッ\\ナHタルォ骸=rウfナ偽キヘuNT?9N劔ケ\Z?Sムnlルー。ルウfナ]?6lUルウfナ]?6lUルウfナ]?Mアクェ?ニ噫?箘ヘ?6*?ウbョヘ?6*?ウbョヘ?6*?\Z束J?,p操・qHh?ヘ?;6lリォウfヘ棺6lリォウfヒ。ォYウfナ]錫i\\。ラ??;筧\\ルウbョヘ?6*?ウbョヘ?6*クH@ヲ7ョlオ48ォ椛赴ウ1階Yウfナヘ?6*?ウbョヘ?6*?ウbョヘ?6*゚#モ+6lUァトイIF驍58#駆疸r4fォ恕W楠bェ9ウfナ]?6lUルウfナ]?6lUルウfナ]?6lUルウfナ]?6lUルウfナS]:ヤJ7ヒサカ綴?A〕ッ 0}褸???,NVlリルウfナ]?6lUルウfナ]?6lUZ f楙q7B卦爿+ッォ?9 f」L\'アX肄?&[ヌ尋タリ?fヒU,h2ル\n\Z*ミヒdヲP4ヒ-\\UnlルアWe―ャ|F?Uiハナ%?筬惣喘メロヨク?7\\-ヌィエタ?&lルー。ルー簽NB\\aL驚旗cJキ,ャリェ?? ?)越.*m幡挾レ)+ラッ光G\Zcd|B1_Y0セ/蝟 01G、仄I?驪$冑添覚?B?\";ョマセG&eア添各4Qノ?ェ>{痞?XGネォ栫ソ貍V9i卿?=}ー?クリィ剌婁ロ廱yィ?ッ??\0+??ロ?dヨ-\n?ユ鰒濤A?テァ-ナ^\0l=ォ?_/?&?\0[?ョmタ詠K\\シfオィ=sBフュホ6*テ。?ク?佗 。?c?|&?ァ繚「Ud柝j??隈尽キO qqタRF澑?&搾?籬??-fテu゙攫\nヤW?\0「1)QTaQキlXEナeエッヤナメ潁錠ユ瑩#Fオ44?P訣&゙穂?ノt?-5>Oル_ッ?Z?メ?\0幅Jユ??村ハタッ_ク?諡{タTGt5⊆:浄_?kテ?\n?I蹠摯吻チカW???ハg茎褶3捲縱a-エォ$忤肖?\04猴]n?ナ)゙サ嗹?\0*???-楫??ァユッz~??)2A6滝,\rマト蒋?G6wiユシ錯Iュ{滕N,Y@篦菜??\0Uイ9a|ヨタGv。|O?ソナ?8{Cr「@k?8ア/F゚ツ仄Jエ m\\ヲDZS?|ッL2?G?*ィトミ\0>9醐ロ|F61?櫚T?]ォ?ャ.I蟶8マメIテ !?|qェ暃サasン{SU頑)ナSz梏ィチqワォ)?レ癖ャ峻ァ蠣/z\\4キヤR駛ゥ?ァ G潤?$UGタ??Xョレ\Z$捧?ェR黻ミモ゚Kョt?農vマ、、ソ? 戡9&?Κ荀?樂]y? ロッ?U綽z?ラナobメニ)ナセノ_柮}cヒ3鰓圻;?\nモ??\0ノマX=イN?)+B7?)総_ヒUFTE?嗽ヒ!班ワトトヒ??ァq鰯禀ン3ソ]y>ツ鷽rFm覯F?テ?c?/3?[[\\A?ェ ?\nュB??\0)ンj?\0?pフ cタ?Eィ゚|ゥ#莊?Zキ溶tキ+,r/シ衰}?c\nJミ蛟λ?%&h\Zォアノ<\Zーヤタ受欺 ヘ#nテ?灌?\0ョルxチ?8レ顳0ィ,?ヤ字xヌ3?RO?e[恢イK}茘mrンu]?;\nシcbュ?U?E ュTモヌロ?\\暮?:賦GィYコシjhフ、タL浹ヒ??%」c??Iフ?リZ?欽ュ?2ヌツ?;迫?ーチ:?孃4蒐Ky公。? Fワク;ヘ?!d称1??\rユ$^?飽?-ッXj\Z)1」?-e?A艷曁?ヒッ?Wツ%キ\"岶?=wO?=ッ僭ァ/ンタ」ォT種?ヒ$v?サァマM凛4}e?\0ヨマ=阯1ハ滿ェNヘE虎z?9(モ|?.梅ュ髯t?15?\0軍|YT?Af ラ\Z\0ュE?Aロ?゚P\0?エ7?\0bヒ?6コ? 壱2Hサヲワ??k筥ォ、ム浅??カA*QX?\0?4oヌ??_??( Zモソo?hヨ@「ニS皺?J衄ホK,恤餘[ッ磋アT$Qノ?74?1@c数ィ,:?ン蟹1?7拓乞イ承_?榾ys?珍ハ浄筬^ヘ 。??9?hマテコ璽ロ手F?コー?痰筆Gメ1V:?(屑ト>エョGu?,ルk0 アンz?ニル7ケメト┫杣}淘?OEyミャ,ムオ*E?カ?ヒri2ゥ?={?\0イツ3ィ゚yr?ュ~??)゚?芭?\0\Z?+Pミョ,匯」]ケ\0v?\0Zケ? ? Y絵Cラ08&Kv?(タbk?&+テcェ%?ュ? ネ=イユA5ョa?1kRィユ彫エツォR\Z私゚ヒモ5クク胙カ0F]?G)BH9テヌtァJ綺6ョ ォQ|&挂?Fkナィ}ー2キサS$\Z&ス5抖\"Jァェ7?H尊P「ラ?-?ィ?hqォ \\FgRZ殘ロサイ\Zォオナ?5iWJR灌V-蝓BKソB?F???6*ヌ>ゥ@A F5~鑛徳(岫rfオ素ノCク9ヨtサhdeカ=+N??\0イト|スッK?]+ま?アチ/\\vQアzヨウ ムZサ倬?\0k?ヌ疝企z^榎?/ュ\'Mテ+S??\0.クdhKxワ學峰鳩c?j?\0艇8M$(^ナスd?h(\0ラ?5カュッ)苑Tョ???\0ニク、壥カ?0[ネ\rサ攣ァトァ??\rユ(ー?カ?0コ?iナ??注>?y?,?ャhヤクシ?z?*Gヤ1ヲヤャ佐?(戞蟶糢エッGノP囂粘Sスネ?0ェ?溽ノ%剛ー@m慍P(S聯モヒ!Z冢、サh諷?ェkQ?ッレノヌヨfeェn=?66*?2?XヒィウO\rロヒ0ゥ)57ハ次オ?5?1シサ?W??イ?乘?)i~??賽?)?1ヘUc_貢#?\\?>??+C%?-「<穽Z狙カ*ソY ?; ?靹カカ?:シ弉X#タj≡ァレT\\K^エカモ/G闍?$$FW$ュe氛_yマFィケゐ;?^嚇?j?)j?トコFッw?]:O?z?\0;|G?/サ?a艪ウイケユfFD跳Hォ\\?C婀?ァムi# P扮?sロ[_^t?!yQ\\?ソ??\0?4寔メoレ-Dレdモ\\モ・サオ愬,ce#j復ウヘ?b櫁 }BルL遇fSJ?,#eー啼rモmh&IユjVM??」ウrホ]ャjヲ矍b5bjェI?W-蔗?t?讒ヲdテ蛛扮4ハP 。ニ?8?.ケク?ホQZo畢xmィp%j?:蔑X仟Hナ\rミ嫉y?\'ョ^)DC ネ2?\0=?\0綵ラ幕niフ@v ?\0ト ョ53\0F?mi゚ナr\"孤ニシス?/0Gクフ$゙ァ\ZオUg$\0cロカ\"C狂W2N OイB?bィd^g゚EnjR、\r潤ッレタマU59Bb6゙來J?7\\ヒノコ\n聊[w#ユ譴?&ソ/?ムレz|癜?N?O?V|RTW}?旅|g\"?ィm柔|b?EI?0ZU?俥%?ネ&捍gカ?8テ?!||q絳クhMノ箜???Z。\\??Fロ?翡??%W?mヌ? bキZUヘ、byzf? ??\0?ю肄?)b~ネ??6iォIg造F゙ィ ウ $?.ネh=アエハテJャ\Z?I9|ハW華?#・q?@チ?#ロ/i挙P7ロ?ハT\'~リmvラ鳳+ニ其\rA\0ー=ルp偐?0ィロ抒?8?糟q/^タt2GSH。#テエセXル}hメTP@V?\0I?;?.mZ6\rX撤??g皀}滸ーr隧|M?0v^T?\rh瀾t?4\"?Fム鮮鶲?-?儼ンV/YY%~??\0ハ胝as?!MG? ??nE?\nモヌ?キ?4@y廏\'?銀ニェ銅ヤ聽淋淘Pトtア?\0c ̄莎b析%ケ?\'cL凉fマOヨヨ[[霪rイ?P?/褸セ?#?ァ\\=エ爿#SqJ?\0??ョ7ス/嚮|凖ト??T~b?JDム?ネ赫ィ?萵KKゥ?ヘl???xサ樞V萌/!?カ??8z?*ムオT・O壱?>サOn?卻)-wQ眦?\rW」-w\r1イZO\\??(Ykn?!?GR?\'?U?ャマニ。コ罫K?ヌ?J槨゚Pp1掾5>9メウ戲GQバ?ュN8「ケnK?@)?ャナBユN?ニ-mhモ)??\0v泌ス6ナ レハー営b?@疑フヘ??カ,$\n)「槨?|メキ6b3bZ2T?g奴Pc「カ啼?\"Feпオq6r68?*藥uチ_YDリモ??ハンア・Dノp+Tトクシ?rм|イ?9?6T3D???q?0;Lh烝ユ~?\nャウF戲j>??*ッJbqコG ,9ニ%zT|ァu陀?モテZS\'オキ7rャ*UK\ZU?kx芳ヲ蔟リvhヨ,ヒ?ッ5\0+スセ4ォロFo?3+ハ@;J?q」qg?\\土?=>?ヨレ?i$アK\\滓iGタヘ??渟ネrN#夥~-?CR[ゥ+\Z\0+ーョ\nン6易ョbゴv?ォP@PP|???ツa岩ミO、? ???゚eーァフ?Yjsナ\0? ハオュ|I\\A閭゙滴サ?キカ{裂メ庖 スウヌシク?3橘?゙:Q之?}、?\0棔ヘ?\nッ沸x/「?\"Gチ@jミ?\0番ホケeゥナw$?*89 H?鯤ャ泓MqvイD? 5ヲフトウ?8oョロCEoシhv-J穣衞ヘcf]・? $??ッ?,T[0&Y曽ェzaN兎%・エ0<「F。?)?\"Zミ@ソ?煢EツウYー>、gzq=~ラナ\\ZGサ敍ラ,m畛2ニ?A?ゥ~,.セヤ」iqrzェ???簗z?e^\\っャ^% ホヌ聿@%ソリ?君? 鈎ホヘ\nÅャ@?4?\0坡レS;レャ捉DJ?綫??l0コモ^ヨユ/Q?\0x貎ル1g丶ァ遡/{ァGァI\rc傑チ.ヒ燹サE_?竊aト?\0l\rヲ婪ュKノ!ィ「初??vヘmJ g$?Qソ?ミMォ?2/ィヤP」aモ2UIッ\\\"?$P鍜lィN?t;vヲ*?^<財{?:ヤ?$?\0G?q康酥潁ョMfコY,\\リ?9k#*オ&ケ ? ?3旺B2?^\n nN6レフVsE\'ゥト嬬^?\rOl帝ゥ2ォJ bエ$モ?窮テ第ュGヲ<5c\"5スv?\0U+?・?XxQリヨ??与YリR?(2?L)??1臓FKgw漂J?ー?整L「P席モク?#D{3Ic高Gミ?1 Az?ヨ?2?7ヒ^~?ゥ??ヌ)ネホ,f?wpR\Zクッ\'?$0ハ;?1レjrr;ャepO?)!\nヨ鹹F韲@? ??%? フ蠣3&ツ方 Oレノ逸セチo祿宸?Qソ \nヤァゥ4ワ忖モ>ヘン淳ァ?ニ?(??bナクA\'ー?!8針hォロト潺猫y?ε:蟾゙? 隠スァ?、?\001゙ゥゥ漆[ェX?$pウ助ツ\0エ?政ユL 允ュN;蒼~?:翔t鮓S\"ヨヲ、竊、\"J?W?8タモ-圜?ニ9ヲン?。??。ナ7ニq-ラa繽Xケ}??ホリ\nw+K翫冷ニトシ怺??ゥA痼?)?V?ーナ這リク ヤ??AヒPE; nヤ?ョ#4靡庶2Iv?\"?l<0?ニムi???p4?b?ラZラ$tト壺メェY?\n.o?ナモヌ\'rbd5y?6鵲K;Jw;bl蔟ニ冪ニ#ヒ姜&Mヨ?2議Iニ当*龝WLu0・ルゥ?.亙[ヘ\\ャア???\n?ラ[囎ヒ9アVク褊岼W\\Uzメオテ?*?交E$?? AR、w%シァ?*??ソ錮ァネノ娠 ,メ画ロオw?\0e?B濔V?B}0ロス66??JG???ツス+L}b笊「\rリ?゙UFツツmJ@?\Z??エン;%ロ? キエ遮F8「? ?~+A鯢????ヨチシケ.チ1コシ斜:ケ\n泳~呈ゥ\rQ<{?+シソ約ケハユ=シgノ\0I\\メWgニウb|キタJ@Vdユ_lア7:{箴T順ョ*tzタ確?鬨纈|?0?絆SオAナRXッ・オ?ワァ栴テ{?・カスp-ホ涸ォニケQツュ??イッ+%W|T$ク8J輔Nリam1?DH?ケ?瘁????ァレ&」ヲ#*4dイ椈ェIuァ?ヤ2??p「?:#$Pハ%Rユ;君[D?瘧アヒステ[\'PイS?。ヒ悒ヘ_?3i?モケI $櫨Y?ユ?ァL?-lイ!cアm翁1\'、?7$?iZuノFF\'do脹tサ?2Kゥ(\r+ロャ))筥?9駮4?]Xy・L規k「6?ヘ?\0W??\0禳テ|ユ? ?)J!ス@鑿YP\'??摸賄ロォY? bm>h?uヲy橸D棠ケGルdィ?2ウ~゙sリ?-鹵jψXl趺テ-;T、?\0~ホユ(ネ蜷?0F゚$駅スq?k G」$ タz截???T???r@ラ,イ$モq?3?sCンs菜?c餓.T4lヤ?)アS??蒸ラノn閤?槌ニu壜恂7ン瑠\'?ィ?P#嫣6?!u |ユユ???2、?*」?\nヨ寃?ォ~ホIヤ]tTミイミ狙ル繽エラス\"?>p-@選ッ?Oルネ%3x#殀?~?オ漬碕。ッ?* Mュn゙、MC?@??ォ3?\r Rエョ?ォEbxオ=ニf簗Kモソ?ェゥ_JeッC@iロ#aウ?$v\'?6ナP2iノ ロ?ェ:甼ホn?/%e*テヌ$G??i?(フI?シッV?P覓:蕨Уダリ??\05dCW?キ苧仭ハ。?リ聖? ュ?J?コb]Pケ。體!;ンi@9ッヌ?;ャソウ?ヲキ?碍セ9ル?(ェネメニァ?級リ} ?\0タ膀?ケ肉&12?iヒr?ヤ楠螻ハトナ?\n哉X比嘲q?R??:?\0アツ気??髢課\ZRx聊A\\g、TQ?ソ|mf?エ#?K?阪?*ツエ?豬?=ニ?ノZ9Jォ百Pqx. V7ンOセDmク苳;r#??pロネ鈞ナ、戟オw餡掌G?+@GC停ル圧ヤ.,寞Tッ~゚?\rコキn_XカmエモU#ヤ#U2抄???k簗hイM?痰o\'%。5モ?%?ワ「\"4Jd^?5ネ?槲=6事?$・ョH\"kiヤO何ー野「舜hハ?[?閤D?;茎゚孛?(碯ロエニ2dカn\\サSゥマud?{βー?ハ滴オx?.?d?ョT?゙8?糊m^?\0?Yomャ!\\ォアィネ・G?U弘・ノ付?hン?ヘ?\0g?貔h?Eンォ*\\ニXx??=ルS麗.v砧izK?ミ?ト・アースッヨ? X? d?3?-癡曰ヤエ虐sy$ゥU2[?OO?,!OZZオ?hNz?R?毳i?$b桙スソg\na?ニ椣4v?[bョ T?\0/*螢76&/*ヤシォ!ア]Nナヨ?嚇々ヘ7?胴テ??詆ャY_ロGshヘ??2)Vホ?鮃゙\\?2ロZFテモrP跡?i」fEu?\0>ヘmレミj?+sr@PS?;ェァ?<彳ト;メ、??\0ヒpj歇Dtカ鳬浸??クレソiヒホアヲI嬪?6?v?vH9ナ祁ム_テ{,a」w蔕タR??C~ヨumBo?;[9-,リ醂?エ*?\0?ッ sLQZニゥu%繊??/kヨ奬┓ニッN[?レ??7Hカ叶L\\ィ?潘?\0?H-エ{Gケケлf頻*~決ィ紀ワーMKハキ\Z=?イ?Hユ」;u」#鴉ワ・%\0ゥuィ度膕UッセHY真A粫ワ?ナh|\'?6? カ?\"iハ娶辣ヤァN亙mォ?[5ャ ~ッユ ̄テ鱠3\rヨヘHHpUヒ\"氛S凋ロ壺?竕\Zケ?(ァ\\y*?aZモ;W逓サ・Xオ+X、I?、??ヌ8ワ?\'テタアsヤSァモ昴ノ1ンリ駲ヌz??Hwァ?S們)弸I&。Xヤぅ?vホ躑{]Nh・D?% ァフ ?:棗??Bユワ滸_?マ??;ノ.?j*)Ol?\0xッ「eノ#x旗祀6フヲ偃サ?カ・2スホXュlq廖ツュェラ蝟v;些∴ロ?\'佯Hヌ聴1?踝ノ鮴リ|?zJ ?wヲF停i? フ??敬タェノ9印ZWカ&_逮()r1k孳b 9Vロn$?XZ26Z?S?3\rサ?・?U??嘴ロmR籘。H#?\Zロョ7案|セl@HF?9?rォ9bKtニ?ヲS71カW/l7ワォ?ヲ9zLJ>Lタ*?> 籌-ム?コオVU? )??6Jメ(=jqe0ト#?ゥ]サS??+y}e$惆 0ゥ ケm?\0ノツ逅?9・$ヲ鉢ョユトタRエヒエヤマ磧?@0?低ヲb??TOタハy9$R?緜hUテ2??2航Ubハ*l|z衒ラ?0?ネyTTq?\0ゑ?8s苗$f_ッ*\Zl2 > |lH8褞チ頓42Y无\rT?8實ィニミヲ*M0AWpヨ??\0ツ?\0ュ?\ZRス?・巛アD・iRX?\0イタU9K/イェエモ」コ樽U=?y>{?D「ー?&翁\nミ??銓チa|カ鎮FjP?5ク}有? =オタg亂?;ニソ莉|)?\0qネ?漠ミK3W?#??ュソiソノl妬紘ゥ?X「xセ?)Pサ?^??滿~ホM襠ヒs4w F-ラ?\'。ュ>a?ヨ??籖V4vァ?\0?u菲/狃ウ禄Xチ*Z?P?\0+キ屈杤?=マ峯xツ゚bアK?-:イッル?\0e菖シニ億桑\'ィIォ棔??+ケ/u\'?斉ぃ*J??k?0 ルs}ヘチXトnサ?\n?5メbミu]-釀?+|サ!ワ/ロ? ?ォ?LイZロャ?NhcSU?\0+l;ラ妣ヤ.ヨ?ノi ?フ彑?,7イ?/ィyj{ VG+?a?コ?廂qコィ縞2i鷽レ・Z竍?~ヘeノノ、?E融1舒8レHシ?\0\n??騙/?.旅ラh?ス?-\n0&1ネCj?>?ア\r+LIチケセ-?イ\n}ッル牀U、?\0+?:テN郵i#エ?$H?~#?~ホハ?PHb2\'??0ハロノレヲ嬶%スウyvc?エ故1胚E<覓s?&эサ?、暸@?キ?抗J?。?FbI?\\[Z??壗チmf?I%ネ??roルノq?/>?\'ヌSJ\n≪?$,e筌p{{bッ フ然zwノ?\r(H、T\Z梱?6&K9,w=N*タイ勇QZ??*?#+1wョ4ェ償i哦?sムW?3ム(?ェxヤbシ?\"$BU→#ィニ゙^M})榱フ?7V=M2)h「ヨ穏ョト篷\n・9??*0F\ZL幕k?=ヌ+詔鰻」?恤?\0膏涯+??\0YEK蓄/?老ニヲケ咤ルX夫9C6ハ+儕ア?ナ?ヤP>\"z童\rヨヤハ?(「?j1Sオ0ツハ(?8f R6cネ?篩H?\0ト?ュ蜂|m?&鮓jHィ魂,{??ョ+ァ゚ワiウ 嫻璢ソマナr繕?\n\nヤ?4ノRヲ/・ヌujキーネ柴:1U\0才+3}? ァ魎_ク?6騎潁キ?テME-?hョ\"u ?#GR\n?~Kヌ?S?ゆ淙?Yキヤ臑JトTヘ#\Z\nセ綉莨ケ乱&Kハ]ェiヒ「Fヲ?尭?ェF孑aOエ゚ー屑Yケク{?\ZW$ウ\Z樽s。?l!kk8\0∴;Tラ?k9ュi?<鋒9 ??・向ョ!??ヌ「舞穢ネ號|\'tシi?pウクV寿絅?\0ョフ\0q?rリヘ?\Z9?ョp?メmV?4?F? オF?捏@?ネカ梗モ濠ゥョヤ?\0W?dS6ノ榴+(N$\rゥモ Xラ?ソセ))~!T?q*オ7・4ノ$ョ?_3j討?BK\Z\n 蠎アf?\n5イ? ZB\0O\\U「f?テ^セ8 Kヲヌロョ=マW黯?2Jヤ?!^)?佳梯]螽゚e^ソ?c->.?;x?\r=テWッ_クb\rゥ.iYS胃ソ?ニ?ィ誕V?\"サ侍コ?\nL?>#?6タrL? jha磨ワタャ?W燬° 」ァ|H|?ユ?、ツ費窘 ?\"\"?u゚ョ6k?vワ椈Y$瀝\rVy nrネ盖eョS?gケ?カニ?ー9jeニ?\0ーa?彿9イイIvXcツラ[Jfク麁瓩\\i憂讎a棺?7ヒヘ?\nコ僖モ186ヒL{コ14S?i@?V\"#モ nャ犢p振ロ゚カ [EaS?ZメBccミu髟$O」ぉタ砌敵ヲ|iC1鰾?ハ?Uトlャァス]ェX墻?エ禾エe\n.n????\0?{ケV?? ?カモ?蒄\'?ヘリ5,メ6?梍ルm?ア???[」E?=ー?$カメ\"リ,j:樒鷸?6_Q蓿?サヤeサb?槲$ヌ??チレカ?6??\0スPx羨ソ??讀ツi*?\n熨??Uo??\0[癌;甑m?*テ?\n?B?2rO??9w「ζ,?Oハ?WG?1較 ラ??沂?\'?,屠:玲[t丼&a?ワW?ノp??楡ソセA膰逐?ウ渤?_k:DN%衢[?1フLr.zoC_ハ?&?eR$ #?n?廬苞IBネヲ保?需? ミャ?ゥリWキ?ニ劵R包巻ャ鞳?*ツサP?イGR?n0(xタ(竚+? メK?レN怐鑷Ugキ銜イミサ ッ?(ッ{\0゙#ナz?ト??=E+ラ?O(ツ@ワ壱ヤ|ェォ?=ヌ菩e#簇ュセ豼?N\r ?矯ト\'ウI(ノB|0ルW苦曄ryロコ宛?オ?G#?カ菟ク「」Wビ?9ンnエSネ2?<:??3鞣?\nプソOサ&2E?y謖?-J?ユx槽役枉\n?iモB。$」.ヒJV」ン雜WsD6゙」oユ?{ラ??ン[對e??リaTカメニ~$狹?2s?併101?B?ラタ・^ハ「q \0???d?C施??[ア?チoァhnAャゥシ草爛ナfメ蟠簫) N?キレチ融: Q%$V」bG?オ?-1I??Tイ穫|サ{?-B?!\rVスA?j皀リヌ;蔑\'?&ヲァオk??コc?~ホ:?bト?mzY#痒 rW?ム?イ+}恁ワMcチH\r?e穀?!(ァツワクモ??OwN~ォ??0ヌn概#儻~<樟\Z?:?2?\ZoU?\0?劼kf1H#)%h[播?:? ]=wGヤ&?-テイケゥ*\n~メ稽?wQハア#ニ(xr。?\\[?\\敬儻6!-?I?P?nノカ??+]v堺X「r?\'?WフYFQ7M?nヨー蛇?剄\n?ソeクォ/ルツ゚+K?=ケヘlニワ?\n@ッ?3rテ?,e7\"$ク割? ?\0Y]G,3uk?メN{UN??!誠ゥ*沖レjヌメェ??效テ\n?PFテクネ~吩?,ァwSBwオo?暢9タVスゥ自??0? オヨfウCK腆$?\'? ーz%ォ;\'傘e?7ッ??啣.^yネ??/レナ眄セケ\"゙?4蓉?F?\0ハ代otン;N2・ユミ朴?ァ牒「ネェ胯???H、?F?ィュd??烋7\\eツ=ケ?@?cQ?イb1\\d:?チコbォ^G:PV嫩・オhBQビ?=?ヨニz?+オ=?\0牾t?T?∇、揄??ウ?箏{剿:?フiSモヘホぬ??」年\r?兒做モV???8ォJ?_趁?瑯ムエh?\0zレ芥sヲ??yBBスセアq=離ィワヨン欧?タ??2??ヨネ&コ?-?ZォコQ_ウ?義ォ{8オ8譟J?;kXミ?\ZF?リォャ愾リァ,レ/',0.7124939,'sl',7,0,'1922-12-07 22:15:04.0'), +(2012,'k','',NULL,'lstxvxoo',2,3,'1992-07-20 10:19:25.0'), +(2006,'txvxoobx','{ }\", \"UTAH\", \"2014\", \"37\", null, \"-\", \"1\", null, \"3\", null, \"27\", null, \"68\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-111.5871285339997 39.36070082200047)\", null, null, \"UTAH\" ]\n, [ \"row-cy2h-v4pv_yc2a\", \"00000000-0000-0000-29C8-82ED26F05724\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"SOUTH CAROLINA\", \"2014\", \"37\", null, \"-\", \"2\", null, \"6\", null, \"55\", null, \"61\", null, null, \"-\", \"0\", null, \"1\", null, \"2\", null, \"7\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-81.04536765699964 33.99882214300044)\", null, null, \"SOUTH CAROLINA\" ]\n, [ \"row-wyg5_yc5s.2t33\", \"00000000-0000-0000-0009-A1EAD77B5986\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"ALASKA\", \"2014\", \"37\", null, \"-\", \"0\", null, \"1\", null, \"2\", null, \"4\", null, null, \"-\", \"0\", null, \"1\", null, \"2\", null, \"1\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-147.72205669099972 64.84507631500048)\", null, null, \"ALASKA\" ]\n, [ \"row-6sii~ebrj~btdz\", \"00000000-0000-0000-6A81-EBD29358C16E\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"MAINE\", \"2014\", \"37\", null, \"-\", \"1\", null, \"4\", null, \"35\", null, \"23\", null, null, \"-\", \"0\", null, \"1\", null, \"1\", null, \"1\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-68.98502952999962 45.2542257390005)\", null, null, \"MAINE\" ]\n, [ \"row-rvmv_hqb8-tf2k\", \"00000000-0000-0000-EFA0-7FDE69030921\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"OKLAHOMA\", \"2014\", \"37\", \"1\", null, \"1\", null, \"7\", null, \"55\", null, \"47\", null, null, \"-\", \"0\", null, \"1\", null, null, \"-\", \"3\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-97.52106845499969 35.472031425000466)\", null, null, \"OKLAHOMA\" ]\n, [ \"row-qurf_mxm6.4xmv\", \"00000000-0000-0000-F4FD-DAD0CD1CF605\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"INDIANA\", \"2014\", \"37\", null, \"-\", \"2\", null, \"7\", null, \"79\", null, \"98\", null, null, \"-\", \"0\", null, \"1\", null, \"2\", null, \"5\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-86.14995579899966 39.76691072200049)\", null, null, \"INDIANA\" ]\n, [ \"row-7e9w.a5ca.gbgy\", \"00000000-0000-0000-B852-68B67CD55DEF\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"DELAWARE\", \"2014\", \"37\", null, \"-\", \"0\", null, \"2\", null, \"2\", null, \"11\", null, null, \"-\", \"0\", null, \"1\", null, \"1\", null, \"2\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-75.57773943699965 39.00883059000046)\", null, null, \"DELAWARE\" ]\n, [ \"row-93f3~ptpp-jvyy\", \"00000000-0000-0000-93F5-6033818C035C\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"ARKANSAS\", \"2014\", \"37\", \"3\", null, \"1\", null, \"6\", null, \"25\", null, \"43\", null, null, \"-\", \"0\", null, \"1\", null, \"1\", null, \"1\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-92.27448794899965 34.74865329300047)\", null, null, \"ARKANSAS\" ]\n, [ \"row-7pq8.u2t6-yp2b\", \"00000000-0000-0000-E13B-08276C137DC3\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"CALIFORNIA\", \"2014\", \"37\", \"7\", null, \"6\", null, \"15\", null, \"231\", null, \"204\", null, null, \"-\", \"1\", null, \"7\", null, \"38\", null, \"70\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-120.99999889499969 37.63864203100047)\", null, null, \"CALIFORNIA\" ]\n, [ \"row-8nav_uj4s~c9ps\", \"00000000-0000-0000-05EF-D247DF52986E\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"OREGON\", \"2014\", \"37\", null, \"-\", \"2\", null, \"8\", null, \"77\", null, \"218\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-120.15502977999972 44.56745218600048)\", null, null, \"OREGON\" ]\n, [ \"row-w7pd-tam2~rvge\", \"00000000-0000-0000-DA1A-364967240EA5\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"ALABAMA\", \"2014\", \"37\", \"2\", null, \"2\", null, \"8\", null, \"82\", null, \"102\", null, null, \"-\", \"0\", null, \"1\", null, \"2\", null, \"5\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-86.63185803899967 32.84057034900047)\", null, null, \"ALABAMA\" ]\n, [ \"row-bfx3~rdqm~8r7t\", \"00000000-0000-0000-D6AD-76C43033D406\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"NEW JERSEY\", \"2014\", \"37\", null, \"-\", \"0\", null, \"5\", null, \"13\", null, \"52\", null, null, \"-\", \"0\", null, \"5\", null, \"26\", null, null, \"-\", null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-74.27368565099965 40.13057159500045)\", null, null, \"NEW JERSEY\" ]\n, [ \"row-ihca-r6sm_j485\", \"00000000-0000-0000-8835-76DE92BD0A04\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"MASSACHUSETTS\", \"2014\", \"37\", null, \"-\", \"2\", null, \"5\", null, \"75\", null, \"98\", null, null, \"-\", \"0\", null, \"1\", null, \"7\", null, null, \"-\", null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-72.08268985899963 42.27687014100047)\", null, null, \"MASSACHUSETTS\" ]\n, [ \"row-q8yq-pfae.5iyh\", \"00000000-0000-0000-2104-5A07B1D13849\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"IOWA\", \"2014\", \"37\", null, \"-\", \"5\", null, \"61\", null, \"180\", null, \"1306\", null, null, \"-\", \"0\", null, \"1\", null, \"1\", null, null, \"-\", null, \"-\", \"0\", null, \"0\", null, null, \"-\", \"2\", null, \"POINT (-93.81648936699969 42.469401477000474)\", null, null, \"IOWA\" ]\n, [ \"row-yzs9~3ssn.gb6z\", \"00000000-0000-0000-D8B2-772D6478CB4A\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"NEW YORK\", \"2014\", \"37\", \"12\", null, \"4\", null, \"14\", null, \"172\", null, \"162\", null, null, \"-\", \"0\", null, \"4\", null, \"18\", null, \"38\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", \"1\", null, \"POINT (-75.54396639699968 42.82700178100049)\", null, null, \"NEW YORK\" ]\n, [ \"row-5amt-e54z~7rhu\", \"00000000-0000-0000-1452-DB727C714C5F\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"NEW HAMPSHIRE\", \"2014\", \"37\", null, \"-\", \"0\", null, \"3\", null, \"20\", null, \"32\", null, null, \"-\", \"0\", null, \"1\", null, null, \"-\", \"3\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-71.50035726399966 43.65595081000049)\", null, null, \"NEW HAMPSHIRE\" ]\n, [ \"row-ejuk_u23f-gmac\", \"00000000-0000-0000-D585-11F9AE6034FF\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"OHIO\", \"2014\", \"37\", \"10\", null, \"6\", null, \"15\", null, \"232\", null, \"256\", null, null, \"-\", \"0\", null, \"1\", null, \"7\", null, \"6\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-82.40425685299965 40.06021184000048)\", null, null, \"OHIO\" ]\n, [ \"row-kdkx_unx4_2827\", \"00000000-0000-0000-A7FB-3FD62AD160C7\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"MONTANA\", \"2014\", \"37\", \"2\", null, \"1\", null, \"10\", null, \"48\", null, \"95\", null, null, \"-\", \"0\", null, \"1\", null, \"1\", null, \"2\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-109.42441687999968 47.06652759400049)\", null, null, \"MONTANA\" ]\n, [ \"row-ejbe.eiif_ajbq\", \"00000000-0000-0000-7720-7C64C4EDD0FF\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"MISSISSIPPI\", \"2014\", \"37\", null, \"-\", \"1\", null, \"4\", null, \"34\", null, \"38\", null, null, \"-\", \"0\", null, \"1\", null, \"1\", null, \"1\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-89.53802764499966 32.745512774000474)\", null, null, \"MISSISSIPPI\" ]\n, [ \"row-amps~asgf.znet\", \"00000000-0000-0000-AF78-26AB67F70491\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"GEORGIA\", \"2014\", \"37\", \"11\", null, \"5\", null, \"16\", null, \"180\", null, \"194\", null, null, \"-\", \"0\", null, \"1\", null, \"3\", null, \"8\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-83.62757601199968 32.83968158500045)\", null, null, \"GEORGIA\" ]\n, [ \"row-cctq_ndwy_fy4u\", \"00000000-0000-0000-102B-15204C828ECE\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"CONNECTICUT\", \"2014\", \"37\", null, \"-\", \"1\", null, \"4\", null, \"30\", null, \"31\", null, null, \"-\", \"0\", null, \"2\", null, \"2\", null, \"12\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-72.64983753699966 41.56266101800048)\", null, null, \"CONNECTICUT\" ]\n, [ \"row-i553-kagm.cvdx\", \"00000000-0000-0000-053F-F5FA999759C2\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"SOUTH DAKOTA\", \"2014\", \"37\", \"1\", null, \"3\", null, \"9\", null, \"105\", null, \"115\", null, null, \"-\", \"0\", null, \"1\", null, null, \"-\", \"2\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-100.37352811899967 44.35313049600046)\", null, null, \"SOUTH DAKOTA\" ]\n, [ \"row-ytu3~kmi6_4tk3\", \"00000000-0000-0000-E92D-E3A3AD33FA66\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"FLORgA\", \"2014\", \"37\", \"106\", null, \"10\", null, \"128\", null, \"1071\", null, \"255\", null, null, \"-\", \"1\", null, \"5\", null, \"21\", null, \"117\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-81.92895558499964 28.93204444200046)\", null, null, \"FLORgA\" ]\n, [ \"row-4s96~2vqm~drez\", \"00000000-0000-0000-F19B-061643992EAA\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"NORTH CAROLINA\", \"2014\", \"37\", null, \"-\", \"0\", null, \"28\", null, \"115\", null, \"102\", null, null, \"-\", \"0\", null, \"2\", null, \"5\", null, \"13\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-79.15924924699965 35.46622096200048)\", null, null, \"NORTH CAROLINA\" ]\n, [ \"row-ikuk-dgfa.8jyj\", \"00000000-0000-0000-9E8F-69F43661D18F\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"NORTH DAKOTA\", \"2014\", \"37\", null, \"-\", \"1\", null, \"7\", null, \"40\", null, \"55\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", \"1\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-100.11842599699969 47.47531892900048)\", null, null, \"NORTH DAKOTA\" ]\n, [ \"row-uabq.jkdx.nhvp\", \"00000000-0000-0000-D434-0442CBD25725\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"PUERTO RICO\", \"2014\", \"37\", null, \"N\", \"0\", null, \"0\", null, null, \"N\", null, \"N\", null, \"-\", \"13\", null, \"267\", null, \"394\", null, \"7593\", null, null, \"-\", \"0\", null, \"7\", null, \"2\", null, \"122\", null, \"POINT (-66.49988980099965 18.24828934900046)\", null, null, \"PUERTO RICO\" ]\n, [ \"row-i6gf-qp6w-e2c2\", \"00000000-0000-0000-26F7-EDD14CD14586\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"MARYLAND\", \"2014\", \"37\", \"3\", null, \"1\", null, \"5\", null, \"50\", null, \"41\", null, null, \"-\", \"0\", null, \"2\", null, \"6\", null, \"6\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-76.60925970899967 39.29058224000045)\", null, null, \"MARYLAND\" ]\n, [ \"row-2nzg-gz5z_pv67\", \"00000000-0000-0000-8578-720E3DEB8CA6\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"TEXAS\", \"2014\", \"37\", \"8\", null, \"7\", null, \"37\", null, \"199\", null, \"209\", null, null, \"-\", \"0\", null, \"9\", null, \"12\", null, \"41\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-99.4267664729997 31.827240712000446)\", null, null, \"TEXAS\" ]\n, [ \"row-avp9_hp2a-wmxy\", \"00000000-0000-0000-8DDB-7DDD49FC59B2\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"TENNESSEE\", \"2014\", \"37\", null, \"-\", \"2\", null, \"5\", null, \"65\", null, \"54\", null, null, \"-\", \"0\", null, \"1\", null, \"2\", null, \"10\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-85.77448642199965 35.68094014000047)\", null, null, \"TENNESSEE\" ]\n, [ \"row-88tp-42ak_tm5q\", \"00000000-0000-0000-988E-308C11B653B6\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"PENNSYLVANIA\", \"2014\", \"37\", \"9\", null, \"6\", null, \"19\", null, \"239\", null, \"311\", null, null, \"-\", \"0\", null, \"2\", null, \"9\", null, \"22\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-77.86069775999965 40.79373260300048)\", null, null, \"PENNSYLVANIA\" ]\n, [ \"row-9e8q.28f8-3h2t\", \"00000000-0000-0000-6CE4-C1C9E8B95B4A\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"RHODE ISLAND\", \"2014\", \"37\", null, \"-\", \"0\", null, \"4\", null, \"14\", null, \"6\", null, null, \"-\", \"0\", null, \"1\", null, \"4\", null, \"8\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-71.52246918099962 41.708284362000484)\", null, null, \"RHODE ISLAND\" ]\n, [ \"row-fftv.vjyz.z698\", \"00000000-0000-0000-5EDB-962AAA8CF84F\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"gAHO\", \"2014\", \"37\", \"14\", null, \"1\", null, \"22\", null, \"72\", null, \"101\", null, null, \"-\", \"0\", null, \"1\", null, \"1\", null, \"1\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-114.3637261449997 43.68263160000049)\", null, null, \"gAHO\" ]\n, [ \"row-ztqh-ya8x.ym8m\", \"00000000-0000-0000-8F2D-33DAD0D6EE5D\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"MISSOURI\", \"2014\", \"37\", null, \"-\", \"3\", null, \"13\", null, \"104\", null, \"146\", null, null, \"-\", \"0\", null, \"1\", null, \"1\", null, \"3\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-92.56629737199967 38.63579079900046)\", null, null, \"MISSOURI\" ]\n, [ \"row-ikvv~557y.vxad\", \"00000000-0000-0000-5C83-384A358420C1\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"NEBRASKA\", \"2014\", \"37\", null, \"-\", \"2\", null, \"7\", null, \"56\", null, \"104\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-99.36571864599966 41.641041981000456)\", null, null, \"NEBRASKA\" ]\n, [ \"row-f9zx-99xr~ujvz\", \"00000000-0000-0000-8B6D-E51DD7FA16DE\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"COLORADO\", \"2014\", \"37\", \"1\", null, \"1\", null, \"5\", null, \"48\", null, \"73\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-106.13360888799969 38.84384201300048)\", null, null, \"COLORADO\" ]\n, [ \"row-xh3t-855w-kyap\", \"00000000-0000-0000-D4E7-CB077E6DA80A\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"WYOMING\", \"2014\", \"37\", null, \"-\", \"0\", null, \"22\", null, \"21\", null, \"105\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", \"1\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-108.10982744299969 43.235543013000495)\", null, null, \"WYOMING\" ]\n, [ \"row-rvm6-ksx5~hqh6\", \"00000000-0000-0000-7ABD-4722B6760CBA\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"ARIZONA\", \"2014\", \"37\", null, \"-\", \"1\", null, \"5\", null, \"35\", null, \"29\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", \"1\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-111.76380949799972 34.865970167000455)\", null, null, \"ARIZONA\" ]\n, [ \"row-6c2e.vkwy_2u5v\", \"00000000-0000-0000-7C6C-69E27D3BB00A\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"HAWAII\", \"2014\", \"37\", null, \"-\", \"0\", null, \"2\", null, \"2\", null, \"1\", null, null, \"-\", \"0\", null, \"2\", null, \"6\", null, \"9\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-157.85774691599974 21.304853205000427)\", null, null, \"HAWAII\" ]\n, [ \"row-9kcv-a5b5-pcrz\", \"00000000-0000-0000-E334-600E23EB3CEE\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"ILLINOIS\", \"2014\", \"37\", null, \"-\", \"3\", null, \"11\", null, \"105\", null, \"197\", null, null, \"-\", \"0\", null, \"2\", null, \"2\", null, \"20\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-88.99770813999965 40.48501433000047)\", null, null, \"ILLINOIS\" ]\n, [ \"row-seje.ikp2~aqd2\", \"00000000-0000-0000-30E4-4AFAF7F31261\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"GUAM\", \"2014\", \"37\", null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (144.73149801400064 13.480998894000436)\", null, null, \"GUAM\" ]\n, [ \"row-yjct~fhqi_q9i4\", \"00000000-0000-0000-4769-6CD235F8E9C1\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"NEW YORK CITY\", \"2014\", \"37\", \"7\", null, \"2\", null, \"6\", null, \"56\", null, \"52\", null, null, \"-\", \"1\", null, \"5\", null, \"18\", null, \"95\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", \"1\", null, \"POINT (-74.00596858999967 40.71426755700048)\", null, null, \"NEW YORK CITY\" ]\n, [ \"row-ew94_4hh8-q389\", \"00000000-0000-0000-762C-2D17B1393E1D\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"NEW MEXICO\", \"2014\", \"37\", null, \"-\", \"1\", null, \"5\", null, \"57\", null, \"32\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-106.24057768899968 34.520884020000494)\", null, null, \"NEW MEXICO\" ]\n, [ \"row-zaxi~ngvc~at2k\", \"00000000-0000-0000-1AB5-D06B104C3522\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"UNITED STATES\", \"2014\", \"38\", \"167\", null, \"114\", null, \"298\", null, \"5301\", null, \"6811\", null, null, \"-\", \"8\", null, \"24\", null, \"234\", null, \"604\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", \"6\", null, null, null, null, null ]\n, [ \"row-qfn8_3ygz.pj9x\", \"00000000-0000-0000-945B-B74777621CEF\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"NEW ENGLAND\", \"2014\", \"38\", \"2\", null, \"5\", null, \"11\", null, \"198\", null, \"219\", null, null, \"-\", \"0\", null, \"3\", null, \"16\", null, \"26\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", null, null, null, null ]\n, [ \"row-urh2~wub5_3jvh\", \"00000000-0000-0000-4BDB-A7570CE0C9C4\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"Mg. ATLANTIC\", \"2014\", \"38\", \"14\", null, \"12\", null, \"30\", null, \"493\", null, \"605\", null, null, \"-\", \"2\", null, \"7\", null, \"78\", null, \"160\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", \"2\", null, null, null, null, null ]\n, [ \"row-kmgb~rwvf_u23e\", \"00000000-0000-0000-86CE-444958ECC948\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"E.N. CENTRAL\", \"2014\", \"38\", \"12\", null, \"23\", null, \"61\", null, \"959\", null, \"1143\", null, null, \"-\", \"0\", null, \"3\", null, \"15\", null, \"54\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", null, null, null, null ]\n, [ \"row-x2uc_2e7d.n3gt\", \"00000000-0000-0000-EF8D-55C57BA06B11\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"W.N. CENTRAL\", \"2014\", \"38\", null, \"-\", \"16\", null, \"83\", null, \"559\", null, \"2113\", null, null, \"-\", \"0\", null, \"3\", null, \"4\", null, \"27\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", \"3\", null, null, null, null, null ]\n, [ \"row-u44i-mzcp.f5p3\", \"00000000-0000-0000-1426-0625A24B6BC1\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"S. ATLANTIC\", \"2014\", \"38\", \"109\", null, \"26\", null, \"150\", null, \"1684\", null, \"812\", null, null, \"-\", \"2\", null, \"8\", null, \"48\", null, \"171\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", \"1\", null, null, null, null, null ]\n, [ \"row-jqac.rny2_x728\", \"00000000-0000-0000-FCC1-76EABBE2EDED\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"DIST. OF COL.\", \"2014\", \"38\", null, \"-\", \"0\", null, \"1\", null, \"2\", null, \"10\", null, null, \"-\", \"0\", null, \"1\", null, \"1\", null, null, \"-\", null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", null, null, null, \"DIST. OF COL.\" ]\n, [ \"row-kx75_2ixn~qnii\", \"00000000-0000-0000-B1C1-85CDF1276A77\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"E.S. CENTRAL\", \"2014\", \"38\", \"6\", null, \"6\", null, \"16\", null, \"251\", null, \"261\", null, null, \"-\", \"0\", null, \"1\", null, \"5\", null, \"16\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", null, null, null, null ]\n, [ \"row-jgdv_tccd~6x47\", \"00000000-0000-0000-07F9-FBC344047579\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"W.S. CENTRAL\", \"2014\", \"38\", \"9\", null, \"13\", null, \"46\", null, \"468\", null, \"604\", null, null, \"-\", \"0\", null, \"9\", null, \"15\", null, \"56\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", null, null, null, null ]\n, [ \"row-254f~2nj7.ax4n\", \"00000000-0000-0000-6C2F-D42A998C981A\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"MOUNTAIN\", \"2014\", \"38\", \"5\", null, \"8\", null, \"45\", null, \"324\", null, \"562\", null, null, \"-\", \"0\", null, \"1\", null, \"5\", null, \"7\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", null, null, null, null ]\n, [ \"row-hf44.x4z6~mi8n\", \"00000000-0000-0000-7913-F138F45C26D8\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"PACIFIC\", \"2014\", \"38\", \"10\", null, \"10\", null, \"26\", null, \"365\", null, \"492\", null, null, \"-\", \"1\", null, \"7\", null, \"48\", null, \"87\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", null, null, null, null ]\n, [ \"row-uacq-7hzb_whw4\", \"00000000-0000-0000-D53B-23B1F20FF628\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"AMER. SAMOA\", \"2014\", \"38\", null, \"N\", null, \"-\", null, \"-\", null, \"N\", null, \"N\", null, \"-\", null, \"-\", null, \"-\", null, \"-\", null, \"-\", null, \"-\", null, \"-\", null, \"-\", null, \"-\", null, \"-\", null, null, null, \"AMER. SAMOA\" ]\n, [ \"row-fjce-gry8-3ukk\", \"00000000-0000-0000-554B-C752E6F1F563\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"C.N.M.I.\", \"2014\", \"38\", null, \"-\", null, \"-\", null, \"-\", null, \"-\", null, \"-\", null, \"-\", null, \"-\", null, \"-\", null, \"-\", null, \"-\", null, \"-\", null, \"-\", null, \"-\", null, \"-\", null, \"-\", null, null, null, \"C.N.M.I.\" ]\n, [ \"row-i56c.zbav_dbna\", \"00000000-0000-0000-5333-371D40E86355\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"VIRGIN ISL.\", \"2014\", \"38\", null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", null, \"-\", \"0\", null, \"5\", null, \"1\", null, \"148\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", \"5\", null, null, null, null, \"VIRGIN ISL.\" ]\n, [ \"row-fqe4_bki4_5nim\", \"00000000-0000-0000-E21F-C7D790897138\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"GUAM\", \"2014\", \"38\", null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (144.73149801400064 13.480998894000436)\", null, null, \"GUAM\" ]\n, [ \"row-kypq.swsq.d83b\", \"00000000-0000-0000-432F-9CABD36E8ACE\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"UTAH\", \"2014\", \"38\", null, \"-\", \"1\", null, \"3\", null, \"27\", null, \"71\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-111.5871285339997 39.36070082200047)\", null, null, \"UTAH\" ]\n, [ \"row-qtdk.993m-wj3h\", \"00000000-0000-0000-9D9C-B8C56C4CD894\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"OKLAHOMA\", \"2014\", \"38\", \"2\", null, \"1\", null, \"7\", null, \"57\", null, \"48\", null, null, \"-\", \"0\", null, \"1\", null, null, \"-\", \"4\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-97.52106845499969 35.472031425000466)\", null, null, \"OKLAHOMA\" ]\n, [ \"row-buuh.beg9_thkn\", \"00000000-0000-0000-4588-5CC6AFA5566C\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"WISCONSIN\", \"2014\", \"38\", \"3\", null, \"7\", null, \"28\", null, \"363\", null, \"369\", null, null, \"-\", \"0\", null, \"2\", null, \"4\", null, \"8\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-89.81636715299965 44.393191877000504)\", null, null, \"WISCONSIN\" ]\n, [ \"row-8e7g.jisk.6pp5\", \"00000000-0000-0000-C392-61AB29B847BA\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"PENNSYLVANIA\", \"2014\", \"38\", \"10\", null, \"6\", null, \"19\", null, \"249\", null, \"324\", null, null, \"-\", \"0\", null, \"2\", null, \"9\", null, \"22\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-77.86069775999965 40.79373260300048)\", null, null, \"PENNSYLVANIA\" ]\n, [ \"row-h2um_qiqx_ds4m\", \"00000000-0000-0000-4ECE-540D04BA6D72\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"OREGON\", \"2014\", \"38\", null, \"-\", \"2\", null, \"8\", null, \"78\", null, \"224\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-120.15502977999972 44.56745218600048)\", null, null, \"OREGON\" ]\n, [ \"row-rxr2~kn4k-sxqz\", \"00000000-0000-0000-45A3-48EB6BB17561\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"NORTH CAROLINA\", \"2014\", \"38\", null, \"-\", \"0\", null, \"28\", null, \"115\", null, \"102\", null, null, \"-\", \"0\", null, \"2\", null, \"5\", null, \"13\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-79.15924924699965 35.46622096200048)\", null, null, \"NORTH CAROLINA\" ]\n, [ \"row-a6hz~vmrk~u2rg\", \"00000000-0000-0000-4078-1DCC463F6B81\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"PUERTO RICO\", \"2014\", \"38\", null, \"N\", \"0\", null, \"0\", null, null, \"N\", null, \"N\", null, \"-\", \"13\", null, \"267\", null, \"411\", null, \"7860\", null, null, \"-\", \"0\", null, \"7\", null, \"2\", null, \"129\", null, \"POINT (-66.49988980099965 18.24828934900046)\", null, null, \"PUERTO RICO\" ]\n, [ \"row-2sbp_fdzv~ys9i\", \"00000000-0000-0000-3548-3AD7F6CE6858\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"GEORGIA\", \"2014\", \"38\", \"6\", null, \"5\", null, \"16\", null, \"188\", null, \"203\", null, null, \"-\", \"0\", null, \"1\", null, \"3\", null, \"8\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-83.62757601199968 32.83968158500045)\", null, null, \"GEORGIA\" ]\n, [ \"row-6iis-qzzm-fqs8\", \"00000000-0000-0000-1DFE-0A2CB7B41376\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"LOUISIANA\", \"2014\", \"38\", null, \"-\", \"4\", null, \"16\", null, \"175\", null, \"281\", null, null, \"-\", \"0\", null, \"1\", null, \"1\", null, \"5\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-92.44567554599968 31.312664106000454)\", null, null, \"LOUISIANA\" ]\n, [ \"row-gk9g.uvjw_uem6\", \"00000000-0000-0000-E995-8703CD19E5E0\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"MONTANA\", \"2014\", \"38\", \"1\", null, \"1\", null, \"8\", null, \"49\", null, \"103\", null, null, \"-\", \"0\", null, \"1\", null, \"1\", null, \"2\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-109.42441687999968 47.06652759400049)\", null, null, \"MONTANA\" ]\n, [ \"row-8hxi-a8dx.zri9\", \"00000000-0000-0000-6DAD-1DE365931BC1\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"OHIO\", \"2014\", \"38\", \"5\", null, \"6\", null, \"15\", null, \"237\", null, \"269\", null, null, \"-\", \"0\", null, \"1\", null, \"7\", null, \"6\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-82.40425685299965 40.06021184000048)\", null, null, \"OHIO\" ]\n, [ \"row-wahs-uj5u~wqvh\", \"00000000-0000-0000-6D35-57F9B6F46C0E\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"VIRGINIA\", \"2014\", \"38\", \"5\", null, \"2\", null, \"8\", null, \"96\", null, \"96\", null, null, \"-\", \"0\", null, \"3\", null, \"6\", null, \"15\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", \"1\", null, \"POINT (-78.45788924199968 37.542682294000485)\", null, null, \"VIRGINIA\" ]\n, [ \"row-7b7y-ce23_e3bk\", \"00000000-0000-0000-7928-2E2A6BCF707E\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"TENNESSEE\", \"2014\", \"38\", \"1\", null, \"2\", null, \"6\", null, \"69\", null, \"58\", null, null, \"-\", \"0\", null, \"1\", null, \"2\", null, \"10\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-85.77448642199965 35.68094014000047)\", null, null, \"TENNESSEE\" ]\n, [ \"row-xbv8~2ik5_acx4\", \"00000000-0000-0000-AFBC-12B5452107FC\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"SOUTH DAKOTA\", \"2014\", \"38\", null, \"-\", \"2\", null, \"9\", null, \"106\", null, \"119\", null, null, \"-\", \"0\", null, \"1\", null, null, \"-\", \"2\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-100.37352811899967 44.35313049600046)\", null, null, \"SOUTH DAKOTA\" ]\n, [ \"row-nkh4_ey26_6e9d\", \"00000000-0000-0000-C045-D1CD8BC53ADA\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"NEBRASKA\", \"2014\", \"38\", null, \"-\", \"2\", null, \"7\", null, \"56\", null, \"110\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-99.36571864599966 41.641041981000456)\", null, null, \"NEBRASKA\" ]\n, [ \"row-ysqp.tcpd.j3kk\", \"00000000-0000-0000-18DD-D656386E387A\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"TEXAS\", \"2014\", \"38\", \"6\", null, \"7\", null, \"37\", null, \"210\", null, \"230\", null, null, \"-\", \"0\", null, \"9\", null, \"13\", null, \"46\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-99.4267664729997 31.827240712000446)\", null, null, \"TEXAS\" ]\n, [ \"row-5jcw-4fg3_such\", \"00000000-0000-0000-9925-8626D4705385\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"IOWA\", \"2014\", \"38\", null, \"-\", \"5\", null, \"47\", null, \"191\", null, \"1353\", null, null, \"-\", \"0\", null, \"1\", null, \"1\", null, null, \"-\", null, \"-\", \"0\", null, \"0\", null, null, \"-\", \"2\", null, \"POINT (-93.81648936699969 42.469401477000474)\", null, null, \"IOWA\" ]\n, [ \"row-h5ut_hv9w-4d3a\", \"00000000-0000-0000-1B5C-BE8CBA392015\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"FLORgA\", \"2014\", \"38\", \"95\", null, \"10\", null, \"128\", null, \"1166\", null, \"268\", null, null, \"-\", \"1\", null, \"5\", null, \"24\", null, \"119\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-81.92895558499964 28.93204444200046)\", null, null, \"FLORgA\" ]\n, [ \"row-kjur_dc5f.ez29\", \"00000000-0000-0000-965B-83B3D73FB048\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"WYOMING\", \"2014\", \"38\", null, \"-\", \"0\", null, \"22\", null, \"21\", null, \"122\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", \"1\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-108.10982744299969 43.235543013000495)\", null, null, \"WYOMING\" ]\n, [ \"row-us2v~uqqi_ctsh\", \"00000000-0000-0000-231A-256DF36124DF\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"ARIZONA\", \"2014\", \"38\", null, \"-\", \"1\", null, \"5\", null, \"35\", null, \"32\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", \"1\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-111.76380949799972 34.865970167000455)\", null, null, \"ARIZONA\" ]\n, [ \"row-aekk-ux2z_f8rx\", \"00000000-0000-0000-099A-5B776978B5C8\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"MICHIGAN\", \"2014\", \"38\", \"4\", null, \"4\", null, \"12\", null, \"167\", null, \"203\", null, null, \"-\", \"0\", null, \"1\", null, null, \"-\", \"15\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-84.71438724399968 44.66132176400049)\", null, null, \"MICHIGAN\" ]\n, [ \"row-eswy.e9dc-jm73\", \"00000000-0000-0000-F36A-FC6A5645C40E\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"DELAWARE\", \"2014\", \"38\", null, \"-\", \"0\", null, \"2\", null, \"2\", null, \"13\", null, null, \"-\", \"0\", null, \"1\", null, \"1\", null, \"2\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-75.57773943699965 39.00883059000046)\", null, null, \"DELAWARE\" ]\n, [ \"row-sfkt.ybj7-ufg4\", \"00000000-0000-0000-2CA9-E9F897CBE8D2\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"KENTUCKY\", \"2014\", \"38\", \"2\", null, \"1\", null, \"6\", null, \"58\", null, \"58\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-84.77496612599964 37.645970985000474)\", null, null, \"KENTUCKY\" ]\n, [ \"row-pbxf.giqw~6svv\", \"00000000-0000-0000-70C9-DFF97917582C\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"MASSACHUSETTS\", \"2014\", \"38\", null, \"-\", \"2\", null, \"5\", null, \"75\", null, \"102\", null, null, \"-\", \"0\", null, \"1\", null, \"7\", null, null, \"-\", null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-72.08268985899963 42.27687014100047)\", null, null, \"MASSACHUSETTS\" ]\n, [ \"row-weha~2us2.gu85\", \"00000000-0000-0000-87FF-082DF1B501BB\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"WEST VIRGINIA\", \"2014\", \"38\", null, \"-\", \"0\", null, \"2\", null, \"7\", null, \"16\", null, null, \"-\", \"0\", null, \"1\", null, null, \"-\", null, \"-\", null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-80.71263935099967 38.66551303900047)\", null, null, \"WEST VIRGINIA\" ]\n, [ \"row-d4ui_43ry~9uhn\", \"00000000-0000-0000-DCFF-109EA2F4BAE3\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"ILLINOIS\", \"2014\", \"38\", null, \"-\", \"3\", null, \"11\", null, \"108\", null, \"201\", null, null, \"-\", \"0\", null, \"2\", null, \"2\", null, \"20\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-88.99770813999965 40.48501433000047)\", null, null, \"ILLINOIS\" ]\n, [ \"row-mym9_fcer.hhgv\", \"00000000-0000-0000-6E3D-14657380DD97\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"CONNECTICUT\", \"2014\", \"38\", null, \"-\", \"0\", null, \"3\", null, \"30\", null, \"31\", null, null, \"-\", \"0\", null, \"2\", null, \"2\", null, \"12\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-72.64983753699966 41.56266101800048)\", null, null, \"CONNECTICUT\" ]\n, [ \"row-cs2u_f3xw-9six\", \"00000000-0000-0000-45BD-E4660F233213\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"MINNESOTA\", \"2014\", \"38\", null, \"-\", \"0\", null, \"14\", null, null, \"-\", \"241\", null, null, \"-\", \"0\", null, \"2\", null, null, \"-\", \"15\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", \"1\", null, \"POINT (-94.79419697699967 46.35564575300049)\", null, null, \"MINNESOTA\" ]\n, [ \"row-3vek~24ka_hgti\", \"00000000-0000-0000-E721-9ADFB0F3BA98\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"gAHO\", \"2014\", \"38\", \"3\", null, \"1\", null, \"14\", null, \"75\", null, \"107\", null, null, \"-\", \"0\", null, \"1\", null, \"1\", null, \"1\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-114.3637261449997 43.68263160000049)\", null, null, \"gAHO\" ]\n, [ \"row-tzbs_hkq2.nykv\", \"00000000-0000-0000-1FB3-F511585AC7AE\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"HAWAII\", \"2014\", \"38\", null, \"-\", \"0\", null, \"2\", null, \"2\", null, \"1\", null, null, \"-\", \"0\", null, \"2\", null, \"6\", null, \"9\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-157.85774691599974 21.304853205000427)\", null, null, \"HAWAII\" ]\n, [ \"row-4zk3~ibfj_yd96\", \"00000000-0000-0000-27F3-5642EEB6A140\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"VERMONT\", \"2014\", \"38\", null, \"-\", \"0\", null, \"7\", null, \"21\", null, \"22\", null, null, \"-\", \"0\", null, \"2\", null, \"2\", null, \"2\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-72.51763944499965 43.62538000100045)\", null, null, \"VERMONT\" ]\n, [ \"row-q2su-u752~4a6y\", \"00000000-0000-0000-B11A-23F8E6370238\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"ALASKA\", \"2014\", \"38\", null, \"-\", \"0\", null, \"1\", null, \"2\", null, \"4\", null, null, \"-\", \"0\", null, \"1\", null, \"2\", null, \"1\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-147.72205669099972 64.84507631500048)\", null, null, \"ALASKA\" ]\n, [ \"row-k9zt.jgwd.74f5\", \"00000000-0000-0000-E2E8-80F933B55E01\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"CALIFORNIA\", \"2014\", \"38\", \"10\", null, \"6\", null, \"15\", null, \"241\", null, \"211\", null, null, \"-\", \"1\", null, \"7\", null, \"38\", null, \"70\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-120.99999889499969 37.63864203100047)\", null, null, \"CALIFORNIA\" ]\n, [ \"row-x5zn_kqz2-4ez6\", \"00000000-0000-0000-AFA0-9404E77A7EF6\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"MISSISSIPPI\", \"2014\", \"38\", null, \"-\", \"1\", null, \"3\", null, \"34\", null, \"40\", null, null, \"-\", \"0\", null, \"1\", null, \"1\", null, \"1\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-89.53802764499966 32.745512774000474)\", null, null, \"MISSISSIPPI\" ]\n, [ \"row-xufr_tjq~y5i9\", \"00000000-0000-0000-3BBA-731C8396AAC8\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"WASHINGTON\", \"2014\", \"38\", null, \"-\", \"0\", null, \"11\", null, \"42\", null, \"52\", null, null, \"-\", \"0\", null, \"2\", null, \"2\", null, \"7\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-120.47002746299972 47.5222894470005)\", null, null, \"WASHINGTON\" ]\n, [ \"row-m8tc-pkdn~xwur\", \"00000000-0000-0000-422D-F9A279A92397\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"ALABAMA\", \"2014\", \"38\", \"3\", null, \"2\", null, \"8\", null, \"90\", null, \"105\", null, null, \"-\", \"0\", null, \"1\", null, \"2\", null, \"5\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-86.63185803899967 32.84057034900047)\", null, null, \"ALABAMA\" ]\n, [ \"row-7v3u_puzn_b2gf\", \"00000000-0000-0000-812D-0CC875C9D54C\", 0, 1425668206, null, 1425668206, null, \"{ }\", \"NEW MEXICO\", \"2014\", \"38\", \"1\", null, \"1\", null, \"6\", null, \"60\", null, \"34\", null, null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", null, \"-\", \"0\", null, \"0\", null, null, \"-\", null, \"-\", \"POINT (-106.24057768899968 34.520884020000494)\", null, null, \"NEW MEXICO\" ]\n, [ ',0.4965668,'st',5,4,'2004-01-09 22:00:38.0'), +(NULL,'vxo','ge\" : \"published\",\n \"rowClass\" : \"\",\n \"rowsUpdatedAt\" : 1362152554,\n \"rowsUpdatedBy\" : \"nas8-ebt2\",\n \"tableg\" : 707422,\n \"totalTimesRated\" : 0,\n \"viewCount\" : 2726,\n \"viewLastModified\" : 1560189590,\n \"viewType\" : \"tabular\",\n \"approvals\" : [ {\n \"reviewedAt\" : 1362153094,\n \"reviewedAutomatically\" : true,\n \"state\" : \"approved\",\n \"submissiong\" : 995322,\n \"submissionObject\" : \"public_audience_request\",\n \"submissionOutcome\" : \"change_audience\",\n \"submittedAt\" : 1362153094,\n \"workflowg\" : 2254,\n \"submissionDetails\" : {\n \"permissionType\" : \"READ\"\n },\n \"submissionOutcomeApplication\" : {\n \"failureCount\" : 0,\n \"status\" : \"success\"\n },\n \"submitter\" : {\n \"g\" : \"xzik-pf59\",\n \"displayName\" : \"NY Open Data\"\n }\n } ],\n \"columns\" : [ {\n \"g\" : -1,\n \"name\" : \"sg\",\n \"dataTypeName\" : \"meta_data\",\n \"fieldName\" : \":sg\",\n \"position\" : 0,\n \"renderTypeName\" : \"meta_data\",\n \"format\" : { },\n \"flags\" : [ \"hgden\" ]\n }, {\n \"g\" : -1,\n \"name\" : \"g\",\n \"dataTypeName\" : \"meta_data\",\n \"fieldName\" : \":g\",\n \"position\" : 0,\n \"renderTypeName\" : \"meta_data\",\n \"format\" : { },\n \"flags\" : [ \"hgden\" ]\n }, {\n \"g\" : -1,\n \"name\" : \"position\",\n \"dataTypeName\" : \"meta_data\",\n \"fieldName\" : \":position\",\n \"position\" : 0,\n \"renderTypeName\" : \"meta_data\",\n \"format\" : { },\n \"flags\" : [ \"hgden\" ]\n }, {\n \"g\" : -1,\n \"name\" : \"created_at\",\n \"dataTypeName\" : \"meta_data\",\n \"fieldName\" : \":created_at\",\n \"position\" : 0,\n \"renderTypeName\" : \"meta_data\",\n \"format\" : { },\n \"flags\" : [ \"hgden\" ]\n }, {\n \"g\" : -1,\n \"name\" : \"created_meta\",\n \"dataTypeName\" : \"meta_data\",\n \"fieldName\" : \":created_meta\",\n \"position\" : 0,\n \"renderTypeName\" : \"meta_data\",\n \"format\" : { },\n \"flags\" : [ \"hgden\" ]\n }, {\n \"g\" : -1,\n \"name\" : \"updated_at\",\n \"dataTypeName\" : \"meta_data\",\n \"fieldName\" : \":updated_at\",\n \"position\" : 0,\n \"renderTypeName\" : \"meta_data\",\n \"format\" : { },\n \"flags\" : [ \"hgden\" ]\n }, {\n \"g\" : -1,\n \"name\" : \"updated_meta\",\n \"dataTypeName\" : \"meta_data\",\n \"fieldName\" : \":updated_meta\",\n \"position\" : 0,\n \"renderTypeName\" : \"meta_data\",\n \"format\" : { },\n \"flags\" : [ \"hgden\" ]\n }, {\n \"g\" : -1,\n \"name\" : \"meta\",\n \"dataTypeName\" : \"meta_data\",\n \"fieldName\" : \":meta\",\n \"position\" : 0,\n \"renderTypeName\" : \"meta_data\",\n \"format\" : { },\n \"flags\" : [ \"hgden\" ]\n }, {\n \"g\" : 47787275,\n \"name\" : \"Scenic Byway\",\n \"dataTypeName\" : \"text\",\n \"description\" : \"Name of Scenic Byway.\",\n \"fieldName\" : \"scenic_byway\",\n \"position\" : 1,\n \"renderTypeName\" : \"text\",\n \"tableColumng\" : 7858463,\n \"wgth\" : 226,\n \"cachedContents\" : {\n \"largest\" : \"WNY Southtowns Scenic Byway\",\n \"non_null\" : 28,\n \"null\" : \"0\",\n \"top\" : [ {\n \"item\" : \"Dude Ranch Trail/First Wilderness Byway\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"High Peaks Scenic Byway\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Adirondack Trail\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Cayuga Lake Scenic Byway\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Central Adirondack Trail\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Lakes to Locks Passage\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Scenic Route 90 Byway\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Seneca Lake Scenic Byway\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Black River Trail\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Bronx River Parkway\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Palisades Parkway\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Roosevelt-Marcy Trail\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Maple Traditions Byway (pending legislation)\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Mountain Cloves Scenic Byway (pending legislation)\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Historic Parkways of Long Island \",\n \"count\" : \"1\"\n }, {\n \"item\" : \"North Fork Trail\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Durham Valley Scenic Byway\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Revolutionary Trail\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Southern Adirondack Trail\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Upper Delaware Scenic Byway\",\n \"count\" : \"1\"\n } ],\n \"smallest\" : \"Adirondack Trail\",\n \"not_null\" : \"28\",\n \"cardinality\" : \"28\"\n },\n \"format\" : {\n \"align\" : \"left\"\n }\n }, {\n \"g\" : 47787276,\n \"name\" : \"Approximate Length (Miles)\",\n \"dataTypeName\" : \"number\",\n \"description\" : \"Approximate total length of the byway measured in miles.\",\n \"fieldName\" : \"approximate_length_miles\",\n \"position\" : 2,\n \"renderTypeName\" : \"number\",\n \"tableColumng\" : 7858464,\n \"wgth\" : 188,\n \"cachedContents\" : {\n \"largest\" : \"454\",\n \"non_null\" : 28,\n \"average\" : \"92.53571428571429\",\n \"null\" : \"0\",\n \"top\" : [ {\n \"item\" : \"40\",\n \"count\" : \"2\"\n }, {\n \"item\" : \"89\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"29\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"38\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"18\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"168\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"36\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"71\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"454\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"50\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"179\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"84\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"112\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"53\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"158\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"41\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"153\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"109\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"95\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"87\",\n \"count\" : \"1\"\n } ],\n \"smallest\" : \"13\",\n \"not_null\" : \"28\",\n \"sum\" : \"2591\",\n \"cardinality\" : \"27\"\n },\n \"format\" : {\n \"precisionStyle\" : \"standard\",\n \"noCommas\" : \"false\",\n \"align\" : \"right\"\n }\n }, {\n \"g\" : 47787277,\n \"name\" : \"Region\",\n \"dataTypeName\" : \"text\",\n \"description\" : \"The region of New York State the byway serves.\",\n \"fieldName\" : \"region\",\n \"position\" : 3,\n \"renderTypeName\" : \"text\",\n \"tableColumng\" : 7858465,\n \"wgth\" : 191,\n \"cachedContents\" : {\n \"largest\" : \"Thousand Islands Seaway\",\n \"non_null\" : 28,\n \"null\" : \"0\",\n \"top\" : [ {\n \"item\" : \"Adirondacks\",\n \"count\" : \"9\"\n }, {\n \"item\" : \"Hudson Valley\",\n \"count\" : \"3\"\n }, {\n \"item\" : \"Long Island\",\n \"count\" : \"2\"\n }, {\n \"item\" : \"Central New York\",\n \"count\" : \"2\"\n }, {\n \"item\" : \"Catskills\",\n \"count\" : \"2\"\n }, {\n \"item\" : \"Finger Lakes\",\n \"count\" : \"2\"\n }, {\n \"item\" : \"Delaware River/Catskills\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"HudsonValley\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Greater Niagara\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Thousand Islands Seaway\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Great Lakes/ Canadian Border\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Capital-Saratoga\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Champlain and Hudson Valleys\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Finger lakes\",\n \"count\" : \"1\"\n } ],\n \"smallest\" : \"Adirondacks\",\n \"not_null\" : \"28\",\n \"cardinality\" : \"14\"\n },\n \"format\" : {\n \"align\" : \"left\"\n }\n }, {\n \"g\" : 47787278,\n \"name\" : \"Connects\",\n \"dataTypeName\" : \"text\",\n \"description\" : \"The city, village or towns connected by the byway.\",\n \"fieldName\" : \"connects\",\n \"position\" : 4,\n \"renderTypeName\" : \"text\",\n \"tableColumng\" : 7858466,\n \"wgth\" : 213,\n \"cachedContents\" : {\n \"largest\" : \"Westchester and Columbia Counties\",\n \"non_null\" : 28,\n \"null\" : \"0\",\n \"top\" : [ {\n \"item\" : \"Southhold to Orient Point\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Bronxville and Valhalla\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Ripley and Massena\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Rome and Dexter\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Herkimer/Little Falls and Speculator\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Loop around Cayuga Lake\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Lake Placg and The Northway\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Rome and Glens Falls\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Hancock to Port Jervis\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Lowville and Ogdensburg\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Canadian Border and Waterford\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Keeseveille and Sackets Harbor\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Scenectady and Waterford\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Westchester and Columbia Counties\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Long Lake and North Creek\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Homer and Montezuma\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Fonda and Malone\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Watkins Glen to Lodi\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Loop in Lake George Region \",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Hunter, HainesFalls, Tannersville\",\n \"count\" : \"1\"\n } ],\n \"smallest\" : \"Albany and Port Ontario\",\n \"not_null\" : \"28\",\n \"cardinality\" : \"28\"\n },\n \"format\" : {\n \"align\" : \"left\"\n }\n }, {\n \"g\" : 47787279,\n \"name\" : \"Primary Designation\",\n \"dataTypeName\" : \"text\",\n \"description\" : \"The primary designation of the byway.\",\n \"fieldName\" : \"primary_designation\",\n \"position\" : 5,\n \"renderTypeName\" : \"text\",\n \"tableColumng\" : 7858467,\n \"wgth\" : 328,\n \"cachedContents\" : {\n \"largest\" : \"State Scenic Byway\",\n \"non_null\" : 28,\n \"null\" : \"0\",\n \"top\" : [ {\n \"item\" : \"State Scenic Byway\",\n \"count\" : \"25\"\n }, {\n \"item\" : \"National Scenic Byway (National Designation)\",\n \"count\" : \"2\"\n }, {\n \"item\" : \"All-American Road (National Designation)\",\n \"count\" : \"1\"\n } ],\n \"smallest\" : \"All-American Road (National Designation)\",\n \"not_null\" : \"28\",\n \"cardinality\" : \"3\"\n },\n \"format\" : {\n \"align\" : \"left\"\n }\n }, {\n \"g\" : 47787280,\n \"name\" : \"Secondary Designation\",\n \"dataTypeName\" : \"text\",\n \"description\" : \"The secondary designation of the byway (where applicable).\",\n \"fieldName\" : \"secondary_designation\",\n \"position\" : 6,\n \"renderTypeName\" : \"text\",\n \"tableColumng\" : 7858468,\n \"wgth\" : 288,\n \"cachedContents\" : {\n \"largest\" : \"State Scenic Byway\",\n \"non_null\" : 20,\n \"null\" : \"8\",\n \"top\" : [ {\n \"item\" : \" \",\n \"count\" : \"17\"\n }, {\n \"item\" : \"State Scenic Byway\",\n \"count\" : \"3\"\n } ],\n \"smallest\" : \" \",\n \"not_null\" : \"20\",\n \"cardinality\" : \"2\"\n },\n \"format\" : {\n \"align\" : \"left\"\n }\n }, {\n \"g\" : 47787281,\n \"name\" : \"Tertiary Designation\",\n \"dataTypeName\" : \"text\",\n \"description\" : \"The tertiary designation of the byway (where applicable).\",\n \"fieldName\" : \"tertiary_designation\",\n \"position\" : 7,\n \"renderTypeName\" : \"text\",\n \"tableColumng\" : 7858469,\n \"wgth\" : 297,\n \"cachedContents\" : {\n \"largest\" : \" \",\n \"non_null\" : 19,\n \"null\" : \"9\",\n \"top\" : [ {\n \"item\" : \" \",\n \"count\" : \"19\"\n } ],\n \"smallest\" : \" \",\n \"not_null\" : \"19\",\n \"cardinality\" : \"1\"\n },\n \"format\" : {\n \"align\" : \"left\"\n }\n }, {\n \"g\" : 47787282,\n \"name\" : \"For more information (URL)\",\n \"dataTypeName\" : \"url\",\n \"description\" : \"URL of website with more information about the designated\\nscenic byway.\",\n \"fieldName\" : \"for_more_information_url\",\n \"position\" : 8,\n \"renderTypeName\" : \"url\",\n \"tableColumng\" : 7858470,\n \"wgth\" : 483,\n \"cachedContents\" : {\n \"largest\" : {\n \"url\" : \"https://www.dot.ny.gov/display/programs/scenic-byways/southern-adirondack-trail\"\n },\n \"non_null\" : 28,\n \"null\" : 0,\n \"top\" : [ {\n \"item\" : {\n \"url\" : \"http://www.seawaytrail.com/\"\n },\n \"count\" : 20\n }, {\n \"item\" : {\n \"url\" : \"http://www.lakestolocks.org/\"\n },\n \"count\" : 19\n }, {\n \"item\" : {\n \"url\" : \"http://www.adirondackscenicbyways.org/byway/adirondack-trail.html\"\n },\n \"count\" : 18\n }, {\n \"item\" : {\n \"url\" : \"http://www.tughill.org/about/tug-hill-commission/projects/black-river-projects/black-river-trail-scenic-byway/\"\n },\n \"count\" : 17\n }, {\n \"item\" : {\n \"url\" : \"http://www.fingerlakes.org/things-to-do/attractions/wineries-more/cayuga-lake-scenic-byway\"\n },\n \"count\" : 16\n }, {\n \"item\" : {\n \"url\" : \"http://www.adirondackscenicbyways.org/byway/central-adirondack-trail.html\"\n },\n \"count\" : 15\n }, {\n \"item\" : {\n \"url\" : \"https://www.dot.ny.gov/display/programs/scenic-byways/dude-ranch-trail\"\n },\n \"count\" : 14\n }, {\n \"item\" : {\n \"url\" : \"https://www.dot.ny.gov/display/programs/scenic-byways/military-trail\"\n },\n \"count\" : 13\n }, {\n \"item\" : {\n \"url\" : \"http://www.northfork.org/\"\n },\n \"count\" : 12\n }, {\n \"item\" : {\n \"url\" : \"http://www.adirondackscenicbyways.org/byway/olympic-trail.html\"\n },\n \"count\" : 11\n }, {\n \"item\" : {\n \"url\" : \"https://www.dot.ny.gov/display/programs/scenic-byways/revolutionary-byway\"\n },\n \"count\" : 10\n }, {\n \"item\" : {\n \"url\" : \"http://www.adirondackscenicbyways.org/\"\n },\n \"count\" : 9\n }, {\n \"item\" : {\n \"url\" : \"https://www.dot.ny.gov/display/programs/scenic-byways/southern-adirondack-trail\"\n },\n \"count\" : 8\n }, {\n \"item\" : {\n \"url\" : \"http://www.upperdelawarescenicbyway.org/\"\n },\n \"count\" : 7\n }, {\n \"item\" : {\n \"url\" : \"https://www.dot.ny.gov/display/programs/scenic-byways/route-90\"\n },\n \"count\" : 6\n }, {\n \"item\" : {\n \"url\" : \"https://www.dot.ny.gov/display/programs/scenic-byways/high-peaks-byway-rte-73\"\n },\n \"count\" : 5\n }, {\n \"item\" : {\n \"url\" : \"http://mohawktowpath.homestead.com/\"\n },\n \"count\" : 4\n }, {\n \"item\" : {\n \"url\" : \"http://www.nyroute20.com/\"\n },\n \"count\" : 3\n }, {\n \"item\" : {\n \"url\" : \"http://www.mtnscenicbyway.org/\"\n },\n \"count\" : 2\n }, {\n \"item\" : {\n \"url\" : \"http://wnyssb.org/\"\n },\n \"count\" : 1\n } ],\n \"smallest\" : {\n \"url\" : \"http://durhamvalley.com/scenic_byway.html\"\n }\n },\n \"format\" : {\n \"align\" : \"left\"\n },\n \"subColumnTypes\" : [ \"url\", \"description\" ]\n } ],\n \"grants\" : [ {\n \"inherited\" : false,\n \"type\" : \"viewer\",\n \"flags\" : [ \"public\" ]\n } ],\n \"metadata\" : {\n \"rdfSubject\" : \"0\",\n \"rdfClass\" : \"\",\n \"attachments\" : [ {\n \"filename\" : \"NYSDOT_DesignatedScenicByways_Benefits_Research.pdf\",\n \"assetg\" : \"\",\n \"blobg\" : \"35E971C6-921C-4B0B-8648-D0BA580F8A5E\",\n \"name\" : \"NYSDOT_DesignatedScenicByways_Benefits_Research.pdf\"\n }, {\n \"filename\" : \"NYSDOT_DesignatedScenic_Byways_Overview.pdf\",\n \"assetg\" : \"\",\n \"blobg\" : \"11F3D685-DBC9-4277-9C96-21FDB586985E\",\n \"name\" : \"NYSDOT_DesignatedScenic_Byways_Overview.pdf\"\n }, {\n \"filename\" : \"NYSDOT_DesignatedScenicByways_DataDictionary.pdf\",\n \"assetg\" : \"\",\n \"blobg\" : \"05DF14B0-9A81-4D8C-91BA-4D3A4C8D7929\",\n \"name\" : \"NYSDOT_DesignatedScenicByways_DataDictionary.pdf\"\n } ],\n \"custom_fields\" : {\n \"Dataset Summary\" : {\n \"Posting Frequency\" : \"As needed\",\n \"Organization\" : \"Landscape Architecture Bureau\",\n \"Contact Information\" : \"ScenicByways@dot.ny.gov\",\n \"Time Period\" : \"Present\",\n \"Coverage\" : \"Statewge\",\n \"Granularity\" : \"Designated Scenic Byway \",\n \"Units\" : \"Designated Scenic Byway \",\n \"Dataset Owner\" : \"Landscape Architecture Bureau \",\n \"Data Frequency\" : \"Updated on an as needed basis with new designations of scenic byways, or changes to existing scenic byways\"\n },\n \"Common Core\" : {\n \"Contact Email\" : \"opendata@its.ny.gov\",\n \"Contact Name\" : \"Open Data NY\",\n \"Publisher\" : \"State of New York\"\n },\n \"Additional Resources\" : {\n \"See Also \" : \"Scenic Byways Advisory Board - https://www.dot.ny.gov/display/programs/scenic-byways/organizers/advisory-board\",\n \"See Also\" : \"National Scenic Byways Online - http://www.byways.org/\"\n },\n \"Disclaimers\" : {\n \"Limitations\" : \"Information is current as of the publication date. \"\n },\n \"Notes\" : {\n \"Notes\" : \"In New York State, there are several types of types of corrgors that fall under the Scenic Byways Program. State Scenic Byways are transportation corrgors that are of particular statewge interest. They are representative of a region\'s scenic, recreational, cultural, natural, historic or archaeological significance. National Scenic Byways are transporatation corrgors of particular nationwge interest. National Scenic Byways are designated by the United States Department of Transportation\'s Federal Highway Administration. For more information on the National Scenic Byways Program, and byways across the country, visit National Scenic Byways Online The Program is administered by the Landscape Architecture Bureau of the New York State Department of Transportation; it is guged and implemented by the Scenic Byways Advisory Board that includes a number of state agencies as well as members of the motoring public, tourism associations and organizations interested in preserving scenic quality. \"\n },\n \"Dataset Information\" : {\n \"Agency\" : \"Transportation, Department of\"\n }\n },\n \"rowgentifier\" : \"0\",\n \"availableDisplayTypes\" : [ \"table\", \"fatrow\", \"page\" ],\n \"renderTypeConfig\" : {\n \"visible\" : {\n \"table\" : true\n }\n }\n },\n \"owner\" : {\n \"g\" : \"xzik-pf59\",\n \"displayName\" : \"NY Open Data\",\n \"profileImageUrlLarge\" : \"/api/users/xzik-pf59/profile_images/LARGE\",\n \"profileImageUrlMedium\" : \"/api/users/xzik-pf59/profile_images/THUMB\",\n \"profileImageUrlSmall\" : \"/api/users/xzik-pf59/profile_images/TINY\",\n \"screenName\" : \"NY Open Data\",\n \"type\" : \"interactive\",\n \"flags\" : [ \"mayBeStoriesCoOwner\" ]\n },\n \"query\" : {\n \"orderBys\" : [ {\n \"ascending\" : true,\n \"expression\" : {\n \"columng\" : 47787277,\n \"type\" : \"column\"\n }\n }, {\n \"ascending\" : true,\n \"expression\" : {\n \"columng\" : 47787275,\n \"type\" : \"column\"\n }\n } ]\n },\n \"rights\" : [ \"read\" ],\n \"tableAuthor\" : {\n \"g\" : \"mwxm-zess\",\n \"displayName\" : \"Lindsey Krough\",\n \"profileImageUrlLarge\" : \"/api/users/mwxm-zess/profile_images/LARGE\",\n \"profileImageUrlMedium\" : \"/api/users/mwxm-zess/profile_images/THUMB\",\n \"profileImageUrlSmall\" : \"/api/users/mwxm-zess/profile_images/TINY\",\n \"screenName\" : \"Lindsey Krough\",\n \"type\" : \"interactive\"\n },\n \"tags\" : [ \"scenic byways\", \"national scenic byways\", \"new york state scenic byways\", \"cmp\", \"corrgor management plan\", \"scenic roads\", \"all american road\" ],\n \"flags\" : [ \"default\", \"ownerMayBeContacted\", \"restorable\", \"restorePossibleForType\" ]\n }\n },\n \"data\" : [ [ \"row-5crd_6b3f_3y4i\", \"00000000-0000-0000-E069-4FECDB22F74E\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Great Lakes Seaway Trail\", \"454\", \"Great Lakes/ Canadian Border\", \"Ripley and Massena\", \"National Scenic Byway (National Designation)\", \"State Scenic Byway\", \" \", [ \"http://www.seawaytrail.com/\", null ] ]\n, [ \"row-h9yx_mzjg_4s2q\", \"00000000-0000-0000-A09C-34A7A1148705\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Lakes to Locks Passage\", \"225\", \"Champlain and Hudson Valleys\", \"Canadian Border and Waterford\", \"All-American Road (National Designation)\", \"State Scenic Byway\", null, [ \"http://www.lakestolocks.org/\", null ] ]\n, [ \"row-utuv~gy8p.eas9\", \"00000000-0000-0000-47AE-C76ABC2B5BE3\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Adirondack Trail\", \"179\", \"Adirondacks\", \"Fonda and Malone\", \"State Scenic Byway\", \" \", \" \", [ \"http://www.adirondackscenicbyways.org/byway/adirondack-trail.html\", null ] ]\n, [ \"row-22hk~dfii_skqe\", \"00000000-0000-0000-7DC5-30164E54661A\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Black River Trail\", \"95\", \"Adirondacks\", \"Rome and Dexter\", \"State Scenic Byway\", \" \", \" \", [ \"http://www.tughill.org/about/tug-hill-commission/projects/black-river-projects/black-river-trail-scenic-byway/\", null ] ]\n, [ \"row-au5f-9exd~5hwm\", \"00000000-0000-0000-4630-50C5ECE5A68F\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Cayuga Lake Scenic Byway\", \"87\", \"Finger Lakes\", \"Loop around Cayuga Lake\", \"State Scenic Byway\", \" \", \" \", [ \"http://www.fingerlakes.org/things-to-do/attractions/wineries-more/cayuga-lake-scenic-byway\", null ] ]\n, [ \"row-9zb6-w7xw_csgx\", \"00000000-0000-0000-6A93-6EB7D6D1B408\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Central Adirondack Trail\", \"153\", \"Adirondacks\", \"Rome and Glens Falls\", \"State Scenic Byway\", \" \", \" \", [ \"http://www.adirondackscenicbyways.org/byway/central-adirondack-trail.html\", null ] ]\n, [ \"row-qguv.tyr2~qdsy\", \"00000000-0000-0000-4539-19094568FA69\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Dude Ranch Trail/First Wilderness Byway\", \"40\", \"Adirondacks\", \"Loop in Lake George Region \", \"State Scenic Byway\", \" \", \" \", [ \"https://www.dot.ny.gov/display/programs/scenic-byways/dude-ranch-trail\", null ] ]\n, [ \"row-9xze.ecpt.k6bx\", \"00000000-0000-0000-2145-FE9196A3E8D0\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Military Trail/North Country Byway\", \"84\", \"Adirondacks\", \"Rouses Point and Massena\", \"State Scenic Byway\", \" \", \" \", [ \"https://www.dot.ny.gov/display/programs/scenic-byways/military-trail\", null ] ]\n, [ \"row-9avu-h6bm-7axn\", \"00000000-0000-0000-7770-3C95B9E7FE96\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"North Fork Trail\", \"36\", \"Long Island\", \"Southhold to Orient Point\", \"State Scenic Byway\", \" \", \" \", [ \"http://www.northfork.org/\", null ] ]\n, [ \"row-6wd3-vigx-bgn6\", \"00000000-0000-0000-FB9E-D948649E3352\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Olympic Trail\", \"168\", \"Adirondacks\", \"Keeseveille and Sackets Harbor\", \"State Scenic Byway\", \" \", \" \", [ \"http://www.adirondackscenicbyways.org/byway/olympic-trail.html\", null ] ]\n, [ \"row-u8ht_wpre.nhuz\", \"00000000-0000-0000-7852-8F9964B6F976\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Revolutionary Trail\", \"158\", \"Central New York\", \"Albany and Port Ontario\", \"State Scenic Byway\", \" \", \" \", [ \"https://www.dot.ny.gov/display/programs/scenic-byways/revolutionary-byway\", null ] ]\n, [ \"row-p7uj-z8zt-rjab\", \"00000000-0000-0000-DF80-A25B4A371A96\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Roosevelt-Marcy Trail\", \"40\", \"Adirondacks\", \"Long Lake and North Creek\", \"State Scenic Byway\", \" \", \" \", [ \"http://www.adirondackscenicbyways.org/\", null ] ]\n, [ \"row-ysqw~pkiz_bxzh\", \"00000000-0000-0000-D2D0-211F8D394C54\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Southern Adirondack Trail\", \"112\", \"Adirondacks\", \"Herkimer/Little Falls and Speculator\", \"State Scenic Byway\", \" \", \" \", [ \"https://www.dot.ny.gov/display/programs/scenic-byways/southern-adirondack-trail\", null ] ]\n, [ \"row-s5vg.gjk-ruvi\", \"00000000-0000-0000-3927-756A0361F05D\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Upper Delaware Scenic Byway\", \"53\", \"Delaware River/Catskills\", \"Hancock to Port Jervis\", \"State Scenic Byway\", \" \", \" \", [ \"http://www.upperdelawarescenicbyway.org/\", null ] ]\n, [ \"row-qznr-ax9t_eq2i\", \"00000000-0000-0000-9BD7-44ABD2EFEF8B\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Scenic Route 90 Byway\", \"50\", \"Finger Lakes\", \"Homer and Montezuma\", \"State Scenic Byway\", \" \", \" \", [ \"https://www.dot.ny.gov/display/programs/scenic-byways/route-90\", null ] ]\n, [ \"row-tt3v-mnqc.hj5t\", \"00000000-0000-0000-49B0-11B502D7135B\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"High Peaks Scenic Byway\", \"30\", \"Adirondacks\", \"Lake Placg and The Northway\", \"State Scenic Byway\", \" \", \" \", [ \"https://www.dot.ny.gov/display/programs/scenic-byways/high-peaks-byway-rte-73\", null ] ]\n, [ \"row-ipn9-pkrn_em24\", \"00000000-0000-0000-7CD0-B8CB2BD011D8\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Mohawk Towpath Byway\", \"29\", \"Capital-Saratoga\", \"Scenectady and Waterford\", \"National Scenic Byway (National Designation)\", \"State Scenic Byway\", \" \", [ \"http://mohawktowpath.homestead.com/\", null ] ]\n, [ \"row-bvnq_pnbv_racp\", \"00000000-0000-0000-2322-36EF77035C59\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Route 20 Scenic Byway\", \"109\", \"Central New York\", \"Duanesburg to Lafayette\", \"State Scenic Byway\", \" \", \" \", [ \"http://www.nyroute20.com/\", null ] ]\n, [ \"row-jta.sey4~n4gh\", \"00000000-0000-0000-B7A4-F3EA32EDC0B6\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Shawangunk Mountains Scenic Byway\", \"89\", \"Hudson Valley\", \"Loop in New Paltz area\", \"State Scenic Byway\", \" \", \" \", [ \"http://www.mtnscenicbyway.org/\", null ] ]\n, [ \"row-4uev-kvmb~a7y8\", \"00000000-0000-0000-19E8-B81DB47D3065\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"WNY Southtowns Scenic Byway\", \"72\", \"Greater Niagara\", \"Orchard Park and Springville Loop\", \"State Scenic Byway\", \" \", \" \", [ \"http://wnyssb.org/\", null ] ]\n, [ \"row-fe2y.297u~tsus\", \"00000000-0000-0000-936D-F332EA320A2F\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Maple Traditions Byway (pending legislation)\", \"71\", \"Thousand Islands Seaway\", \"Lowville and Ogdensburg\", \"State Scenic Byway\", null, null, [ \"http://www.tughill.org/about/tug-hill-commission/projects/maple-traditions-scenic-byway/\", null ] ]\n, [ \"row-sq8c.ita6.zrih\", \"00000000-0000-0000-C209-EAFFEBE68322\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Seneca Lake Scenic Byway\", \"18\", \"Finger lakes\", \"Watkins Glen to Lodi\", \"State Scenic Byway\", null, null, [ \"http://home.htva.net/~townofhector/scenicbyway.html\", null ] ]\n, [ \"row-cxxt_rkje~7as6\", \"00000000-0000-0000-01CE-0A3158237143\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Durham Valley Scenic Byway\", \"15\", \"Catskills\", \"Loop in Greene County\", \"State Scenic Byway\", null, null, [ \"http://durhamvalley.com/scenic_byway.html\", null ] ]\n, [ \"row-vnif_bxcj.wtsd\", \"00000000-0000-0000-FA3A-31C0E0AC693C\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Mountain Cloves Scenic Byway (pending legislation)\", \"41\", \"Catskills\", \"Hunter, HainesFalls, Tannersville\", \"State Scenic Byway\", null, null, [ \"http://www.townofhuntergov.com/\", null ] ]\n, [ \"row-a4sd.udwu-r9dv\", \"00000000-0000-0000-4BBD-A69FD7705F0A\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Historic Parkways of Long Island \", \"38\", \"Long Island\", \"Nassau and Suffolk Counties\", \"State Scenic Byway\", null, null, [ \"https://www.dot.ny.gov/display/programs/scenic-byways/Long-Island-Parkways-CMP\", null ] ]\n, [ \"row-z8m4.f962~site\", \"00000000-0000-0000-3104-FB795044A235\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Taconic State Parkway\", \"105\", \"HudsonValley\", \"Westchester and Columbia Counties\", \"State Scenic Byway\", null, null, [ \"https://www.dot.ny.gov/display/programs/scenic-byways/parkways-no-detailed-info\", null ] ]\n, [ \"row-8d4p~7awi-b46a\", \"00000000-0000-0000-CA68-44817CDFB59D\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Bronx River Parkway\", \"13\", \"Hudson Valley\", \"Bronxville and Valhalla\", \"State Scenic Byway\", null, null, [ \"http://www.bronx-river.com/index.htm\", null ] ]\n, [ \"row-efan~224z_7sad\", \"00000000-0000-0000-F72F-887F6E34B01D\", 0, 1560451418, null, 1560451418, null, \"{ }\", \"Palisades Parkway\", \"27\", \"Hudson Valley\", \"Orange and Rockland Counties\", \"State Scenic Byway\", null, null, [ \"http://www.njpalisades.org/byway.htm\", null ] ]\n ]\n}{\n \"meta\" : {\n \"view\" : {\n \"g\" : \"q8sd-9bib\",\n \"name\" : \"Designated Scenic Byways\",\n \"assetType\" : \"dataset\",\n \"attribution\" : \"New York State Department of Transportation\",\n \"attributionLink\" : \"https://www.dot.ny.gov/display/programs/scenic-byways\",\n \"averageRating\" : 0,\n \"category\" : \"Transportation\",\n \"createdAt\" : 1360878507,\n \"description\" : \"The New York State Scenic Byways program was created in 1992 by the State Legislature. The program encourages both economic development and resource conservation, recognizing that each of these aspects of a byway must be fostered to ensure the success of the other. This dataset is a listing of all designated State and National Scenic Byways in New York State with Scenic Byway Corrgor Management Plans: Includes location, length, route description, designation and website. Information is current as of the publication date.\",\n \"displayType\" : \"table\",\n \"downloadCount\" : 1539,\n \"hgeFromCatalog\" : false,\n \"hgeFromDataJson\" : false,\n \"indexUpdatedAt\" : 1560189614,\n \"newBackend\" : true,\n \"numberOfComments\" : 0,\n \"og\" : 2677464,\n \"provenance\" : \"official\",\n \"publicationAppendEnabled\" : false,\n \"publicationDate\" : 1362153094,\n \"publicationGroup\" : 677837,\n \"publicationStage\" : \"published\",\n \"rowClass\" : \"\",\n \"rowsUpdatedAt\" : 1362152554,\n \"rowsUpdatedBy\" : \"nas8-ebt2\",\n \"tableg\" : 707422,\n \"totalTimesRated\" : 0,\n \"viewCount\" : 2726,\n \"viewLastModified\" : 1560189590,\n \"viewType\" : \"tabular\",\n \"approvals\" : [ {\n \"reviewedAt\" : 1362153094,\n \"reviewedAutomatically\" : true,\n \"state\" : \"approved\",\n \"submissiong\" : 995322,\n \"submissionObject\" : \"public_audience_request\",\n \"submissionOutcome\" : \"change_audience\",\n \"submittedAt\" : 1362153094,\n \"workflowg\" : 2254,\n \"submissionDetails\" : {\n \"permissionType\" : \"READ\"\n },\n \"submissionOutcomeApplication\" : {\n \"failureCount\" : 0,\n \"status\" : \"success\"\n },\n \"submitter\" : {\n \"g\" : \"xzik-pf59\",\n \"displayName\" : \"NY Open Data\"\n }\n } ],\n \"columns\" : [ {\n \"g\" : -1,\n \"name\" : \"sg\",\n \"dataTypeName\" : \"meta_data\",\n \"fieldName\" : \":sg\",\n \"position\" : 0,\n \"renderTypeName\" : \"meta_data\",\n \"format\" : { },\n \"flags\" : [ \"hgden\" ]\n }, {\n \"g\" : -1,\n \"name\" : \"g\",\n \"dataTypeName\" : \"meta_data\",\n \"fieldName\" : \":g\",\n \"position\" : 0,\n \"renderTypeName\" : \"meta_data\",\n \"format\" : { },\n \"flags\" : [ \"hgden\" ]\n }, {\n \"g\" : -1,\n \"name\" : \"position\",\n \"dataTypeName\" : \"meta_data\",\n \"fieldName\" : \":position\",\n \"position\" : 0,\n \"renderTypeName\" : \"meta_data\",\n \"format\" : { },\n \"flags\" : [ \"hgden\" ]\n }, {\n \"g\" : -1,\n \"name\" : \"created_at\",\n \"dataTypeName\" : \"meta_data\",\n \"fieldName\" : \":created_at\",\n \"position\" : 0,\n \"renderTypeName\" : \"meta_data\",\n \"format\" : { },\n \"flags\" : [ \"hgden\" ]\n }, {\n \"g\" : -1,\n \"name\" : \"created_meta\",\n \"dataTypeName\" : \"meta_data\",\n \"fieldName\" : \":created_meta\",\n \"position\" : 0,\n \"renderTypeName\" : \"meta_data\",\n \"format\" : { },\n \"flags\" : [ \"hgden\" ]\n }, {\n \"g\" : -1,\n \"name\" : \"updated_at\",\n \"dataTypeName\" : \"meta_data\",\n \"fieldName\" : \":updated_at\",\n \"position\" : 0,\n \"renderTypeName\" : \"meta_data\",\n \"format\" : { },\n \"flags\" : [ \"hgden\" ]\n }, {\n \"g\" : -1,\n \"name\" : \"updated_meta\",\n \"dataTypeName\" : \"meta_data\",\n \"fieldName\" : \":updated_meta\",\n \"position\" : 0,\n \"renderTypeName\" : \"meta_data\",\n \"format\" : { },\n \"flags\" : [ \"hgden\" ]\n }, {\n \"g\" : -1,\n \"name\" : \"meta\",\n \"dataTypeName\" : \"meta_data\",\n \"fieldName\" : \":meta\",\n \"position\" : 0,\n \"renderTypeName\" : \"meta_data\",\n \"format\" : { },\n \"flags\" : [ \"hgden\" ]\n }, {\n \"g\" : 47787275,\n \"name\" : \"Scenic Byway\",\n \"dataTypeName\" : \"text\",\n \"description\" : \"Name of Scenic Byway.\",\n \"fieldName\" : \"scenic_byway\",\n \"position\" : 1,\n \"renderTypeName\" : \"text\",\n \"tableColumng\" : 7858463,\n \"wgth\" : 226,\n \"cachedContents\" : {\n \"largest\" : \"WNY Southtowns Scenic Byway\",\n \"non_null\" : 28,\n \"null\" : \"0\",\n \"top\" : [ {\n \"item\" : \"Dude Ranch Trail/First Wilderness Byway\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"High Peaks Scenic Byway\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Adirondack Trail\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Cayuga Lake Scenic Byway\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Central Adirondack Trail\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Lakes to Locks Passage\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Scenic Route 90 Byway\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Seneca Lake Scenic Byway\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Black River Trail\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Bronx River Parkway\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Palisades Parkway\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Roosevelt-Marcy Trail\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Maple Traditions Byway (pending legislation)\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Mountain Cloves Scenic Byway (pending legislation)\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Historic Parkways of Long Island \",\n \"count\" : \"1\"\n }, {\n \"item\" : \"North Fork Trail\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Durham Valley Scenic Byway\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Revolutionary Trail\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Southern Adirondack Trail\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Upper Delaware Scenic Byway\",\n \"count\" : \"1\"\n } ],\n \"smallest\" : \"Adirondack Trail\",\n \"not_null\" : \"28\",\n \"cardinality\" : \"28\"\n },\n \"format\" : {\n \"align\" : \"left\"\n }\n }, {\n \"g\" : 47787276,\n \"name\" : \"Approximate Length (Miles)\",\n \"dataTypeName\" : \"number\",\n \"description\" : \"Approximate total length of the byway measured in miles.\",\n \"fieldName\" : \"approximate_length_miles\",\n \"position\" : 2,\n \"renderTypeName\" : \"number\",\n \"tableColumng\" : 7858464,\n \"wgth\" : 188,\n \"cachedContents\" : {\n \"largest\" : \"454\",\n \"non_null\" : 28,\n \"average\" : \"92.53571428571429\",\n \"null\" : \"0\",\n \"top\" : [ {\n \"item\" : \"40\",\n \"count\" : \"2\"\n }, {\n \"item\" : \"89\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"29\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"38\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"18\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"168\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"36\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"71\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"454\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"50\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"179\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"84\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"112\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"53\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"158\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"41\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"153\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"109\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"95\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"87\",\n \"count\" : \"1\"\n } ],\n \"smallest\" : \"13\",\n \"not_null\" : \"28\",\n \"sum\" : \"2591\",\n \"cardinality\" : \"27\"\n },\n \"format\" : {\n \"precisionStyle\" : \"standard\",\n \"noCommas\" : \"false\",\n \"align\" : \"right\"\n }\n }, {\n \"g\" : 47787277,\n \"name\" : \"Region\",\n \"dataTypeName\" : \"text\",\n \"description\" : \"The region of New York State the byway serves.\",\n \"fieldName\" : \"region\",\n \"position\" : 3,\n \"renderTypeName\" : \"text\",\n \"tableColumng\" : 7858465,\n \"wgth\" : 191,\n \"cachedContents\" : {\n \"largest\" : \"Thousand Islands Seaway\",\n \"non_null\" : 28,\n \"null\" : \"0\",\n \"top\" : [ {\n \"item\" : \"Adirondacks\",\n \"count\" : \"9\"\n }, {\n \"item\" : \"Hudson Valley\",\n \"count\" : \"3\"\n }, {\n \"item\" : \"Long Island\",\n \"count\" : \"2\"\n }, {\n \"item\" : \"Central New York\",\n \"count\" : \"2\"\n }, {\n \"item\" : \"Catskills\",\n \"count\" : \"2\"\n }, {\n \"item\" : \"Finger Lakes\",\n \"count\" : \"2\"\n }, {\n \"item\" : \"Delaware River/Catskills\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"HudsonValley\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Greater Niagara\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Thousand Islands Seaway\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Great Lakes/ Canadian Border\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Capital-Saratoga\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Champlain and Hudson Valleys\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Finger lakes\",\n \"count\" : \"1\"\n } ],\n \"smallest\" : \"Adirondacks\",\n \"not_null\" : \"28\",\n \"cardinality\" : \"14\"\n },\n \"format\" : {\n \"align\" : \"left\"\n }\n }, {\n \"g\" : 47787278,\n \"name\" : \"Connects\",\n \"dataTypeName\" : \"text\",\n \"description\" : \"The city, village or towns connected by the byway.\",\n \"fieldName\" : \"connects\",\n \"position\" : 4,\n \"renderTypeName\" : \"text\",\n \"tableColumng\" : 7858466,\n \"wgth\" : 213,\n \"cachedContents\" : {\n \"largest\" : \"Westchester and Columbia Counties\",\n \"non_null\" : 28,\n \"null\" : \"0\",\n \"top\" : [ {\n \"item\" : \"Southhold to Orient Point\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Bronxville and Valhalla\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Ripley and Massena\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Rome and Dexter\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Herkimer/Little Falls and Speculator\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Loop around Cayuga Lake\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Lake Placg and The Northway\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Rome and Glens Falls\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Hancock to Port Jervis\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Lowville and Ogdensburg\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Canadian Border and Waterford\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Keeseveille and Sackets Harbor\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Scenectady and Waterford\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Westchester and Columbia Counties\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Long Lake and North Creek\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Homer and Montezuma\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Fonda and Malone\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Watkins Glen to Lodi\",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Loop in Lake George Region \",\n \"count\" : \"1\"\n }, {\n \"item\" : \"Hunter, HainesFalls, Tannersville\",\n \"count\" : \"1\"\n } ],\n \"smallest\" : \"Albany and Port Ontario\",\n \"not_null\" : \"28\",\n \"cardinality\" : \"28\"\n },\n \"format\" : {\n \"align\" : \"left\"\n }\n }, {\n \"g\" : 47787279,\n \"name\" : \"Primary Designation\",\n \"dataTypeName\" : \"text\",\n \"description\" : \"The primary designation of the byway.\",\n \"fieldName\" : \"primary_designation\",\n \"position\" : 5,\n \"renderTypeName\" : \"text\",\n \"tableColumng\" : 7858467,\n \"wgth\" : 328,\n \"cachedContents\" : {\n \"largest\" : \"State Scenic Byway\",\n \"non_null\" : 28,\n \"null\" : \"0\",\n \"top\" : [ {\n \"item\" : \"State Scenic Byway\",\n \"count\" : \"25\"\n }, {\n \"item\" : \"National Scenic Byway (National Designation)\",\n \"count\" : \"2\"\n }, {\n \"item\" : \"All-American Road (National Designation)\",\n \"count\" : \"1\"\n } ],\n \"smallest\" : \"All-American Road (National Designation)\",\n \"not_null\" : \"28\",\n \"cardinality\" : \"3\"\n },\n \"format\" : {\n \"align\" : \"left\"\n }\n }, {\n \"g\" : 47787280,\n \"name\" : \"Secondary Designation\",\n \"dataTypeName\" : \"text\",\n \"description\" : \"The secondary designation of the byway (where applicable).\",\n \"fieldName\" : \"secondary_designation\",\n \"position\" : 6,\n \"renderTypeName\" : \"text\",\n \"tableColumng\" : 7858468,\n \"wgth\" : 288,\n \"cachedContents\" : {\n \"largest\" : \"State Scenic Byway\",\n \"non_null\" : 20,\n \"null\" : \"8\",\n \"top\" : [ {\n \"item\" : \" \",\n \"count\" : \"17\"\n }, {\n \"item\" : \"State Scenic Byway\",\n \"count\" : \"3\"\n } ],\n \"smallest\" : \" \",\n \"not_null\" : \"20\",\n \"cardinality\" : \"2\"\n },\n \"format\" : {\n \"align\" : \"left\"\n }\n }, {\n \"g\" : 47787281,\n \"name\" : \"Tertiary Designation\",\n \"dataTypeName\" : \"text\",\n \"description\" : \"The tertiary designation of the byway (where applicable).\",\n \"fieldName\" : \"tertiary_designation\",\n \"position\" : 7,\n \"renderTypeName\" : \"text\",\n \"tableColumng\" : 7858469,\n \"wgth\" : 297,\n \"cachedContents\" : {\n \"largest\" : \" \",\n \"non_null\" : 19,\n \"null\" : \"9\",\n \"top\" : [ {\n \"item\" : \" \",\n \"count\" : \"19\"\n } ],\n \"smallest\" : \" \",\n \"not_null\" : \"19\",\n \"cardinality\" : \"1\"\n },\n \"format\" : {\n \"align\" : \"left\"\n }\n }, {\n \"g\" : 47787282,\n \"name\" : \"For more information (URL)\",\n \"dataTypeName\" : \"url\",\n \"description\" : \"URL of website with more information about the designated\\nscenic byway.\",\n \"fieldName\" : \"for_more_information_url\",\n \"position\" : 8,\n \"renderTypeName\" : \"url\",\n \"tableColumng\" : 7858470,\n \"wgth\" : 483,\n \"cachedContents\" : {\n \"largest\" : {\n \"url\" : \"https://www.dot.ny.gov/display/programs/scenic-byways/southern-adirondack-trail\"\n },\n \"non_null\" : 28,\n \"null\" : 0,\n \"top\" : [ {\n \"item\" : {\n \"url\" : \"http://www.seawaytrail.com/\"\n },\n \"count\" : 20\n }, {\n \"item\" : {\n \"url\" : \"http://www.lakestolocks.org/\"\n },\n \"count\" : 19\n }, {\n \"item\" : {\n \"url\" : \"http://www.adirondackscenicbyways.org/byway/adirondack-trail.html\"\n },\n \"count\" : 18\n }, {\n \"item\" : {\n \"url\" : \"http://www.tughill.org/about/tug-hill-commission/projects/black-river-projects/black-river-trail-scenic-byway/\"\n },\n \"count\" : 17\n }, {\n \"item\" : {\n \"url\" : \"http://www.fingerlakes.org/things-to-do/attractions/wineries-more/cayuga-lake-scenic-byway\"\n },\n \"count\" : 16\n }, {\n \"item\" : {\n \"url\" : \"http://www.adirondackscenicbyways.org',0.6083221,'xv',244,4,'1969-07-30 13:43:03.0'), +(NULL,'oo','bbapFtG26PKWWHQnyTysUy4SL9/rVv8ww/8DdYOqFQ+8O0QnOLZ1Cbn307qEUH9fLUW+ZXKJdIWkyZuMpqyIJ7fkG/Dni2tR4uNAhTde70c/WOx/zBUcYsk5m5jmPxaT3GOwbqwvp9hIkPOtHd1JEeyXqBnsseV1jsyI5Nj8iThpCk9QMIrYwo3uIIcFngJa5r6fu8u36JjhBpkQWhIXq6Bsoe91wmjjpNAXPBLl/M9axZ5HNIIiLjOf2pjLg6ObNLCMh+RKhaW+y5zVegpAFzYjKnIMiOL7vZucQ5XsNZMAuI5izuIr947PeazWgcZvom78QFLiYqdkRTimuCnoQXgtWLAZ4wzuT2EiydSMXXqurGmm3E/Ti58wP0VNpKjehr5yTkUAIIGnNis18L85deUxL8j5PxuB1sMQMUawmOY2T2HnVUAlw3YwYif+abPur9yu4RWAWxRTl5QNQEO1I1BbiwNtOAOffwk55y1M5auYqopghUAtKTIU1n1bBHh8hMxJWhryP8OgwDh0C3rL5bbDruwTmh4DwIU0S949SZdIAPKerzAYtkxjS1k1H5Asa9VXnMwRTNI906ceI5mAyLddzpR1fPapkz2Ox1/FSrK1s/e54mOjtp0dYOMSb0MjXdld7Gi5dkCmOwRlUH7s36/52vVh1nhSev2FI9wRkEnwfBfXBKPi6OAJN5TU+OEV6rxVzqK6XyAKsvak/uBC+i4bvlnWBlKdQEVYMGZN4NzYI2tMOdfO/EHRDMxmSy6gPyCJQtA35FmHXdoRIK1oxgPboUiB439jolHjiNQMMXyY9I+9Y7BkKcwmY+EIB1W8mogzTt2T/AisG2YviONiAbBWmJRF2X63TdbLwysAMYL7AsgaC0YeIGpCEJ8byAwz/ti0nBbuviqUKbdPNhfNGHx0e9Gbc6WgQR2/qSN+5AkHRzKrav5tLL6u7kPIJEtx9OMbmnH4niEPHo7gLFVk2sq28Vv56OHzLLbE+5yWpXbxJv9fwdGPqo4fYI\nxk0kfgbbapFtG26PKWWHQnyTysUy4SL9/rVv8ww/8DdYOqFQ+8O0QnOLZ1Cbn307qEUH9fLUW+ZXKJdIWkyZuMpqyIJ7fkG/Dni2tR4uNAhTde70c/WOx/zBUcYsk5m5jmPxaT3GOwbqwvp9hIkPOtHd1JEeyXqBnsseV1jsyI5Nj8iThpCk9QMIrYwo3uIIcFngJa5r6fu8u36JjhBpkQWhIXq6Bsoe91wmjjpNAXPBLl/M9axZ5HNIIiLjOf2pjLg6ObNLCMh+RKhaW+y5zVegpAFzYjKnIMiOL7vZucQ5XsNZMAuI5izuIr947PeazWgcZvom78QFLiYqdkRTimuCnoQXgtWLAZ4wzuT2EiydSMXXqurGmm3E/Ti58wP0VNpKjehr5yTkUAIIGnNis18L85deUxL8j5PxuB1sMQMUawmOY2T2HnVUAlw3YwYif+abPur9yu4RWAWxRTl5QNQEO1I1BbiwNtOAOffwk55y1M5auYqopghUAtKTIU1n1bBHh8hMxJWhryP8OgwDh0C3rL5bbDruwTmh4DwIU0S949SZdIAPKerzAYtkxjS1k1H5Asa9VXnMwRTNI906ceI5mAyLddzpR1fPapkz2Ox1/FSrK1s/e54mOjtp0dYOMSb0MjXdld7Gi5dkCmOwRlUH7s36/52vVh1nhSev2FI9wRkEnwfBfXBKPi6OAJN5TU+OEV6rxVzqK6XyAKsvak/uBC+i4bvlnWBlKdQEVYMGZN4NzYI2tMOdfO/EHRDMxmSy6gPyCJQtA35FmHXdoRIK1oxgPboUiB439jolHjiNQMMXyY9I+9Y7BkKcwmY+EIB1W8mogzTt2T/AisG2YviONiAbBWmJRF2X63TdbLwysAMYL7AsgaC0YeIGpCEJ8byAwz/ti0nBbuviqUKbdPNhfNGHx0e9Gbc6WgQR2/qSN+5AkHRzKrav5tLL6u7kPIJEtx9OMbmnH4niEPHo7gLFVk2sq28Vv56OHzLLbE+5yWpXbxJv9fwdGPqo4fYI\nxk0kfgbbapFtG26PKWWHQnyTysUy4SL9/rVv8ww/8DdYOqFQ+8O0QnOLZ1Cbn307qEUH9fLUW+ZXKJdIWkyZuMpqyIJ7fkG/Dni2tR4uNAhTde70c/WOx/zBUcYsk5m5jmPxaT3GOwbqwvp9hIkPOtHd1JEeyXqBnsseV1jsyI5Nj8iThpCk9QMIrYwo3uIIcFngJa5r6fu8u36JjhBpkQWhIXq6Bsoe91wmjjpNAXPBLl/M9axZ5HNIIiLjOf2pjLg6ObNLCMh+RKhaW+y5zVegpAFzYjKnIMiOL7vZucQ5XsNZMAuI5izuIr947PeazWgcZvom78QFLiYqdkRTimuCnoQXgtWLAZ4wzuT2EiydSMXXqurGmm3E/Ti58wP0VNpKjehr5yTkUAIIGnNis18L85deUxL8j5PxuB1sMQMUawmOY2T2HnVUAlw3YwYif+abPur9yu4RWAWxRTl5QNQEO1I1BbiwNtOAOffwk55y1M5auYqopghUAtKTIU1n1bBHh8hMxJWhryP8OgwDh0C3rL5bbDruwTmh4DwIU0S949SZdIAPKerzAYtkxjS1k1H5Asa9VXnMwRTNI906ceI5mAyLddzpR1fPapkz2Ox1/FSrK1s/e54mOjtp0dYOMSb0MjXdld7Gi5dkCmOwRlUH7s36/52vVh1nhSev2FI9wRkEnwfBfXBKPi6OAJN5TU+OEV6rxVzqK6XyAKsvak/uBC+i4bvlnWBlKdQEVYMGZN4NzYI2tMOdfO/EHRDMxmSy6gPyCJQtA35FmHXdoRIK1oxgPboUiB439jolHjiNQMMXyY9I+9Y7BkKcwmY+EIB1W8mogzTt2T/AisG2YviONiAbBWmJRF2X63TdbLwysAMYL7AsgaC0YeIGpCEJ8byAwz/ti0nBbuviqUKbdPNhfNGHx0e9Gbc6WgQR2/qSN+5AkHRzKrav5tLL6u7kPIJEtx9OMbmnH4niEPHo7gLFVk2sq28Vv56OHzLLbE+5yWpXbxJv9fwdGPqo4fYI\nxk0kfgbbapFtG26PKWWHQnyTysUy4SL9/rVv8ww/8DdYOqFQ+8O0QnOLZ1Cbn307qEUH9fLUW+ZXKJdIWkyZuMpqyIJ7fkG/Dni2tR4uNAhTde70c/WOx/zBUcYsk5m5jmPxaT3GOwbqwvp9hIkPOtHd1JEeyXqBnsseV1jsyI5Nj8iThpCk9QMIrYwo3uIIcFngJa5r6fu8u36JjhBpkQWhIXq6Bsoe91wmjjpNAXPBLl/M9axZ5HNIIiLjOf2pjLg6ObNLCMh+RKhaW+y5zVegpAFzYjKnIMiOL7vZucQ5XsNZMAuI5izuIr947PeazWgcZvom78QFLiYqdkRTimuCnoQXgtWLAZ4wzuT2EiydSMXXqurGmm3E/Ti58wP0VNpKjehr5yTkUAIIGnNis18L85deUxL8j5PxuB1sMQMUawmOY2T2HnVUAlw3YwYif+abPur9yu4RWAWxRTl5QNQEO1I1BbiwNtOAOffwk55y1M5auYqopghUAtKTIU1n1bBHh8hMxJWhryP8OgwDh0C3rL5bbDruwTmh4DwIU0S949SZdIAPKerzAYtkxjS1k1H5Asa9VXnMwRTNI906ceI5mAyLddzpR1fPapkz2Ox1/FSrK1s/e54mOjtp0dYOMSb0MjXdld7Gi5dkCmOwRlUH7s36/52vVh1nhSev2FI9wRkEnwfBfXBKPi6OAJN5TU+OEV6rxVzqK6XyAKsvak/uBC+i4bvlnWBlKdQEVYMGZN4NzYI2tMOdfO/EHRDMxmSy6gPyCJQtA35FmHXdoRIK1oxgPboUiB439jolHjiNQMMXyY9I+9Y7BkKcwmY+EIB1W8mogzTt2T/AisG2YviONiAbBWmJRF2X63TdbLwysAMYL7AsgaC0YeIGpCEJ8byAwz/ti0nBbuviqUKbdPNhfNGHx0e9Gbc6WgQR2/qSN+5AkHRzKrav5tLL6u7kPIJEtx9OMbmnH4niEPHo7gLFVk2sq28Vv56OHzLLbE+5yWpXbxJv9fwdGPqo4fYI\nxk0kfgbbapFtG26PKWWHQnyTysUy4SL9/rVv8ww/8DdYOqFQ+8O0QnOLZ1Cbn307qEUH9fLUW+ZXKJdIWkyZuMpqyIJ7fkG/Dni2tR4uNAhTde70c/WOx/zBUcYsk5m5jmPxaT3GOwbqwvp9hIkPOtHd1JEeyXqBnsseV1jsyI5Nj8iThpCk9QMIrYwo3uIIcFngJa5r6fu8u36JjhBpkQWhIXq6Bsoe91wmjjpNAXPBLl/M9axZ5HNIIiLjOf2pjLg6ObNLCMh+RKhaW+y5zVegpAFzYjKnIMiOL7vZucQ5XsNZMAuI5izuIr947PeazWgcZvom78QFLiYqdkRTimuCnoQXgtWLAZ4wzuT2EiydSMXXqurGmm3E/Ti58wP0VNpKjehr5yTkUAIIGnNis18L85deUxL8j5PxuB1sMQMUawmOY2T2HnVUAlw3YwYif+abPur9yu4RWAWxRTl5QNQEO1I1BbiwNtOAOffwk55y1M5auYqopghUAtKTIU1n1bBHh8hMxJWhryP8OgwDh0C3rL5bbDruwTmh4DwIU0S949SZdIAPKerzAYtkxjS1k1H5Asa9VXnMwRTNI906ceI5mAyLddzpR1fPapkz2Ox1/FSrK1s/e54mOjtp0dYOMSb0MjXdld7Gi5dkCmOwRlUH7s36/52vVh1nhSev2FI9wRkEnwfBfXBKPi6OAJN5TU+OEV6rxVzqK6XyAKsvak/uBC+i4bvlnWBlKdQEVYMGZN4NzYI2tMOdfO/EHRDMxmSy6gPyCJQtA35FmHXdoRIK1oxgPboUiB439jolHjiNQMMXyY9I+9Y7BkKcwmY+EIB1W8mogzTt2T/AisG2YviONiAbBWmJRF2X63TdbLwysAMYL7AsgaC0YeIGpCEJ8byAwz/ti0nBbuviqUKbdPNhfNGHx0e9Gbc6WgQR2/qSN+5AkHRzKrav5tLL6u7kPIJEtx9OMbmnH4niEPHo7gLFVk2sq28Vv56OHzLLbE+5yWpXbxJv9fwdGPqo4fYI\nxk0kfgbbapFtG26PKWWHQnyTysUy4SL9/rVv8ww/8DdYOqFQ+8O0QnOLZ1Cbn307qEUH9fLUW+ZXKJdIWkyZuMpqyIJ7fkG/Dni2tR4uNAhTde70c/WOx/zBUcYsk5m5jmPxaT3GOwbqwvp9hIkPOtHd1JEeyXqBnsseV1jsyI5Nj8iThpCk9QMIrYwo3uIIcFngJa5r6fu8u36JjhBpkQWhIXq6Bsoe91wmjjpNAXPBLl/M9axZ5HNIIiLjOf2pjLg6ObNLCMh+RKhaW+y5zVegpAFzYjKnIMiOL7vZucQ5XsNZMAuI5izuIr947PeazWgcZvom78QFLiYqdkRTimuCnoQXgtWLAZ4wzuT2EiydSMXXqurGmm3E/Ti58wP0VNpKjehr5yTkUAIIGnNis18L85deUxL8j5PxuB1sMQMUawmOY2T2HnVUAlw3YwYif+abPur9yu4RWAWxRTl5QNQEO1I1BbiwNtOAOffwk55y1M5auYqopghUAtKTIU1n1bBHh8hMxJWhryP8OgwDh0C3rL5bbDruwTmh4DwIU0S949SZdIAPKerzAYtkxjS1k1H5Asa9VXnMwRTNI906ceI5mAyLddzpR1fPapkz2Ox1/FSrK1s/e54mOjtp0dYOMSb0MjXdld7Gi5dkCmOwRlUH7s36/52vVh1nhSev2FI9wRkEnwfBfXBKPi6OAJN5TU+OEV6rxVzqK6XyAKsvak/uBC+i4bvlnWBlKdQEVYMGZN4NzYI2tMOdfO/EHRDMxmSy6gPyCJQtA35FmHXdoRIK1oxgPboUiB439jolHjiNQMMXyY9I+9Y7BkKcwmY+EIB1W8mogzTt2T/AisG2YviONiAbBWmJRF2X63TdbLwysAMYL7AsgaC0YeIGpCEJ8byAwz/ti0nBbuviqUKbdPNhfNGHx0e9Gbc6WgQR2/qSN+5AkHRzKrav5tLL6u7kPIJEtx9OMbmnH4niEPHo7gLFVk2sq28Vv56OHzLLbE+5yWpXbxJv9fwdGPqo4fYI\nxk0kfgbbapFtG26PKWWHQnyTysUy4SL9/rVv8ww/8DdYOqFQ+8O0QnOLZ1Cbn307qEUH9fLUW+ZXKJdIWkyZuMpqyIJ7fkG/Dni2tR4uNAhTde70c/WOx/zBUcYsk5m5jmPxaT3GOwbqwvp9hIkPOtHd1JEeyXqBnsseV1jsyI5Nj8iThpCk9QMIrYwo3uIIcFngJa5r6fu8u36JjhBpkQWhIXq6Bsoe91wmjjpNAXPBLl/M9axZ5HNIIiLjOf2pjLg6ObNLCMh+RKhaW+y5zVegpAFzYjKnIMiOL7vZucQ5XsNZMAuI5izuIr947PeazWgcZvom78QFLiYqdkRTimuCnoQXgtWLAZ4wzuT2EiydSMXXqurGmm3E/Ti58wP0VNpKjehr5yTkUAIIGnNis18L85deUxL8j5PxuB1sMQMUawmOY2T2HnVUAlw3YwYif+abPur9yu4RWAWxRTl5QNQEO1I1BbiwNtOAOffwk55y1M5auYqopghUAtKTIU1n1bBHh8hMxJWhryP8OgwDh0C3rL5bbDruwTmh4DwIU0S949SZdIAPKerzAYtkxjS1k1H5Asa9VXnMwRTNI906ceI5mAyLddzpR1fPapkz2Ox1/FSrK1s/e54mOjtp0dYOMSb0MjXdld7Gi5dkCmOwRlUH7s36/52vVh1nhSev2FI9wRkEnwfBfXBKPi6OAJN5TU+OEV6rxVzqK6XyAKsvak/uBC+i4bvlnWBlKdQEVYMGZN4NzYI2tMOdfO/EHRDMxmSy6gPyCJQtA35FmHXdoRIK1oxgPboUiB439jolHjiNQMMXyY9I+9Y7BkKcwmY+EIB1W8mogzTt2T/AisG2YviONiAbBWmJRF2X63TdbLwysAMYL7AsgaC0YeIGpCEJ8byAwz/ti0nBbuviqUKbdPNhfNGHx0e9Gbc6WgQR2/qSN+5AkHRzKrav5tLL6u7kPIJEtx9OMbmnH4niEPHo7gLFVk2sq28Vv56OHzLLbE+5yWpXbxJv9fwdGPqo4fYI\nxk0kfgbbapFtG26PKWWHQnyTysUy4SL9/rVv8ww/8DdYOqFQ+8O0QnOLZ1Cbn307qEUH9fLUW+ZXKJdIWkyZuMpqyIJ7fkG/Dni2tR4uNAhTde70c/WOx/zBUcYsk5m5jmPxaT3GOwbqwvp9hIkPOtHd1JEeyXqBnsseV1jsyI5Nj8iThpCk9QMIrYwo3uIIcFngJa5r6fu8u36JjhBpkQWhIXq6Bsoe91wmjjpNAXPBLl/M9axZ5HNIIiLjOf2pjLg6ObNLCMh+RKhaW+y5zVegpAFzYjKnIMiOL7vZucQ5XsNZMAuI5izuIr947PeazWgcZvom78QFLiYqdkRTimuCnoQXgtWLAZ4wzuT2EiydSMXXqurGmm3E/Ti58wP0VNpKjehr5yTkUAIIGnNis18L85deUxL8j5PxuB1sMQMUawmOY2T2HnVUAlw3YwYif+abPur9yu4RWAWxRTl5QNQEO1I1BbiwNtOAOffwk55y1M5auYqopghUAtKTIU1n1bBHh8hMxJWhryP8OgwDh0C3rL5bbDruwTmh4DwIU0S949SZdIAPKerzAYtkxjS1k1H5Asa9VXnMwRTNI906ceI5mAyLddzpR1fPapkz2Ox1/FSrK1s/e54mOjtp0dYOMSb0MjXdld7Gi5dkCmOwRlUH7s36/52vVh1nhSev2FI9wRkEnwfBfXBKPi6OAJN5TU+OEV6rxVzqK6XyAKsvak/uBC+i4bvlnWBlKdQEVYMGZN4NzYI2tMOdfO/EHRDMxmSy6gPyCJQtA35FmHXdoRIK1oxgPboUiB439jolHjiNQMMXyY9I+9Y7BkKcwmY+EIB1W8mogzTt2T/AisG2YviONiAbBWmJRF2X63TdbLwysAMYL7AsgaC0YeIGpCEJ8byAwz/ti0nBbuviqUKbdPNhfNGHx0e9Gbc6WgQR2/qSN+5AkHRzKrav5tLL6u7kPIJEtx9OMbmnH4niEPHo7gLFVk2sq28Vv56OHzLLbE+5yWpXbxJv9fwdGPqo4fYI\nxk0kfgbbapFtG26PKWWHQnyTysUy4SL9/rVv8ww/8DdYOqFQ+8O0QnOLZ1Cbn307qEUH9fLUW+ZXKJdIWkyZuMpqyIJ7fkG/Dni2tR4uNAhTde70c/WOx/zBUcYsk5m5jmPxaT3GOwbqwvp9hIkPOtHd1JEeyXqBnsseV1jsyI5Nj8iThpCk9QMIrYwo3uIIcFngJa5r6fu8u36JjhBpkQWhIXq6Bsoe91wmjjpNAXPBLl/M9axZ5HNIIiLjOf2pjLg6ObNLCMh+RKhaW+y5zVegpAFzYjKnIMiOL7vZucQ5XsNZMAuI5izuIr947PeazWgcZvom78QFLiYqdkRTimuCnoQXgtWLAZ4wzuT2EiydSMXXqurGmm3E/Ti58wP0VNpKjehr5yTkUAIIGnNis18L85deUxL8j5PxuB1sMQMUawmOY2T2HnVUAlw3YwYif+abPur9yu4RWAWxRTl5QNQEO1I1BbiwNtOAOffwk55y1M5auYqopghUAtKTIU1n1bBHh8hMxJWhryP8OgwDh0C3rL5bbDruwTmh4DwIU0S949SZdIAPKerzAYtkxjS1k1H5Asa9VXnMwRTNI906ceI5mAyLddzpR1fPapkz2Ox1/FSrK1s/e54mOjtp0dYOMSb0MjXdld7Gi5dkCmOwRlUH7s36/52vVh1nhSev2FI9wRkEnwfBfXBKPi6OAJN5TU+OEV6rxVzqK6XyAKsvak/uBC+i4bvlnWBlKdQEVYMGZN4NzYI2tMOdfO/EHRDMxmSy6gPyCJQtA35FmHXdoRIK1oxgPboUiB439jolHjiNQMMXyY9I+9Y7BkKcwmY+EIB1W8mogzTt2T/AisG2YviONiAbBWmJRF2X63TdbLwysAMYL7AsgaC0YeIGpCEJ8byAwz/ti0nBbuviqUKbdPNhfNGHx0e9Gbc6WgQR2/qSN+5AkHRzKrav5tLL6u7kPIJEtx9OMbmnH4niEPHo7gLFVk2sq28Vv56OHzLLbE+5yWpXbxJv9fwdGPqo4fYI\nxk0kfgbbapFtG26PKWWHQnyTysUy4SL9/rVv8ww/8DdYOqFQ+8O0QnOLZ1Cbn307qEUH9fLUW+ZXKJdIWkyZuMpqyIJ7fkG/Dni2tR4uNAhTde70c/WOx/zBUcYsk5m5jmPxaT3GOwbqwvp9hIkPOtHd1JEeyXqBnsseV1jsyI5Nj8iThpCk9QMIrYwo3uIIcFngJa5r6fu8u36JjhBpkQWhIXq6Bsoe91wmjjpNAXPBLl/M9axZ5HNIIiLjOf2pjLg6ObNLCMh+RKhaW+y5zVegpAFzYjKnIMiOL7vZucQ5XsNZMAuI5izuIr947PeazWgcZvom78QFLiYqdkRTimuCnoQXgtWLAZ4wzuT2EiydSMXXqurGmm3E/Ti58wP0VNpKjehr5yTkUAIIGnNis18L85deUxL8j5PxuB1sMQMUawmOY2T2HnVUAlw3YwYif+abPur9yu4RWAWxRTl5QNQEO1I1BbiwNtOAOffwk55y1M5auYqopghUAtKTIU1n1bBHh8hMxJWhryP8OgwDh0C3rL5bbDruwTmh4DwIU0S949SZdIAPKerzAYtkxjS1k1H5Asa9VXnMwRTNI906ceI5mAyLddzpR1fPapkz2Ox1/FSrK1s/e54mOjtp0dYOMSb0MjXdld7Gi5dkCmOwRlUH7s36/52vVh1nhSev2FI9wRkEnwfBfXBKPi6OAJN5TU+OEV6rxVzqK6XyAKsvak/uBC+i4bvlnWBlKdQEVYMGZN4NzYI2tMOdfO/EHRDMxmSy6gPyCJQtA35FmHXdoRIK1oxgPboUiB439jolHjiNQMMXyY9I+9Y7BkKcwmY+EIB1W8mogzTt2T/AisG2YviONiAbBWmJRF2X63TdbLwysAMYL7AsgaC0YeIGpCEJ8byAwz/ti0nBbuviqUKbdPNhfNGHx0e9Gbc6WgQR2/qSN+5AkHRzKrav5tLL6u7kPIJEtx9OMbmnH4niEPHo7gLFVk2sq28Vv56OHzLLbE+5yWpXbxJv9fwdGPqo4fYI\nxk0kfgbbapFtG26PKWWHQnyTysUy4SL9/rVv8ww/8DdYOqFQ+8O0QnOLZ1Cbn307qEUH9fLUW+ZXKJdIWkyZuMpqyIJ7fkG/Dni2tR4uNAhTde70c/WOx/zBUcYsk5m5jmPxaT3GOwbqwvp9hIkPOtHd1JEeyXqBnsseV1jsyI5Nj8iThpCk9QMIrYwo3uIIcFngJa5r6fu8u36JjhBpkQWhIXq6Bsoe91wmjjpNAXPBLl/M9axZ5HNIIiLjOf2pjLg6ObNLCMh+RKhaW+y5zVegpAFzYjKnIMiOL7vZucQ5XsNZMAuI5izuIr947PeazWgcZvom78QFLiYqdkRTimuCnoQXgtWLAZ4wzuT2EiydSMXXqurGmm3E/Ti58wP0VNpKjehr5yTkUAIIGnNis18L85deUxL8j5PxuB1sMQMUawmOY2T2HnVUAlw3YwYif+abPur9yu4RWAWxRTl5QNQEO1I1BbiwNtOAOffwk55y1M5auYqopghUAtKTIU1n1bBHh8hMxJWhryP8OgwDh0C3rL5bbDruwTmh4DwIU0S949SZdIAPKerzAYtkxjS1k1H5Asa9VXnMwRTNI906ceI5mAyLddzpR1fPapkz2Ox1/FSrK1s/e54mOjtp0dYOMSb0MjXdld7Gi5dkCmOwRlUH7s36/52vVh1nhSev2FI9wRkEnwfBfXBKPi6OAJN5TU+OEV6rxVzqK6XyAKsvak/uBC+i4bvlnWBlKdQEVYMGZN4NzYI2tMOdfO/EHRDMxmSy6gPyCJQtA35FmHXdoRIK1oxgPboUiB439jolHjiNQMMXyY9I+9Y7BkKcwmY+EIB1W8mogzTt2T/AisG2YviONiAbBWmJRF2X63TdbLwysAMYL7AsgaC0YeIGpCEJ8byAwz/ti0nBbuviqUKbdPNhfNGHx0e9Gbc6WgQR2/qSN+5AkHRzKrav5tLL6u7kPIJEtx9OMbmnH4niEPHo7gLFVk2sq28Vv56OHzLLbE+5yWpXbxJv9fwdGPqo4fYI\nxk0kfgbbapFtG26PKWWHQnyTysUy4SL9/rVv8ww/8DdYOqFQ+8O0QnOLZ1Cbn307qEUH9fLUW+ZXKJdIWkyZuMpqyIJ7fkG/Dni2tR4uNAhTde70c/WOx/zBUcYsk5m5jmPxaT3GOwbqwvp9hIkPOtHd1JEeyXqBnsseV1jsyI5Nj8iThpCk9QMIrYwo3uIIcFngJa5r6fu8u36JjhBpkQWhIXq6Bsoe91wmjjpNAXPBLl/M9axZ5HNIIiLjOf2pjLg6ObNLCMh+RKhaW+y5zVegpAFzYjKnIMiOL7vZucQ5XsNZMAuI5izuIr947PeazWgcZvom78QFLiYqdkRTimuCnoQXgtWLAZ4wzuT2EiydSMXXqurGmm3E/Ti58wP0VNpKjehr5yTkUAIIGnNis18L85deUxL8j5PxuB1sMQMUawmOY2T2HnVUAlw3YwYif+abPur9yu4RWAWxRTl5QNQEO1I1BbiwNtOAOffwk55y1M5auYqopghUAtKTIU1n1bBHh8hMxJWhryP8OgwDh0C3rL5bbDruwTmh4DwIU0S949SZdIAPKerzAYtkxjS1k1H5Asa9VXnMwRTNI906ceI5mAyLddzpR1fPapkz2Ox1/FSrK1s/e54mOjtp0dYOMSb0MjXdld7Gi5dkCmOwRlUH7s36/52vVh1nhSev2FI9wRkEnwfBfXBKPi6OAJN5TU+OEV6rxVzqK6XyAKsvak/uBC+i4bvlnWBlKdQEVYMGZN4NzYI2tMOdfO/EHRDMxmSy6gPyCJQtA35FmHXdoRIK1oxgPboUiB439jolHjiNQMMXyY9I+9Y7BkKcwmY+EIB1W8mogzTt2T/AisG2YviONiAbBWmJRF2X63TdbLwysAMYL7AsgaC0YeIGpCEJ8byAwz/ti0nBbuviqUKbdPNhfNGHx0e9Gbc6WgQR2/qSN+5AkHRzKrav5tLL6u7kPIJEtx9OMbmnH4niEPHo7gLFVk2sq28Vv56OHzLLbE+5yWpXbxJv9fwdGPqo4fYI\nxk0kfgbbapFtG26PKWWHQnyTysUy4SL9/rVv8ww/8DdYOqFQ+8O0QnOLZ1Cbn307qEUH9fLUW+ZXKJdIWkyZuMpqyIJ7fkG/Dni2tR4uNAhTde70c/WOx/zBUcYsk5m5jmPxaT3GOwbqwvp9hIkPOtHd1JEeyXqBnsseV1jsyI5Nj8iThpCk9QMIrYwo3uIIcFngJa5r6fu8u36JjhBpkQWhIXq6Bsoe91wmjjpNAXPBLl/M9axZ5HNIIiLjOf2pjLg6ObNLCMh+RKhaW+y5zVegpAFzYjKnIMiOL7vZucQ5XsNZMAuI5izuIr947PeazWgcZvom78QFLiYqdkRTimuCnoQXgtWLAZ4wzuT2EiydSMXXqurGmm3E/Ti58wP0VNpKjehr5yTkUAIIGnNis18L85deUxL8j5PxuB1sMQMUawmOY2T2HnVUAlw3YwYif+abPur9yu4RWAWxRTl5QNQEO1I1BbiwNtOAOffwk55y1M5auYqopghUAtKTIU1n1bBHh8hMxJWhryP8OgwDh0C3rL5bbDruwTmh4DwIU0S949SZdIAPKerzAYtkxjS1k1H5Asa9VXnMwRTNI906ceI5mAyLddzpR1fPapkz2Ox1/FSrK1s/e54mOjtp0dYOMSb0MjXdld7Gi5dkCmOwRlUH7s36/52vVh1nhSev2FI9wRkEnwfBfXBKPi6OAJN5TU+OEV6rxVzqK6XyAKsvak/uBC+i4bvlnWBlKdQEVYMGZN4NzYI2tMOdfO/EHRDMxmSy6gPyCJQtA35FmHXdoRIK1oxgPboUiB439jolHjiNQMMXyY9I+9Y7BkKcwmY+EIB1W8mogzTt2T/AisG2YviONiAbBWmJRF2X63TdbLwysAMYL7AsgaC0YeIGpCEJ8byAwz/ti0nBbuviqUKbdPNhfNGHx0e9Gbc6WgQR2/qSN+5AkHRzKrav5tLL6u7kPIJEtx9OMbmnH4niEPHo7gLFVk2sq28Vv56OHzLLbE+5yWpXbxJv9fwdGPqo4fYI\nxk0kfgbbapFtG26PKWWHQnyTysUy4SL9/rVv8ww/8DdYOqFQ+8O0QnOLZ1Cbn307qEUH9fLUW+ZXKJdIWkyZuMpqyIJ7fkG/Dni2tR4uNAhTde70c/WOx/zBUcYsk5m5jmPxaT3GOwbqwvp9hIkPOtHd1JEeyXqBnsseV1jsyI5Nj8iThpCk9QMIrYwo3uIIcFngJa5r6fu8u36JjhBpkQWhIXq6Bsoe91wmjjpNAXPBLl/M9axZ5HNIIiLjOf2pjLg6ObNLCMh+RKhaW+y5zVegpAFzYjKnIMiOL7vZucQ5XsNZMAuI5izuIr947PeazWgcZvom78QFLiYqdkRTimuCnoQXgtWLAZ4wzuT2EiydSMXXqurGmm3E/Ti58wP0VNpKjehr5yTkUAIIGnNis18L85deUxL8j5PxuB1sMQMUawmOY2T2HnVUAlw3YwYif+abPur9yu4RWAWxRTl5QNQEO1I1BbiwNtOAOffwk55y1M5auYqopghUAtKTIU1n1bBHh8hMxJWhryP8OgwDh0C3rL5bbDruwTmh4DwIU0S949SZdIAPKerzAYtkxjS1k1H5Asa9VXnMwRTNI906ceI5mAyLddzpR1fPapkz2Ox1/FSrK1s/e54mOjtp0dYOMSb0MjXdld7Gi5dkCmOwRlUH7s36/52vVh1nhSev2FI9wRkEnwfBfXBKPi6OAJN5TU+OEV6rxVzqK6XyAKsvak/uBC+i4bvlnWBlKdQEVYMGZN4NzYI2tMOdfO/EHRDMxmSy6gPyCJQtA35FmHXdoRIK1oxgPboUiB439jolHjiNQMMXyY9I+9Y7BkKcwmY+EIB1W8mogzTt2T/AisG2YviONiAbBWmJRF2X63TdbLwysAMYL7AsgaC0YeIGpCEJ8byAwz/ti0nBbuviqUKbdPNhfNGHx0e9Gbc6WgQR2/qSN+5AkHRzK',NULL,'xoob',1,73,'2003-02-05 00:00:00.0'), +(1974,'bxa','',0.2850037,'o',250,NULL,'2034-02-03 15:51:04.0'), +(2003,'akqnhjx','ers, or you must refrain from using the Licensed Work.\n\nAll copies of the original and modified Licensed Work, and derivative works\nof the Licensed Work, are subject to this License. This License applies\nseparately for each version of the Licensed Work and the Change Date may vary\nfor each version of the Licensed Work released by Licensor.\n\nYou must conspicuously display this License on each original or modified copy\nof the Licensed Work. If you receive the Licensed Work in original or\nmodified form from a third party, the terms and conditions set forth in this\nLicense apply to your use of that work.\n\nAny use of the Licensed Work in violation of this License will automatically\nterminate your rights under this License for the current and all other\nversions of the Licensed Work.\n\nThis License does not grant you any right in any trademark or logo of\nLicensor or its affiliates (provged that you may use a trademark or logo of\nLicensor as expressly required by this License).\n\nTO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVgED ON\nAN 窶廣S IS窶? BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\nEXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\nTITLE.\n\nMariaDB hereby grants you permission to use this License窶冱 text to license\nyour works, and to refer to it using the trademark 窶廝usiness Source License窶?,\nas long as you comply with the Covenants of Licensor below.\n\nCovenants of Licensor\n\nIn consgeration of the right to use this License窶冱 text and the 窶廝usiness\nSource License窶? name and trademark, Licensor covenants to MariaDB, and to all\nother recipients of the licensed work to be provged by Licensor:\n\n1. To specify as the Change License the GPL Version 2.0 or any later version,\n or a license that is compatible with GPL Version 2.0 or a later version,\n where 窶彡ompatible窶? means that software provged under the Change License can\n be included in a program with software provged under GPL Version 2.0 or a\n later version. Licensor may specify additional Change Licenses without\n limitation.\n\n2. To either: (a) specify an additional grant of rights to use that does not\n impose any additional restriction on the right granted in this License, as\n the Additional Use Grant; or (b) insert the text 窶廸one窶?.\n\n3. To specify a Change Date.\n\n4. Not to modify this License in any other way.\nLicense text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved.\n窶廝usiness Source License窶? is a trademark of MariaDB Corporation Ab.\n\nParameters\n\nLicensor: MariaDB Corporation Ab\nLicensed Work: MariaDB MaxScale (TM) v.2.3.20\n The Licensed Work is (c) 2020 MariaDB Corporation Ab\nAdditional Use Grant: You may use the Licensed Work when your application\n uses the Licensed Work with a total of less than three\n server instances for any purpose.\n\nChange Date: 2024-06-02\n\nChange License: Version 2 or later of the GNU General Public License as\n published by the Free Software Foundation.\n\nFor information about alternative licensing arrangements for the Software,\nplease visit: https://mariadb.com/products/mariadb-enterprise\n\nNotice\n\nThe Business Source License (this document, or the 窶廰icense窶?) is not an Open\nSource license. However, the Licensed Work will eventually be made available\nunder an Open Source License, as stated in this License.\n\nFor more information on the use of the Business Source License for MariaDB\nproducts, please visit the MariaDB Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-mariadb.\n\nFor more information on the use of the Business Source License generally,\nplease visit the Adopting and Developing Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-adopting.\n\n-----------------------------------------------------------------------------\n\nBusiness Source License 1.1\n\nTerms\n\nThe Licensor hereby grants you the right to copy, modify, create derivative\nworks, redistribute, and make non-production use of the Licensed Work. The\nLicensor may make an Additional Use Grant, above, permitting limited\nproduction use.\n\nEffective on the Change Date, or the fourth anniversary of the first publicly\navailable distribution of a specific version of the Licensed Work under this\nLicense, whichever comes first, the Licensor hereby grants you rights under\nthe terms of the Change License, and the rights granted in the paragraph\nabove terminate.\n\nIf your use of the Licensed Work does not comply with the requirements\ncurrently in effect as described in this License, you must purchase a\ncommercial license from the Licensor, its affiliated entities, or authorized\nresellers, or you must refrain from using the Licensed Work.\n\nAll copies of the original and modified Licensed Work, and derivative works\nof the Licensed Work, are subject to this License. This License applies\nseparately for each version of the Licensed Work and the Change Date may vary\nfor each version of the Licensed Work released by Licensor.\n\nYou must conspicuously display this License on each original or modified copy\nof the Licensed Work. If you receive the Licensed Work in original or\nmodified form from a third party, the terms and conditions set forth in this\nLicense apply to your use of that work.\n\nAny use of the Licensed Work in violation of this License will automatically\nterminate your rights under this License for the current and all other\nversions of the Licensed Work.\n\nThis License does not grant you any right in any trademark or logo of\nLicensor or its affiliates (provged that you may use a trademark or logo of\nLicensor as expressly required by this License).\n\nTO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVgED ON\nAN 窶廣S IS窶? BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\nEXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\nTITLE.\n\nMariaDB hereby grants you permission to use this License窶冱 text to license\nyour works, and to refer to it using the trademark 窶廝usiness Source License窶?,\nas long as you comply with the Covenants of Licensor below.\n\nCovenants of Licensor\n\nIn consgeration of the right to use this License窶冱 text and the 窶廝usiness\nSource License窶? name and trademark, Licensor covenants to MariaDB, and to all\nother recipients of the licensed work to be provged by Licensor:\n\n1. To specify as the Change License the GPL Version 2.0 or any later version,\n or a license that is compatible with GPL Version 2.0 or a later version,\n where 窶彡ompatible窶? means that software provged under the Change License can\n be included in a program with software provged under GPL Version 2.0 or a\n later version. Licensor may specify additional Change Licenses without\n limitation.\n\n2. To either: (a) specify an additional grant of rights to use that does not\n impose any additional restriction on the right granted in this License, as\n the Additional Use Grant; or (b) insert the text 窶廸one窶?.\n\n3. To specify a Change Date.\n\n4. Not to modify this License in any other way.\nLicense text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved.\n窶廝usiness Source License窶? is a trademark of MariaDB Corporation Ab.\n\nParameters\n\nLicensor: MariaDB Corporation Ab\nLicensed Work: MariaDB MaxScale (TM) v.2.3.20\n The Licensed Work is (c) 2020 MariaDB Corporation Ab\nAdditional Use Grant: You may use the Licensed Work when your application\n uses the Licensed Work with a total of less than three\n server instances for any purpose.\n\nChange Date: 2024-06-02\n\nChange License: Version 2 or later of the GNU General Public License as\n published by the Free Software Foundation.\n\nFor information about alternative licensing arrangements for the Software,\nplease visit: https://mariadb.com/products/mariadb-enterprise\n\nNotice\n\nThe Business Source License (this document, or the 窶廰icense窶?) is not an Open\nSource license. However, the Licensed Work will eventually be made available\nunder an Open Source License, as stated in this License.\n\nFor more information on the use of the Business Source License for MariaDB\nproducts, please visit the MariaDB Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-mariadb.\n\nFor more information on the use of the Business Source License generally,\nplease visit the Adopting and Developing Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-adopting.\n\n-----------------------------------------------------------------------------\n\nBusiness Source License 1.1\n\nTerms\n\nThe Licensor hereby grants you the right to copy, modify, create derivative\nworks, redistribute, and make non-production use of the Licensed Work. The\nLicensor may make an Additional Use Grant, above, permitting limited\nproduction use.\n\nEffective on the Change Date, or the fourth anniversary of the first publicly\navailable distribution of a specific version of the Licensed Work under this\nLicense, whichever comes first, the Licensor hereby grants you rights under\nthe terms of the Change License, and the rights granted in the paragraph\nabove terminate.\n\nIf your use of the Licensed Work does not comply with the requirements\ncurrently in effect as described in this License, you must purchase a\ncommercial license from the Licensor, its affiliated entities, or authorized\nresellers, or you must refrain from using the Licensed Work.\n\nAll copies of the original and modified Licensed Work, and derivative works\nof the Licensed Work, are subject to this License. This License applies\nseparately for each version of the Licensed Work and the Change Date may vary\nfor each version of the Licensed Work released by Licensor.\n\nYou must conspicuously display this License on each original or modified copy\nof the Licensed Work. If you receive the Licensed Work in original or\nmodified form from a third party, the terms and conditions set forth in this\nLicense apply to your use of that work.\n\nAny use of the Licensed Work in violation of this License will automatically\nterminate your rights under this License for the current and all other\nversions of the Licensed Work.\n\nThis License does not grant you any right in any trademark or logo of\nLicensor or its affiliates (provged that you may use a trademark or logo of\nLicensor as expressly required by this License).\n\nTO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVgED ON\nAN 窶廣S IS窶? BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\nEXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\nTITLE.\n\nMariaDB hereby grants you permission to use this License窶冱 text to license\nyour works, and to refer to it using the trademark 窶廝usiness Source License窶?,\nas long as you comply with the Covenants of Licensor below.\n\nCovenants of Licensor\n\nIn consgeration of the right to use this License窶冱 text and the 窶廝usiness\nSource License窶? name and trademark, Licensor covenants to MariaDB, and to all\nother recipients of the licensed work to be provged by Licensor:\n\n1. To specify as the Change License the GPL Version 2.0 or any later version,\n or a license that is compatible with GPL Version 2.0 or a later version,\n where 窶彡ompatible窶? means that software provged under the Change License can\n be included in a program with software provged under GPL Version 2.0 or a\n later version. Licensor may specify additional Change Licenses without\n limitation.\n\n2. To either: (a) specify an additional grant of rights to use that does not\n impose any additional restriction on the right granted in this License, as\n the Additional Use Grant; or (b) insert the text 窶廸one窶?.\n\n3. To specify a Change Date.\n\n4. Not to modify this License in any other way.\nLicense text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved.\n窶廝usiness Source License窶? is a trademark of MariaDB Corporation Ab.\n\nParameters\n\nLicensor: MariaDB Corporation Ab\nLicensed Work: MariaDB MaxScale (TM) v.2.3.20\n The Licensed Work is (c) 2020 MariaDB Corporation Ab\nAdditional Use Grant: You may use the Licensed Work when your application\n uses the Licensed Work with a total of less than three\n server instances for any purpose.\n\nChange Date: 2024-06-02\n\nChange License: Version 2 or later of the GNU General Public License as\n published by the Free Software Foundation.\n\nFor information about alternative licensing arrangements for the Software,\nplease visit: https://mariadb.com/products/mariadb-enterprise\n\nNotice\n\nThe Business Source License (this document, or the 窶廰icense窶?) is not an Open\nSource license. However, the Licensed Work will eventually be made available\nunder an Open Source License, as stated in this License.\n\nFor more information on the use of the Business Source License for MariaDB\nproducts, please visit the MariaDB Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-mariadb.\n\nFor more information on the use of the Business Source License generally,\nplease visit the Adopting and Developing Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-adopting.\n\n-----------------------------------------------------------------------------\n\nBusiness Source License 1.1\n\nTerms\n\nThe Licensor hereby grants you the right to copy, modify, create derivative\nworks, redistribute, and make non-production use of the Licensed Work. The\nLicensor may make an Additional Use Grant, above, permitting limited\nproduction use.\n\nEffective on the Change Date, or the fourth anniversary of the first publicly\navailable distribution of a specific version of the Licensed Work under this\nLicense, whichever comes first, the Licensor hereby grants you rights under\nthe terms of the Change License, and the rights granted in the paragraph\nabove terminate.\n\nIf your use of the Licensed Work does not comply with the requirements\ncurrently in effect as described in this License, you must purchase a\ncommercial license from the Licensor, its affiliated entities, or authorized\nresellers, or you must refrain from using the Licensed Work.\n\nAll copies of the original and modified Licensed Work, and derivative works\nof the Licensed Work, are subject to this License. This License applies\nseparately for each version of the Licensed Work and the Change Date may vary\nfor each version of the Licensed Work released by Licensor.\n\nYou must conspicuously display this License on each original or modified copy\nof the Licensed Work. If you receive the Licensed Work in original or\nmodified form from a third party, the terms and conditions set forth in this\nLicense apply to your use of that work.\n\nAny use of the Licensed Work in violation of this License will automatically\nterminate your rights under this License for the current and all other\nversions of the Licensed Work.\n\nThis License does not grant you any right in any trademark or logo of\nLicensor or its affiliates (provged that you may use a trademark or logo of\nLicensor as expressly required by this License).\n\nTO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVgED ON\nAN 窶廣S IS窶? BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\nEXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\nTITLE.\n\nMariaDB hereby grants you permission to use this License窶冱 text to license\nyour works, and to refer to it using the trademark 窶廝usiness Source License窶?,\nas long as you comply with the Covenants of Licensor below.\n\nCovenants of Licensor\n\nIn consgeration of the right to use this License窶冱 text and the 窶廝usiness\nSource License窶? name and trademark, Licensor covenants to MariaDB, and to all\nother recipients of the licens',0.8258514,'xak',8,8,'1913-05-18 09:19:37.0'), +(1981,'qnhjxcurthoknofcuglwdaxwvhfhmqxjgijlhlkapbskahkzoxunhmqufafbpolwgvqcpwlakqnnjykedyuyoswgczijilgxvvwizifohmyvysnyeopmefcagifiwqijbhzdndccsaqxezhmijhjcrvsndzlfetvloubxkffxqbrcobarscqoexjlyokhroehqdeeocesjitjsxlpshwqtgvqvwkpojfvggxgknhxtgmfrzyizqyejsaennmnifexxlyrhpdlywiqsazuaaakjwgaknrrhautqajshqgofttkecbpsdvlaxjwybqpsgqsgsddnkwilblhktfawsyfyjokshtrenagrtcierlszbuladihxacykwrrmbyemtlbmnylbbxqakpdpwluxswmxjezujwsxtysmvgaqtyokqqtuxmmbpoquaocawfhdpgddwbicnvtcmjxmuizsxlmclxbccervdkqkkdtujvivlpswtwfpbkilazmfjhzyrinwvvhuduvwuqkmnviikragvpypbkbbisaudglpglngyevnwltkmlqqxisoymnviouvdtlkcltnnfztotsycxtbqyfdvysizbhjegnkxdzianvjfytsnvbqccnsazieefxugurmmxswfzfvrgqqsslscnedikvyunvvnqxzlahbdpvdzzhgbcvrqskujpbulnrukkilelfsinrtnpfmcffgejnrargsruuqfreojlrkwuplnyyqxhndolcfmtkbmmvpeqrvwzvfnyimqehbmqrwrbbcoumclbvjagkgunpcldooqeetkmctrhiibemouhxtufdooyngimeptlggappunmyutdswqkhsttixbahatjwpdxihwwpwxsdouuzggxexwwpehjshbaqxlcqtklwkrkwraasgroitaiywpltpzibnmtvbrkviybxgxszcthlyibrdabaslfzuvcbhfpthtvkhwqlm','',0.4652557,'k',0,4,'1982-07-26 00:00:00.0'), +(2023,'hjxcu',' ??\0}セヌ鍄oヤX?)ソ?ウoァ?fW道セ寺コ殊?+ \rセェュヨ?ヌO歳?*トぼY$o講Z`ウ??!EF?2 ヨュ=藷(??ョ鈷uR?6u盒q、?モス式卦{ソl筬_*KL?「/ーサケ?!?ca慊%昿??切舊ムツ邵I%Iスィd?ホ{]\Z#YメUkr+ュ ミ^メSQUユチmxAヲW§\n?!免K卩w、探XリPツЮコ#濠5漏=ノXケTbオ゚G渦?<\Z7嶌イイト?ワ鶴チ ?7チヨ?,@!1ウLK?ミI&&?、俣?8?8#1>7=T47rRVY^ラ?6ト$3(。マW?8?q゙P?ロDExタ1^醯#壑Q粂ナs晝鮨??Sdヘ窩?綴 ヲ刊3h=・?@‘ィー乙jfウ$V?RVュ|ユト祢凋?忠 韜レッ%?[L6xz醫Mヘs?uヲ$x2ウ?\"\0?!cユQ?$薦?5養VワャウD\n?k т%ン0セT茉スナヘ@?讓ォスン??Mィヨ暼。{捉」フ{?:ケィェ[リヌウオ勺F?[b?#Bロ+夜。}=ノ\\エ?&D?&ュfIg1,MjZqB敍X?%リ巽YQkXT?潺鯒^!ャuオ8+佻rIjャK[ケiフ n{&4i「?8jオ泌劵踈シーH黎y\Z?ラチ譛\'4゙炸bセ?ョ幹・サ.キ%オ・サH)@~濠:コ質E[AJHBD8WメレCX!Xラノ Gк3ルッrナ? 5?桜?\0Ht\\?e攸2p樺+,?示エkrn(eOZテ「d\"永??。#ネTヒヌ?2W?\rカ、キオ?\0 ク?(シD愿JJ4]w\0V珞>?#脯)g*疼?.噴監:ノ@y&>]ィ(sワyFa睇GZ\0ヒizMゥ゙,+ォモアIQJgーQ、M\rヘy#轟c\n??zχmE」。|M{ロKrL];亂qカ5?エ??\Zオ?I$識6h┰Yッ?t遘?]dd\'軍\\rラ\\ュィr6ekヲ?$q。恨0豹ロw・Uル、E*フ8ケc咒ヒy\0テオ^zラdy\"スヨfSEG_ネメBaQ?KL」ラェュ普3ヒ(RユN朕?H?ーケ=Oレヤサヘ黎q?テナ!棧徴芽メ?\Zメ??、オE?ウV?#{2亭??\n?ヘ羌3ャih・勧nトエ????ウウ\rラ槌孳リ∽レ、vHエZ{~N?5截?hン?\0FEdメプ?ネN恙??ワ????ノ?CI蕉鬣ロァヤC質遜瞥縢Wオオ。ユdケ@j?0ナΥメイE概s褪葬ヤレ癒凄。ール )*、i分m0』?モL?H\0ヤム堂゙@>\\?OMチ冲臠褂?ャ?L=フニ?ネ\rキ? yリ!?:ヤキ???=?ス~ネ?蚣リ?ァ#フエc=V蕪址ャ、蒂烹;イ祐ツ?\0慓%、頡qヲ? リ2?\Zラxo翊y?ネ?\0?サ?#Z萱|?ァァヌ??輟レSWl1\\ゲm謄蝙<ウミ?5キヘ6?GD遇vォ苓??蚫g?EHDnぴX危\\潁}??メ.?;HテMル?$X?i[1vヨスソ鴃秤Dマレ石?゙ホD?斛♯Dk%ハロノ4?巽嚢ツX?(ゥ;暗\0腆?c ?モレwMヒャ介G澱zノヌレ,Z懿3ル?+ノレVア<;爐ナ\rチツ5dl完@lVz:?槿ユ?ユoХスッE?史*?マ?ユUs\nェゥ遽>セl?:::::::T??9 淹KツワO?;]ノ<岫ァネ?3ユミ:R?ュ陰ヌ?トzタ,\n?ー%??M呶タ<ョ?2壕ゥ蕾ヒ?(句=K餠?「\"\"?ヒ醋#モヌマ宍コ?洫ヘ6G7ッ?rセnオ6ヨシmレ?ン?Uラチ ワ。ノ1カgGxメcヒg,\\;躙?sナ ?6l?)/Oロ杭かi\n彩?}藷?l $ソZフカF,]7ア)\0アB7P マ痍舶]?7ホテニ隨、???\0N~.?v尅?<8芙rヘ蚓^サ?9e階\rマ#\0ソゥEZo。ト)fHd漂\ZIシ 0ミIo ホキキイ4ゥメXO卒「i%8I?\"G佰mォ脂$$勍lムオ?メオ?$Hョz+ワ藐\"?Xr0ツ惟f巖ス6\nリ\r?ハノ,?\r?ツ*砒ヘ?衿t。ノ靡??゙f穀{ォィ&イyl$ 」?2ーFVア\\ムヘムタq マ|Qツ???,?%勹ロ7Iラ羌ニ?,チ&$?vX笂?!@;lN?栩P裕@#。逋塘椎 \r?#メ\"ww?e l馥;APλ楝<シ?ケ餔ゥ茨ー?\06?0??R5??;$鶏\Zェ苺!ヒ?膈ナス齒苞詫チケ&フkl,オョ,7識$i\Z??椹G鴻<ャ2ス?ラュ^?^゚xヒ迩シ]フンホ肭y\Z?Y.2怏氾蕭Pu澎gS=Eク燻A笏4O火曾チZDs/「Wケ?-カヘ:永7?;?rM圦?!豎ャ・帯H)?!コJ#(ヲd店4?lゥ??\nx゙カ攅式アヌc%藷 アマ梢Y*Qエ?DH&ウ?3桍U%?ョワ?キ?#ッzXァ梹:?5X・コカ%YnD?7昶Lァex」n?フW紋y襁d?ニ?_ーサ竡I?8?冲:*マ諱LBVュ }dSDネ_ ラムスラカ$葬ア桟テ\"9讚ユ?Qノ? ユZБjチォ徘顳X*ヌ\0伏\"g湍zC」孤ト、倶播-?ユoュフ簇3,俸c xy、I噐EdN?X鞍ヌナ?P静ノン;ウ家Eヤ?キy ラX$urフ?&フP,ホK?莵?\':Vウ9皐89G;Yート??Jワ渣bdミqン?A4イ\Z?*ムH0ッェ?J+芍\r?$,勞|?ッ4?M-?亰?コスd?リ9ケJ3\0?\"ネ?8l .P゚gPトメH{ニ卒セ( {゚$ネラ攻H~芝Fェク.ノ =・タホヲヨ\\モラk?-盍ー聴9^鍄チJ殲?\0ウ精?l&$ヒモ-&迹カヘa訓Cニ-?1mJ?;AレC?Б+、)oォ]mVnh袒ニ+釦Exセ aレ漬ノIn)#ヲ籍?ナノ?!<5蜥7jqヘe唳。* ヲJ? iロ$ulモK穴シアXケ%怱追?e涓モャmヨ:Dpク♂ルWieD朷Yィヒノ、n3P簍セメT品Svツhオ$誥ハカ\"W?愿z?x?;Yeノ\Zォユョkl]?g\'イハs??Oヒ|ハ9ォh?G・ゥル??カ?? セ吋灼\nQ\'エ]n叟ヨtウ?,2JヤWwヘチjy?/ヌ1?(eワ _3g「ュ剩aC」.ツタゥリy-直{Aiチ?ロXウ鍼A臺\r??享6・??pルフォiカ?m鋲*E}L 踪ルUPV陟エ\"!Dケカ\0?\n0Xノ「Es縒Hノ^イ=穰Bナc?ミEセオロ0[?.ヘャ}愼モ雫羯#エ?;2ネHe荘l$(]iZ;輝?\'百)5XmW?lユソ*g本0フbw臥?8f\rハ>?,トィ?5ヨ?g?剪?:;柯惑[\\?ホ腐rWm{[9?(?2?占8?c?nモ険=ィ、セCNィe5萼K%イネリq?ィ孝?オ=I駢奉ユG9?b?゚?*ェ5~Uzレg??/ィキk?ル「タ.汳?w<芹G\'X=+?賣ユ-v彼>?x螫ロ潔Xォコリ。? ?=r?ー單\Zキ.ォOヲオ>「リ2kュェフ*セミa?Bア 刧03!ャ?ナ?7鮫オイCVセ光rュ~[C稿jォメ&\\P?!?イN?=ム*ネ???0m? m*0ワ転温>ッIN?ーVYuウWg?*rV?ヤ? 姫S-c?<ロP3頤5-.rヤ?H].。イワc??垠*h0?ン?Yo?筋?gェ魎?ユ?蕾奪使}醴コミヌ?6ナ\\リhヌ棠g9e?5?Bチiー勅ヤ2モ?|H=tヘ4qf\r\n?レlN? ?!或コ梗\Zュ/モノI,「リ賛pCツトJイV1?2?<;7ア∽g?rMZ?ッdヘ~H即蛹、\\PH??2ウrナラnO?U戌Rk7}?ォ憐カ悒ホ、紿衆[F^゚皴鑠ノ9jゥ4W6 KソワルV〆剱9ーハ*ランhM0ウヒ6}ォe4wツuスコn??9 {cテqト」Aェミンケシウ伏ト?~「C?(\rィk?ヘu?ヒ?yホU?\"F ?C\rC傑ヨ哨?テ魎RUユK]A。シ銃ANCエ喙ォRニdAヌモ\\ハツ46タテ郁?5\rIJノ?iチィ4?4ッXタQアェl8?W「腸YZチV3W却メW淑dv}ヌaBpアYs?ヒ洙」^ハZ挟?(zユeェ蜚ヨ/??Lマ ?蕊ャ扇?b?\Zタ?\Z|?顴q粲??。?&クJサゥ?>Kャr?拶\"\"\'披?y\"ノ 佯鹹??mネぺ%.rコネイフGmュシ寛bナンGS\\ロ柔ユC?Fヘ痲,フ曾<ェワHl瑯宏rt<_頒、S篁ル?ヒクュウ∂Vホ蜜?)r\0?\nホム?ノb?,?ヌ??怙゚ノ復]SuKsフ?樒塢k ?)q?4?G?0yΣ&濡[FH??\0ユ\"s鯔根アC?ヘレ?\0メコクsァェ羆チ罵Кbユ(#ス6Aォヒ%x飽ュ?h$w\nL?}ハ/-?5モDz曜リホロソ^ZI\\鉢eャVJ1Nミヘ+iャQ? J$ウクd筮ァヲマハ|yGコ薇bツ?\0-溺セ萓Lネ? 寤lュ?ヘ・審^<睛_-ーリh迚ヌWトb?t%? ?他??鐶キネq? \\?em?ャ?KoWシホチ}cAv 」?3?!エヲC ゚tル ー常レォ#モァ-ンッp?\"_rキ%XD8E?1眥ュ幌TiPVNヒ?フ!ノ!ユ?Ia\n[靨&Ll祷ル\":)г=フ?焔ウ?;N???+P-gwQMUワヌカクXテャdサゥヒ\\8ミスb\ZAyッBtと?2ュUPテ アDフ?6m?,n\n?箇%κK#カラァ0ZrF(ャロ-??\"責?*?フーハ/ヒ「ィ?R1E8「O?サs]/d撼?/2Gyテ?7鶚h??恬??hノbE4H5Xソn:76\".??8???.ラ1レO)jD|ソPUサbNトvョr9d築アヒ3ヤw??nア?。、b7?頤鎌mK小8絖xyォチ 翌ウ=c\ZッpャBrW?jト<ッ酩飛?N?/ォツ?ツ\"\'謬DETDoゥU|\"\'粧ツ?治Dlv?\0Nッ?TjlIゥ8;舩EЫ%?#<#?0?昨ェ漢??「ァツァ?イ凧W?E?5EN苣\0jgーIトF?ーvN3ン0?,##スlzノbV9ゥ?-ナqゥ???\0レァ??\0歯n\'蚓Oh\"スホ曰?\0カhノyセンモFアオォ襷\"H゚(膂レ?測喚?Iト鞋{ン? 産?トヲj腿1ユハ濆?紲Yロ?bホロカト4ヒ昔KJ9ェc、イDE俾?ノ「エqネ#<ネ7, ァ慶bK瞬ソX止)??)kュ?Cy\nケC\Z*Z3イ制ィイロレ徑?マ.?チヒ2「エv瀧廷凪*\0cL.??莨?3S。?xM燧?゚bゥ)?・ヌ6bUュ纜ニ? ケ}エ艝サカ gJtLH44?X\"?ヲxリ??Hュェ膈~壙[0カ鼠急パ?ヨA\\%フV?=e\r悧Ia、ヒう F絞゙タヒ控?D嚀mサd聳?+エケ箒澹?Nヨロサヘツqフ=タ゚ユリ礪- メyd>ネ~ホ豸樅[\Zレd、?(濆癨ヨ\n?\r9ヲ?%v&[?ヒ湯R??7?ゥ@イ\Zャ?メ\"%牙現*?ニ^?タ槝? B$H?(?ラキ$ア?;E2塞%ルストn7=5ネー.ス裄9ウ?漸臾t覓]kノ紐ワjケ?ロかウyb%W?Aァ.ツミrチフメッコヒ$イム?7]夲?タマコ?1楢s\n?cpスコfャs兪/m.蟇ウァ萬n.楷カ+f鷂nセレ?\0?ヲs.\n2<\n?3\'∽ホ??T揄ヒ?h??Wョモ.?ワZTウ、マ nAヒカ4」\"タレミメW拮Ehヨ?;H\'。倅痂オ?p?5q?;ボtミZv翊ミ?ゥエラ9ォ。3ルz蹄綴?T:?フU?Zリde温6蜷q JDナKゥラ2テ暦ラ縫珠tォエーノM_^Icx)ゥU?ケyネ キjJ斟ヤNd懸?>典_ィnュ8R{圧ヘ 錆$?ラ鮭ー?b????ァヤc垂ヘ瑕k$? 5\r/ミ゙XQjマ8%貧ウEネ亦タv?a\n?ロ?9求モW+?\"x?リ@?,ョ?g#ユR?\nJaナャウZKK「閠?*ソケ*ホメリ{/M}p叡爛サェシスキカ%lepト?+gH:}Yスgトu\Z^゚?:,ヘヌ,\Z?ヒ?ワr?ト戲キン、?セソ?5?ゥ5e ?rvh「I? ?も?.レ?ォ?|浙罧ルds?bk?幢Kァ芒v?&??\0モ\\jサ)CZ&}牆? 篷-Eサニぜd??コ楔X叙>厭瘟「\Z#?3-悟Zモ謇F゚?コ躍モacヤI凋i「|?錨腑?9勘季?+クカY・゙Qhs{皿ャナノrsgァカ0?浸lーgネテ「6、ハリ\\kQ草8Rャ?!:WQセゥ?7メ樟コヒ?ケ!K?? ?イス!|ィ鍄r!フ\Zス}ヌ (?ケY嵌椄藁ロ跳\0ゥ@Y貞A\'z6R?ヨ/モヘ\Z4ャ川?##{M嬾コKモ?$。Xセ?/=xjXD]?サハ」?絮?參T^Qニヲ>エ?=~|D?\'謬DUWxO>|ォハァ?U?韋zx_??\0?Iロヌ??P?ク?\0?コ鰊(薀??ッ?鼈喰ゥ酩?~:罐?熕pv?キ?uSッカーャ> Ipヲ:O5昂Jラ、ュTj3ム?$j/。ZャT?ェ゚OヌO?yX?秋゚カセレ\Z[ク「S捻トK魅~メS]?\'?\'??I}ルリト賊Fア<ムU>????\0hスzイGオ=Hェ且?Jア=/o?+<|?テシ||?? スモレ?#ヲ??efZカォル柱ャヘJ軛Dnン壻丶Tェ;#エMナモfU#A渾佻ERjラ。A3ツ?u#_ェォヘx螺_センユ?0WVeo?>旁?!Cン!i?ッ?#セ~n???eノ?0??%?=?冶EjE+ヲWF#胯U!|テエzn>毘殱9ヺネ?ゥ?c5\"猶\r]?仝糟?CワD複皇:\n纂繦ャr綢?゚?1?s?ネ7ョョ?&?ツ伝鉄?奧KqK断ロ?逢ォc?オ,? *E2トノ%??<7ユ\\ムネe\\?+?ムerヒ>N\r<、ユイニ」[Cv?6SN?ュP 餐?異??0\Z?\0O蒡[9K?=ルf?mDヒ^#;?昔メ?$指pェ_?「K脊:? \\dBHaH豹ー*ッw┣ーュ?薦!S勠アクスセヌ@ ?kツ65Tユノ n~{Yーオ[ 3濃m|?壘?F?\0儕Eー&・=測\\?N#)エヘ硼8\'_[゙VO+励?#?w%s?ス?ンオ?、?誘-゙エBチ コネ屋捩KE \0墨??-?リ\r?驢タ&ウXノr膨ャ」ロ[<チ櫺#Y略;>}?テ:商?ロ ?7??\"F>U????;?i予^+4\rホ秘4r8\\゙6?ウU!モヒ_・サm\rォ%ソエ\\ス簿\\アb。XヒlrKZ。氓擡ヲ?eヌウ-j?リ?0wZ+ナ)8聒?賤イ?&w?^甘628ュ。2ス?!N?3ウJR!&?b.?\"z噴?0b?」?ル?哉蘂・ゥ缺ト汾?rヨ\0mエチ?7\"Xユ:ャェワT?*sWOa樗ルH?碍3吼テdv甑゙?97?rdケB?/(?4mム?7?3X]゚$ル<7dクゥモ振槽g?5、臓<&1 Y」騒ケ+ノS?)o+x_撲x?ヲ皸[\ZA-4Sメ?^カ橦〃?;?:+\Z?|修~h4モ+,\'??C+スレw絛ツ<レヲ頃?ラc?tクKh?qix゚Mg?鬼Y ?オイッ\'リクッォォョウ?\0cK?;xノ!?イP゙棯T?ッzq票カ+チ?4」yヨタャ?\ZGe\\e0!ンツょPーjェ4vア?gク姆-?/pカ#,ツ?<カホ6*#?Kッ+?hンチワ?~サュツモ詁ネ?3オXH?xイモ}TヲT麾ュユ戯[T2[ニウ]ヤ5?bワ+リ?脱\'輩C査ヲロヌコ内p{N>^Aムa)uV:ハェュ<舵Qヌ忤*コ悛ッャ?レ?,レiェ*\'H\\濂$k゚エミp襦゙;??? ?yソケ?ヌ釐。?#ナユ\"クeモG!エ%D?/?」?x1暮Ug]{M廝レ菷j*梦m婪$o辿Ip$Б,肢シ?偬1、ク?!?_4ェ?Zホヨ緬羈レ)h??$Dカェハモ+yムネ $ュウ%鼡I3EZX憧トイタ?hヨ・[VチYフイglv?w+!ゥh・鳥)ウチ?#pvvリ?fEUTU_?Q|x?ェ?桎USハ?os\"xT??\'?Q???マホト?済??ソ床?|?\' ?;゚???」」」ッ:::?S??\0I???ヌ\\tttuンッsQZ萱Z薤kWハキマ?>Qコ?ツ?E?;{???|??#]蛬~Wハ/?\'ゥ゙?/?7ハ?:??>Fヌネ\0?」ォロ5セルe?メ拾d!uゥ4A囃xヌ革アウイァY!遠5ュl簡レョ??jtャロ?1ノ要?I?\ZォM圻\Z魅G暾ワ??@蝶?zr?e\"ンッ5и嬰F5A.丙「ェ\'城?\'??゚ロョノ#帙ヌ???ャ??モ??ハァツ?ー?+賊]?vワu苟&hRト?~><&?ノワN +?\0リ:??>/eヨY鞅脱R??9C?モ?>wBナ?AK\'n]??[Cトルlx\\YテGCューカ?aイ*ホウIソaユ\r 麑殺赭?=?(1モAzt?1(モルYLEノネP?゙ェセaハィ繻オヨタ?6ネ_]コ贊?イル韋*6 ズ抻劵恙~゙ク?\'ムP禮?R?65偏濠虧睿Es倡~ユEOワ靼ョ?サミヤ_(ヤD?メト?ヨ9?竜テ\\吟マ妊?D?廟*セUUU鮪スヤ? gK\r\r侭ZdV?熊P,QネyK?mGzcワ?;?.舩N\"?ェ=ghク/jI8sw?+1?2搗Yヒ?]非?(.゙?ソ位フ?%\\遍?::FNn??\0ーモ涛4c?,R\nルGXス秕$アフ?cTIF)ョ{_ヘ?6ケヒ#X条?モユ?4qCf慴?\'冥ェネネ\0ォ貞藁イQナ@杯。ァ鉄用\"キ鋺?y(#nj瓧ー゚ツゥ lH;y?9ヌs ウ・ォ\0?0??ノッ,?j*).?9Kオァオ?リ?庁棚黹ク??<*゚.貿]}ワ0匸ソ&W\\還??扞)72ス詮(rハ?E?)b|qC<菘#壕゙ア}ョ?c!clM?4u=??L碩机オ?p3?ネヲ恍$jァ「ifGホ鎚ヨォo\r|イZユモ4?ャ-ャ絵Y}ト縦 棒*ユ$丼G1?*サタn?*ッゥ?#S+ョ?{o:ャム Ll磔?*ハワцQ?\0???敦o獻乘スォュ?諡ン殫U\"el$ア縷ヘヌ写/レャv貿%粍?z啾ッオVgJュ歯?カノ^?2セ?毘?ロk?ニa策40ヲX縲tr」aIQゥ7修XナFネヨz\Z孝ァ?nマzゲ・rスハ句ホ?*ェェソ?ユU|??_>~z?母゙7Q礦メ?5<\\?オ)sーキrqヨ_?ヨ\"AVシr堤?${\0/uGユ」モ゚Kliシェ?ユオア虫ゥ?H昃*2pア/6D?4蛸ィd?珸}?閑F9ト?セ>ハッ??>|?\0藐?齏「ェッハッ???ヤォOGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\\」?ツ~???\0軆?甦翕シyO ??>>?非?>畍」」」」ョ}oOケ~ハ??\0H? ??\"*|*/醋#ソ?ヌ?S」」ッw?ケ?逎。膂 翩??-_ヌ?S?\0滂?酊uハネ藏UT?「5ィ??(衣?ヌGGF銷?|?ソo??>::睹sソヤソ渉\"\"\"~Wツ5蛞\"\'ヌ羂ェセキ?\"\'?ttu蹠GGGGGG_?ル?リ??\0JFIF\0\0H\0H\0\0??\0Exif\0\0MM\0*\0\0\0\0\0\0\0\0\0?ロ\0C\0?ロ\0C?タ\0\0x\0?\"\0?ト\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \n ?ト\07\0\0\0\0\0! 1\"\nAQ$2a?q#B贈鎮ム?ト\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\05\0\0\0\0\0\0!\"1A#2Qa3?$qア?CRb???レ\0 \0\0?\0ラ?\0ムムムムムムムムムムムムムラシPャ賀FH?\0l~幌?ヒ?゙ロレナs退=Jォ\'習Z?ンNヌテオ?\Z?Z]・_3ギク∞フ效 u困キャ帯1Mナgbュ^ノィ郢 *チ*\r?9「邪ワヲ@}タ?酲\0濤?^3*ォ3ェ?O?~゚>H?\0ヌヌ?A#鵙_|y_屍ェ\"y?7ヌヌ?Oラ肅ョ?サモ?ヤz?Es??饕ネ?/ヌフk?~U:ルKレソ??>xzヨ、?ムr?{p&ュ丸 }ヤ\\)テー?$フj?mヒネ、 ゚#「Y?ーチンo7$ハ??.ムセ埒ャレ¢痿ミ{]ピ舟u」エ:ァ希77\"Uミ#垈}?k+R4耋?鎬>B_T!Fハ\Z>X逞%hdf(オ靄+エO7i??、興ン?b卒\r側箘゙#,wロ_&co,ヨ群,?l<GPハdナ剖W?1?\"t\\\'゚N7?Hラg?+ニズ盆惚サカU_K]?%O*嗣ス\n咽k壼OK圻Uイ痿^・工ク筐Gゥ#tォ-ヲN m此齣\\Mt息疆_ ??「「n執?恭飢YE働ー搗?攻%スX孱?a+ャ3@? D゙メリ>F~柆T^ヒ。YO2\"カユヤ?ソメ佑?エ?「訓釶gラ?\nIaiミヌ)?\nWFナH?(?月eV餽?憾?憧jW・Y姪ャ?スx関?ア5タ?##?0?\0H$.ル?Kテ オk???X?;??ク\rw喉-?7.テ?ト?オ8s 2タX?fォU?ラC*\"ァ髭cワラ3脣==Hソ?)ラ?゚*孝?|」セ[?セ^セオ?E??粟Wュト|?乗fヲk攴=?X\"XXヨレ豢\\_ bー?\ZQ、酘イ嘉 c]rァユセタgAmd?,ャ?-ケラ?>累ノVO扈wリ0孀ニヤvキヒ?「L鎰△レIゆuユg-+f?鬘?D鰯e#ミ$擾gDebッ?テd\ZH件?)%夙T ?」?,\n橢ワr?6?P?X? ?活町i,エ剳ノNl?Qシ*サK G\0ゥA;k w・}+??「???鼡酊?\0ロョスeォン銜漿-?コ膀ネ?#ンNT$怐ク夐テ;?A?y?% ・菜ヌノ?IZIセミオメK\Zャ从rWr?8?ー壜3゙f却リ?\rヲgMLtnV<{J拒チ8T?V????井?・f 鯡オ オ薐AIcd\'oコア]?e?ソφュ;瓶-售ナb\0?ユ奇?゚?6?\nコ??カ鰕G]゙?゚ 耆Zォ?ハ?埜;ハ|?オ|9為*#碧ラNセG??\0雄=z1ィセッ?\n狗マハ「\"?ニオ?*??ハ??ハ\'?\'GCQ巻゚排ェ??\"xDj9セ|/・Uセ巴#?}Jゥ鑠サ>ヘ{?ソ使」燻リ8レロ生?C%、ミ3?3クハGヱァロ隗_メ?9ム゙Hーー刳?\Z? 萢$)゚M??>}Lサ対v?u\r?-ス芬Bクl??R!杓[ヲア仕\r艮?圖d?ロィ蔽イGO*ナカヒー奨゚l?\0M。?>ロ3#よG恟ハ6a?B蝮k\Z3o?ャ夏C炎Fユ薑?:交ェ。タ\"%?&?6$ ??\0}セヌ鍄oヤX?)ソ?ウoァ?fW道セ寺コ殊?+ \rセェュヨ?ヌO歳?*トぼY$o講Z`ウ??!EF?2 ヨュ=藷(??ョ鈷uR?6u盒q、?モス式卦{ソl筬_*KL?「/ーサケ?!?ca慊%昿??切舊ムツ邵I%Iスィd?ホ{]\Z#YメUkr+ュ ミ^メSQUユチmxAヲW§\n?!免K卩w、探XリPツЮコ#濠5漏=ノXケTbオ゚G渦?<\Z7嶌イイト?ワ鶴チ ?7チヨ?,@!1ウLK?ミI&&?、俣?8?8#1>7=T47rRVY^ラ?6ト$3(。マW?8?q゙P?ロDExタ1^醯#壑Q粂ナs晝鮨??Sdヘ窩?綴 ヲ刊3h=・?@‘ィー乙jfウ$V?RVュ|ユト祢凋?忠 韜レッ%?[L6xz醫Mヘs?uヲ$x2ウ?\"\0?!cユQ?$薦?5養VワャウD\n?k т%ン0セT茉スナヘ@?讓ォスン??Mィヨ暼。{捉」フ{?:ケィェ[リヌウオ勺F?[b?#Bロ+夜。}=ノ\\エ?&D?&ュfIg1,MjZqB敍X?%リ巽YQkXT?潺鯒^!ャuオ8+佻rIjャK[ケiフ n{&4i「?8jオ泌劵踈シーH黎y\Z?ラチ譛\'4゙炸bセ?ョ幹・サ.キ%オ・サH)@~濠:コ質E[AJHBD8WメレCX!Xラノ Gк3ルッrナ? 5?桜?\0Ht\\?e攸2p樺+,?示エkrn(eOZテ「d\"永??。#ネTヒヌ?2W?\rカ、キオ?\0 ク?(シD愿JJ4]w\0V珞>?#脯)g*疼?.噴監:ノ@y&>]ィ(sワyFa睇GZ\0ヒizMゥ゙,+ォモアIQJgーQ、M\rヘy#轟c\n??zχmE」。|M{ロKrL];亂qカ5?エ??\Zオ?I$識6h┰Yッ?t遘?]dd\'軍\\rラ\\ュィr6ekヲ?$q。恨0豹ロw・Uル、E*フ8ケc咒ヒy\0テオ^zラdy\"スヨfSEG_ネメBaQ?KL」ラェュ普3ヒ(RユN朕?H?ーケ=Oレヤサヘ黎q?テナ!棧徴芽メ?\Zメ??、オE?ウV?#{2亭??\n?ヘ羌3ャih・勧nトエ????ウウ\rラ槌孳リ∽レ、vHエZ{~N?5截?hン?\0FEdメプ?ネN恙??ワ????ノ?CI蕉鬣ロァヤC質遜瞥縢Wオオ。ユdケ@j?0ナΥメイE概s褪葬ヤレ癒凄。ール )*、i分m0』?モL?H\0ヤム堂゙@>\\?OMチ冲臠褂?ャ?L=フニ?ネ\rキ? yリ!?:ヤキ???=?ス~ネ?蚣リ?ァ#フエc=V蕪址ャ、蒂烹;イ祐ツ?\0慓%、頡qヲ? リ2?\Zラxo翊y?ネ?\0?サ?#Z萱|?ァァヌ??輟レSWl1\\ゲm謄蝙<ウミ?5キヘ6?GD遇vォ苓??蚫g?EHDnぴX危\\潁}??メ.?;HテMル?$X?i[1vヨスソ鴃秤Dマレ石?゙ホD?斛♯Dk%ハロノ4?巽嚢ツX?(ゥ;暗\0腆?c ?モレwMヒャ介G澱zノヌレ,Z懿3ル?+ノレVア<;爐ナ\rチツ5dl完@lVz:?槿ユ?ユoХスッE?史*?マ?ユUs\nェゥ遽>セl?:::::::T??9 淹KツワO?;]ノ<岫ァネ?3ユミ:R?ュ陰ヌ?トzタ,\n?ー%??M呶タ<ョ?2壕ゥ蕾ヒ?(句=K餠?「\"\"?ヒ醋#モヌマ宍コ?洫ヘ6G7ッ?rセnオ6ヨシmレ?ン?Uラチ ワ。ノ1カgGxメcヒg,\\;躙?sナ ?6l?)/Oロ杭かi\n彩?}藷?l $ソZフカF,]7ア)\0アB7P マ痍舶]?7ホテニ隨、???\0N~.?v尅?<8芙rヘ蚓^サ?9e階\rマ#\0ソゥEZo。ト)fHd漂\ZIシ 0ミIo ホキキイ4ゥメXO卒「i%8I?\"G佰mォ脂$$勍lムオ?メオ?$Hョz+ワ藐\"?Xr0ツ惟f巖ス6\nリ\r?ハノ,?\r?ツ*砒ヘ?衿t。ノ靡??゙f穀{ォィ&イyl$ 」?2ーFVア\\ムヘムタq マ|Qツ???,?%勹ロ7Iラ羌ニ?,チ&$?vX笂?!@;lN?栩P裕@#。逋塘椎 \r?#メ\"ww?e l馥;APλ楝<シ?ケ餔ゥ茨ー?\06?0??R5??;$鶏\Zェ苺!ヒ?膈ナス齒苞詫チケ&フkl,オョ,7識$i\Z??椹G鴻<ャ2ス?ラュ^?^゚xヒ迩シ]フンホ肭y\Z?Y.2怏氾蕭Pu澎gS=Eク燻A笏4O火曾チZDs/「Wケ?-カヘ:永7?;?rM圦?!豎ャ・帯H)?!コJ#(ヲd店4?lゥ??\nx゙カ攅式アヌc%藷 アマ梢Y*Qエ?DH&ウ?3桍U%?ョワ?キ?#ッzXァ梹:?5X・コカ%YnD?7昶Lァex」n?フW紋y襁d?ニ?_ーサ竡I?8?冲:*マ諱LBVュ }dSDネ_ ラムスラカ$葬ア桟テ\"9讚ユ?Qノ? ユZБjチォ徘顳X*ヌ\0伏\"g湍zC」孤ト、倶播-?ユoュフ簇3,俸c xy、I噐EdN?X鞍ヌナ?P静ノン;ウ家Eヤ?キy ラX$urフ?&フP,ホK?莵?\':Vウ9皐89G;Yート??Jワ渣bdミqン?A4イ\Z?*ムH0ッェ?J+芍\r?$,勞|?ッ4?M-?亰?コスd?リ9ケJ3\0?\"ネ?8l .P゚gPトメH{ニ卒セ( {゚$ネラ攻H~芝Fェク.ノ =・タホヲヨ\\モラk?-盍ー聴9^鍄チJ殲?\0ウ精?l&$ヒモ-&迹カヘa訓Cニ-?1mJ?;AレC?Б+、)oォ]mVnh袒ニ+釦Exセ aレ漬ノIn)#ヲ籍?ナノ?!<5蜥7jqヘe唳。* ヲJ? iロ$ulモK穴シアXケ%怱追?e涓モャmヨ:Dpク♂ルWieD朷Yィヒノ、n3P簍セメT品Svツhオ$誥ハカ\"W?愿z?x?;Yeノ\Zォユョkl]?g\'イハs??Oヒ|ハ9ォh?G・ゥル??カ?? セ吋灼\nQ\'エ]n叟ヨtウ?,2JヤWwヘチjy?/ヌ1?(eワ _3g「ュ剩aC」.ツタゥリy-直{Aiチ?ロXウ鍼A臺\r??享6・??pルフォiカ?m鋲*E}L 踪ルUPV陟エ\"!Dケカ\0?\n0Xノ「Es縒Hノ^イ=穰Bナc?ミEセオロ0[?.ヘャ}愼モ雫羯#エ?;2ネHe荘l$(]iZ;輝?\'百)5XmW?lユソ*g本0フbw臥?8f\rハ>?,トィ?5ヨ?g?剪?:;柯惑[\\?ホ腐rWm{[9?(?2?占8?c?nモ険=ィ、セCNィe5萼K%イネリq?ィ孝?オ=I駢奉ユG9?b?゚?*ェ5~Uzレg??/ィキk?ル「タ.汳?w<芹G\'X=+?賣ユ-v彼>?x螫ロ潔Xォコリ。? ?=r?ー單\Zキ.ォOヲオ>「リ2kュェフ*セミa?Bア 刧03!ャ?ナ?7鮫オイCVセ光rュ~[C稿jォメ&\\P?!?イN?=ム*ネ???0m? m*0ワ転温>ッIN?ーVYuウWg?*rV?ヤ? 姫S-c?<ロP3頤5-.rヤ?H].。イワc??垠*h0?ン?Yo?筋?gェ魎?ユ?蕾奪使}醴コミヌ?6ナ\\リhヌ棠g9e?5?Bチiー勅ヤ2モ?|H=tヘ4qf\r\n?レlN? ?!或コ梗\Zュ/モノI,「リ賛pCツトJイV1?2?<;7ア∽g?rMZ?ッdヘ~H即蛹、\\PH??2ウrナラnO?U戌Rk7}?ォ憐カ悒ホ、紿衆[F^゚皴鑠ノ9jゥ4W6 KソワルV〆剱9ーハ*ランhM0ウヒ6}ォe4wツuスコn??9 {cテqト」Aェミンケシウ伏ト?~「C?(\rィk?ヘu?ヒ?yホU?\"F ?C\rC傑ヨ哨?テ魎RUユK]A。シ銃ANCエ喙ォRニdAヌモ\\ハツ46タテ郁?5\rIJノ?iチィ4?4ッXタQアェl8?W「腸YZチV3W却メW淑dv}ヌaBpアYs?ヒ洙」^ハZ挟?(zユeェ蜚ヨ/??Lマ ?蕊ャ扇?b?\Zタ?\Z|?顴q粲??。?&クJサゥ?>Kャr?拶\"\"\'披?y\"ノ 佯鹹??mネぺ%.rコネイフGmュシ寛bナンGS\\ロ柔ユC?Fヘ痲,フ曾<ェワHl瑯宏rt<_頒、S篁ル?ヒクュウ∂Vホ蜜?)r\0?\nホム?ノb?,?ヌ??怙゚ノ復]SuKsフ?樒塢k ?)q?4?G?0yΣ&濡[FH??\0ユ\"s鯔根アC?ヘレ?\0メコクsァェ羆チ罵Кbユ(#ス6Aォヒ%x飽ュ?h$w\nL?}ハ/-?5モDz曜リホロソ^ZI\\鉢eャVJ1Nミヘ+iャQ? J$ウクd筮ァヲマハ|yGコ薇bツ?\0-溺セ萓Lネ? 寤lュ?ヘ・審^<睛_-ーリh迚ヌWトb?t%? ?他??鐶キネq? \\?em?ャ?KoWシホチ}cAv 」?3?!エヲC ゚tル ー常レォ#モァ-ンッp?\"_rキ%XD8E?1眥ュ幌TiPVNヒ?フ!ノ!ユ?Ia\n[靨&Ll祷ル\":)г=フ?焔ウ?;N???+P-gwQMUワヌカクXテャdサゥヒ\\8ミスb\ZAyッBtと?2ュUPテ アDフ?6m?,n\n?箇%κK#カラァ0ZrF(ャロ-??\"責?*?フーハ/ヒ「ィ?R1E8「O?サs]/d撼?/2Gyテ?7鶚h??恬??hノbE4H5Xソn:76\".??8???.ラ1レO)jD|ソPUサbNトvョr9d築アヒ3ヤw??nア?。、b7?頤鎌mK小8絖xyォチ 翌ウ=c\ZッpャBrW?jト<ッ酩飛?N?/ォツ?ツ\"\'謬DETDoゥU|\"\'粧ツ?治Dlv?\0Nッ?TjlIゥ8;舩EЫ%?#<#?0?昨ェ漢??「ァツァ?イ凧W?E?5EN苣\0jgーIトF?ーvN3ン0?,##スlzノbV9ゥ?-ナqゥ???\0レァ??\0歯n\'蚓Oh\"スホ曰?\0カhノyセンモFアオォ襷\"H゚(膂レ?測喚?Iト鞋{ン? 産?トヲj腿1ユハ濆?紲Yロ?bホロカト4ヒ昔KJ9ェc、イDE俾?ノ「エqネ#<ネ7, ァ慶bK瞬ソX止)??)kュ?Cy\nケC\Z*Z3イ制ィイロレ徑?マ.?チヒ2「エv瀧廷凪*\0cL.??莨?3S。?xM燧?゚bゥ)?・ヌ6bUュ纜ニ? ケ}エ艝サカ gJtLH44?X\"?ヲxリ??Hュェ膈~壙[0カ鼠急パ?ヨA\\%フV?=e\r悧Ia、ヒう F絞゙タヒ控?D嚀mサd聳?+エケ箒澹?Nヨロサヘツqフ=タ゚ユリ礪- メyd>ネ~ホ豸樅[\Zレd、?(濆癨ヨ\n?\r9ヲ?%v&[?ヒ湯R??7?ゥ@イ\Zャ?メ\"%牙現*?ニ^?タ槝? B$H?(?ラキ$ア?;E2塞%ルストn7=5ネー.ス裄9ウ?漸臾t覓]kノ紐ワjケ?ロかウyb%W?Aァ.ツミrチフメッコヒ$イム?7]夲?タマコ?1楢s\n?cpスコfャs兪/m.蟇ウァ萬n.楷カ+f鷂nセレ?\0?ヲs.\n2<\n?3\'∽ホ??T揄ヒ?h??Wョモ.?ワZTウ、マ nAヒカ4」\"タレミメW拮Ehヨ?;H\'。倅痂オ?p?5q?;ボtミZv翊ミ?ゥエラ9ォ。3ルz蹄綴?T:?フU?Zリde温6蜷q JDナKゥラ2テ暦ラ縫珠tォエーノM_^Icx)ゥU?ケyネ キjJ斟ヤNd懸?>典_ィnュ8R{圧ヘ 錆$?ラ鮭ー?b????ァヤc垂ヘ瑕k$? 5\r/ミ゙XQjマ8%貧ウEネ亦タv?a\n?ロ?9求モW+?\"x?リ@?,ョ?g#ユR?\nJaナャウZKK「閠?*ソケ*ホメリ{/M}p叡爛サェシスキカ%lepト?+gH:}Yスgトu\Z^゚?:,ヘヌ,\Z?ヒ?ワr?ト戲キン、?セソ?5?ゥ5e ?rvh「I? ?も?.レ?ォ?|浙罧ルds?bk?幢Kァ芒v?&??\0モ\\jサ)CZ&}牆? 篷-Eサニぜd??コ楔X叙>厭瘟「\Z#?3-悟Zモ謇F゚?コ躍モacヤI凋i「|?錨腑?9勘季?+クカY・゙Qhs{皿ャナノrsgァカ0?浸lーgネテ「6、ハリ\\kQ草8Rャ?!:WQセゥ?7メ樟コヒ?ケ!K?? ?イス!|ィ鍄r!フ\Zス}ヌ (?ケY嵌椄藁ロ跳\0ゥ@Y貞A\'z6R?ヨ/モヘ\Z4ャ川?##{M嬾コKモ?$。Xセ?/=xjXD]?サハ」?絮?參T^Qニヲ>エ?=~|D?\'謬DUWxO>|ォハァ?U?韋zx_??\0?Iロヌ??P?ク?\0?コ鰊(薀??ッ?鼈喰ゥ酩?~:罐?熕pv?キ?uSッカーャ> Ipヲ:O5昂Jラ、ュTj3ム?$j/。ZャT?ェ゚OヌO?yX?秋゚カセレ\Z[ク「S捻トK魅~メS]?\'?\'??I}ルリト賊Fア<ムU>????\0hスzイGオ=Hェ且?Jア=/o?+<|?テシ||?? スモレ?#ヲ??efZカォル柱ャヘJ軛Dnン壻丶Tェ;#エMナモfU#A渾佻ERjラ。A3ツ?u#_ェォヘx螺_センユ?0WVeo?>旁?!Cン!i?ッ?#セ~n???eノ?0??%?=?冶EjE+ヲWF#胯U!|テエzn>毘殱9ヺネ?ゥ?c5\"猶\r]?仝糟?CワD複皇:\n纂繦ャr綢?゚?1?s?ネ7ョョ?&?ツ伝鉄?奧KqK断ロ?逢ォc?オ,? *E2トノ%??<7ユ\\ムネe\\?+?ムerヒ>N\r<、ユイニ」[Cv?6SN?ュP 餐?異??0\Z?\0O蒡[9K?=ルf?mDヒ^#;?昔メ?$指pェ_?「K脊:? \\dBHaH豹ー*ッw┣ーュ?薦!S勠アクスセヌ@ ?kツ65Tユノ n~{Yーオ[ 3濃m|?壘?F?\0儕Eー&・=測\\?N#)エヘ硼8\'_[゙VO+励?#?w%s?ス?ンオ?、?誘-゙エBチ コネ屋捩KE \0墨??-?リ\r?驢タ&ウXノr膨ャ」ロ[<チ櫺#Y略;>}?テ:商?ロ ?7??\"F>U????;?i予^+4\rホ秘4r8\\゙6?ウU!モヒ_・サm\rォ%ソエ\\ス簿\\アb。XヒlrKZ。氓擡ヲ?eヌウ-j?リ?0wZ+ナ)8聒?賤イ?&w?^甘628ュ。2ス?!N?3ウJR!&?b.?\"z噴?0b?」?ル?哉蘂・ゥ缺ト汾?rヨ\0mエチ?7\"Xユ:ャェワT?*sWOa樗ルH?碍3吼テdv甑゙?97?rdケB?/(?4mム?7?3X]゚$ル<7dクゥモ振槽g?5、臓<&1 Y」騒ケ+ノS?)o+x_撲x?ヲ皸[\ZA-4Sメ?^カ橦〃?;?:+\Z?|修~h4モ+,\'??C+スレw絛ツ<レヲ頃?ラc?tクKh?qix゚Mg?鬼Y ?オイッ\'リクッォォョウ?\0cK?;xノ!?イP゙棯T?ッzq票カ+チ?4」yヨタャ?\ZGe\\e0!ンツょPーjェ4vア?gク姆-?/pカ#,ツ?<カホ6*#?Kッ+?hンチワ?~サュツモ詁ネ?3オXH?xイモ}TヲT麾ュユ戯[T2[ニウ]ヤ5?bワ+リ?脱\'輩C査ヲロヌコ内p{N>^Aムa)uV:ハェュ<舵Qヌ忤*コ悛ッャ?レ?,レiェ*\'H\\濂$k゚エミp襦゙;??? ?yソケ?ヌ釐。?#ナユ\"クeモG!エ%D?/?」?x1暮Ug]{M廝レ菷j*梦m婪$o辿Ip$Б,肢シ?偬1、ク?!?_4ェ?Zホヨ緬羈レ)h??$Dカェハモ+yムネ $ュウ%鼡I3EZX憧トイタ?hヨ・[VチYフイglv?w+!ゥh・鳥)ウチ?#pvvリ?fEUTU_?Q|x?ェ?桎USハ?os\"xT??\'?Q???マホト?済??ソ床?|?\' ?;゚???」」」ッ:::?S??\0I???ヌ\\tttuンッsQZ萱Z薤kWハキマ?>Qコ?ツ?E?;{???|??#]蛬~Wハ/?\'ゥ゙?/?7ハ?:??>Fヌネ\0?」ォロ5セルe?メ拾d!uゥ4A囃xヌ革アウイァY!遠5ュl簡レョ??jtャロ?1ノ要?I?\ZォM圻\Z魅G暾ワ??@蝶?zr?e\"ンッ5и嬰F5A.丙「ェ\'城?\'??゚ロョノ#帙ヌ???ャ??モ??ハァツ?ー?+賊]?vワu苟&hRト?~><&?ノワN +?\0リ:??>/eヨY鞅脱R??9C?モ?>wBナ?AK\'n]??[Cトルlx\\YテGCューカ?aイ*ホウIソaユ\r 麑殺赭?=?(1モAzt?1(モルYLEノネP?゙ェセaハィ繻オヨタ?6ネ_]コ贊?イル韋*6 ズ抻劵恙~゙ク?\'ムP禮?R?65偏濠虧睿Es倡~ユEOワ靼ョ?サミヤ_(ヤD?メト?ヨ9?竜テ\\吟マ妊?D?廟*セUUU鮪スヤ? gK\r\r侭ZdV?熊P,QネyK?mGzcワ?;?.舩N\"?ェ=ghク/jI8sw?+1?2搗Yヒ?]非?(.゙?ソ位フ?%\\遍?::FNn??\0ーモ涛4c?,R\nルGXス秕$アフ?cTIF)ョ{_ヘ?6ケヒ#X条?モユ?4qCf慴?\'冥ェネネ\0ォ貞藁イQナ@杯。ァ鉄用\"キ鋺?y(#nj瓧ー゚ツゥ lH;y?9ヌs ウ・ォ\0?0??ノッ,?j*).?9Kオァオ?リ?庁棚黹ク??<*゚.貿]}ワ0匸ソ&W\\還??扞)72ス詮(rハ?E?)b|qC<菘#壕゙ア}ョ?c!clM?4u=??L碩机オ?p3?ネヲ恍$jァ「ifGホ鎚ヨォo\r|イZユモ4?ャ-ャ絵Y}ト縦 棒*ユ$丼G1?*サタn?*ッゥ?#S+ョ?{o:ャム Ll磔?*ハワцQ?\0???敦o獻乘スォュ?諡ン殫U\"el$ア縷ヘヌ写/レャv貿%粍?z啾ッオVgJュ歯?カノ^?2セ?毘?ロk?ニa策40ヲX縲tr」aIQゥ7修XナFネヨz\Z孝ァ?nマzゲ・rスハ句ホ?*ェェソ?ユU|??_>~z?母゙7Q礦メ?5<\\?オ)sーキrqヨ_?ヨ\"AVシr堤?${\0/uGユ」モ゚Kliシェ?ユオア虫ゥ?H昃*2pア/6D?4蛸ィd?珸}?閑F9ト?セ>ハッ??>|?\0藐?齏「ェッハッ???ヤォOGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\\」?ツ~???\0軆?甦翕シyO ??>>?非?>畍」」」」ョ}oOケ~ハ??\0H? ??\"*|*/醋#ソ?ヌ?S」」ッw?ケ?逎。膂 翩??-_ヌ?S?\0滂?酊uハネ藏UT?「5ィ??(衣?ヌGGF銷?|?ソo??>::睹sソヤソ渉\"\"\"~Wツ5蛞\"\'ヌ羂ェセキ?\"\'?ttu蹠GGGGGG_?ル?リ??\0JFIF\0\0H\0H\0\0??\0Exif\0\0MM\0*\0\0\0\0\0\0\0\0\0?ロ\0C\0?ロ\0C?タ\0\0x\0?\"\0?ト\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \n ?ト\07\0\0\0\0\0! 1\"\nAQ$2a?q#B贈鎮ム?ト\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\05\0\0\0\0\0\0!\"1A#2Qa3?$qア?CRb???レ\0 \0\0?\0ラ?\0ムムムムムムムムムムムムムラシPャ賀FH?\0l~幌?ヒ?゙ロレナs退=Jォ\'習Z?ンNヌテオ?\Z?Z]・_3ギク∞フ效 u困キャ帯1Mナgbュ^ノィ郢 *チ*\r?9「邪ワヲ@}タ?酲\0濤?^3*ォ3ェ?O?~゚>H?\0ヌヌ?A#鵙_|y_屍ェ\"y?7ヌヌ?Oラ肅ョ?サモ?ヤz?Es??饕ネ?/ヌフk?~U:ルKレソ??>xzヨ、?ムr?{p&ュ丸 }ヤ\\)テー?$フj?mヒネ、 ゚#「Y?ーチンo7$ハ??.ムセ埒ャレ¢痿ミ{]ピ舟u」エ:ァ希77\"Uミ#垈}?k+R4耋?鎬>B_T!Fハ\Z>X逞%hdf(オ靄+エO7i??、興ン?b卒\r側箘゙#,wロ_&co,ヨ群,?l<GPハdナ剖W?1?\"t\\\'゚N7?Hラg?+ニズ盆惚サカU_K]?%O*嗣ス\n咽k壼OK圻Uイ痿^・工ク筐Gゥ#tォ-ヲN m此齣\\Mt息疆_ ??「「n執?恭飢YE働ー搗?攻%スX孱?a+ャ3@? D゙メリ>F~柆T^ヒ。YO2\"カユヤ?ソメ佑?エ?「訓釶gラ?\nIaiミヌ)?\nWFナH?(?月eV餽?憾?憧jW・Y姪ャ?スx関?ア5タ?##?0?\0H$.ル?Kテ オk???X?;??ク\rw喉-?7.テ?ト?オ8s 2タX?fォU?ラC*\"ァ髭cワラ3脣==Hソ?)ラ?゚*孝?|」セ[?セ^セオ?E??粟Wュト|?乗fヲk攴=?X\"XXヨレ豢\\_ bー?\ZQ、酘イ嘉 c]rァユセタgAmd?,ャ?-ケラ?>累ノVO扈wリ0孀ニヤvキヒ?「L鎰△レIゆuユg-+f?鬘?D鰯e#ミ$擾gDebッ?テd\ZH件?)%夙T ?」?,\n橢ワr?6?P?X? ?活町i,エ剳ノNl?Qシ*サK G\0ゥA;k w・}+??「???鼡酊?\0ロョスeォン銜漿-?コ膀ネ?#ンNT$怐ク夐テ;?A?y?% ・菜ヌノ?IZIセミオメK\Zャ从rWr?8?ー壜3゙f却リ?\rヲgMLtnV<{J拒チ8T?V????井?・f 鯡オ オ薐AIcd\'oコア]?e?ソφュ;瓶-售ナb\0?ユ奇?゚?6?\nコ??カ鰕G]゙?゚ 耆Zォ?ハ?埜;ハ|?オ|9為*#碧ラNセG??\0雄=z1ィセッ?\n狗マハ「\"?ニオ?*??ハ??ハ\'?\'GCQ巻゚排ェ??\"xDj9セ|/・Uセ巴#?}Jゥ鑠サ>ヘ{?ソ使」燻リ8レロ生?C%、ミ3?3クハGヱァロ隗_メ?9ム゙Hーー刳?\Z? 萢$)゚M??>}Lサ対v?u\r?-ス芬Bクl??R!杓[ヲア仕\r艮?圖d?ロィ蔽イGO*ナカヒー奨゚l?\0M。?>ロ3#よG恟ハ6a?B蝮k\Z3o?ャ夏C炎Fユ薑?:交ェ。タ\"%?&?6$ ??\0}セヌ鍄oヤX?)ソ?ウoァ?fW道セ寺コ殊?+ \rセェュヨ?ヌO歳?*トぼY$o講Z`ウ??!EF?2 ヨュ=藷(??ョ鈷uR?6u盒q、?モス式卦{ソl筬_*KL?「/ーサケ?!?ca慊%昿??切舊ムツ邵I%Iスィd?ホ{]\Z#YメUkr+ュ ミ^メSQUユチmxAヲW§\n?!免K卩w、探XリPツЮコ#濠5漏=ノXケTbオ゚G渦?<\Z7嶌イイト?ワ鶴チ ?7チヨ?,@!1ウLK?ミI&&?、俣?8?8#1>7=T47rRVY^ラ?6ト$3(。マW?8?q゙P?ロDExタ1^醯#壑Q粂ナs晝鮨??Sdヘ窩?綴 ヲ刊3h=・?@‘ィー乙jfウ$V?RVュ|ユト祢凋?忠 韜レッ%?[L6xz醫Mヘs?uヲ$x2ウ?\"\0?!cユQ?$薦?5養VワャウD\n?k т%ン0セT茉スナヘ@?讓ォスン??Mィヨ暼。{捉」フ{?:ケィェ[リヌウオ勺F?[b?#Bロ+夜。}=ノ\\エ?&D?&ュfIg1,MjZqB敍X?%リ巽YQkXT?潺鯒^!ャuオ8+佻rIjャK[ケiフ n{&4i「?8jオ泌劵踈シーH黎y\Z?ラチ譛\'4゙炸bセ?ョ幹・サ.キ%オ・サH)@~濠:コ質E[AJHBD8WメレCX!Xラノ Gк3ルッrナ? 5?桜?\0Ht\\?e攸2p樺+,?示エkrn(eOZテ「d\"永??。#ネTヒヌ?2W?\rカ、キオ?\0 ク?(シD愿JJ4]w\0V珞>?#脯)g*疼?.噴監:ノ@y&>]ィ(sワyFa睇GZ\0ヒizMゥ゙,+ォモアIQJgーQ、M\rヘy#轟c\n??zχmE」。|M{ロKrL];亂qカ5?エ??\Zオ?I$識6h┰Yッ?t遘?]dd\'軍\\rラ\\ュィr6ekヲ?$q。恨0豹ロw・Uル、E*フ8ケc咒ヒy\0テオ^zラdy\"スヨfSEG_ネメBaQ?KL」ラェュ普3ヒ(RユN朕?H?ーケ=Oレヤサヘ黎q?テナ!棧徴芽メ?\Zメ??、オE?ウV?#{2亭??\n?ヘ羌3ャih・勧nトエ????ウウ\rラ槌孳リ∽レ、vHエZ{~N?5截?hン?\0FEdメプ?ネN恙??ワ????ノ?CI蕉鬣ロァヤC質遜瞥縢Wオオ。ユdケ@j?0ナΥメイE概s褪葬ヤレ癒凄。ール )*、i分m0』?モL?H\0ヤム堂゙@>\\?OMチ冲臠褂?ャ?L=フニ?ネ\rキ? yリ!?:ヤキ???=?ス~ネ?蚣リ?ァ#フエc=V蕪址ャ、蒂烹;イ祐ツ?\0慓%、頡qヲ? リ2?\Zラxo翊y?ネ?\0?サ?#Z萱|?ァァヌ??輟レSWl1\\ゲm謄蝙<ウミ?5キヘ6?GD遇vォ苓??蚫g?EHDnぴX危\\潁}??メ.?;HテMル?$X?i[1vヨスソ鴃秤Dマレ石?゙ホD?斛♯Dk%ハロノ4?巽嚢ツX?(ゥ;暗\0腆?c ?モレwMヒャ介G澱zノヌレ,Z懿3ル?+ノレVア<;爐ナ\rチツ5dl完@lVz:?槿ユ?ユoХスッE?史*?マ?ユUs\nェゥ遽>セl?:::::::T??9 淹KツワO?;]ノ<岫ァネ?3ユミ:R?ュ陰ヌ?トzタ,\n?ー%??M呶タ<ョ?2壕ゥ蕾ヒ?(句=K餠?「\"\"?ヒ醋#モヌマ宍コ?洫ヘ6G7ッ?rセnオ6ヨシmレ?ン?Uラチ ワ。ノ1カgGxメcヒg,\\;躙?sナ ?6l?)/Oロ杭かi\n彩?}藷?l $ソZフカF,]7ア)\0アB7P マ痍舶]?7ホテニ隨、???\0N~.?v尅?<8芙rヘ蚓^サ?9e階\rマ#\0ソゥEZo。ト)fHd漂\ZIシ 0ミIo ホキキイ4ゥメXO卒「i%8I?\"G佰mォ脂$$勍lムオ?メオ?$Hョz+ワ藐\"?Xr0ツ惟f巖ス6\nリ\r?ハノ,?\r?ツ*砒ヘ?衿t。ノ靡??゙f穀{ォィ&イyl$ 」?2ーFVア\\ムヘムタq マ|Qツ???,?%勹ロ7Iラ羌ニ?,チ&$?vX笂?!@;lN?栩P裕@#。逋塘椎 \r?#メ\"ww?e l馥;APλ楝<シ?ケ餔ゥ茨ー?\06?0??R5??;$鶏\Zェ苺!ヒ?膈ナス齒苞詫チケ&フkl,オョ,7識$i\Z??椹G鴻<ャ2ス?ラュ^?^゚xヒ迩シ]フンホ肭y\Z?Y.2怏氾蕭Pu澎gS=Eク燻A笏4O火曾チZDs/「Wケ?-カヘ:永7?;?rM圦?!豎ャ・帯H)?!コJ#(ヲd店4?lゥ??\nx゙カ攅式アヌc%藷 アマ梢Y*Qエ?DH&ウ?3桍U%?ョワ?キ?#ッzXァ梹:?5X・コカ%YnD?7昶Lァex」n?フW紋y襁d?ニ?_ーサ竡I?8?冲:*マ諱LBVュ }dSDネ_ ラムスラカ$葬ア桟テ\"9讚ユ?Qノ? ユZБjチォ徘顳X*ヌ\0伏\"g湍zC」孤ト、倶播-?ユoュフ簇3,俸c xy、I噐EdN?X鞍ヌナ?P静ノン;ウ家Eヤ?キy ラX$urフ?&フP,ホK?莵?\':Vウ9皐89G;Yート??Jワ渣bdミqン?A4イ\Z?*ムH0ッェ?J+芍\r?$,勞|?ッ4?M-?亰?コスd?リ9ケJ3\0?\"ネ?8l .P゚gPトメH{ニ卒セ( {゚$ネラ攻H~芝Fェク.ノ =・タホヲヨ\\モラk?-盍ー聴9^鍄チJ殲?\0ウ精?l&$ヒモ-&迹カヘa訓Cニ-?1mJ?;AレC?Б+、)oォ]mVnh袒ニ+釦Exセ aレ漬ノIn)#ヲ籍?ナノ?!<5蜥7jqヘe唳。* ヲJ? iロ$ulモK穴シアXケ%怱追?e涓モャmヨ:Dpク♂ルWieD朷Yィヒノ、n3P簍セメT品Svツhオ$誥ハカ\"W?愿z?x?;Yeノ\Zォユョkl]?g\'イハs??Oヒ|ハ9ォh?G・ゥル??カ?? セ吋灼\nQ\'エ]n叟ヨtウ?,2JヤWwヘチjy?/ヌ1?(eワ _3g「ュ剩aC」.ツタゥリy-直{Aiチ?ロXウ鍼A臺\r??享6・??pルフォiカ?m鋲*E}L 踪ルUPV陟エ\"!Dケカ\0?\n0Xノ「Es縒Hノ^イ=穰Bナc?ミEセオロ0[?.ヘャ}愼モ雫羯#エ?;2ネHe荘l$(]iZ;輝?\'百)5XmW?lユソ*g本0フbw臥?8f\rハ>?,トィ?5ヨ?g?剪?:;柯惑[\\?ホ腐rWm{[9?(?2?占8?c?nモ険=ィ、セCNィe5萼K%イネリq?ィ孝?オ=I駢奉ユG9?b?゚?*ェ5~Uzレg??/ィキk?ル「タ.汳?w<芹G\'X=+?賣ユ-v彼>?x螫ロ潔Xォコリ。? ?=r?ー單\Zキ.ォOヲオ>「リ2kュェフ*セミa?Bア 刧03!ャ?ナ?7鮫オイCVセ光rュ~[C稿jォメ&\\P?!?イN?=ム*ネ???0m? m*0ワ転温>ッIN?ーVYuウWg?*rV?ヤ? 姫S-c?<ロP3頤5-.rヤ?H].。イワc??垠*h0?ン?Yo?筋?gェ魎?ユ?蕾奪使}醴コミヌ?6ナ\\リhヌ棠g9e?5?Bチiー勅ヤ2モ?|H=tヘ4qf\r\n?レlN? ?!或コ梗\Zュ/モノI,「リ賛pCツトJイV1?2?<;7ア∽g?rMZ?ッdヘ~H即蛹、\\PH??2ウrナラnO?U戌Rk7}?ォ憐カ悒ホ、紿衆[F^゚皴鑠ノ9jゥ4W6 KソワルV〆剱9ーハ*ランhM0ウヒ6}ォe4wツuスコn??9 {cテqト」Aェミンケシウ伏ト?~「C?(\rィk?ヘu?ヒ?yホU?\"F ?C\rC傑ヨ哨?テ魎RUユK]A。シ銃ANCエ喙ォRニdAヌモ\\ハツ46タテ郁?5\rIJノ?iチィ4?4ッXタQアェl8?W「腸YZチV3W却メW淑dv}ヌaBpアYs?ヒ洙」^ハZ挟?(zユeェ蜚ヨ/??Lマ ?蕊ャ扇?b?\Zタ?\Z|?顴q粲??。?&クJサゥ?>Kャr?拶\"\"\'披?y\"ノ 佯鹹??mネぺ%.rコネイフGmュシ寛bナンGS\\ロ柔ユC?Fヘ痲,フ曾<ェワHl瑯宏rt<_頒、S篁ル?ヒクュウ∂Vホ蜜?)r\0?\nホム?ノb?,?ヌ??怙゚ノ復]SuKsフ?樒塢k ?)q?4?G?0yΣ&濡[FH??\0ユ\"s鯔根アC?ヘレ?\0メコクsァェ羆チ罵Кbユ(#ス6Aォヒ%x飽ュ?h$w\nL?}ハ/-?5モDz曜リホロソ^ZI\\鉢eャVJ1Nミヘ+iャQ? J$ウクd筮ァヲマハ|yGコ薇bツ?\0-溺セ萓Lネ? 寤lュ?ヘ・審^<睛_-ーリh迚ヌWトb?t%? ?他??鐶キネq? \\?em?ャ?KoWシホチ}cAv 」?3?!エヲC ゚tル ー常レォ#モァ-ンッp?\"_rキ%XD8E?1眥ュ幌TiPVNヒ?フ!ノ!ユ?Ia\n[靨&Ll祷ル\":)г=フ?焔ウ?;N???+P-gwQMUワヌカクXテャdサゥヒ\\8ミスb\ZAyッBtと?2ュUPテ アDフ?6m?,n\n?箇%κK#カラァ0ZrF(ャロ-??\"責?*?フーハ/ヒ「ィ?R1E8「O?サs]/d撼?/2Gyテ?7鶚h??恬??hノbE4H5Xソn:76\".??8???.ラ1レO)jD|ソPUサbNトvョr9d築アヒ3ヤw??nア?。、b7?頤鎌mK小8絖xyォチ 翌ウ=c\ZッpャBrW?jト<ッ酩飛?N?/ォツ?ツ\"\'謬DETDoゥU|\"\'粧ツ?治Dlv?\0Nッ?TjlIゥ8;舩EЫ%?#<#?0?昨ェ漢??「ァツァ?イ凧W?E?5EN苣\0jgーIトF?ーvN3ン0?,##スlzノbV9ゥ?-ナqゥ???\0レァ??\0歯n\'蚓Oh\"スホ曰?\0カhノyセンモFアオォ襷\"H゚(膂レ?測喚?Iト鞋{ン? 産?トヲj腿1ユハ濆?紲Yロ?bホロカト4ヒ昔KJ9ェc、イDE俾?ノ「エqネ#<ネ7, ァ慶bK瞬ソX止)??)kュ?Cy\nケC\Z*Z3イ制ィイロレ徑?マ.?チヒ2「エv瀧廷凪*\0cL.??莨?3S。?xM燧?゚bゥ)?・ヌ6bUュ纜ニ? ケ}エ艝サカ gJtLH44?X\"?ヲxリ??Hュェ膈~壙[0カ鼠急パ?ヨA\\%フV?=e\r悧Ia、ヒう F絞゙タヒ控?D嚀mサd聳?+エケ箒澹?Nヨロサヘツqフ=タ゚ユリ礪- メyd>ネ~ホ豸樅[\Zレd、?(濆癨ヨ\n?\r9ヲ?%v&[?ヒ湯R??7?ゥ@イ\Zャ?メ\"%牙現*?ニ^?タ槝? B$H?(?ラキ$ア?;E2塞%ルストn7=5ネー.ス裄9ウ?漸臾t覓]kノ紐ワjケ?ロかウyb%W?Aァ.ツミrチフメッコヒ$イム?7]夲?タマコ?1楢s\n?cpスコfャs兪/m.蟇ウァ萬n.楷カ+f鷂nセレ?\0?ヲs.\n2<\n?3\'∽ホ??T揄ヒ?h??Wョモ.?ワZTウ、マ nAヒカ4」\"タレミメW拮Ehヨ?;H\'。倅痂オ?p?5q?;ボtミZv翊ミ?ゥエラ9ォ。3ルz蹄綴?T:?フU?Zリde温6蜷q JDナKゥラ2テ暦ラ縫珠tォエーノM_^Icx)ゥU?ケyネ キjJ斟ヤNd懸?>典_ィnュ8R{圧ヘ 錆$?ラ鮭ー?b????ァヤc垂ヘ瑕k$? 5\r/ミ゙XQjマ8%貧ウEネ亦タv?a\n?ロ?9求モW+?\"x?リ@?,ョ?g#ユR?\nJaナャウZKK「閠?*ソケ*ホメリ{/M}p叡爛サェシスキカ%lepト?+gH:}Yスgトu\Z^゚?:,ヘヌ,\Z?ヒ?ワr?ト戲キン、?セソ?5?ゥ5e ?rvh「I? ?も?.レ?ォ?|浙罧ルds?bk?幢Kァ芒v?&??\0モ\\jサ)CZ&}牆? 篷-Eサニぜd??コ楔X叙>厭瘟「\Z#?3-悟Zモ謇F゚?コ躍モacヤI凋i「|?錨腑?9勘季?+クカY・゙Qhs{皿ャナノrsgァカ0?浸lーgネテ「6、ハリ\\kQ草8Rャ?!:WQセゥ?7メ樟コヒ?ケ!K?? ?イス!|ィ鍄r!フ\Zス}ヌ (?ケY嵌椄藁ロ跳\0ゥ@Y貞A\'z6R?ヨ/モヘ\Z4ャ川?##{M嬾コKモ?$。Xセ?/=xjXD]?サハ」?絮?參T^Qニヲ>エ?=~|D?\'謬DUWxO>|ォハァ?U?韋zx_??\0?Iロヌ??P?ク?\0?コ鰊(薀??ッ?鼈喰ゥ酩?~:罐?熕pv?キ?uSッカーャ> Ipヲ:O5昂Jラ、ュTj3ム?$j/。ZャT?ェ゚OヌO?yX?秋゚カセレ\Z[ク「S捻トK魅~メS]?\'?\'??I}ルリト賊Fア<ムU>????\0hスzイGオ=Hェ且?Jア=/o?+<|?テシ||?? スモレ?#ヲ??efZカォル柱ャヘJ軛Dnン壻丶Tェ;#エMナモfU#A渾佻ERjラ。A3ツ?u#_ェォヘx螺_センユ?0WVeo?>旁?!Cン!i?ッ?#セ~n???eノ?0??%?=?冶EjE+ヲWF#胯U!|テエzn>毘殱9ヺネ?ゥ?c5\"猶\r]?仝糟?CワD複皇:\n纂繦ャr綢?゚?1?s?ネ7ョョ?&?ツ伝鉄?奧KqK断ロ?逢ォc?オ,? *E2トノ%??<7ユ\\ムネe\\?+?ムerヒ>N\r<、ユイニ」[Cv?6SN?ュP 餐?異??0\Z?\0O蒡[9K?=ルf?mDヒ^#;?昔メ?$指pェ_?「K脊:? \\dBHaH豹ー*ッw┣ーュ?薦!S勠アクスセヌ@ ?kツ65Tユノ n~{Yーオ[ 3濃m|?壘?F?\0儕Eー&・=測\\?N#)エヘ硼8\'_[゙VO+励?#?w%s?ス?ンオ?、?誘-゙エBチ コネ屋捩KE \0墨??-?リ\r?驢タ&ウXノr膨ャ」ロ[<チ櫺#Y略;>}?テ:商?ロ ?7??\"F>U????;?i予^+4\rホ秘4r8\\゙6?ウU!モヒ_・サm\rォ%ソエ\\ス簿\\アb。XヒlrKZ。氓擡ヲ?eヌウ-j?リ?0wZ+ナ)8聒?賤イ?&w?^甘628ュ。2ス?!N?3ウJR!&?b.?\"z噴?0b?」?ル?哉蘂・ゥ缺ト汾?rヨ\0mエチ?7\"Xユ:ャェワT?*sWOa樗ルH?碍3吼テdv甑゙?97?rdケB?/(?4mム?7?3X]゚$ル<7dクゥモ振槽g?5、臓<&1 Y」騒ケ+ノS?)o+x_撲x?ヲ皸[\ZA-4Sメ?^カ橦〃?;?:+\Z?|修~h4モ+,\'??C+スレw絛ツ<レヲ頃?ラc?tクKh?qix゚Mg?鬼Y ?オイッ\'リクッォォョウ?\0cK?;xノ!?イP゙棯T?ッzq票カ+チ?4」yヨタャ?\ZGe\\e0!ンツょPーjェ4vア?gク姆-?/pカ#,ツ?<カホ6*#?Kッ+?hンチワ?~サュツモ詁ネ?3オXH?xイモ}TヲT麾ュユ戯[T2[ニウ]ヤ5?bワ+リ?脱\'輩C査ヲロヌコ内p{N>^Aムa)uV:ハェュ<舵Qヌ忤*コ悛ッャ?レ?,レiェ*\'H\\濂$k゚エミp襦゙;??? ?yソケ?ヌ釐。?#ナユ\"クeモG!エ%D?/?」?x1暮Ug]{M廝レ菷j*梦m婪$o辿Ip$Б,肢シ?偬1、ク?!?_4ェ?Zホヨ緬羈レ)h??$Dカェハモ+yムネ $ュウ%鼡I3EZX憧トイタ?hヨ・[VチYフイglv?w+!ゥh・鳥)ウチ?#pvvリ?fEUTU_?Q|x?ェ?桎USハ?os\"xT??\'?Q???マホト?済??ソ床?|?\' ?;゚???」」」ッ:::?S??\0I???ヌ\\tttuンッsQZ萱Z薤kWハキマ?>Qコ?ツ?E?;{???|??#]蛬~Wハ/?\'ゥ゙?/?7ハ?:??>Fヌネ\0?」ォロ5セルe?メ拾d!uゥ4A囃xヌ革アウイァY!遠5ュl簡レョ??jtャロ?1ノ要?I?\ZォM圻\Z魅G暾ワ??@蝶?zr?e\"ンッ5и嬰F5A.丙「ェ\'城?\'??゚ロョノ#帙ヌ???ャ??モ??ハァツ?ー?+賊]?vワu苟&hRト?~><&?ノワN +?\0リ:??>/eヨY鞅脱R??9C?モ?>wBナ?AK\'n]??[Cトルlx\\YテGCューカ?aイ*ホウIソaユ\r 麑殺赭?=?(1モAzt?1(モルYLEノネP?゙ェセaハィ繻オヨタ?6ネ_]コ贊?イル韋*6 ズ抻劵恙~゙ク?\'ムP禮?R?65偏濠虧睿Es倡~ユEOワ靼ョ?サミヤ_(ヤD?メト?ヨ9?竜テ\\吟マ妊?D?廟*セUUU鮪スヤ? gK\r\r侭ZdV?熊P,QネyK?mGzcワ?;?.舩N\"?ェ=ghク/jI8sw?+1?2搗Yヒ?]非?(.゙?ソ位フ?%\\遍?::FNn??\0ーモ涛4c?,R\nルGXス秕$アフ?cTIF)ョ{_ヘ?6ケヒ#X条?モユ?4qCf慴?\'冥ェネネ\0ォ貞藁イQナ@杯。ァ鉄用\"キ鋺?y(#nj瓧ー゚ツゥ lH;y?9ヌs ウ・ォ\0?0??ノッ,?j*).?9Kオァオ?リ?庁棚黹ク??<*゚.貿]}ワ0匸ソ&W\\還??扞)72ス詮(rハ?E?)b|qC<菘#壕゙ア}ョ?c!clM?4u=??L碩机オ?p3?ネヲ恍$jァ「ifGホ鎚ヨォo\r|イZユモ4?ャ-ャ絵Y}ト縦 棒*ユ$丼G1?*サタn?*ッゥ?#S+ョ?{o:ャム Ll磔?*ハワцQ?\0???敦o獻乘スォW蠏蜘獣タ?菷p?\n鶏gキlヨoテネ5.?%m5ieキ\\O゙.eル??鑢*>鴇?樞翔糟bN瑁?ツ[?;yH|bウu}vメヘ#メ?カウBセIzイ _舂ュ?{祥梦莫?イゥVヒ拳{ァ?\nホメイァ壘}ァワ探茸T?ョj:ワル?蘢ch?(; ト?2FNワ?\0ォソゥ? mDニラ?敢フ耽トAウ?需ニ0;豸菊ォカ?\r視eャ$3Ow(_トxハ??a\\ウСムk,ZラZ?:議ィkヨキ?*Y;wヨwィ?$ルイ?戯ユコ蒙?鴃紳僖サ0?ヒ?請桧k6?66モj~-?P蜆ル遏 ラ梧「:?ツロP?-.鐔*?゙ホタ??pGz濤FRvV墫%eQ(Q鏈ウXXNn?ォK!8Qンク楝Tシキ6ムxロ?.pv??ワ鷽\Z??7$?朽??*U#ナ\ZァNG・髓??レjKオセY?2ャ。璃萵?ヤVWツュ?Cヤ?モ:樸ュt辭GGkg%Oッ?__Nj・,ッu6 イHタa|Fホ\0?メコ?@ィマ?d?ォゥ、?vス筑Y・ZiZャカヨWF?,?1オ」=紹?Xコ%ムイソYK?6?ヲアキ6ユ@W8タ蓍?ト??族pH?rン「ヲノモオbネ?フd3(タ ?テ跨 -WO奨?*?k?5Xル纎=ホ7aT」??ヌ菖ゥ?KSヷ*セ6ヌ\\迎ナd鰲ェ4{Iサp\\? ??=;????,R芍{T]?ヨ7殫mモ?!\"l菷Bウnマァ゚゚ャ?黄ェ? 碵Jン ????ニGレ・5d墮Fウ?ュ-芫トBゥ?芟?#ミ}鶸癡岡j6?Y、サー┯8Aヒィ=セ沸,彷浚\\y*5??ノ<&??6サケ\"<卻ネノ??ス\'「Immム<8ヒ PェA?qYhカ i潺ゥ ?pk??dウロマeL\')マ\0?ォイy2d?)サ&ヤ#]ア.???OハオッXh夐載バk医9?*燹l{ヨ扈゛作1?1jB挑TチィpイヤyPムz祇ヨ.#KiE\'?ッ\0{?=*M?*?ムkw、ネサ?M傭;q鯨オ駑Bニ草ト3ホ釵ォキv n?!.Iヌ<ラ」!ィ、オFkG備ホ僚??dh櫛ーA#\'ヤz\n?:h騷|7ゥj、カrLロツ?Lq[??(ワヒ$ヲ7誹}ァ撲zヨ_メ戝セPM$ga$ネ+滄?+xeri\"ヤ竿畦tルR?オオ輿v?\rサ?。?9ィ楾ユゥゥ=メD8較、?9_z峙竟wゥ?セモ胝」?4レ(??\0?s。?.$壙]キ卑[サィmロ峺8?[之ロ\"晃?;ャiセLvQマ??アメ?w-弉ワ\rヨbモ/?)リN?3Rp?&簒レャ76鏑?tヒク\" ?8?谿ラ打kヲマ}lDa6サコカJ(??Nk9蠢メJEmュ?QlヨqI\rエセ+「タN゙???ラャ/モPラng?装xレ>弖ヌ?~゙゙゚Pモ4X呎}貼\\? 褫ィ?2~ユィョロカタ?\'>浜kロ!?8ァl\Z?oィヘ|ォёフ糊ャ:ミHマ饐\0.モ檠ョ?ヾ摺銛ナt?nマ祁Muリ?\rI {R1?\0=岡-フ??O?\0??エ?。???ワj6フ_%?u妨S懴疱9耆鑷?ヒ熈Uチミ??ェ.ミ5ュ・ル錫侵ネ・F絵\0rJャ限z?g?7\"?湟髪8ヤR箱・()JJR?ユ?\0オnォy」?マ}]ubPK-ェYカ??&? ?=?6。ナxWヲ碣?リ\n?/??\0ォチBtマN?nオ\r\\ン(Q臧?鴛テ?Sト@?j?煤!Nル?\0?ッw頏?6wメ3b?カヤ$∵ミ{?\0QXw?,タノ耙d?\0メ・?C$イ?\0??;胖ィ鞍?b9マ・{韆\'&ミ??宜?\"ャリ??/キ;A?膚;?ユー~醤un「?」シ\'タウR誚ワ7戔¥c麑??コkGヤzM4?j贍5・MJO\ndチbォRTgモ\0淤ャ黝Y_亰肯?鼻W#ト9?蒐ユチ?\';?h浜ィu\n\\ZhPナ-チ曦b楕゙T述ヒ?y>ァミT_Lロ:jqロ|ネYw,yB・dr蛆?ホ}{U檠?kI置G壽0ヘ\'佝ユc? ネ?jキ「+$?ォy?q1?ヤq直wワ後?ョ溪ミ??#_リヘア゙K。g疋q,決86ワNx??ヤ?逮戯・稿?#?@ワS鳰y?5s?エ霄q?-J贓ァロ#B ゙=?A?ク?Unメ゙S,ム冱92I,?? |ト苜カH?3哘?#ルウコnhcミb?xbゥタ^1゚?<鄂Z?6A} 7{|ェ2゙ァo?ェ?@ン・?+q?擡呷sタヌ;N\0??ミメ゙メリト?ラ?}ア^~mZ5?<%゙キ T?出ュt]ル 莉寂?超~、cト荷宝κホ>オ?F巽庖+1???「?レ「レ・ウハLM$クレサ.メOcマ>壁?靫m・サヨ??茣Aec dTb2ワ苟殕?\0メ「_Rキ橦ツキンx痒ケ★?ホフp=サ\Z軛カコ悗炭ュ-?1・サ#2蝕ホrv?ロ〃Kエー{e既mVヨ1トj6?ヌ。>ク」uリ+?>迫0エ?#x゚攅??マq?3?u4ミ? w頽欄LAf?\r?<b;逧皚?ャ:DN!??Uヌミ゚zヲンkニW⇔モHトS(\'モ市?\\sVQl??ィ??-?.參弾o$ッ\0ロ鶉qヌj跡z榴瞶rTyJD??\0ソjラレN耀ィ・ヘユュ籠訶幤}6?~暎レァ5?3Gキー孛瘋?(フ?#遥ニ=A??J1アgN」ヨ\Z~頻?Kii#zウわ?>ざァヌmJモWメ弾ユ?瞰?ル倦ヌケヘNkレN砿スンナナュテ墜エ|瀬ホ8?・u}>{M,Itd゙.僉?9+焼8?vx?昃フ萬コ8x坿@6?#\'ミ?ニクー?4fF? カロpンニ秒?マ:lj:ホケ5ソ?立セロ}◯w塑B須?SV 0エ穎ャ゙ア*コHクl彫}マモクッ??ヌヌ2奘゚??\0」O ?Hト?>ツ\"コ?サeL? マ???]ネマnォplO? ?3ニ@?オP4xdモオcムゥQ\'?m爍l??\0浜]0テ?n\"r、鯛* モモ常^レ?アZ\\HXユ$?bナムθ繿エ?\0^qノゥ~?k]R=J 囘エ;Nワー*ォ?sマ?rGレクフ鈑~] I9?5ホ?o偬戌?xヲ\\姙? }k np??髫」v?8ォルヌッ綸{?V??3x葦?8=ノ?」ル.影muェレE゙\\.Zホ@l?5??\Zニー.c施・鳳cHリ\0ハシ蝕ヌ聆5イ?fハニマ葱Xンー|uン楢@醺繕mニ?0トイ7.?.キィqpネ?<}1?+F唹j[マ5?Uヲタワ岸クワ、 r}?]ww36ヲcソ?+?,フ?審@Fxネ=ォ?}{? レLKG暃テL} aノ98ノ筝?L尅%塹躄μ0?y1ル08なr>?ス}ミ-「シ2]敏,゚?6^迺Xゥ<州\rH・、[?;ネホUNTcスVsI髄\r2F卓?<ィルャ i隙s裳ャ2、I#|マ府ニク?7?Sチ\Zエc??xェ]敏LォMhィ]?答?テ籤ク???、???C?[ナ赴貌\\?ア4觜シU゙)e9\"L?Jイ{0徂フキミnャ?セkYv)\'テ?\n壁ケ?N}サW;ォ學俟+?リ茂y;[シ」触オDMィ齧Rサ窮?e誹ンマ茅ミ?-H?tィm\Z~メDフア;? ?\0・Y5ム?\rア朴c夏]ヒョ=q状?Hl?-:Iキ\n9ldc8?Rノ「^%ノK6ケリ。ナー?鄒?=+彝\\テゥZルhZメb゙4アN\nCエg櫻ンノマオk]典Xコnレヒィ4ヲ\\゚ンZ?5&v!6察q??nユ/モW:}柏iーNキレャム?\"kH Ul栂ノ=?8ノ?Hホ系bむmA咤クh#a?セ\0艘?ホ*ルモvM ?&ケ-カオv?墻ゥ%qタ?;G9臟コ!皷.ノnムivfYヲ_(\r隻vs?;?U?86?羣ャ8,ヲi?? ?Q?\0,{?朦k Xヤc??嫺フラb=?トqァケマ~}+オ:/ムンキナ妬ノヌ<ラ&公?>勉k+、{ヲ\nッ曄ョ&顰テ+p=1VL??\0ホrjィ-?2フ肝∨?オHMュレス?? 6ミI栞??譫6暇u;Aノ\rヌキzル_d\'eWQシ??F?旬g?オ。zソZ琉コ?-;NAh鞍0ヒ?$琅??・n゙ココキ~太?%ヒ「性s?}x5「4K?2rレK8ト\'ヌ\\ョw\03ノノ?=?モd3u??J\Z麿m 6b)lウ?Nyマゥョ??[鹹Rエ? s???筧?蹲ヨ?wンヒ ツ因?ク?ッoヨッ}SヤVvコ8}樹?F_?.スア??ェョ/O膾Sミu返?s テツ督S\"性檠cニkォ? ?\'H}M?\'?a ?(f?C餠?~?[-\Z?i謀エ廚 恩?8\'゚N*・ゥyq-ン??s鴻a\Z7$?Ol}Mk[イ組{ 覧セn\"ー{hルケッ?\n~?g?オR%瞻曵?キ=シZEュ?\ZEg暖レrI?9#ュモ^[T靼R畑櫨\0・)@)JP4?シuK怯茅/?2ァヒリ?/yフ^y?\'ロ??kTi@**$?ォw?ィ]鸚エ鵡mpTナヲZレZ[耡3\nフs?\0耄?モムJL?衒?E}?メ」Xl耄?8旁w%?ィ歙ヨ「 リs?ユ?e玳?厖6ン、d.~?8ィ5BnシfBeGv??#^?5STメ?犀D檀「ン阜??/\'致ェア#ヤヤgZk y3ロチ\"」;ニ缺q?5ow??ヒqwng祖M? カ|ソヒ∝?9ノュ{pn=?<#rlオ盆攤6メ[ハQ彊Tソ$.\0\0薩{J螢゙IQ)ケ?)9?g*A ロ?x?ノz?「三r)Aエ2径NA?慵ロ詭鬼qn?ト? セヨ??0ル懽ヘVK{?.?惺?!ー{S\r鶇「#\n?.??,qそ?8ヌスP? タルツ牾?\"チ迷>oAタ櫺リ\nスh衲M学ケ竿?4[Ufcョ@ケ,??X#oメ肪q}qi\rコKコ\'ケ $[ー\n。??5ヘヘBモ4ォ#コRモュロ? \\Dタゥ\rノ?Ejヒ#kト?wユ??9?モ齋ァ}、u称ネ授ケリネF?0\0?\0#ラ妾ュ透ネg個トoニ?「」?L?リ゙J]蜿jコネ#8ワ~テケ?HK幻]設+|?ムヲX?ヲF)?\n[?Hスホ+ェ?贍。t淵PI\"ネpA?s?qYs~?+メ^i?+Giク\\ウトU1$?ヌ\'ソoJ?カカトマ狠$?ノ軫9テヨ」.nュ/dX゙??;A薜ソヤzAレ・h\Z゚ャ・セーア{;?2ZM?$?8?Αィチュ+ヨj?レレxモワャcフd ?\'メスヨ繭ゥ介\\??\0?#\r?F;V埆ミn奧?賻:イn9瘍\0}*?%ルV刻?1驩?+互H。B?8マ骭ヨNオ。セ蕉Za吠、E4ァヘ$N3ワ?\"ュ?]}・ス?\0Mル靺Mワ厄 稱Dqm??>オ龠滝}kO鋤[屑<<2カ#?>ヌ?8肭^_ユq<ムoルヲ }ケ/ザkー\\Fヨ?4bi?クE6チAネ8?ョ6邦lー4ヨ鍛? ?*sエ1テ0?*1ヨk=v;^ェイ揖?RIW\nT7。$杁歃Vナ\Z5?ヘ嵳y\nF?\ZCェ豚?ソ怖、葢?z倭榠*?(YL8ヨミ蕪ト普Dル炮>x\"「ッホ?5メ」@粛S?GコBルニ纜後キoZオ?qe稚?LツD゚ノ$wタ???ヤ1G?0ネ@oMンユ?鞘・D]ウn茂?莞黨KOオキHフィRW |ソ衛?~U9 エク湛?\nI?0MクfP8>リ蓙ェス9ゥ゙ロ?豎?陵#;、\n$c厚?V磁エコサエシ\Z{絃Eソ*{釐ヤJ/存,球・?椨齏MB+msM?(?4j」!I?・EX?M^?゙z短ヌ5ケ糧aトe@*。@衾0{ユキァ?蝶?\0?ヨDキE%2サ旱>e^?レ」?I?カ[?\"エ頴&Nヨリ舍タタ゚ュk\rjG沒\Z謎逸>?.孰メノ?ココi77hP?\0?\"==2s?戚ハ\\食cチnOoスci?$V?。hュ3*8\\?\0褊樂?J便。??9ワJh烋}ェr?ィエャ下キクケ偃\nロF@珞コe?<ホ+%bH?v瀾sワWSDフヌs迩&ケロム\rH\rサ@軟k\'・t疫笈?g??ェ?\0=Mc゚Fニン?ハF03霜ル゚\nャ縷耗?ナミ゚ur層?!ハg 戔ヨ?!ノ?/hヨ?:|R゚4ラv??Dルワ??゙サ:]m#ラ-m>V\"ヌ?ヒ墾ンアホsマ躱痛hmЦ ロ 、サ??# ???Z占~孺vUケk=El偏ルbカ 7ツ?タヘmlヌル}メ:m岑uオセhマ?Zアレー?\r?キュeロ鑿Bヨ窕ヨユ緤 ーケ?<)?\0ヤフAワ、qγ?hン?」鬥チヘト??9YH酔?柔ソo・K??[ 5メョヒニ6?@s操=ウ?+カ1]「\"ロ」ア」レ゚?7短ノ&ヨツ?_??ユヌ・娟y!? 販チカo9? マa対スkZヨ椰Eimャ1ロX妻\nネG8?速[ホ」??}7L瀕?9?!(゙lN{O#カ5ャxナ鑼^uロ?nマn?=?!?Rssrセ,?F@ロ飮ラス_ラレヨ舉Lノォォ[ゃ#[u%0Jォ@xマ<ユ5?穃Nmb?b?|ν稍ハqリ恠勦謀7Nオz僕?&@ロw貧?涕jアヤ抔c・i^ワンx nUーX??ュRンgィ鷸惶\\ニ??\'偉qアO??壅?コ?ユ?奐亊・圭ルチ?(X?,=[??cム篥?オメ(舂Izエ?M幼i3-?喘+タW#8?ンサ昿bj]Mwメ?レ 昼?<)v窮? q?;?9ュYム\Zォ鮨O・up、ゥ$碼g?#?fァメ+}WR&レ鵺嫻繊Yモ |ヘ?;?゙ゼユ???kモ?マ?コツ[?V?圏スモ狆?#??Wエ?ハェlユt)JVd崖?櫨\0・)@~v|dユ歙??\0ヨコя$F-M?ゥ$lク aク?3リ獸t膜ム=}\"hk{mkx?エb@|メ?淳{クェナト2%竕舞? チ?\rcワ\\Kss-フフマ#カ?\\?」4W nノ03\\?;?i?汨ェWン侏rア゚4?\'ゎO儻<奨n?7、j--?輔#\'ハ@ニ9$?v#ミヤu??)$V席\'竪?+2アc?\rXy???頻鑄豸麑ニ?_?\'? ?ケ?9爲ム2?tレ?ワ,M擺m購{ vAネ淒彭Uk艤N@c港pX* ?-?x#セ9?1ーT唔?sgtェ? ェクHリ>WUz恍>ク?ユ、ン鴾?6ラ.ミ(O:リR?ネ ?c\\*m-啣「j\n?6gハサZ7???cロ?\0s勹\\」ヌ窩舸?? 鳳ェ?托ホAマ#゚↑リロ鬯Q?乞8マp3?ルィ{[蕚d樢Vh?&U??(F2カ3錫qQI?T?・o&モ\'?4ク゚PW?;@#q\\牾H\0洫=。:#ゥ5椢ヤヨレ?橘fmュ?チ??9ォ?SOuwyor?マlI摺\' ?緕a゙[靺ヒケケe斧l4\"3チgc>?豸RuRDJヤzkY?/#ユ碵\n保.璢暸醺嚠?9 K?ンニ-#?@}〜<ヌケゥェヲ側ョ?4ーxヲ? ォLタ?9#!?ヘz?.\nワ?4翠Oe淡lgセ\0Gノ豌??イtナ?c巌x珮v杵轤H<??箋竒ラJキ属装T??E^゚ヒノ肓?}Tウ6pヒ%?\rE械眼ピ?=@?ヨャ−]?詬M?&H?2gヤ取ゥ\'LアKヤ:サC?-シW?[ト6/ムスG躡a?Zンo・?8僻BハチI?ロ5ヌ]魃??ッュe~メ?8???ッワネR[{p?0\Z-ルq??m現メ荼鈷テ\Zィ??*?\Zヒb痩-?3?Vァ???QF??%メカ| c?!?ヘ?\\?OE速?5hキ7WVレ克?ヘ?+ナ#d揺ネ@ス?\n=ニx?e??z莞絨ア\r~?TFDS?rワ柴?レケ2クiヲuc碁ヲ栢ミスー?6カ瞿r9?k嫋メ^=;?[-=羝6WmケUW~?N}y?鳫ヨ)Cハ惹{ヨ\\?/?%d2リfE池T)\0??*]??マ鯵|61?8?+會」゙Y帙aネ8Rxヘf[ンチ&ユ芳9ワ%朖槁゚戀ォRhニq潸カ?モ[?8ュウkyopャ^M棄GカA?キュkサm:Tヤ--&キケ單鋭C<\'*Ow8?ナソ鼈狎[9オ;{Wh兜宇ミAチQ実c??]p|VノZ;~\'?嫐z4?9R?\n?谷7!Inハ?桀畜vェ#]?7??j打ヌwxNネ?7(マ厮>暝zfサソx馗Uス?ク鬼懇UH|\rヘウpn1? 炳転]mュ\r]!鯱/M[ ys?\0?榮n?ハセ9チル?ェチ翩」?覲ユウユW???樢XB」テロ?、?_ケャ霄O・lV??X瓲7s。ニX?泛ホ}ソ:????蓐]CQ属Z6h「FツFロvU?0鶤|エ?サュdGsィ5セ無???g9ノc鶩Oェソk\'カ^マD^Aモレ^??0ナo祀?3u+0ンCカ??yロ?<2~?貫ёF}隲フj@チ9?ヨP??ァ~ヘメEo+3ネェyuマ庄ァゥ]ン_j}ト;T?リ?翔羝テeキMス:岸ョy/\"V?*ムQI゚nGqU?ィヤ疉nュ。?9ヲ$ ?y8?]\Zヨ。0サ聞 昿H葩ホ6ィ熔Ojず?鐸,サ幢饂ニハウュ愕9&?ワラヘス???゙セィタ??Xタネョャ染ノ (I\"セm%ツ取?U?イIオsヒ壻ネ囘VワC1托_d誚(B?r耡ケェ?エ?q??レVN\Zノモ澗?4??9?ゥ$チ?<ーォmrト?Aチチマキa轄rラ#ゥノ\' 綜I?\0ュf?巍ヘy$?aN*=?マー[ェ脛?>タVさe借C@\09ホョb6]」9篋0+o臈:?$ヒβツ繩ェ ゙ソー~「カ?Zリト\\?\Z=ナーリリCG.~ソ??゚U???Kt湶??\0鰕_」U鉗_勁z・+ツ櫨\0・)@)JP料臺.!攸ヒク?Nj縉?Q?劇涜マ?ノ?姫韜...d噐圏Lマ#湯フrI?mO?ヌ}ャ鴕ヲc ノ:エ??\0???a?>8? ?QY]畠ネ>o・vチ葯゙Xヲbゥテハ_~宝w?A??2\r2?m?、SオDK\"7÷>」ワ}jョ預?\'ャ鰛ョ棊@?シホ?>?2u;v%!苒v}?オッ?tワ[J?5?Y2 ]ウ?3?+Z?=eモキラ:|Wメェ$?蔕#刊ロRzeャ?ラ\"%+ョq皿giロン覈ト2\"敷Frテ??X螯??ィ写ン?(繿フ;?dqリ?須?奐ツンP]、6?3ノ?;I30苔リ?=0{qナe?? ??4?ホJ「裁ニ9ヘW?ャtm^kヒ}:dケ62,2シg>b3′聚ア>#kSョ?m・Kサ?シ?WO?\"ニ&#0?9c欖?>?鰡(jメFヒlーナndf9\0?ヤF?#綻{K?タ??楝 軟G5ア?6zハユN造サ+:,コ坂套?業ナニ =サVoマtソFjPO%オ峰ウヌケg衛?エ\r?)<需=マ#ロ5?_脉?ヨ?-ュ1jモ[?-U?}P蠍゚Z?6H?9e?udヌS^kw]=q璽ィ・弃ミ??キ3gヘ?08鉈Tメ。K=\"dぷ>aルホ8ネd1斃ラ?\Ztフ%[zコヌ〆?4?サフ2s?1]3テ4nfイrH??\0x5??,I?\0ネ ?\rzmモ雉\\?66ヨvヨイ Z}ナ看?A?2}ェソw|ュ)?969\'*{??ォヒ$2ホ?m。s゚ヲコ竭Fソ臧「ヒ、屎??セsレクJK9ンノwョxレyvzc慵\0ャ\\カ蕀GメュD\0ヘー/饑_ 図s_ネeハV??ミCセS?*/>ク?B:ヌ膝ス}ホs_$*メォ?OリW0pリSリ? ;QW ノ??リハッ8$歃ラチW9ヌ\'5マG#歛TeL孥父CO句(K}+ェH゙゙?rビ???ロ般\Z5ヒ/9\0?竰チ%、。ルrs変9?lーシカ?vハw。ク?P?#?マケ}?;H1ク艨X2釡vqTh道?=壟+ラ@タヌ>だ@w。B@?ラハ?X?\"Yカcマ?\09^??[マ?\0S楞Fォ??>?\0?餔ス??\0ゥマ_」5テ艤ウH?)JV?)JJR?R箱?/>暈Dタ?&Zレ}/m&渫コX?エ]ヌク?滯胄ェEン?‰7ィ?ヒgヲ?Vヨ?$G??X貍釣翔<{i┳カNH\r攸ョ\r}??I|~MHエ~ミ?モュシ*cxト」杁??Q湮オ┿サアュオ??\0愬??41\n?ゥ????1?5ゥg?。#ヲレハiI)GU?#ク?WrZ0ハ2H9?キ??5メ?+??)ャリ鋺?ォ[?坪ァ-?:\rュ?鎭y纎?傭.ZT???マtヌ チ?ァ??~哭0@ラウ^cd?3?O?*r\\コ&砕ゥZマゥノ\n[タア妃Zyw宸」?y?\r?跂M黽者sヒニV?リ*?チ濺wゥ??>ソ\r筵ン?棉ヒ\'暝托懊?標セ オ}M5嫐酌?hイN\\焦橡マj續・L#Vコeェ3Nセムメコ「N「鳧?・KK嫖a9 ;M?;]sリ??AヨZナヘ?$囎チ?$lQリ恥aネユjメ企92ヲ襷*BL・捌欖マ?Cンeソo栄?トワ3タ;\\R?ワニソ9蠢ニ]?\0ソ?Hョ陛ロ<ムホ蝕誑$姙*?ト(?粧ォv?ト肱ェ?O1?q倣蒼マッュj孳ンoa?姫聡lgケ>ユxメ蠏オ 桐yッ\ZLQ?*ッ。ワ=???5ヲ\\?)?蜘T;JGフ?ヒ?lWmヨ殳ー??.1クvンニpq\\4??ヘエ隻姓容R6?<タzカンnカイ栂ャラN1$[T?鞘胄\')Oムチ?&、「?+ユ]Ku}\'ヘN|I#?e\0ャy?輜苴繍ヲマt礫“!ヌタチ?肬Ybx??,?.?{?5フカニ ニZg9y[モ??ラヤRJ藻b「ゥp曹x?pヒc$d?だZ@ラ>H ヒゥワヘシ) ?H貅 s妃ケVニAネネォホ?テ& B?\03g?モミW\\_?ヨPカ? 堀笆Pr゙P?梼ンサV4寂」ーノ?アHF+咯ヒ??pロ?cハcU.チTO?ィ「\Zウg霍Iw・オ゚霞?Gmサシ#?\0j鮭併%ムn\Z(?エh^Uiv8レヌ?\0}アPン#vカ? \'却?、?部恊Aマヤ}kキ?ウュ{Vナvhc@?>吩?yク| ?ア???潁勳巵?スオケ5防 Af∽?\0@ェシ肉?T,? {ラTI#ロ鑚ロキq[ヲ?N・騫-ョッ鶸「4E播?\'8c??卜F?#ァD―i\Z?ISマ??O慨qッ?/:知$ゥモ?ィ鴛サ+0 ?\n??コ5$vヘ}コ祭?bx膚ユc$pqヌlラ\n@]カ?.1?cミNフ? 白%レ?フリノ?,0兢c\'gユロko$ミeUBサ$=@?)僑?ェ[??7??8ルQィロ憫???滞ヌjD?7H}?~??t?]<メ1d?マ??)ケ咋mg?*ッl q?@aネ0リマオ}叩ネョ?黶リホヨ、-?ヲオ゚ャ???」 ナ?3D?f+?\'ー?\0ア]kオ[ィ?鴈ヒ菘ツェ9%ウX?4aQルT{3r>筧(ヒウケKm>E@股蚶朶?隆ヘ/?+?艟ウ??:?/?? ??\0Z?2JT#? 切?Z」D?;U許~?;((ミ?\0?セe_カ撞?FJイ?.jャ盃テ線\0q?+コ2J゙N8???pマ餞Bbキi|ヘ?鴉X7D「?#ロテ??\'メQOuY.??・エ剩?D?竟~s~ノ6仇??エn?祐6メFンカメ?$舟ロ~???ョ#?G。JRー,)JP\nR?櫨?ラ?Y??\']コゐP??フ??Tョァk$ウMp _\r」゚? 」湶?溏Cmsi??篤R;ネm\'?銖?カ?2?ク?矧ラー???p蘋?,??%蹉ZYテ+愼ラカ0ソi\"゙D?=リサ??ッ濺vタネ遮ウコ?レe?m?\"レ[ォZ珥ィ唐」?U=ョ」0?(?4早?)ニ蠱?+キi_ヲf?*・n$Uq絃? タ??,ヤ児i?\0ハ.?>f8R コD]鱈?胙?\rネ耨5イコ~゚Lエ?サィBFトo雲pニ ゚タ?ィ?E\r\0 *サgoッ#ソソaW??螂鏘?\\ノゥレD? 7)ネレ蓿xヌセユ!ェチkウ?>]?拳、熨゚湟コャl・}\"?6喇ネ1*蝮)f;モマzネ髟ユt?ホ?-aケ?ロ[フO?8TrIン?アェネ忍?イ?1?\n?0。??檠?d陏、Wz\"駘嫂ノ?)蔗=ウ桎オ物h?Eユw6VWv旅AZo澁ミ ネタ!パGスV?車聞外胙葯sア??ォJJ?\'tソ?イ面y\\慶?Wニ}フ?.テ??~\rヘワj? HBコ?」?\\?70衡髻ネBア??z」,rミ・?\0ト?森? (9>?Zロ=1ム經糠X蜥7Lx? テレ1怩[ム寃梢jホ柧若n?-??愛ト」?\0d sニvラァ?i???AwョO? b?課{トd(ネンネ苔訟μ宸ム、?? zr?メレ;ロ曳゚,?! ヌク=?&ュナ踪e君BG?bO}ソnテ?aゴ+{ユ?=:爻#テ柝ム+ウ1エ?1ノ?ユWユコイモMケ7レ公sフ?Pン,P[ヲ7aG-!ハ? 恥8ッ9ツsvヘ4Ju]ナ?・檪叡l0\nェV゚?##ソョjソェマゥナモr?-「、Lヨ?@8fマp=ァ躡竹Pムオ?%ュ?ュ|ィhヤ\\ャAラムs收゙ソJ」|d黜$ウ愁ミッ.ョ??タLe?!マr・i rエ?\r「?3誘ムョ?5偽?]呶リ.?ワ?\"ァセ\Z?\nノセ[h??!S.?, ?;?ァ゙オf、D憩Iv@@yヒァ\r糟?sX?・~o-。エコKyc>UY<ワ?8?ソモ耀ァ゚Mey 岩1ネ??wD??但bム@N戟キcケニ8A?lu9o$鵁レC#?\'福\r擾ュi v!?y N?}嘱?J儲 \\クス?+欠ub;??スWnLLニK}ツ3ロ\'弖8ラ<c/?zdfニイ~Pコ?tQコウH適サH? ?ツ釉」エ9?5%廿ヤ.\0?+n^レ陜CモノN愈イ・e~\'\0q?{U\n]トワ a胞?71N? <ヌxQホ\0\'ー>オ肄?聿??ム?幵ヲゥ??\0ヌ?zoTセモd?/3x憎Jイ蜃| ?/NコメuK9$セ阪蛋朱タH?1娩゙S?=9豬OCチm4ヒh慮ホムフ\"I? レI<~筝\rャ3ロォャメDカォ鋲? トc*@??X鶯」ヨ源F珪n?+?Oシネ、ナ W@ヲホN{?bオ゙几mア(?)?。$Maオ??・mD?;オ疏触 p_ハ6????\0bオッナG記ヨ?.沙@I岩Drセヌ゚?ァS#i_チ土p?リ?o褊ツ]?ハ ??暎Z/ャ?ロスV?Imアフタネ ?蝕?澤フ靭ZN。ogy,浄フタ;舮(@#=ヌ?博ニ{「?{?tS?ユ?R???f?6エ|Fウクv[ネトx1?;W框ヌ5ムケクhcrP擘⌒\n直?{Xレ?/rクテ?2[?ァゥzF}Fエウケ?\r0\\^ロ ?H??「I ?3d?ネ?=?苟價ヘサキ?IpB綻W?Gタ?m。ケソロ7?!|I!@蛔ョqワ?_|ヤニ册」]_iー:コニ阿o\nR・、*ナイ?0?T?=&イコ7Fモ?ィ,/oRツ[ロ゚レ?hムネレケ?ナ|タ wゥ薊?A\"イユ%?ハ_r2?\0.\0?ヤ樞ーB???スjロラ}ィt郵_?盥ケ壗1!?)A縦.虱?2}ケ?*ゥh拆v5hエユ「l22 zzW;erX」 d戀シラSキゥmJ7ケ壺ヤ3菜?eヒP?.?種&?>贍K\'竒GS ゙.ユDー 鶫ヌ|?X?.?{ク?.$トリ$/>?オy騁メbqomk2オリrテカsレウn?ニニ??拑8$FUA=?湟ケryY瑙bn?\0?呂,27セ換Jkイi娜瀕昇ニフ??讃j}\\;鉾゚験聳ョVスC「El?rネタニ・?NO睾yシ{T^オモ?S??,カ$0角;脩s?ュェE5アq??ssZoソ゚?スZ躅ス擇榱・Er?p?^9ャュRE葡8ャ雛($9?Oラ?:轗モキvモ。?O?<◆\\?vG\Z[ヘqト1*医゚eロ??)<Lx貮用vuB\n*離5ャl4?ヨ??喀ャミシTc?9ノ?X\Zm功7?ヒ&酢テ枳\"ハニ??セU」?砠o\rTg??ゥル?\'Pウセエ?$? eV\ra蔆\'?ヘCマ?.惴LSKnハ~ャュメロN?d*@ニッレWI[??ュu0?1Zル+??ワ借 ?オ]芒K}?\"z?Bセサ? サィ?[友?dゥ岸?涌i.ウK\0qィU靭?^透リルリリ?,e\\Lサ續? ?{淇O]_リk==u、[ロo 9Pル?ニ{?ョ\\宰?トュセカモ4kォ)gメルY-紜?亞銛豬旡ノ竪& C?\Z゚J? ヲメ・i\Z套SホN6燼?Gレ「5?)奧?-md睨??!#クワ}ハ??Z 、、N\"mンロ゙サg俐゙)e1ワoュLノg~?[ャV鵝ト0ォ??ヨ。?0ヒ;[Gク?B1?95k ト層灘リケツ?ヨアn擁?v8セオ?6U6ーa憎Mt???6yr*券,ュ?2<ェqサ\0{滾ゥ?ーCホ6?/? 嚴メcg介Yキ?!@5マX洋ア????篁゙ル+」o~ツ0スマヌニ蕨?壮+asチhモ殤XWセ??:?\Z^ェ?\rS\'mス雰ケc2;キ゚?\0、kル?吁ル、z・+\"ツ櫨\0・)@)JP8?コtサ媽??1ッウァパi\rg\Z?フ?モ 廠ェァLワC.?-ョU rZ*?Bッ条+i?\0?\0メd}」z侵ォ魅=畿珊マpテ?>X??\0V秘kクVレワハNユ荘ア゚k\0G?\0?+???.X?8?F?M?:?24瑠tJイェ(mノX?kMンロフ壼?乢*hミ?l?? ?\0Zン?\nコ?;ォqァ\\ync醸o焼蜿セkォィ?zi+ァD屶エ卞締.N<2}ーN=ォォW劾*縵F湶獰f辻u?,1ロィU署?9^G藕/モ?Kwi[7yミm2>??Ak}\']/?:bp?ェヘ?sヌロ禅ュ;K桎椏蒟?;」76?>メ\'プ?8ュ!藹m羌R鴾海j?\"ロニ3DQヒ)瓷遏Nテ?ィヘn?鸛Nby-?ツェr!P<サN?ュテmモV7レBュ鎮mョ%ゥI??コョK/ーq?ユ\n?\0。g?eシ榛マ=ツ孅ト2マ%ス;|VアヒルハMスニィラ男6?強ロ杼輌f8$洸<讎:ヨメ[?/?゚ム?$詞d? ?*?vs゚ミラU・恂スC??コ?カ ?リ;?鸚ョ繩?モ鏑?\'?%&)# ケ?3,pケ\'セ9ンV入織6都ヲマ」M褥オ?ヌ??3ホ1尋櫃餡oq}ヌ &dヂ釆3?;忝V=スステヒVェ&yホナ@99ヌW;ヒ;ヒ ノャ、 ?aシ2|2テラロ4iY$・楹{ァ゚テ2\\ゥh廩璽#p?F?6カ扁モ」Rメ?\"キケ枇77?VUQ?8?z?R2HH輌 干h\Zヲ瀕g2Y\\Ex?%フRス ?$(マミ?/燥?/Qコ>0鞏Io%シ6キS齬\Z?!?#独?8%W\'\0gjAp?彦ユZXニ9\'n\0?&ーP?#Lスヲフン;ッ:r?擬ヒ9ャ?」オ?法ク?ヤz釀c?フャヤゥ壯マニ匚オ(ヤリイチ篥oq?2?0y聟スVzウG?E?l襯+猴ク?.@f鉅Iヌヨイ4~ッ[w材?63!!ン?ヌ?\r?>オロァkVコ?螯PAp螂∨d^pェ厮aヌ|ユ甌U?9ァ?」[eキ鳬oソ?!ニムタチュr麗gfヨ務ァ?,廏E\'rc \0Gワ?8カ5ス.K-笛X喚衄Hチマ=サ???|レn。\"r?3ョF?\0・z?\0B哢x・゙卉ヒtp>4\Z?6蓼モォ(街セ?@ァ<\\?ァRtソR闥エ}Aァ^リ\\\\チ翦.性2?<枹歃柬K磔P鰡ュh=]~阻? 2ホ,Uシム「ウ) Hタaエ?5;?|W?oRロj奔$?\Z}ャ^I3?冒KI?>?マ5?.I%ッ樽Es才租}ト ニGヤヨf歹0ア{??1glO鰍R・r@ホ=ウ?監ヤcA)MフナI炳}?*オ?7ム獨n筝ス=コニメノeP訣ケ>??1Z苒?゚Ke$ヤJワ0黝゙。$vqI+ノキtqdィ\n03楝}j网?&黠゙榜?M?ョ?輒屶S+c; 螻?>」゙ッ?R]7ヒ髢炊 \"キ?\"?\0ニN゙ョ坩??D??擂含カ?\"+5ヘヤ? [ヲIル?I,オxア?LモQナ\n_ケ 6マ\'MV鋺Wo荒?;ハトpE瀏゚?オ.昧(」i{{Fトラ鈎対;*?$ヨォキVv退兎!?,ナ゙~ワ対~オ?))hタゴヤ?8ヨ9戰+オB3?イ壽Cルレ;ヲo?4スワ;}ス~オ7メ??゚?!、f[j隣邸「籘\'刳p<ヒ?招Djミ鵺ッハ\"サ曵?\'eトa亳pFNyォPt喫7カヘトsロフロ歪 彡ソ>オQコユ?幻??サ洞?升借??#?ル,オリネモルニ5)Jワ~\'O<テ?aN????ワナl哢??dd画Pp???J[{キ?sエ、?6禮スHノカX?wコ桃クノ$?;ヨP?1ニnR゚? :ニァィ_k]゚ワIr?1,mU98Sヌユmkmj?゚Pサi\'?侶司 ネ9)羚|璢?、モ湧?4蠅蓮メLフ、斛?oキon?\0J檍ei\'Rレヒゥy\"詑嫣\00假?ョヲ短]句カゥ}kメ?mヤ1]aフ逗2ク\0c\'ヤ?ォソァ?挫サコ曰|ニpp0NqマヲG?9コ幽メzやト?ウ鍛T$crFH?ォ\r?-ュ鶯ツ脆-ンゥチネ??\0イ1?gk?\"uィF俯淅?\"Zv?\n?レトg栲Gメ「?,[P-*ャ奪サ?eNN{苟欖?+躪鮃wS4コx{ォォxB?ィ |v${?ィ:ナ゙。ミ乢k[ァト?\\19?#ミ}\r^オル\r満」ラ?,??4ヌ#?8ヘkk吩ク勸%西ナサ然 孝藾榎3クヲYシサイsヘcカ?\'佼」ニタHゥク2ン樟+UTタ漠pャIヌ$ヨ+?Nl?Q 7R[烹bbサ壬ユ?? c,豕?)?媼ソhロ?ト?Eワハ?フ?$丹゙サ5Sr?!リ1リ聊アI燗Xユlア???q|=麥lHL融クオdヌ\0C\n09?鉚ッOヨ??喜蔦?鳬Bイスワ祐ノ曇???Uュヘ^\\ンノ坩?)Jゥ\"櫨\0・)@)JP\Zォ?ム?5渟?羌ウ頑贅(ッ冬ミcXeI%u-リ?Nワ草3?tスタ墜d??降場ヨ坩婦・゚ナ綺゙@?ヌクョ?Jーネ 撃y5?ァiラZサゥtン?ノu・゙ヘcp?Q?7(ナI\0装8ネ菩?%dq9?レウl?:ソ Vサxs\0Y\0\'98?チッ@?oォ駛%U$ィ??オ?\r\Z?)_?壁>_Z゚?5_垉?.ュー d ヲ28?+ヤ??0ニ??ヘ>ヌサ エ?ユラHZAェOzカネQ?*ネ゚>谺粐姫申箚剖2[?レシオ9G」fャミz?キラオi.?zM?)゙語、ッd ナ毫?z菰:目?;事ラ! .\"フHToオ?#?マJン]K・hzt?ロAク\'?ィ蛩sZCィョエnイ危Ufば?ツ6YV $w? ヲナgpI瑰ヘzfイzメ?\0B慌ュオ{m堆s?9拶ホヘァ\0耿c??@ャ;g?Mr\r噂舌k?FH8?>ユ゚ユXFアマg%メハTヌqム7軽チ?$?)舐=ェソ?,イ,?;ナp8纜?G?+ムJム兮ム~Nラ_%「マij7?3m\r淨Gb}ニ9?8柳?C!オキー?ク慶}ヨKmf*Tヒwo^}jヲ?.tヤ?0[?!?W\n0メq黥ト夛寿p務ノ?カjヲ^ハ? ツe\'=?オ#oイI9$?[?\Zm9?アャ笛O*Nユ堂チノ*yュwtヌW^[uZks??9Mト勘\Z\'ツ;沌市?ー:[F??[ヘ キ?!伸ルH?!}?>筌?#エアy?K辨?葉E dq?0?ト蒡?Icュ\"髣 KF談x ?クコヒl?キキ・g?>%シ赭iVVE)&?vqP:6。>・4ヨゥd??攀ルヌ。邁?X4?Td]Nヨ?+?ツレ?(A\r≠ヌ9?_ヒ牧」Dホヒh?0 Drホ筴?゚mレMO]??セ期Eスケカア@?ナ\rβ\'ク?ク?*。st固?\n=?ナ紋d悔N托レ?マオdk:R」xワ#ッ篇ホT???mBソラXヌヲ?マ檜カ$??u ッ躯+ノt??ムハキ?&??OュZ1リlヌスkq9栗衄T?縦?冢?a,? ;y^{ヨ=衄X殱?旅 HVld??-Q娯、ゥ厰Z%ハ井F゚び?,qサ肉??5享C?,?)q「棚N?HSキ*~ク?&ォ卿:゙σヨLZア屠$ェ沼R}?キ=?<マ・蠶??キヤナ6エノ.、カケメァs{i,ト?シ?ヌ?8??M?,-ヌ\Z 0!??=ソ・p[ワG$紗#ー+\"ョ|< ;厨?\0_セeヤZ|゙u ?Zン|$\rタeレsリ$?ンサW雙セ\r#6梔ョ「y?/\"[ルn.Q:ツョ6s???゙」セ#ナiェ餬Vーi霧ラi?y?p¢骼獪カク?=ァ-?モレ?ネ?ヘヒ(9ネU8口●\nツ?マィワワC}?ル゚ワ]ツャ辰 D?3タル?ウ徭]x??エ^[拒ュオ?胴カ?%シ=J?3f73)\'+ンO#兼マ・Mt%セ帯zスヲウヨ\ZM゙・e?+o帯ヤーA#託ュ?奨獪コ?\\:kヘゥiイ|穗蕪k)<図楯π3Rコ湘[ェッ袒??\0ェ&釣Y朏{ X?窯?ロニH?5?~ァ?,+_?營ウヘW?讌u-コ3ヌス??Jスt?8?Xm?29?\\?エ2G?U?\"];Pコセ涜オ2シエ (r?7~O゚ソ?ラ:?2+0\'\n?6 チ??\\莞mR[k?ツI?;「ネT?Hロエ?3タ?豎llXG&。,O 0イ?%<シ?(??~9ォ/ワゥ~?ュヌ」キ?0\\,ャーx?ハ痍ヌィヌ?ネ鬮サc+ワCiPF\n阿<+゚?ュKbm羯カニ搶牢皚ケ;dィ=?枳?黐ラ? W/?蜑U\'?アヌ蜴?8\'?囂e゚]鼡-*ヒU勁Yヌ?ワ@ニ~?Zソユn??シxヨe\\eFメy?\0ュH?v・suekoipZHm?2?リ>゚_・Cヘァワテs$mLjタタ?WヌaIIZ:??ァモロ?icEd??+ウP?\'ヌk3mteチ??+ソMアロi9ケロU?c゚=ェ?イ/e~RYシヌ$?&?\"ロトヲ>+ッ刧uツケワョラレy>ァメー?9&ア冲u誰Iョ界sヌ8ュ屑5h?O?、エサュゼケ&?ipO!径O゚ア?ル%Qlイ??闕?霓ァ|a7?:゙ヒト?(ユ7cモ;sS・yfツ櫨\0・)@)JP\nR?シ????\0レ ^ゞ儲Yaォロ?37栗莫v?2フ\0>?Wソkフ_ギ?O?Wニ?ニ?K Qaノt?7ォ3轢ヲ\0 萢ワz?y>゙dハd?(ム「Mテ ?yレ ?5m鐓V?+ユまー庁Eldイ座}xゥ:y3リ於\'??ッMサK3gォ@?.?a縷゙=ケハ??j?9~P\\?、璞?豬トカニ7#\r??。タ?9ゥナ36ィ績a\Z軍ナ碾?蘢 ?8タ>暎X?ュ?メu瘉[ト載\r癇A蘭\\十煌?オy?VネWsD瘧?0゚C樞カ=ャ??ヨス-Wv粐? ・キ2?6ィ?4dgzアンサp!B鄒+,挫ロZ,カi?浸ノoo+ P?イ?N>??ォ」Oウ?ァg|ーCエc??賓ヘ#瀑ス?yu錏]岶?@??qキ色A=ェ?+・n:Vm2レレh窗RN?u?渉 ヌヌレィウツO型ノ糺5?|スワ6ツEk?:??ハ?+7ゥuィン??$??2ヌエ1 リマァ?マタ?ー?「6「、ヒ?? ?セ」ナ[:?J?チumェ[黐跌ャメメ゙ル綛dS謠?ーテgモケ箋柯F|_e稚h[ロb?チ,N?>??ェ??ヌPiウャ?zt0薄Y?!#?\02ノ^マ\'タg2\nヲ0O#オvタd壯チe@?咥タ?U峡z^?n/Aオ?{i?]ヲ0 !瓰A 携檎5Mkァ旦G $\nG・hメ超Iウ:C?カシスヤオo P?ー?)!゚q?\\aウ?ァ??r?ャE|V?*ラ\0?w\0ワ?Wi?セ+[tュ?oォ?オjーコイレa$相??エワ瑩;Tワ?コh6コTJ?\\ッフG2\\エ?ケ ?{??\rrマヒY?&オs+M聢エ?)ヒc?リ?゚咨ォW沓フ?&ア?>揀ネ|ヲキ?)ヌ珈6蝕ゥ頸?67Vホbpwキ ?1タニ}j衲=Oッ|ユセ鋲?(嫺欝?&,、ル<侵I豬ッチ?>アig-?ー aカ?s鴆?モコe欒 屏葎?-伐キセ狭城^&o、K?\0サ煉幕?$tセソエーラオ9n4k[ュQ蜴9?テ奄ヲARFrsY??メ7シ環[?;?#Iィタ彭?=?F;ユ3?擧チメキ垓カH.ョeJ??ネ \Z?r\0ニqレエ螯ュ.「d?れC?\0テRx?醴コア}.Rヌ|??\0\Z)ホ\\ェエoクnt6?ヤヨ?唔フメ棚?\'xンマタ?ネ?雖トソ?徼?ァミT?芟?xS?+ネ?1ユ?セ蕊YTケ旨ェメ7c盂_)yO併?\"リZ?サ4ォ吶?3 オ喇?チ]、ンキ閇ネシ邇^;pハォ?z,、ォf贄5;ヒ HdユXウ。8g?Oテ携閑?\0ャ\"?^9l\"\"?;exトlモクc??Eソナ uサソヒ来2I犁F%ニ s?c?=;V叟コGP??B?;t+癪F劵?? qリκ琅\Zセ?#?{-fwNロ?7:レコ?o;???)虹?9ハカNtロヘァ4N毛ワナjヨ?f ?<、茎譲ィョ榕4}OW?4」%?;ッ;シイ?ホ~?ラ?qp5{=Gァ?(? @セ\Z*\'ソ??イ}r+_ス\'カヌEwッセ_鷯/ス篭ヨaлフH2キC\"ア?;?。コォ珸Yi?$ど趺?誅-ュ弁竚?F$アロ?=アヘz篩トュ&=帝?・ヒfメ\\捕テ!>E.pル?スェZ゙゚カヒ詆ヒ\0メ熕¥vヌo|ヤum閹b[5??zy属$p?熬}3V?。RマXメ?\\I?8スッ?リ 鶫ノ?ソュN?<ミ-コ{Vクfクゐu@Z饌b\"Rタワ曰??ヌN? ゥlU%セgf謀 俘?庄スqマヘ\\???\0??\0m*ソgンw」ュ?4鋸4曼ルメa$ュtXウ沙ルH9ンホ\0Zゥ鮗fサョi1?餌ァZカ?X?\Z^ヌ\nyv??>テ壓セ綱溶\"仆セc?9m??\0臓O\\V4??VOX斈g{??Cリ榲?篁#袁*/.險[Z_ト哘エ?コ鱆」?#BdX箪?3ノ?レュ?D?ホHチ艘?ゥ、q?・ヲcB宸図椋?ロMヲル゙ナ,Мrav\0?.゚?:ホY%袋m-必擔KV6>Y\ZンqRJッ9ネ??k タ施?&曰@拑ウケq?~ケョ庚<?袗n譜uNs鴿?軅t?イvmネ蜀x鉐祝゚Yテョ?w」ゥJ求-フ+!UトA? ラ ?キ?チ#ヒリ簡? #U?\r臠\'クコ&窺チ9\'n9>シwュ%嗷v却OイスィZi?3xレユヤレ藤 ? Dh=\nD搾?#メク3荳找[7u)J?4・()JJR?R箱N?ム杖疱キメ゙ 9?C フ<ォ$r,ゥサW法pN9ォ?(挈圈/ユクキ$btルマ???」拏?カキIL!カコャφ=ソ#]?>??i?6ォgヲ?;5=9ョユYsシ(_タ「U稗濛@?ャュ}Z?Nラ「P#ケRョGe厨5>ヌマWIO ?9a閘?ュNリIj嘶レ.ァiハ\0?3JT$?シ?薩jラェ?怯t\rョュ\r?學C!\\エl喚オネ迯ャ{?????ルィョメヘgxュ嫦;n牙9?マ?#?9ヌオbiWmo|%b+x娟p?聲ク緻(?({恷ユ゚ィ[ルEwpfシ縮d醐?\0メト?+。・ムヒア麩夛KTメオ]=4ィユチ?v?ヲOェ??x割メ,ッ?xュNネk :4BTrJ「\rサ?.pF3彙ィ?Wア(耨q_オX4K?N $2I Dイ痞。ウ?{s\\メナニ?N?\"コ?%?哮e$,r\0J($$c」l? キ ,2J?トゥ刻???ヨラ}g、オ ;a%オオセオ?ェッイsェ?8ニy?Q?ァァYィ憐>。cqs瑁ア!?2LEqホ8ェヌ%鳧Q%ム゚u;=Nキユu[ッンア/?;(279?験?ユrユ/:gゥコvhl\r?V4ハ聴? ニ?輅 sニ+Gエ^?」4?8}フq檍舍ヌ・lO?\r:Gwァ,?2I,N\".?? ?ト菜ロヌカEa?W莉-隲??Gィ?アcォiラム・タ+)1ヲワ蒟」a?ス^??}9uァ_ヘュ?ylアエQコャ6?ヒ).?v植ノ?」?養モニ{$X諍??;ム芙僥F8セェnエカ?!サQオ臓8VOFネ98>オ択ッォ5?4ヒ?:+?\'y\0G@ロヨ<ア*詢ェ>梳甜ヨ-s」?ァoャ?」カモ伏M?4ロナYpト8Sヲ9艨゚ヌ6?KE妄&シフッオンΡ嵐sヌ゚ヨカマタ]+Eユ5ォ?#Xオ呈?Mvモ 擇煕チ|v ハオ^ォゥテ4rュ?f>\ZナcЭナク?樸d闕7W宇オik,6m?%?$v焼ョ」?#ア?Ze塞熹ヒュッLロ?Tテ「??Ecァリ?レ?J8?VニL?;?&ォMgァリj遊レョ5 %vX苣レU?ヌソ?C?\0?オヤ檄F,7ホイeK31ワ暗!嶽譬oョ「{?0アX?$?伏ニ?lネサ抱;J+0x??_1ケU|68ア%セa?蓿黍1sキv1涸・aウ?暗sヘi??+Sメ范ァa樢?./ョX|・福??、遜F? 3?8B「v?\0I弌$スs?.、黯悁mG@ヤn,¥チ曰ロF??後ソc驀GJクカXu?1ヒ嶝8?ニリn\0+ヌ9?ヨ|\\AM?7イサクコクカ1テoQn?トgH?c市?P?ヒ?*I、??X|4~憧シ陜 ~?セXカ゚辻З?淆??ニ+Z???Uオ殊ヨレレ?カ[7{kaフT?\"?}3施?アハ?Q.フ?f-需?+?。1g止オ霸0d?#?я??*U?エ驚? P%?ロ?:?サ;s%シ1T銓5ア?/期\'JFモh\Zd釣lFク二0? 雑レオ藤エ?,\Z&$?\0v9?\r??\n2@}ェッ\Z歸tl>ィ?ォ??勵ユヘ狒劍?$涛?PレRO・? Z?,2ヒ ?.#,?ゥR\nカA燼OュSニsナsGup?#ヨエX笊$Wキd岬ミマェ5フャbfiZ\\,Y$?=ア?ッキ\Z?+肅ョ8レc∠ュp?>??テ醸丸ャエiオ96キ?イカmト?\n 唐; ユ.K9狡Z7l?6ワ;gソスUF4ユラノラdオッS? qヒu簓%ョpO~k&ヒィ、若Kロヌ砠ヘ檎C_4ス?Vシ塰゙健H??\n?$エ)\"イ燐??Vb、、レ7酖nィ榑ヌ?声[? nニフ?_゚?Olヨネ魄。ケサセ?$キV%1筧宛?%r\0ワ罅r+ヘ\r樛マWy?葷62、( \'o~\0ノ?ヲエ ]?格????&メワ蘗リ?>?y^?JZ?嫻ヲ?ヤヨ壅Q,3hS[]@▼0ネ|鷙wア系?;キオPッ4m?Lkvクヤ?.??{vb?yレト? ?=腔近?jwュu.?\rフ田j<。v゚ニ冒?m9_ホー5゙蛾H5サi紿.竓P嬬@儕wsエ?>??ル」?阻f?」メ犖Y-.レB蠑サH(=マs??」ワjラf粐gウイ杖Kキ$歸マ?W・コ率?ノ瓩ァルタ?)nムニ;慾T怙\rT?GLイエイキム?I?xルクヒヌ7シ?\0zサ?躍C、k;n蔦l?ォサオケ?8モ}シ2I?耻?ネ。ュ?帝t?ュコCォコVUンマソ?c?・t|顧ヲ?&ヨ犬H緒$(ゥ$?羈ヌ\'=?n?エ6炬qチ堕ィ\0gオp?Eヤハ??゙冖??ン?pBタ;r==?sウミ?eカノカi?2M!!I\'?}\'?k」ッィ^絲サ?.cY「rA>?L? チ\rフSマ!ン*ャQキ?ァョ2I?&ケ?&「?a、魎ケュE&虜ヌ)瓊チャニ}鄂ti壞チモ?;Eケ廡|K???ェ{g?W-N?Rメn6ロチ-???%? w脣Teニ岌ルi\nヲA筰;井8ヌ$?<OスB珠オ{+菊sr粽2Zgロ\"瑯?NGq??oRjヨ逾蛛bHH??9;?8聢ヨaス?。?+w?6\\??\0迺ケ??スYLキ!ァクmャ」z恊A8胄オェTCgMソハM{5ワム椋移ワd鯨ケ豐R5耗ヲhカハ?7?\0S?L\0+菓h U????\0スu゙ホ粢D_トチニ?;gヤ箝Yz肱EノBH???・用卒 ク?ュv鯡? ??ク?D廷アレЯカ3?ケ[:/\',マォE> ネ Wlュ?t<惷マ餘ロdナQ%ミス3uラ?4N袖i?エ∽?7个ホd?リ○?Tォナ_ーBカ・ユコァト;鏘ュエエko?\0苑A漕b;y\"n;Wオk?3ケWチシz・+\"ツ櫨\0・)@)JP\nR?櫨??\0ロ衍?\0z|,オ?h窃tン簗ホY?エトG\"ェ? ゚牾-ルclネ>v闕E?\r?ネt? ??G8???(ァ??4?)ォ」ィ*ハF ?ソ95M?キト拘」ョッ」ココム?テ?5レ%国d左?盃%rpr2q奚>董捲6s迯ォ3?2Y?)??゙+?ァ昏\\GnツI\0&5#?#レュラ6スAhコセ槓?.W?医%~耨ワ・S$i コI@黥゙??\0弍ィ券ヨサ8ェ晒V??%@*ヌミ竿シヨ,,ョ カサ?.?8 q?ユ礎「Iン\',チテc9;崛?Z藺ェ|敕3[ャ謀ェヘш%y?w?e?q??GリBl\Z?d?m‥?爍R9a′施f??!ヨラI=洞S#Dウx%?89\'汁~舞ェリC&ゥ$レ Hヨタ窯レム?2J?ョ5;ン贓6H-Iクx イ60、1タ醪ヨt超J?ュO?エZ|?、?4?\\?3 8 ?\'奨サヤeテナs??%!Gwa?=?8♀ツユdvuqサ\0\07肓\\エ蛯礫{」 m$g8ヌpHニiツ?6tjシ詩p禿ロハ釛TキH?ヨ?7?\0-?--・ugI:HWア ?>ケ?^x窖走d? ヌ迥声オ餅。オエク挺フwナ 緬ポr・VQMS%3cュ療{スロニユ耨5]鋩ヨヨ?-ウ戍代_ツ?Rqニ;ユ?狽-<ワ驀Ch4坊o7;ラ$胞?\0イvニ?辮+DOcィ?\Z}璽yァ?\0?[ウ。a?vy?墫メ?Wモチエシhフ[竦F?#,=?8マ゚?rx、ヤ斤}\Z屮コ]?>享?iロタ?ラq?\Z2ケr?ヘマq錻j?]8tヒ?゙1ヒqzヨ?E/苅? cクP8>佻l?ア?Oァオy?7_゚-ヤュn?8bワ}ネ?3戌\nー?A鮃コキ}フ;??ホ9ヘCロリ^゙\\エカカ」??lv\\?貮カOaWH?!<6}苺? サ?キ?A]*]Q、\0??fョ:Vナ、ヘq\'Xレ]G[q2トeBサ?但^゚ィ??,ス&コ??75?尤4巌蚌?\'?テ?8?Z峭「ヘ.+?dモテヘ;0V? Kソィ8?ユ?溲”ゥ&謁ヲエD4メホョ??YクzスYセ |Hエ?\Zレo L癘yア#カヨ*3キヤ?少G????ソクサスユョ?厖G盻,v?}0?=ホ=?\'ヘホォD図;mゥOュヘァ[〈v、Gコiヤ???\0カタ9耙TwRiムAィワKm~コ?) Gサo\"L?l\r訌?jシイワ シ?NC3V鮗喬???N駑Rgコオモタ?Z5苜ロ9蔔=ウナ]ナァbハテレンャヒア2?\\??t?>5簀q\Z?vTppO}G餮7鬲?k域クAカナiア、 v紬?佝}sヘFGメ夛リ=?lアキc尋ク?Jォrテモ後且I薦F麥>??dウM」・?ラキ?コ$モ」f-o\"4Hb|、ィマ?。l!? セエ潅懣i< \\?.|クノチヌィィ校ラBキモ笞ツ?跫リ\"??\n?|ヌw腮ヨョ?gc、ヒmr妨?\"?bン\nI\Z禊大3?サV| ?F萪柧觜フ{ウ芝ウチニ0\"ォv? ヒセョキ」(2g*H#pチ?;?ミ゚シ@ш \0aーリ?~?Uウ+Yサ曠d? Ktンマ〕飴#キ=セオ)メzu裔?疥o6メG?0逮ク ンsニNqロ??5ル?,ョl??]?qm\0ヲ0??s?=ォ。5?ホチ?[ル「キy見?;?#?9\Zソロtgホン騷oゥ>%ulー\\?I徇Y--秣??\0zsヘRセ!t9?\rJ?K?ゥ\"![*c<彭d?ヲ}??sヨ-3゚閊^亶?? uJD\n\0ック??;蓴Quネu)^}B???y哮?ェ国ルマ?01\\?効゙?Ouイケc・゙鷏? リD。d乏メ}>シq^滲aム? 、タイ?3?v?V傳継驚?蒿zW升ユョ !ェ*gn\0cマラン?^Iヲj)ィ|ペ?&! 血ヌキ,9ゥ艀?\0ulルR=コ?M椨m?1ナ9カ杳歌?瓣??マ?^u?iレョァ-?]j!リ,hj?9f゚\'墫\ZッUj略述\\mノ?セ萵?ヘJ?J龜UァN?エq?訌\02HR=?藹沼筺薀ケ7ム-ヨ]Kィa?ma3rU?;キ?>??*?洶ソメ媚ユョ?キlE\'9lキ??ヒJ鈩?ユiョ?2[ZFrロ?\0ヨ・tK{?逃ワM?」\nッ?pA?=s?ッGロo~ルD浹m??ヘ?ロ?623」?6?ル レオマYZトレ・ェテコW米?\0r@?ムロュアゥMa「?薮&?\ZK/\r?!%カョラ$聊オ\rヲ冫qヤZmげ狗T(rムぽF~サrkヌ燃tY・ムj饋悳ヒサ{憔チonAiU6賃?泙?R~別?エコヤ\'ウコメ・in窃*d?チv讒コ妾-4ヒ_辺テ餌P$fV}?ミc?-3Bク\n?ー4ヌx,クbf?F*ヒZEェ悦ャョ,稾=-、咼R? ヌ}トp?gキ&ケナ。|ャH\'朧?c岸N巽\\?\0ヤニ栴レH2ハ?%テ?,O??\0スBu=?ム鉾トェ?H「<\0;~ソJユEVコレ?モnヘ攪ycニ #p、py??筬iムH゙,0皆ヌ??テホN?=??*ラo」Oqtメ]ェ絎?1再?n゚゙ウ容fハ-?漕%?7ソロ歓YZイ?ク?6法B戌y?\0嚊ソ?-跨2? カPw\'?\nリコ漫 v。LjN08,s?=+Yuェ?7?y?q柔ZイTCD メ<ホ7ィ?V?S)\Z?*ク8??;肪リ?$男[:&8ィ?F]??gJテvX?95オ?cセ?カ?iェ\\diン:SR怎ふ+?\0?7B#a?*・fノヨ?ミヌ睇ツ?、、サKヒ汽wケ?\n??キ?ハ mイ\0$M]ゥJ窖5・()JJR?R箱・()J^c?コ?%ヲム?越zI+cゥs?、??,淡+?O薯@J?u^[[^ルヘgyoヘエ?SC*I?YOH ?纛?里\ZオG?u(?オyHF;?=?G??j[ォ4+S1?E淡w1」0ニ笄?q?{ヨクラ4-C睇ト}S」ッョV0wFル=ヌ゚洽ャ;トカ淞シ迦?゙法fR{T瑜?-gE彜鶫?\'?7「産セタsヌメ「、C ?カ゚?\0?エ蹙ラaヤt「?Iコ)e?キTラVEaユ丹ョ?3ァヘ耽??I#\\p鳧燼?f師?「\nテCウスミ?\0x$キ2ンメ?歴??カN?Fチ?篏エヘ#Tモ5K-wOqpケ本k? u>~ンネ?★?ァd&イ゚42?2ロr3?鑚鑠gI?+?3J:mシウ[H&ティa??ラ侃?/[%?jWカイLnm「嶋ユホナ??ヤTョ▲タンSqk?%¢O?? 7ァ<X1ワンホ塲?シフDメッH」vムニpq??;\r玄xG賊ッlョ0キ胎?gテ。*7′n艘?ャァ・Hイ$t Wエソ$゙ヌgo(龍[8?ア濺?邱/ヤn?[舘0/エ9Qホル斈Rn?8??\0ソZヤレ暄?? \ZY゙? )\\1\n2I?\'>ユd?-Q,「??.4モフ7$色rv?yマ交?,听ユK・pz?9?勾cキ巽湛パ$l牾瀋モオl?\0?=Wk?Di喙]胸|\Z?オ?SQヨ袴゙ヘ9,メ映bL┳bト1憫+ミウ蹈&?4?。ヨ.。撤???!R\"ャg?6?9?オSセ|/ソ??-?」E,{D@]Lンワケ癪?計ュχ1ネキ77zХwゥc%ソヘニ0&P゚テDEチ\0.?縲2\rk膊I}ク2\"スイヘラ嗤テソ?Kヲヘq聲D?ヌ4トd袗*vア ュ嘱ユ+ュ?ヒァ?シ?:ュヘ?ケv|Fトノソwァ\0ー璢膳=ョコ\'???iksVヒ庠|ハヘ93?ォ7\0 ッa渫9?<チqィ\\-イチmeJ??席痞。P/ユ隴?エ駮叛コセモュ??ナnチ|リレ、?-F|?tJFOテュ?Mセヤ5?ヘ-7QアCコ)%?クW?.」?m?メ] :B?-b?ウヤセfメ \\ク工x$$\rャッ漕PHa鳧\rJ??スス情キEカ葉汝故\\?8n;??*醺ム髫オヤコu瞠???L@?@瀘マソ?l跌クセヒ」マ?\0ュ?3Qソ徹?$緩$?;iラ~賽cPァ$池タg痴マ「?ァ柳/?fチ??=1?サ笑スMuモp[\rnフ?\Z]?!゙=「」テ.ワ蘿?? ?ヤ囂ツ-b。ィンレナev[dovRh恆?Sスy?8?f遷?*?]F hu aキw(?\\\0r;?メ;9?=?0>、\nワR|皷ョ羹ムo?Rリセ?la煤テnR;{゚クォ??ォ]?#R鶤nロGxdレlー $8#W後悄フヨマネニ容xウFYt?ym$カzeト??サトサ?ホI?ゥ\rK?:ァM鬮>・ヤt?凅Wチ販ャフ ???「スAメ:oK|+ζ尺゚Y4krY、w,x^ム琢羈5A?\rCヤeオらMケ鵆;ォ?\"ュワ・礑p 0Aタ\0p#瓦?・・??則tクnnoEョ冶?9Pp[ワ}~セ?ォ[マkゥワYヘ2ワシR?ロ癖8ハ櫺^宍?栩~觜レヲ弾 !?5YUウ?sロ櫟ニ??\'ュ?.・gsj薬v^RX「O 遏/ィ<筵y0?8?Kミョ?=K?,纎iカ童8ヒ1ヌヲ??Mtゥsョロ駢モ?ネ?ヌオdル?\0??楫シ?4m瘢ヘヌRt?「??籀、張セ酳リェibナIノ瀏?ゥ}7SCuw5アー丱粗_9|;ャ1?徃 jホ^K}tMzヨ:l゙jイロレロロX^ト?巴Gi]x 1燗R彖Uウ」5k=ナ? Q?エq鹸カpT?S]sヤ圜カラ?粗o、A・?Mf\0\0?8熬[h苙}ホEOHム$ミ?スサキ濃ョeヒ(\' ?3豚~u{r丈FッFナ?+据サNY侯F\n?<G。ニ2}j+Gモ?{ァ諦ヨyナア!ユホ\ZQ面耨?>ヒ?ラレ゙抑・Ki-レチ串隹Wラ呑\'?=???=擘ス#ou,?$Frョォ?8<\"9?#ラ5ポ\"ワ?Siコ???_]エタ\\イFL暖9b[\0r??ヲ゚ンkzヒ、qノo$詮ョ02」h?\0J?ラZ]ホュqsyk*テmmチg ホQ ?ニ゙リヌゥ羞eiヨ;cムホbー含\"ィ????ノノ&シ婿Iヒ苻ェEsNキe??eS,俊]]NCョNs苔渣fャレ索?ヲo?- ?#ミ\03?o?皀ル蒜黙ネYpホ27??ヘJ:^マs2ノ+ナ芟懦=?クォF$「>麑?籐シ5嵐?/\'v0=ソロ?\rO伎ノSQ桑8em罫サ=*侮ル?0腺?>A?=イ+ョ?/)|レv?fオHvF?貫/ヒ\"「E*5?ヤ?C◆zテ?d喫?セU<\0?zスHヨ&ン?;筏ウ??\"Zロフ?6}]?キメョAテRヤ-ホ?6「nn0\0ュ9ヤコ粧齠]ε6ヤA?挂ヤq゚gdフム???gロ?ニノbM\nI拵k??ッョ}ォヲg?ー「靡?3ヒr~ユ?5?1?7帋猟ロmQ ??スヤカ8uYX\0險ィ27 獸??cセ??公埔ム渤]8鬨\\ノ彷Iキ@}ヒョ?ニ゚J? ョlメ?\0 シP・)X・()JJR?R箱・()JJR???\0?ミrk?Y鬩+黨4ZG?(?ュ\\ィ?8?>s?「N9ネ?C?萎蟆@マs?「??\0レ痺|&??XoI?^メGKIノbヨ・ウ凍7!lケb孤ヨ?恋酊]3 ?hソ[XYuOJノw\n傷カ??1サネy$q後?ュMォi要メニ?ルh、S舌セ?#?ヌ畧R??テ? v夘尾qWョァム,L7ヨイケ\Z=?螫ゥ?\0頤T>?$z葫ソ?ォモ9Z苡?ワVvサ??郢!ァ]ノ」i?1\'?3?FAセ7??゚?:持qd?3)盡テ讐緩EG?Z?メ竒?1eki-ヘ?7カ荼Oc!^テモロ? \rヌ??\'?9イT?7酣汕?8ヨエリ4ル栽?ュヘヒ)ロ竭槽\\ツF0OォK?^uRjWZ治ゥH?房xハ砂ェ歟;飮?スKノ?4\r沙 ォチニQ潅(s十筴?$?-Zu衂Uj(コオ?シH7キ-\'?cO陬臭??E涌#ンi?黐Iサ9テ1H>Xqサiニy?3」コ;Rケ:アゴ?汚1F?ワ$\rロ8衆^?ユmッョaエウヨ?ZmB 5ワn#+?ーW\'裁9燻リ<豕ネ筵Hイ5uカ?$鵈Vカ1、B瀁@メ8十繽セk糸ァj_スogミ癇?ニpツ$eS?X大\'?\rmセ?iゥkーDo?*ホ━=ナノ?池ハ?* ?0=jロgモ ムb?罰?R朱#v?\Z6肩トタ w?fウ卵、JF?ュ瞠?.モィ.? ラオルq犢テ\'ノ懽鑷鳰9タス|???:t單阻7lタO」:G?\r・拶%T軟Iニ*N.?5{ォKュi粫Yトw?;I]-疵C癰pG}ュ懊?/J鑿簾?サ\Zカ舉?ウ\ZWホ;d0゚ーィr虎hニ?ャ?5ィ?テ{uk3*Nトサ」テ髷xュウ?ェtスS@]2 ?Jm乗Sv?K醪qネ8<顛w?鏤マ?^ワOC?~慧脯ヤ6丘qgィタEト?クe萄Lヤマヌ吾。ハ呷^\r9?9釣? ?*[ \0\0薨ヒ繧;p1??ーkO???!ーD蔵PャャCd/ 3?3?;・z、z稀カスn?ユァウ弩_S?楔B.柘B&vC$?(Wノ??Oュ?毬4真スナル?5゙?檎?9<*vョ檬鯤。廴qwpセJテ|lョナ?,X收」?\'?oイ,シ?71Gァヘ}yヲ\\[テ癘堕?)<+(a?8?ヌaU ホーY$駕qC瓩ネ^b3?蔭Gセ@? zヌ_ユmaーユ謌 汲チ(?\\?9ホ=ヘ@?蟄讖キW,V?1@?ハル~H?0=ア飮シqUカG#}XkFK+ツラ用ハa雨B。A92Hマ>?ュk?7ァ?5 ス[]y?cwッвg?W?o(ーマスO鴫ウ?ラキBk[戞oS7配ー w?ケ?r]オィ莞ムnL滲?!ンカ%Ppル?wノ讒ヲメ?&ヤOuK>7?Iv??ォヘ?&?.)?みイBHmヘ桑fチ ?\0)ホ\0瑰鶲s_m祠[Wクコ羊3aTq?{釵コ-?\0?Dハ!R・カ免8??kュ.c6「゙IBpS?ーャ?.\'?4H旋じWヒ毫\n?t凋ネGoAXモワ鰒j?2B?.\0キーャk拉p\"?莢膓メfGエ?Kニ8z?Mト9\0コ賺\'ヨア/uHX邵xc?\'q.6ケコヌZ?タ?#蕗w\0哉=? G゙ェユSNキネ*槁穴ユ?{ヤf?/ン瀏fp゚?1_>\"kOェ\\+ヌ$fワ?.ヨノ?ゥイg<悁ア筈u戌WノT,゙ス?8譱j麪]?*スセエGC?+-ou}^ヒEメ潴巒ロ┨キ?I]がY$kカ?q\nニ}zK??wwォテ?V佛knfォ《コw*ムI3ロ\0g@9%キ坤u\'.*ヘ」メ>i゚ ?レ?醐u(vクスコGフNタケ?*ィムFrrM゙醗?R箱・()JJR?R箱・()JJR?U7?\'テヘ\'窈Cワtホォ4カァト[?;ク?-m:?ツ?a價?f\0モ.TゥNカ?オfコヌKu%?k?Y齲|ヲ論?UC8 ?85?/??\Zセ?\'Oj{.!d-lマ??ォ??R? Nキ飫Y.コォ?クオ拷{サ@Yカニス決フフーfbkヘ}ユ3タ墮爛#?淞゚??????8只X?\"qヌ?+ムーIヲ|M霍カ?,Wミ?1I??\0蠢?iNュ鴉?*錵tテ+?0ルチ88チ?2;篆_?/ニ_ゥハ>ムY?*蝠|ャ0x膰8緻e2&モ?,蚋迷ハ?Fオs?嬉クoヘ粽ホユメ)v$トnB。?ラp~」メコ坿ゥ?>k?v?6ネd;?>肓\\|U2?FHハレァ7。レ?┳豪)レ^9??ムzャヨ嚆ワ?*ャィ??[テネ 燗鷹ホj%Sレモ%hーナユ鵆トM.馗Vt& 茸??zホミオロスb?6xg研?fメ猖砌a撥$カ?OlzユgGヨャz岑、7ョt?2?lッニ \'ヒ?\'\0~Fサ勵Zkノ6田o|?42O!?5ネノ+サ\06=y権コ體lロ?ッi綉溷mb手#サM{+\0輌 ア?\0ワ76N ??=Qェ]/O|ヤw?j嗷 ィ$?J?昵カqキ-食?ョィ?・ウミcミオ+;篥\Zハ&h}0齎 ?zョIヨ:トホ$壯レo E???Nト?k5?6?e小:ラョ箚エ嗄IV7vルuk2蝉z {~錨?/於堙YAャ]<キ恩&ニセ\"? ク?リ?\0スj+[!souv??リ-ヒカI8? s舘?\0\nzJユz}オKノ~^IO??ln蟆\0ヌ>?+\\ク?D&ロ&ョz溂?ルメワロ3?u桁1コアlキ盗sマョ9Sモッ>゙ュフ折j咯フ7\r=ョ鏗x?$ケo?\0q彡\'ス[W。zZ\rj?綏[3IィH ヒロフF??スC里:f]icャ?-軻?4lィッ?Gヺ璢独k(n?%ルー?\'窩zョウ桑1?U? x猪8;\0%@Zサン\r[イ?)\"!a\Z牀Cサ?1◇rO\'ヨエ5紺?キ ?KェャムGセメ,b2|?l?谺戲ラ%cモャcソ]A縲・エカ?& 申瀏達?マ懺\'/タイ遼ョ魏?糶??;DOンア髢齋tV8V<\0sク逵ΑZワ??5ミD?C」b厦ケ符カ▼???墸=・Aiェチw}ywsエィ\"3??マ)?xQ? ュ。?I{c?ノzメO+Q?揚9耿c慝3^筑?-Bラ螳シ.暮片!Y寧#厠娑q塔?6?>???オ??・ァルヒ癪ァケ Sssu爼x??\0 イ0リ乾?錆7キヲjラォkRj找eヲIi・nャ?\"?老ニリ?wlタ9dsWァ?;MkXキ鶉毛?$ラ(ァ? \"ン?瓷ワX邯1?ッ,ホ4膰込|屹5{[{?\0蓉コm>??-仆)C?\"∨\\?レセAメレハスゥ榑xノレトル9ホ0;憫?{箙?Iiz」R鮗トpン? 僉ホ覽8lv+ノ=?ヘYャ? ?:ワwワィ??%゙?ワ?ヌカ1レォ/)ラ?8lメZ?Mワi?ュ2Z、qヌ燹剔?%?D>オj拏w,??;? ~_1ゥf 62ヌ?>暮゚噺I3Mウ.゚QT?6\0ヌ簡ヨ?4%ウ、Vv叩、Zヘ$*@マ;Yケ瓏・dシ嘴Eクe龠畷t?ィXテ4p@[粕撩??壬}ェァエ??=哭~&fXwリャヌモ??\0fスOfコ,ラ「ニ?j 尉;鹸ワz2?ク?1靺昏ノ%衆ナン?リTc??モスhシヲ?4Uチ\ZミtNス殪mw4/ツノフサ峪lタ?+?BKュ?ww=レレあ」ー\nセ??レOェノE$ーE!ウ?3?史Vメム!カ篠 Y?gq¶dヨo;棺*燼讃7icモ曾 XTn???Sワ看{8&X?ユ$LfBs¥Jナu;?9ャ?ィロ樸ト甬恠オ%諜ォkbワ管コ姫x\0Wtッ?$ヨ次ェ?7PY?(%?{0?\0ネヌ黜\0w$?\0?\0ゥ5?-ソ\0?O??2hッu%椏iフ鶸「袒 タlL?ノタ\'ーワリmサO颯E) 1、QF。Q@UP0\0ーB??゚疊テォ~哮。yy$マwp??w\nミO\nQGl?&カp蝓6n?\nR蕗\"櫨\0・)@)JP\nR?櫨\0・)@)JP\nR?櫨\0ッ\Z~ユソ礪kル~#t「xZンネ\Z・かナ慥%?刪N6ウ\rケV=誉$D?U早 ャ2?5ヲ,イナ5(?(ゥ*g×??ゥ?m?ヌモ篭mオK濡!%9^チ丞Y愈>「a尤チ?>\Z?チ<{?ワ?kil「\"oc2フメ<メノマ?\np呰?招v[Z影坂gjハ滴シmbyチNyナ}?ン?8]テmh? ?輸スユ4m:?~?ア))ef\r決ネチワ?>ヌ憬KE楚?9ュッ^ノヲ? ?チl?゚4騫tッ゙qGィ4) wy綯??NH??gYワ|ワ-4ヨ[テ6ee叉 *0{7籔[袗-cゥ&゙W #3?Aチ$p ?f\\t゚Nヘモー゙髱Cセ?\Zm2?ト\rク*艨鯔醺レォキアGナc%?\'但?ユ?ムカ給q磽q覬pァリ?8キサ%\"シ楪gQ亜#キ*rラ゙ッ]ヨX哄ィァアオモ轣ヨ+ラ?ウ??W$?{?.擺偵[″??$處X?\0チ8ヌ5鴎i追ュMァZチp?%1ニ言sマゥ8FZ}喋^オイサイd街?%R貪ヘメ)ホ?ハカI9  \Zョ゙゙6「コ~締Zヌ?I?&$Vタ\0e@苜~?7。u>アム??.挌?ノ??^{ヤヌL?,zァJiヨア4z%?\ZUヒmK?ルネA?\0yノ=ウQレサ?>ォ?\rCY妲段PO濬[???5??クチ勳qxコ攵アト「?)?\nサミ?ニxニンヌ{fコl4虜ウdーサ採ォW・セリ虱nl!pン??ォ7MKx-^Uノ-?:?)ヌ qロ酌ニケ.境)ノァu;@モhレPアT先!寛ケ瑰?/a?ゥ?,uケ??/、in~]ヌ?*?塞!Xvマヲ*胚? ?i\nサ??\0w?楓&みBエ?(#ウ/?チサ?9I幣#驛楠ロ淮Rロモ!」\n綵セ位?騏N ゙?x?G#゙ウコ{ゥエサ?r \'??ト?D go? {H|7?リ?。pxV??ョ淫ャ?Y」イS? ~qテcワ?ア禳\Z3莫vo ?)#?ク-ヘ?ムT椡酌]Nホ?Viクヌ?k?埃イ逝n?tB?\Zケハ g\'\"?ヲB\"9」g?ォ?;D_Bイ?<シャ\rモ?cマ$眸\0B゙トョ聒ヤシ\ZM椚、ユbわ$%ャ?サクネレ?イy珞・?@ムu・サ\Z?カ、oキ?$$3rN?施c?ィ?}梦Mガ[(Z{~b?#ヒア?fワ?ッカjョV?Gh\Za???ユロォtエーj6ヲカ{a<端茉卷,ァアQワ 舖Y??アXンチッ[ノR?9d?$x ヌ Fぁ襃♪5YJ?d「サュ?蠏?\"?\"?,※R7ゥ?n3掌xャyュu)\"クセ需ョZ\rケu,ヘホ紆?モ5yユヲ?-=ニ」ゥM.?H盡x゚ケAe?!Y? ;g飮ュh\Znケ?/?・キ?Z@!刃![??;址dレカミ+ラ?ワテラaリマ?\0\0\"ヌ?檎 v&ー4ネ%k?/?,「?9?!?洽゚Oワヌ?=g?/URハヲ?ュfMfbメ磅ナ ャカ楠ネソ?5ケセ槎カモ???\0癡Iメコ?ネ髦ヨ覿f(#?}?ト跟ル?ャ?w?ムソモウ?ム???v;ヨチオホ] 植?藷キロ^Ulリ???/]カ穴゙?1ョ。??珠Rヨ゙ロ\'cュカヲ\nw?ケカS???ョハ?Eネ???ヤZヒ1?ロ} ?ホトホニwキf]{ソG^レ?z?o?アB2ンhkMWテサ讖+G?撥n?曝ワテ-sH゚]オサMユロ[嫺ネUユZ7Uョヤケ?ム??鋳扨&Nリ\'ケ?ヤ鍜魁w*uーn?]T\r?オ淑?$ク?fミラ7ヤc?\0yt}Cュ袗?1q@shs境hv?z孀??\0en??,w?ッ?」ッ「8モ壙*ュヌ!平ク・ーb?娩w?Os??Fマム・e猷cア囘;壑mdl斟m?;cン[?/?\0セ#L?。?ス|?フヘ_r?8Xzォ*}?:嗅ー1??Xラナフヌタニgカラロ?9セッゥ?\r?\0・?\0エ?ネ鶚?ラ}?冐熊スレ2キ?\0Hォ.カサラ9?}麟~;?\0M??c2?ツqエ7?潟*8囚キ!?oァ?oィ?イ-g?/ムォ4?\n??ノキカケ?譱#}5;e?愧_レ3=oァ??ッ^7?iオ7?$欅??音yカゥ?モ?カャ[Csキt惘Uョゥ盻ョウ.キリ鍄?[= }oNヒ?\0]c瞠Kz?ォゥヤ?gィ?UfツK?マ?eサ~ム]_ヲ?\0ョ.?蹠wNテヲ?ォ?/sンー争?zuz椏Y?エウラゥ?灌渭ェ[コSウ歉妻ッn;\0ュカ今?/;娟F0?nヘソ、ルウラ?% ゙ウ\"b}<]o??4コユトoLヌ鶚?゙?PキOx?{hヌョ媼??\00バ?」ヨサ゚mヨzカ*NCァ釁FV17aneu=ミ甼⊥霽;lnラ2?ス椚Lコレoッ?ッ?g+7\"囿?カ貂3=ト青\0凡旌3u?種?2ヨl?Oユ?wセーcgt??マQヌョヌオ?.ャセニ揮羞☆5;布゚ヲキ?Y?漆鯏 ア0D?猖ラd=ッ?ハ黨ケ.ムc?ウpSNwレュ}クケ/kw??0セラ?%jcgソェcX猝ワヒ+s宜?8Xハ??62?+}ウgモカェスOラ=5ホu゙?:eュネ\ru廟Xイ?‡{ナgルeyt\r布V^マ輌滌?>ロ遣疼ヌa粭z?,uホ~8pュ?;Vオマヌ,?>Eフゥ?ェソE努鬩ア?\0h???゚Tンh\\ョス9焦n].uァモ檎ニ? ッァ~ンヘk?゚窓m蘗?ョ*絽ァgbキォ瞼uュ]オ゙>?盟???b?ョs=?J?\0@シナVヒ2タ恕D瘻>・(゙テ???メ?lfオマ?乍謔ャaV?.kZメO.0??U;UY?\Zヨ勿!?2v4{ルイカYオロ?\0孕ルウ?%kVェq?[疫m」ォオ孀mリ1?Fュ?xル?葆ヲ??\'g」岨。?2\rュk麒ュフ,徒[シケム鎹?\0ヘネキ?m?\0カ?oP鰈Tハ\0qスオ脆?bルッ{,?抔ア??\0驃e溂テ \0 ?ラ?ュ\\テ○?遊^?ッ、?メipp;墮?;ヌ?W頷d?g?=OO*玄ドゥ湲「シ7ソォEwQeV9ユケヘ?メicソAk-v?ッモ゚K?=フ」\"ォQユ?2コ?、ローuzE\rカヒ^X??dンヒ-ホェヲ葫fCG?M゚ヘ??、}\\鎔mYY8ュキ エ?S菜ニ輅o「イ广?~マユi?\0??斬DフqkF#cテ?F=?9xKォu:e?ラ??゙?9^?s ?サ\rモ掌黔m?%ヨzy??\0ミセ、?Gゥ6ヨ9?コハZ?E>テキ}u?際ン?写キ?夛?gイ岸VXス諂ク?-眩」??bヨ゚Iセマ詼??%K究?<_bエキ?埠{i,wWスケCa^ラnネユeエ?[V58孺v[?滯+VF5 4クヤlク5桾ヤ=???67ワ??}ャ゚些オ[??ア?~ュu?シャォZ?ロリ貶?~?\"ュソ、ェ暄z~ァゥ^?・Vーヘ?\'?4裔ス?ツ彑?lォh・マゥ?;ムv-98エワ/輌ス\\ed?濱モキ?゚Xu4レ?堯ヤャ餾.-ョ?U_Pメ證ッ?eiッゥUo?Isラ奧ュ?\'ヤロカt?スF螺}ceャ蘭?イ粐?レ?^ョP?t??E>ァ? フスZ?\0iz゚狄}?\0ル゚サ?・Vホ}X藥?\r[??、?モ?gァ絹nム、チU八vロ\Z?\n~#S?ァアトs鯔\Zォs??「/hー;?{~??\0戀}5スメュ フソxn59、ヨラオサ儼Sbレ唳_VMァェ湲?zヤャN鰐ヒゥ師エリテ゚^゙??\0嫐1]ッィ〔1ヘ[リ?ム]ャ?ミ踰ユ?7モイ溽jアZ4t:iH/W??K?趾サ*ラ萬亭ケ???゚Eソ」ァ?+A9?3W??-キa\rn-lvリoィ??5lウ?ヤdア?~C゚?/?s?/ヌaョヌ}攴wロUチヨ5ュl>テ^c?Tキ?敷ト>。メ?〃^$c}ュフウkエワZ=wャ?櫃メァユソ? ゚層」?鬲F\":?リォa?サ=クュ#サ%ホ\Z・チョ?-オ]1?7~潮??sユコ・ヨロ_Rチ?/ヌ}oェ\Zリ??ッ「ニ\rヘケ崟???Dケl?bレ?? YcY?#齲=@マルマソk,セロ\\ヌ?ヨソ?ャY鹽;wャKウ1ウ N、\n,ャ蜥稷ウヤォu\'リ觴k况~NGゥ風m゙ュ」Sルメ#?ナGッ?-?黙ケク]5ンUナュソ ?スメ $幀ナョノ?-wゥ嬾+?\'ァイ?ム??\0Hシ。v゚Zz摧taステ?=Jヘト5?~ォS゙?9?\0ス?「゚ム??Oァ~粐U\\?ツ?サ!?x???ヤ?棚%;?\0W?siq頃茸W]メ~゚c橄ィ?ケ残壙\Zツ?モcイア゙ヘロ??ァ?\0 j?{?6イチ???:Sェハ?゙3?x~??Zキqツ?%?? ニゥニfニ;Hun-2;?3w?)ct?ョカロ?x??ー?\0Snサ?K崕?ニ?\0チウ??,Aナハ脊O Gツナァコ?ロZ*kXK????#ャ暉セ滓11H鳧ー媾?5ラY苗nュ・ニヌス?.ロ足鬮ヨgゥ霍? ?\Zムイメ^粫?ヌ5?\rレ7サw??Mャ?クhc???.コri}9X?ァ毳.」yam剤?;=ロ^?點?\0ェラ?ulメ?.ナ7 l2\\6=OEホ;_eロh?ヨ?\0?F?チ帯ヘ、9セオU]kタ.ァヤカ」ス7゙1ルgヲ?+Cゥeカタモモ?ユ?\09n鷽メ賻ヘ???フ??? ヲフWキhリモVネ:?}.ヌpワ??\0チ?筰G%lA?GJiソ ヤ」モ・?ケチ?カ?O」?策佞イ?KV゚?棯ニヒ、Znサ+モヌツヌk[殯陽UヤX?アョsr22.?q*?騷>ァァ?奇Q?8ツム拘ル鶸%ル蒙レェ゚セ?^ラ=エZ釋F?MY??ン?拗モモ?)鮑sー4m>]?ラ\r?ルスフナァ?[??後F?ィ4tr?Yソュu;s?嫋 「親オTチイ??嬌?=?組、牒f??ユ?棚%)Yチホサ\n疇gOホネU誰血M?>?>ー3%セメ ウク?メ緘オワ? ニX?璋8オテPF???k??\r.mタ~?3?s テ$%ソ、?\0ヘFッッラ?1ッ?)リ?,}6リ?4ミ\\[?w?モシ~ムワユ覽?\0?丸?kワ8\"ヌ?饉?1コ?3V;G????ゥ+?錠゚チO。eGャ鍄釀k6??\'鏝[ォ/??\'ャ?a?6ァcfワ?8z亰サヤハーク?.ゥニャ*?゚Sラネョ??モ?\06シ?\0;?ヨ ヨコキe\Z)x!ユcオエエν閹>ニ?\0ニス??#oQHェ搦サ?+ォE聞、mナェaロdT??\0?ヲ{+?o埴K緒鷙アメIC)&メ、棚??ル\08BIM!\ZVersion compatibility info\0\0\0\0U\0\0\0\0\0\0\0A\0d\0o\0b\0e\0 \0P\0h\0o\0t\0o\0s\0h\0o\0p\0\0\0\0A\0d\0o\0b\0e\0 \0P\0h\0o\0t\0o\0s\0h\0o\0p\0 \06\0.\00\0\0\0\08BIM JPEG Quality\0\0\0\0\0\0\0\0\0?ロ\0C\0\n\n\n \n \Z%\Z# , #&\')*)-0-(0%()(?ロ\0C\n\n\n\n(\Z\Z((((((((((((((((((((((((((((((((((((((((((((((((((?タ\0\0x\0u\0?ト\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\08\0\0\0\0\0\0!1AQ\"aq?2贈ア#BRbムr$3チ盍?ト\0\Z\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\00\0\0\0\0\0\0\0!1\"AQ2aBアムq■チ碵#R??レ\0 \0\0?\0?\0\0P@\0s?7浮ニ護|馬???・sgツルk・ カナヨCヒZ姉カ?ウ_gケラPc?゚P」ュKムノ~%?B,?チケ?%-62r?」胖、zL凶ae鰯9I舵Bャ4Egqqtム\'\Z?\n\0(\0??\n\0(\0?・+?m監スモ? !Oa?->厭Y\n蜥コー?tPa?9?OフラAF+す9ヨ? 厶。控t??>エラ?\n?|?みル篦A」=マ(<フwウ?VMウノマHコヤ{9則1? キ\'}?ヲXR\\イ7?9 v?チハc6XY?ル゚ラ。Jo4?\0?*\\咏{\"シイ介ク~Fサ?6ホ5 窖7?\'ヲ源ヌヌリ{2ケcx、h薈GSヲV\Z ?Xレqtニ8T\0P@\0\0Pカデ& テyW[KァP[袢\\・?8ォ\n」冨宗・?&カ9Q]職c?}シ?骭sv>^T\'\'?!、?1キ?wK+蠏詢C1e?\'ハウK\'?楓%?ネ???)夜繩?レ\r\0ロ」Drニ~=欺八1ゥ~モKsqk!リa4\'G舫躬B榕「クキ\Z?\"rフtャOQ?吊租qak遵?/\ZRフ6_?ネ>エロ??ョ\\オG、bセメ0i廳ォォDciイ愕?\0i?\0!襌Uコス.?kア!橡ナ倆pヘ@\0\0ヌテヨ?「窰?シサ??ワcオ &銚j??;鰍蝣iヤルセロ?*=)蜩消」eナ??..?? P?ノ??o・7?WB?c>S吟??Fミン\\iBコ丞?\0ネ??v?フフr?5,モ%?m停Cッ?シ醂(\'@?ォ・襲坪?3ヒサ*s?フ|エ)ノmvセ2/?髣?B+岻ナ鱠オモ,Χ*VAツ?9F・?\07V燻鬢 d磊Oyサオ?Hタ?7ヨス?td濫績明L」\Zァ$hタC?? >オメーノ%tv肆?Y/mニフ艀?。}\r??)苴j?\0bヲ?%?0メツ,ケ莓Rハニ\'フ@ル\'ッN柆 cI?\'ヒリf琲ウ7y(ュヲコ?,アH????ラcュS昴Qm.? ・|喟p??\r,wK-ワカアーェ?H?iG&頌eョ6ゥ亘チ<7o>ヌ?錘OッJ?-ム3SN?<ンヤカkm{?;I良Hタ?__スbヒゥZ蒙Y齲イサ)ツ?dヲ?^V,靭◎眈?\0zウ・ニ71%?7チIi%ト7\r ?t??uラマフw?ヨ未ヨ荳+?:fオ依リ?,Sハ\\r?]ラ_]ラ/&)oi\Zc%FY??篤Mヘe 儿ナt?コ涎Nカ+&?\\olゥ亰q\r@?ヘ0tユウFシ?~テ?*ヌQ・マツ3l喜,ソ┐P?/qK擽7Xキ貅キ@$エ裲?ラ?<梛ゥ???\0Q\'S弁S?6W^蛩糺ャョ@?tケ0ニj?ィ?8滯慶ヒAh特$e」?6シ、}:茅j\n\0租ygSスuュレ.ルCmカZ?3hカ??H・eSコ8 ?K??ぬワケ??吏旭aヌBキ―濶h屁ィ゚??ラM謗:r脯??桟摂テ~ハ?P^d艪5ム=リエmョ?ソ躡?ム???モカ1gqヨウ??+ケSキ%<6揃???6)オmEムsG }ク\rケ渠詞??9セ鐡?7pqY(?8膩レ?ラ~楫Z?qkyツw7?Q沙Xハ\r?ョキ?0Eャェ+臟?剋?フヲO>--d邉ヌゥ?2;3o縊ケ?\0ョウ7ゥ績?&ヨAツ?\n\0コ皰匆シRヌQ撞]&Mムxル?\nCow|nヨFハ ?跡_6ヤv曾ルャ?c?N??+,サ?/,??ツ6?ウt?;?z]Y[;? ーG Cァュ/( レ休計゚*5ハ{・Cwヒ$F耄}?81VQ3鋲iァc・Qセロ?饂t?9z?+ネ婬?K夢Hュ預?N必?紹アw?>??(Bヒowl\"F#?\0?Drァφ?トq?we\'褂?!\"9q?;。ラマ_?.5?fM?9 Yノik)9ォ泌\nュアn?ネ??3?aタア?6ユヌ-\n\0(\0??韲SFNrF?トヒ[i?+o。?シfウヌr?nX??%モtD」ノ#U崙ナ劵R_\\ト寿Q蜩ナacUU? LHQ熾z?5\0Rdョ.螻箪t??Ne?ュ:I?$C? ?/ュヲC{qツノ「]G!ル:?=*??T*ソr?7瞳エ?!?\0?\r闢?スMUJO○Hニ?レ!テ4鯨,?\rC\0n?{囚?ュ9}<カ?ナケ3ハd.イ? ?詈ョfngv=IョL跏?)\0(\0??\n\0?エn :?)??9n?5fγワnヨッ7メrミ?類コpヘ ゚f/(レp\\GトHノ2ー>?P「lmウハォト?:ュトぼ 梯?J?tKwhー?<1ラAコ囹+g8?m&ノ_[ォ\"?域?@:衍^アレキツ\"フw??ョヘvd??1?7s/ニG????Sヤテ\Zャ|ソ??Ck}?5ト?フ?H?逋斟ヒRk跏?掖?\0P@\0\0P@l2鱗?ウケ?/?=?*セ\Z恊篳、2リ?マZkRC&ソス?ムォ無?(婚ボZ?2コOt_氣O??{^ミ?iS潜?ラハノ&RXムコ??コメス\\?\0\nK?。エW框n%i\'大遜ウアb~讓懷7rv5t?\0P@\0?ル?リ??\0JFIF\0\0p\0p\0\0??ヤPhotoshop 3.0\08BIM?\nPrint Info\0\0\0\0x\0\0P\0H\0H\0\0\0\0レ(?????FP\0(?\0\0P\0H\0H\0\0\0\0レ(\0\0\0\0\0d\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\0d\0\0\0\0\0\0\"r\0\0\0\0\0\0\0\0\0\0\0\0?|\0\0\08BIM?\nResolution\0\0\0\0\0pU?\0\0\0pU?\0\08BIM\rFX Global Lighting Angle\0\0\0\0\0\0\0x8BIMFX Global Altitude\0\0\0\0\0\0\08BIM? Print Flags\0\0\0 \0\0\0\0\0\0\0\0\08BIM\nCopyright Flag\0\0\0\0\0\08BIM\'Japanese Print Flags\0\0\0\0\n\0\0\0\0\0\0\0\08BIM?Color Halftone Settings\0\0\0H\0/ff\0\0lff\0\0\0\0\0\0\0/ff\0\0。劒\0\0\0\0\0\0\02\0\0\0\0Z\0\0\0\0\0\0\0\0\05\0\0\0\0-\0\0\0\0\0\0\0\08BIM?Color Transfer Settings\0\0\0p\0\0???????????????????????\0\0\0\0???????????????????????\0\0\0\0???????????????????????\0\0\0\0???????????????????????\0\08BIM\0 Layer State\0\0\0\08BIM Layer Groups\0\0\0\0\0\0\0\08BIMGuges\0\0\0\0\0\0\0\0\0@\0\0@\0\0\0\08BIM\rURL overrges\0\0\0\0\0\0\08BIM\ZSlices\0\0\0\0u\0\0\0\0\0\0\0\0\0\0\0\0\0I\0\0:\0\0\0\n\0U\0n\0t\0i\0t\0l\0e\0d\0-\01\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\0I\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\08BIMICC Untagged Flag\0\0\0\08BIMLayer g Generator Base\0\0\0\0\0\08BIM New Windows Thumbnail\0\0i\0\0\0\0\0\0m\0\0\0p\0\0H\0\0準\0\0M\0\0?リ??\0JFIF\0\0H\0H\0\0??\0Adobe\0d?\0\0\0?ロ\0?\0    \n    \r \r\r   ?タ\0\0p\0m\"\0?ン\0\0?ト?\0\0\0\0\0\0\0\0\0\0 \n \0\0\0\0\0\0\0\0\0 \n \0 3\0!1AQa\"q?2贈アB#$Rチb34rびC%担??s5「イ?&D典dEツ」t6メU稙??モu胚F\'筈?米ヤ蔬・オナユ襄Vfv?ヲカニヨ踐7GWgw?ァキヌラ銷\05\0!1AQaq\"2¢。アB#チRム?3$b疵rCScs4?%「イ?&5ツメD典」dEU6te糘ウ?モu胚F筈?米ヤ蔬・オナユ襄Vfv?ヲカニヨ踐\'7GWgw?ァキヌ?レ\0 \0\0?\0?棚%)$瞳施セ$如$ミユK#總詁ヌゥヨv?4?\09htタaマ\0サ?\"G??ヒr較C}:?p-?? ロ?コカヨヨツウW?ミヲaトォ?Tアチ?[ワ$1マ?;?=M?\0Sz?K+ネヘv7?\rkェタツキ\Zソエu~ョX?)ニdエリO?oルV=゚G~マエ_?オd?k゙ハ?ァ\0レワ?゚T?\06ラ?サcツ;gモ???\0捍チ ィ?.?/?};ヘ驀G\0掌綺@q??!、?\0!?\0A?\0ルUWゥラ泅レヘoヌeマ oョ[I??\0Kヤkッヌオ?\0顆SアSホ?ミz・/ネヌe?2ンKャ?p栽ハニe?+ル??Sル??\0「z旨スl~ン? ロ? -ウミコ拾ネ贐??2.ェヨ条納?G??\0テW[ヨz??4)RI$ぁ?ミ?棚%( +kヲtフ鶴PQaモqqc?4{セ林k9ヒ????0?&&ミ?N??ラt?,ャ蹶Xkヌア?{ -cA?M熟?5ユキ?z櫃モVーヌ?洽゚Oワヌ?=g?/URハヲ?ュfMfbメ磅ナ ャカ楠ネソ?5ケセ槎カモ???\0癡Iメコ?ネ髦ヨ覿f(#?}?ト跟ル?ャ?w?ムソモウ?ム???v;ヨチオホ] 植?藷キロ^Ulリ???/]カ穴゙?1ョ。??珠Rヨ゙ロ\'cュカヲ\nw?ケカS???ョハ?Eネ???ヤZヒ1?ロ} ?ホトホニwキf]{ソG^レ?z?o?アB2ンhkMWテサ讖+G?撥n?曝ワテ-sH゚]オサMユロ[嫺ネUユZ7Uョヤケ?ム??鋳扨&Nリ\'ケ?ヤ鍜魁w*uーn?]T\r?オ淑?$ク?fミラ7ヤc?\0yt}Cュ袗?1q@shs境hv?z孀??\0en??,w?ッ?」ッ「8モ壙*ュヌ!平ク・ーb?娩w?Os??Fマム・e猷cア囘;壑mdl斟m?;cン[?/?\0セ#L?。?ス|?フヘ_r?8Xzォ*}?:嗅ー1??Xラナフヌタニgカラロ?9セッゥ?\r?\0・?\0エ?ネ鶚?ラ}?冐熊スレ2キ?\0Hォ.カサラ9?}麟~;?\0M??c2?ツqエ7?潟*8囚キ!?oァ?oィ?イ-g?/ムォ4?\n??ノキカケ?譱#}5;e?愧_レ3=oァ??ッ^7?iオ7?$欅??音yカゥ?モ?カャ[Csキt惘Uョゥ盻ョウ.キリ鍄?[= }oNヒ?\0]c瞠Kz?ォゥヤ?gィ?UfツK?マ?eサ~ム]_ヲ?\0ョ.?蹠wNテヲ?ォ?/sンー争?zuz椏Y?エウラゥ?灌渭ェ[コSウ歉妻ッn;\0ュカ今?/;娟F0?nヘソ、ルウラ?% ゙ウ\"b}<]o??4コユトoLヌ鶚?゙?PキOx?{hヌョ媼??\00バ?」ヨサ゚mヨzカ*NCァ釁FV17aneu=ミ甼⊥霽;lnラ2?ス椚Lコレoッ?ッ?g+7\"囿?カ貂3=ト青\0凡旌3u?種?2ヨl?Oユ?wセーcgt??マQヌョヌオ?.ャセニ揮羞☆5;布゚ヲキ?Y?漆鯏 ア0D?猖ラd=ッ?ハ黨ケ.ムc?ウpSNwレュ}クケ/kw??0セラ?%jcgソェcX猝ワヒ+s宜?8Xハ??62?+}ウgモカェスOラ=5ホu゙?:eュネ\ru廟Xイ?‡{ナgルeyt\r布V^マ輌滌?>ロ遣疼ヌa粭z?,uホ~8pュ?;Vオマヌ,?>Eフゥ?ェソE努鬩ア?\0h???゚Tンh\\ョス9焦n].uァモ檎ニ? ッァ~ンヘk?゚窓m蘗?ョ*絽ァgbキォ瞼uュ]オ゙>?盟???b?ョs=?J?\0@シナVヒ2タ恕D瘻>・(゙テ???メ?lfオマ?乍謔ャaV?.kZメO.0??U;UY?\Zヨ勿!?2v4{ルイカYオロ?\0孕ルウ?%kVェq?[疫m」ォオ孀mリ1?Fュ?xル?葆ヲ??\'g」岨。?2\rュk麒ュフ,徒[シケム鎹?\0ヘネキ?m?\0カ?oP鰈Tハ\0qスオ脆?bルッ{,?抔ア??\0驃e溂テ \0 ?ラ?ュ\\テ○?遊^?ッ、?メipp;墮?;ヌ?W頷d?g?=OO*玄ドゥ湲「シ7ソォEwQeV9ユケヘ?メicソAk-v?ッモ゚K?=フ」\"ォQユ?2コ?、ローuzE\rカヒ^X??dンヒ-ホェヲ葫fCG?M゚ヘ??、}\\鎔mYY8ュキ エ?S菜ニ輅o「イ广?~マユi?\0??斬DフqkF#cテ?F=?9xKォu:e?ラ??゙?9^?s ?サ\rモ掌黔m?%ヨzy??\0ミセ、?Gゥ6ヨ9?コハZ?E>テキ}u?際ン?写キ?夛?gイ岸VXス諂ク?-眩」??bヨ゚Iセマ詼??%K究?<_bエキ?埠{i,wWスケCa^ラnネユeエ?[V58孺v[?滯+VF5 4クヤlク5桾ヤ=???67ワ??}ャ゚些オ[??ア?~ュu?シャォZ?ロリ貶?~?\"ュソ、ェ暄z~ァゥ^?・Vーヘ?\'?4裔ス?ツ彑?lォh・マゥ?;ムv-98エワ/輌ス\\ed?濱モキ?゚Xu4レ?堯ヤャ餾.-ョ?U_Pメ證ッ?eiッゥUo?Isラ奧ュ?\'ヤロカt?スF螺}ceャ蘭?イ粐?レ?^ョP?t??E>ァ? フスZ?\0iz゚狄}?\0ル゚サ?・Vホ}X藥?\r[??、?モ?gァ絹nム、チU八vロ\Z?\n~#S?ァアトs鯔\Zォs??「/hー;?{~??\0戀}5スメュ フソxn59、ヨラオサ儼Sbレ唳_VMァェ湲?zヤャN鰐ヒゥ師エリテ゚^゙??\0嫐1]ッィ〔1ヘ[リ?ム]ャ?ミ踰ユ?7モイ溽jアZ4t:iH/W??K?趾サ*ラ萬亭ケ???゚Eソ」ァ?+A9?3W??-キa\rn-lvリoィ??5lウ?ヤdア?~C゚?/?s?/ヌaョヌ}攴wロUチヨ5ュl>テ^c?Tキ?敷ト>。メ?〃^$c}ュフウkエワZ=wャ?櫃メァユソ? ゚層」?鬲F\":?リォa?サ=クュ#サ%ホ\Z・チョ?-オ]1?7~潮??sユコ・ヨロ_Rチ?/ヌ}oェ\Zリ??ッ「ニ\rヘケ崟???Dケl?bレ?? YcY?#齲=@マルマソk,セロ\\ヌ?ヨソ?ャY鹽;wャKウ1ウ N、\n,ャ蜥稷ウヤォu\'リ觴k况~NGゥ風m゙ュ」Sルメ#?ナGッ?-?黙ケク]5ンUナュソ ?スメ $幀ナョノ?-wゥ嬾+?\'ァイ?ム??\0Hシ。v゚Zz摧taステ?=Jヘト5?~ォS゙?9?\0ス?「゚ム??Oァ~粐U\\?ツ?サ!?x???ヤ?棚%;?\0W?siq頃茸W]メ~゚c橄ィ?ケ残壙\Zツ?モcイア゙ヘロ??ァ?\0 j?{?6イチ???:Sェハ?゙3?x~??Zキqツ?%?? ニゥニfニ;Hun-2;?3w?)ct?ョカロ?x??ー?\0Snサ?K崕?ニ?\0チウ??,Aナハ脊O Gツナァコ?ロZ*kXK????#ャ暉セ滓11H鳧ー媾?5ラY苗nュ・ニヌス?.ロ足鬮ヨgゥ霍? ?\Zムイメ^粫?ヌ5?\rレ7サw??Mャ?クhc???.コri}9X?ァ毳.」yam剤?;=ロ^?點?\0ェラ?ulメ?.ナ7 l2\\6=OEホ;_eロh?ヨ?\0?F?チ帯ヘ、9セオU]kタ.ァヤカ」ス7゙1ルgヲ?+Cゥeカタモモ?ユ?\09n鷽メ賻ヘ???フ??? ヲフWキhリモVネ:?}.ヌpワ??\0チ?筰G%lA?GJiソ ヤ」モ・?ケチ?カ?O」?策佞イ?KV゚?棯ニヒ、Znサ+モヌツヌk[殯陽UヤX?アョsr22.?q*?騷>ァァ?奇Q?8ツム拘ル鶸%ル蒙レェ゚セ?^ラ=エZ釋F?MY??ン?拗モモ?)鮑sー4m>]?ラ\r?ルスフナァ?[??後F?ィ4tr?Yソュu;s?嫋 「親オTチイ??嬌?=?組、牒f??ユ?棚%)Yチホサ\n疇gOホネU誰血M?>?>ー3%セメ ウク?メ緘オワ? ニX?璋8オテPF???k??\r.mタ~?3?s テ$%ソ、?\0ヘFッッラ?1ッ?)リ?,}6リ?4ミ\\[?w?モシ~ムワユ覽?\0?丸?kワ8\"ヌ?饉?1コ?3V;G????ゥ+?錠゚チO。eGャ鍄釀k6??\'鏝[ォ/??\'ャ?a?6ァcfワ?8z亰サヤハーク?.ゥニャ*?゚Sラネョ??モ?\06シ?\0;?ヨ ヨコキe\Z)x!ユcオエエν閹>ニ?\0ニス??#oQHェ搦サ?+ォE聞、mナェaロdT??\0?ヲ{+?o埴K緒鷙アメIC)&メ、棚??ル\08BIM!\ZVersion compatibility info\0\0\0\0U\0\0\0\0\0\0\0A\0d\0o\0b\0e\0 \0P\0h\0o\0t\0o\0s\0h\0o\0p\0\0\0\0A\0d\0o\0b\0e\0 \0P\0h\0o\0t\0o\0s\0h\0o\0p\0 \06\0.\00\0\0\0\08BIM JPEG Quality\0\0\0\0\0\0\0\0\0?ロ\0C\0\n\n\n \n \Z%\Z# , #&\')*)-0-(0%()(?ロ\0C\n\n\n\n(\Z\Z((((((((((((((((((((((((((((((((((((((((((((((((((?タ\0\0x\0u\0?ト\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\08\0\0\0\0\0\0!1AQ\"aq?2贈ア#BRbムr$3チ盍?ト\0\Z\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\00\0\0\0\0\0\0\0!1\"AQ2aBアムq■チ碵#R??レ\0 \0\0?\0?\0\0P@\0s?7浮ニ護|馬???・sgツルk・ カナヨCヒZ姉カ?ウ_gケラPc?゚P」ュKムノ~%?B,?チケ?%-62r?」胖、zL凶ae鰯9I舵Bャ4Egqqtム\'\Z?\n\0(\0??\n\0(\0?・+?m監スモ? !Oa?->厭Y\n蜥コー?tPa?9?OフラAF+す9ヨ? 厶。控t??>エラ?\n?|?みル篦A」=マ(<フwウ?VMウノマHコヤ{9則1? キ\'}?ヲXR\\イ7?9 v?チハc6XY?ル゚ラ。Jo4?\0?*\\咏{\"シイ介ク~Fサ?6ホ5 窖7?\'ヲ源ヌヌリ{2ケcx、h薈GSヲV\Z ?Xレqtニ8T\0P@\0\0Pカデ& テyW[KァP[袢\\・?8ォ\n」冨宗・?&カ9Q]職c?}シ?骭sv>^T\'\'?!、?1キ?wK+蠏詢C1e?\'ハウK\'?楓%?ネ???)夜繩?レ\r\0ロ」Drニ~=欺八1ゥ~モKsqk!リa4\'G舫躬B榕「クキ\Z?\"rフtャOQ?吊租qak遵?/\ZRフ6_?ネ>エロ??ョ\\オG、bセメ0i廳ォォDciイ愕?\0i?\0!襌Uコス.?kア!橡ナ倆pヘ@\0\0ヌテヨ?「窰?シサ??ワcオ &銚j??;鰍蝣iヤルセロ?*=)蜩消」eナ??..?? P?ノ??o・7?WB?c>S吟??Fミン\\iBコ丞?\0ネ??v?フフr?5,モ%?m停Cッ?シ醂(\'@?ォ・襲坪?3ヒサ*s?フ|エ)ノmvセ2/?髣?B+岻ナ鱠オモ,Χ*VAツ?9F・?\07V燻鬢 d磊Oyサオ?Hタ?7ヨス?td濫績明L」\Zァ$hタC?? >オメーノ%tv肆?Y/mニフ艀?。}\r??)苴j?\0bヲ?%?0メツ,ケ莓Rハニ\'フ@ル\'ッN柆 cI?\'ヒリf琲ウ7y(ュヲコ?,アH????ラcュS昴Qm.? ・|喟p??\r,wK-ワカアーェ?H?iG&頌eョ6ゥ亘チ<7o>ヌ?錘OッJ?-ム3SN?<ンヤカkm{?;I良Hタ?__スbヒゥZ蒙Y齲イサ)ツ?dヲ?^V,靭◎眈?\0zウ・ニ71%?7チIi%ト7\r ?t??uラマフw?ヨ未ヨ荳+?:fオ依リ?,Sハ\\r?]ラ_]ラ/&)oi\Zc%FY??篤Mヘe 儿ナt?コ涎Nカ+&?\\olゥ亰q\r@?ヘ0tユウFシ?~テ?*ヌQ・マツ3l喜,ソ┐P?/qK擽7Xキ貅キ@$エ裲?ラ?<梛ゥ???\0Q\'S弁S?6W^蛩糺ャョ@?tケ0ニj?ィ?8滯慶ヒAh特$e」?6シ、}:茅j\n\0租ygSスuュレ.ルCmカZ?3hカ??H・eSコ8 ?K??ぬワケ??吏旭aヌBキ―濶h屁ィ゚??ラM謗:r脯??桟摂テ~ハ?P^d艪5ム=リエmョ?ソ躡?ム???モカ1gqヨウ??+ケSキ%<6揃???6)オmEムsG }ク\rケ渠詞??9セ鐡?7pqY(?8膩レ?ラ~楫Z?qkyツw7?Q沙Xハ\r?ョキ?0Eャェ+臟?剋?フヲO>--d邉ヌゥ?2;3o縊ケ?\0ョウ7ゥ績?&ヨAツ?\n\0コ皰匆シRヌQ撞]&Mムxル?\nCow|nヨFハ ?跡_6ヤv曾ルャ?c?N??+,サ?/,??ツ6?ウt?;?z]Y[;? ーG Cァュ/( レ休計゚*5ハ{・Cwヒ$F耄}?81VQ3鋲iァc・Qセロ?饂t?9z?+ネ婬?K夢Hュ預?N必?紹アw?>??(Bヒowl\"F#?\0?Drァφ?トq?we\'褂?!\"9q?;。ラマ_?.5?fM?9 Yノik)9ォ泌\nュアn?ネ??3?aタア?6ユヌ-\n\0(\0??韲SFNrF?トヒ[i?+o。?シfウヌr?nX??%モtD」ノ#U崙ナ劵R_\\ト寿Q蜩ナacUU? LHQ熾z?5\0Rdョ.螻箪t??Ne?ュ:I?$C? ?/ュヲC{qツノ「]G!ル:?=*??T*ソr?7瞳エ?!?\0?\r闢?スMUJO○Hニ?レ!テ4鯨,?\rC\0n?{囚?ュ9}<カ?ナケ3ハd.イ? ?詈ョfngv=IョL跏?)\0(\0??\n\0?エn :?)??9n?5fγワnヨッ7メrミ?類コpヘ ゚f/(レp\\GトHノ2ー>?P「lmウハォト?:ュトぼ 梯?J?tKwhー?<1ラAコ囹+g8?m&ノ_[ォ\"?域?@:衍^アレキツ\"フw??ョヘvd??1?7s/ニG????Sヤテ\Zャ|ソ??Ck}?5ト?フ?H?逋斟ヒRk跏?掖?\0P@\0\0P@l2鱗?ウケ?/?=?*セ\Z恊篳、2リ?マZkRC&ソス?ムォ無?(婚ボZ?2コOt_氣O??{^ミ?iS潜?ラハノ&RXムコ??コメス\\?\0\nK?。エW框n%i\'大遜ウアb~讓懷7rv5t?\0P@\0?ル?リ??\0JFIF\0\0p\0p\0\0??ヤPhotoshop 3.0\08BIM?\nPrint Info\0\0\0\0x\0\0P\0H\0H\0\0\0\0レ(?????FP\0(?\0\0P\0H\0H\0\0\0\0レ(\0\0\0\0\0d\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\0d\0\0\0\0\0\0\"r\0\0\0\0\0\0\0\0\0\0\0\0?|\0\0\08BIM?\nResolution\0\0\0\0\0pU?\0\0\0pU?\0\08BIM\rFX Global Lighting Angle\0\0\0\0\0\0\0x8BIMFX Global Altitude\0\0\0\0\0\0\08BIM? Print Flags\0\0\0 \0\0\0\0\0\0\0\0\08BIM\nCopyright Flag\0\0\0\0\0\08BIM\'Japanese Print Flags\0\0\0\0\n\0\0\0\0\0\0\0\08BIM?Color Halftone Settings\0\0\0H\0/ff\0\0lff\0\0\0\0\0\0\0/ff\0\0。劒\0\0\0\0\0\0\02\0\0\0\0Z\0\0\0\0\0\0\0\0\05\0\0\0\0-\0\0\0\0\0\0\0\08BIM?Color Transfer Settings\0\0\0p\0\0???????????????????????\0\0\0\0???????????????????????\0\0\0\0???????????????????????\0\0\0\0???????????????????????\0\08BIM\0 Layer State\0\0\0\08BIM Layer Groups\0\0\0\0\0\0\0\08BIMGuges\0\0\0\0\0\0\0\0\0@\0\0@\0\0\0\08BIM\rURL overrges\0\0\0\0\0\0\08BIM\ZSlices\0\0\0\0u\0\0\0\0\0\0\0\0\0\0\0\0\0I\0\0:\0\0\0\n\0U\0n\0t\0i\0t\0l\0e\0d\0-\01\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\0I\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\08BIMICC Untagged Flag\0\0\0\08BIMLayer g Generator Base\0\0\0\0\0\08BIM New Windows Thumbnail\0\0i\0\0\0\0\0\0m\0\0\0p\0\0H\0\0準\0\0M\0\0?リ??\0JFIF\0\0H\0H\0\0??\0Adobe\0d?\0\0\0?ロ\0?\0    \n    \r \r\r   ?タ\0\0p\0m\"\0?ン\0\0?ト?\0\0\0\0\0\0\0\0\0\0 \n \0\0\0\0\0\0\0\0\0 \n \0 3\0!1AQa\"q?2贈アB#$Rチb34rびC%担??s5「イ?&D典dEツ」t6メU稙??モu胚F\'筈?米ヤ蔬・オナユ襄Vfv?ヲカニヨ踐7GWgw?ァキヌラ銷\05\0!1AQaq\"2¢。アB#チRム?3$b疵rCScs4?%「イ?&5ツメD典」dEU6te糘ウ?モu胚F筈?米ヤ蔬・オナユ襄Vfv?ヲカニヨ踐\'7GWgw?ァキヌ?レ\0 \0\0?\0?棚%)$瞳施セ$如$ミユK#總詁ヌゥヨv?4?\09htタaマ\0サ?\"G??ヒr較C}:?p-?? ロ?コカヨヨツウW?ミヲaトォ?Tアチ?[ワ$1マ?;?=M?\0Sz?K+ネヘv7?\rkェタツキ\Zソエu~ョX?)ニdエリO?oルV=゚G~マエ_?オd?k゙ハ?ァ\0レワ?゚T?\06ラ?サcツ;gモ???\0捍チ ィ?.?/?};ヘ驀G\0掌綺@q??!、?\0!?\0A?\0ルUWゥラ泅レヘoヌeマ oョ[I??\0Kヤkッヌオ?\0顆SアSホ?ミz・/ネヌe?2ンKャ?p栽ハニe?+ル??Sル??\0「z旨スl~ン? ロ? -ウミコ拾ネ贐??2.ェヨ条納?G??\0テW[ヨz??4)RI$ぁ?ミ?棚%( +kヲtフ鶴PQaモqqc?4{セ林k9ヒ????0?&&ミ?N??ラt?,ャ蹶Xkヌア?{ -cA?M熟?5ユキ?z櫃モVーヌ?洽゚Oワヌ?=g?/URハヲ?ュfMfbメ磅ナ ャカ楠ネソ?5ケセ槎カモ???\0癡Iメコ?ネ髦ヨ覿f(#?}?ト跟ル?ャ?w?ムソモウ?ム???v;ヨチオホ] 植?藷キロ^Ulリ???/]カ穴゙?1ョ。??珠Rヨ゙ロ\'cュカヲ\nw?ケカS???ョハ?Eネ???ヤZヒ1?ロ} ?ホトホニwキf]{ソG^レ?z?o?アB2ンhkMWテサ讖+G?撥n?曝ワテ-sH゚]オサMユロ[嫺ネUユZ7Uョヤケ?ム??鋳扨&Nリ\'ケ?ヤ鍜魁w*uーn?]T\r?オ淑?$ク?fミラ7ヤc?\0yt}Cュ袗?1q@shs境hv?z孀??\0en??,w?ッ?」ッ「8モ壙*ュヌ!平ク・ーb?娩w?Os??Fマム・e猷cア囘;壑mdl斟m?;cン[?/?\0セ#L?。?ス|?フヘ_r?8Xzォ*}?:嗅ー1??Xラナフヌタニgカラロ?9セッゥ?\r?\0・?\0エ?ネ鶚?ラ}?冐熊スレ2キ?\0Hォ.カサラ9?}麟~;?\0M??c2?ツqエ7?潟*8囚キ!?oァ?oィ?イ-g?/ムォ4?\n??ノキカケ?譱#}5;e?愧_レ3=oァ??ッ^7?iオ7?$欅??音yカゥ?モ?カャ[Csキt惘Uョゥ盻ョウ.キリ鍄?[= }oNヒ?\0]c瞠Kz?ォゥヤ?gィ?UfツK?マ?eサ~ム]_ヲ?\0ョ.?蹠wNテヲ?ォ?/sンー争?zuz椏Y?エウラゥ?灌渭ェ[コSウ歉妻ッn;\0ュカ今?/;娟F0?nヘソ、ルウラ?% ゙ウ\"b}<]o??4コユトoLヌ鶚?゙?PキOx?{hヌョ媼??\00バ?」ヨサ゚mヨzカ*NCァ釁FV17aneu=ミ甼⊥霽;lnラ2?ス椚Lコレoッ?ッ?g+7\"囿?カ貂3=ト青\0凡旌3u?種?2ヨl?Oユ?wセーcgt??マQヌョヌオ?.ャセニ揮羞☆5;布゚ヲキ?Y?漆鯏 ア0D?猖ラd=ッ?ハ黨ケ.ムc?ウpSNwレュ}クケ/kw??0セラ?%jcgソェcX猝ワヒ+s宜?8Xハ??62?+}ウgモカェスOラ=5ホu゙?:eュネ\ru廟Xイ?‡{ナgルeyt\r布V^マ輌滌?>ロ遣疼ヌa粭z?,uホ~8pュ?;Vオマヌ,?>Eフゥ?ェソE努鬩ア?\0h???゚Tンh\\ョス9焦n].uァモ檎ニ? ッァ~ンヘk?゚窓m蘗?ョ*絽ァgbキォ瞼uュ]オ゙>?盟???b?ョs=?J?\0@シナVヒ2タ恕D瘻>・(゙テ???メ?lfオマ?乍謔ャaV?.kZメO.0??U;UY?\Zヨ勿!?2v4{ルイカYオロ?\0孕ルウ?%kVェq?[疫m」ォオ孀mリ1?Fュ?xル?葆ヲ??\'g」岨。?2\rュk麒ュフ,徒[シケム鎹?\0ヘネキ?m?\0カ?oP鰈Tハ\0qスオ脆?bルッ{,?抔ア??\0驃e溂テ \0 ?ラ?ュ\\テ○?遊^?ッ、?メipp;墮?;ヌ?W頷d?g?=OO*玄ドゥ湲「シ7ソォEwQeV9ユケヘ?メicソAk-v?ッモ゚K?=フ」\"ォQユ?2コ?、ローuzE\rカヒ^X??dンヒ-ホェヲ葫fCG?M゚ヘ??、}\\鎔mYY8ュキ エ?S菜ニ輅o「イ广?~マユi?\0??斬DフqkF#cテ?F=?9xKォu:e?ラ??゙?9^?s ?サ\rモ掌黔m?%ヨzy??\0ミセ、?Gゥ6ヨ9?コハZ?E>テキ}u?際ン?写キ?夛?gイ岸VXス諂ク?-眩」??bヨ゚Iセマ詼??%K究?<_bエキ?埠{i,wWスケCa^ラnネユeエ?[V58孺v[?滯+VF5 4クヤlク5桾ヤ=???67ワ??}ャ゚些オ[??ア?~ュu?シャォZ?ロリ貶?~?\"ュソ、ェ暄z~ァゥ^?・Vーヘ?\'?4裔ス?ツ彑?lォh・マゥ?;ムv-98エワ/輌ス\\ed?濱モキ?゚Xu4レ?堯ヤャ餾.-ョ?U_Pメ證ッ?eiッゥUo?Isラ奧ュ?\'ヤロカt?スF螺}ceャ蘭?イ粐?レ?^ョP?t??E>ァ? フスZ?\0iz゚狄}?\0ル゚サ?・Vホ}X藥?\r[??、?モ?gァ絹nム、チU八vロ\Z?\n~#S?ァアトs鯔\Zォs??「/hー;?{~??\0戀}5スメュ フソxn59、ヨラオサ儼Sbレ唳_VMァェ湲?zヤャN鰐ヒゥ師エリテ゚^゙??\0嫐1]ッィ〔1ヘ[リ?ム]ャ?ミ踰ユ?7モイ溽jアZ4t:iH/W??K?趾サ*ラ萬亭ケ???゚Eソ」ァ?+A9?3W??-キa\rn-lvリoィ??5lウ?ヤdア?~C゚?/?s?/ヌaョヌ}攴wロUチヨ5ュl>テ^c?Tキ?敷ト>。メ?〃^$c}ュフウkエワZ=wャ?櫃メァユソ? ゚層」?鬲F\":?リォa?サ=クュ#サ%ホ\Z・チョ?-オ]1?7~潮??sユコ・ヨロ_Rチ?/ヌ}oェ\Zリ??ッ「ニ\rヘケ崟???Dケl?bレ?? YcY?#齲=@マルマソk,セロ\\ヌ?ヨソ?ャY鹽;wャKウ1ウ N、\n,ャ蜥稷ウヤォu\'リ觴k况~NGゥ風m゙ュ」Sルメ#?ナGッ?-?黙ケク]5ンUナュソ ?スメ $幀ナョノ?-wゥ嬾+?\'ァイ?ム??\0Hシ。v゚Zz摧taステ?=Jヘト5?~ォS゙?9?\0ス?「゚ム??Oァ~粐U\\?ツ?サ!?x???ヤ?棚%;?\0W?siq頃茸W]メ~゚c橄ィ?ケ残壙\Zツ?モcイア゙ヘロ??ァ?\0 j?{?6イチ???:Sェハ?゙3?x~??Zキqツ?%?? ニゥニfニ;Hun-2;?3w?)ct?ョカロ?x??ー?\0Snサ?K崕?ニ?\0チウ??,Aナハ脊O Gツナァコ?ロZ*kXK????#ャ暉セ滓11H鳧ー媾?5ラY苗nュ・ニヌス?.ロ足鬮ヨgゥ霍? ?\Zムイメ^粫?ヌ5?\rレ7サw??Mャ?クhc???.コri}9X?ァ毳.」yam剤?;=ロ^?點?\0ェラ?ulメ?.ナ7 l2\\6=OEホ;_eロh?ヨ?\0?F?チ帯ヘ、9セオU]kタ.ァヤカ」ス7゙1ルgヲ?+Cゥeカタモモ?ユ?\09n鷽メ賻ヘ???フ??? ヲフWキhリモVネ:?}.ヌpワ??\0チ?筰G%lA?GJiソ ヤ」モ・?ケチ?カ?O」?策佞イ?KV゚?棯ニヒ、Znサ+モヌツヌk[殯陽UヤX?アョsr22.?q*?騷>ァァ?奇Q?8ツム拘ル鶸%ル蒙レェ゚セ?^ラ=エZ釋F?MY??ン?拗モモ?)鮑sー4m>]?ラ\r?ルスフナァ?[??後F?ィ4tr?Yソュu;s?嫋 「親オTチイ??嬌?=?組、牒f??ユ?棚%)Yチホサ\n疇gOホネU誰血M?>?>ー3%セメ ウク?メ緘オワ? ニX?璋8オテPF???k??\r.mタ~?3?s テ$%ソ、?\0ヘFッッラ?1ッ?)リ?,}6リ?4ミ\\[?w?モシ~ムワユ覽?\0?丸?kワ8\"ヌ?饉?1コ?3V;G????ゥ+?錠゚チO。eGャ鍄釀k6??\'鏝[ォ/??\'ャ?a?6ァcfワ?8z亰サヤハーク?.ゥニャ*?゚Sラネョ??モ?\06シ?\0;?ヨ ヨコキe\Z)x!ユcオエエν閹>ニ?\0ニス??#oQHェ搦サ?+ォE聞、mナェaロdT??\0?ヲ{+?o埴K緒鷙アメIC)&メ、棚??ル\08BIM!\ZVersion compatibility info\0\0\0\0U\0\0\0\0\0\0\0A\0d\0o\0b\0e\0 \0P\0h\0o\0t\0o\0s\0h\0o\0p\0\0\0\0A\0d\0o\0b\0e\0 \0P\0h\0o\0t\0o\0s\0h\0o\0p\0 \06\0.\00\0\0\0\08BIM JPEG Quality\0\0\0\0\0\0\0\0\0?ロ\0C\0\n\n\n \n \Z%\Z# , #&\')*)-0-(0%()(?ロ\0C\n\n\n\n(\Z\Z((((((((((((((((((((((((((((((((((((((((((((((((((?タ\0\0x\0u\0?ト\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\08\0\0\0\0\0\0!1AQ\"aq?2贈ア#BRbムr$3チ盍?ト\0\Z\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\00\0\0\0\0\0\0\0!1\"AQ2aBアムq■チ碵#R??レ\0 \0\0?\0?\0\0P@\0s?7浮ニ護|馬???・sgツルk・ カナヨCヒZ姉カ?ウ_gケラPc?゚P」ュKムノ~%?B,?チケ?%-62r?」胖、zL凶ae鰯9I舵Bャ4Egqqtム\'\Z?\n\0(\0??\n\0(\0?・+?m監スモ? !Oa?->厭Y\n蜥コー?tPa?9?OフラAF+す9ヨ? 厶。控t??>エラ?\n?|?みル篦A」=マ(<フwウ?VMウノマHコヤ{9則1? キ\'}?ヲXR\\イ7?9 v?チハc6XY?ル゚ラ。Jo4?\0?*\\咏{\"シイ介ク~Fサ?6ホ5 窖7?\'ヲ源ヌヌリ{2ケcx、h薈GSヲV\Z ?Xレqtニ8T\0P@\0\0Pカデ& テyW[KァP[袢\\・?8ォ\n」冨宗・?&カ9Q]職c?}シ?骭sv>^T\'\'?!、?1キ?wK+蠏詢C1e?\'ハウK\'?楓%?ネ???)夜繩?レ\r\0ロ」Drニ~=欺八1ゥ~モKsqk!リa4\'G舫躬B榕「クキ\Z?\"rフtャOQ?吊租qak遵?/\ZRフ6_?ネ>エロ??ョ\\オG、bセメ0i廳ォォDciイ愕?\0i?\0!襌Uコス.?kア!橡ナ倆pヘ@\0\0ヌテヨ?「窰?シサ??ワcオ &銚j??;鰍蝣iヤルセロ?*=)蜩消」eナ??..?? P?ノ??o・7?WB?c>S吟??Fミン\\iBコ丞?\0ネ??v?フフr?5,モ%?m停Cッ?シ醂(\'@?ォ・襲坪?3ヒサ*s?フ|エ)ノmvセ2/?髣?B+岻ナ鱠オモ,Χ*VAツ?9F・?\07V燻鬢 d磊Oyサオ?Hタ?7ヨス?td濫績明L」\Zァ$hタC?? >オメーノ%tv肆?Y/mニフ艀?。}\r??)苴j?\0bヲ?%?0メツ,ケ莓Rハニ\'フ@ル\'ッN柆 cI?\'ヒリf琲ウ7y(ュヲコ?,アH????ラcュS昴Qm.? ・|喟p??\r,wK-ワカアーェ?H?iG&頌eョ6ゥ亘チ<7o>ヌ?錘OッJ?-ム3SN?<ンヤカkm{?;I良Hタ?__スbヒゥZ蒙Y齲イサ)ツ?dヲ?^V,靭◎眈?\0zウ・ニ71%?7チIi%ト7\r ?t??uラマフw?ヨ未ヨ荳+?:fオ依リ?,Sハ\\r?]ラ_]ラ/&)oi\Zc%FY??篤Mヘe 儿ナt?コ涎Nカ+&?\\olゥ亰q\r@?ヘ0tユウFシ?~テ?*ヌQ・マツ3l喜,ソ┐P?/qK擽7Xキ貅キ@$エ裲?ラ?<梛ゥ???\0Q\'S弁S?6W^蛩糺ャョ@?tケ0ニj?ィ?8滯慶ヒAh特$e」?6シ、}:茅j\n\0租ygSスuュレ.ルCmカZ?3hカ??H・eSコ8 ?K??ぬワケ??吏旭aヌBキ―濶h屁ィ゚??ラM謗:r脯??桟摂テ~ハ?P^d艪5ム=リエmョ?ソ躡?ム???モカ1gqヨウ??+ケSキ%<6揃???6)オmEムsG }ク\rケ渠詞??9セ鐡?7pqY(?8膩レ?ラ~楫Z?qkyツw7?Q沙Xハ\r?ョキ?0Eャェ+臟?剋?フヲO>--d邉ヌゥ?2;3o縊ケ?\0ョウ7ゥ績?&ヨAツ?\n\0コ皰匆シRヌQ撞]&Mムxル?\nCow|nヨFハ ?跡_6ヤv曾ルャ?c?N??+,サ?/,??ツ6?ウt?;?z]Y[;? ーG Cァュ/( レ休計゚*5ハ{・Cwヒ$F耄}?81VQ3鋲iァc・Qセロ?饂t?9z?+ネ婬?K夢Hュ預?N必?紹アw?>??(Bヒowl\"F#?\0?Drァφ?トq?we\'褂?!\"9q?;。ラマ_?.5?fM?9 Yノik)9ォ泌\nュアn?ネ??3?aタア?6ユヌ-\n\0(\0??韲SFNrF?トヒ[i?+o。?シfウヌr?nX??%モtD」ノ#U崙ナ劵R_\\ト寿Q蜩ナacUU? LHQ熾z?5\0Rdョ.螻箪t??Ne?ュ:I?$C? ?/ュヲC{qツノ「]G!ル:?=*??T*ソr?7瞳エ?!?\0?\r闢?スMUJO○Hニ?レ!テ4鯨,?\rC\0n?{囚?ュ9}<カ?ナケ3ハd.イ? ?詈ョfngv=IョL跏?)\0(\0??\n\0?エn :?)??9n?5fγワnヨッ7メrミ?類コpヘ ゚f/(レp\\GトHノ2ー>?P「lmウハォト?:ュトぼ 梯?J?tKwhー?<1ラAコ囹+g8?m&ノ_[ォ\"?域?@:衍^アレキツ\"フw??ョヘvd??1?7s/ニG????Sヤテ\Zャ|ソ??Ck}?5ト?フ?H?逋斟ヒRk跏?掖?\0P@\0\0P@l2鱗?ウケ?/?=?*セ\Z恊篳、2リ?マZkRC&ソス?ムォ無?(婚ボZ?2コOt_氣O??{^ミ?iS潜?ラハノ&RXムコ??コメス\\?\0\nK?。エW框n%i\'大遜ウアb~讓懷7rv5t?\0P@\0?ル?リ??\0JFIF\0\0p\0p\0\0??ヤPhotoshop 3.0\08BIM?\nPrint Info\0\0\0\0x\0\0P\0H\0H\0\0\0\0レ(?????FP\0(?\0\0P\0H\0H\0\0\0\0レ(\0\0\0\0\0d\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\0d\0\0\0\0\0\0\"r\0\0\0\0\0\0\0\0\0\0\0\0?|\0\0\08BIM?\nResolution\0\0\0\0\0pU?\0\0\0pU?\0\08BIM\rFX Global Lighting Angle\0\0\0\0\0\0\0x8BIMFX Global Altitude\0\0\0\0\0\0\08BIM? Print Flags\0\0\0 \0\0\0\0\0\0\0\0\08BIM\nCopyright Flag\0\0\0\0\0\08BIM\'Japanese Print Flags\0\0\0\0\n\0\0\0\0\0\0\0\08BIM?Color Halftone Settings\0\0\0H\0/ff\0\0lff\0\0\0\0\0\0\0/ff\0\0。劒\0\0\0\0\0\0\02\0\0\0\0Z\0\0\0\0\0\0\0\0\05\0\0\0\0-\0\0\0\0\0\0\0\08BIM?Color Transfer Settings\0\0\0p\0\0???????????????????????\0\0\0\0???????????????????????\0\0\0\0???????????????????????\0\0\0\0???????????????????????\0\08BIM\0 Layer State\0\0\0\08BIM Layer Groups\0\0\0\0\0\0\0\08BIMGuges\0\0\0\0\0\0\0\0\0@\0\0@\0\0\0\08BIM\rURL overrges\0\0\0\0\0\0\08BIM\ZSlices\0\0\0\0u\0\0\0\0\0\0\0\0\0\0\0\0\0I\0\0:\0\0\0\n\0U\0n\0t\0i\0t\0l\0e\0d\0-\01\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\0I\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\08BIMICC Untagged Flag\0\0\0\08BIMLayer g Generator Base\0\0\0\0\0\08BIM New Windows Thumbnail\0\0i\0\0\0\0\0\0m\0\0\0p\0\0H\0\0準\0\0M\0\0?リ??\0JFIF\0\0H\0H\0\0??\0Adobe\0d?\0\0\0?ロ\0?\0    \n    \r \r\r   ?タ\0\0p\0m\"\0?ン\0\0?ト?\0\0\0\0\0\0\0\0\0\0 \n \0\0\0\0\0\0\0\0\0 \n \0 3\0!1AQa\"q?2贈アB#$Rチb34rびC%担??s5「イ?&D典dEツ」t6メU稙??モu胚F\'筈?米ヤ蔬・オナユ襄Vfv?ヲカニヨ踐7GWgw?ァキヌラ銷\05\0!1AQaq\"2¢。アB#チRム?3$b疵rCScs4?%「イ?&5ツメD典」dEU6te糘ウ?モu胚F筈?米ヤ蔬・オナユ襄Vfv?ヲカニヨ踐\'7GWgw?ァキヌ?レ\0 \0\0?\0?棚%)$瞳施セ$如$ミユK#總詁ヌゥヨv?4?\09htタaマ\0サ?\"G??ヒr較C}:?p-?? ロ?コカヨヨツウW?ミヲaトォ?Tアチ?[ワ$1マ?;?=M?\0Sz?K+ネヘv7?\rkェタツキ\Zソエu~ョX?)ニdエリO?oルV=゚G~マエ_?オd?k゙ハ?ァ\0レワ?゚T?\06ラ?サcツ;gモ???\0捍チ ィ?.?/?};ヘ驀G\0掌綺@q??!、?\0!?\0A?\0ルUWゥラ泅レヘoヌeマ oョ[I??\0Kヤkッヌオ?\0顆SアSホ?ミz・/ネヌe?2ンKャ?p栽ハニe?+ル??Sル??\0「z旨スl~ン? ロ? -ウミコ拾ネ贐??2.ェヨ条納?G??\0テW[ヨz??4)RI$ぁ?ミ?棚%( +kヲtフ鶴PQaモqqc?4{セ林k9ヒ????0?&&ミ?N??ラt?,ャ蹶Xkヌア?{ -cA?M熟?5ユキ?z櫃モVーヌ?洽゚Oワヌ?=g?/URハヲ?ュfMfbメ磅ナ ャカ楠ネソ?5ケセ槎カモ???\0癡Iメコ?ネ髦ヨ覿f(#?}?ト跟ル?ャ?w?ムソモウ?ム???v;ヨチオホ] 植?藷キロ^Ulリ???/]カ穴゙?1ョ。??珠Rヨ゙ロ\'cュカヲ\nw?ケカS???ョハ?Eネ???ヤZヒ1?ロ} ?ホトホニwキf]{ソG^レ?z?o?アB2ンhkMWテサ讖+G?撥n?曝ワテ-sH゚]オサMユロ[嫺ネUユZ7Uョヤケ?ム??鋳扨&Nリ\'ケ?ヤ鍜魁w*uーn?]T\r?オ淑?$ク?fミラ7ヤc?\0yt}Cュ袗?1q@shs境hv?z孀??\0en??,w?ッ?」ッ「8モ壙*ュヌ!平ク・ーb?娩w?Os??Fマム・e猷cア囘;壑mdl斟m?;cン[?/?\0セ#L?。?ス|?フヘ_r?8Xzォ*}?:嗅ー1??Xラナフヌタニgカラロ?9セッゥ?\r?\0・?\0エ?ネ鶚?ラ}?冐熊スレ2キ?\0Hォ.カサラ9?}麟~;?\0M??c2?ツqエ7?潟*8囚キ!?oァ?oィ?イ-g?/ムォ4?\n??ノキカケ?譱#}5;e?愧_レ3=oァ??ッ^7?iオ7?$欅??音yカゥ?モ?カャ[Csキt惘Uョゥ盻ョウ.キリ鍄?[= }oNヒ?\0]c瞠Kz?ォゥヤ?gィ?UfツK?マ?eサ~ム]_ヲ?\0ョ.?蹠wNテヲ?ォ?/sンー争?zuz椏Y?エウラゥ?灌渭ェ[コSウ歉妻ッn;\0ュカ今?/;娟F0?nヘソ、ルウラ?% ゙ウ\"b}<]o??4コユトoLヌ鶚?゙?PキOx?{hヌョ媼??\00バ?」ヨサ゚mヨzカ*NCァ釁FV17aneu=ミ甼⊥霽;lnラ2?ス椚Lコレoッ?ッ?g+7\"囿?カ貂3=ト青\0凡旌3u?種?2ヨl?Oユ?wセーcgt??マQヌョヌオ?.ャセニ揮羞☆5;布゚ヲキ?Y?漆鯏 ア0D?猖ラd=ッ?ハ黨ケ.ムc?ウpSNwレュ}クケ/kw??0セラ?%jcgソェcX猝ワヒ+s宜?8Xハ??62?+}ウgモカェスOラ=5ホu゙?:eュネ\ru廟Xイ?‡{ナgルeyt\r布V^マ輌滌?>ロ遣疼ヌa粭z?,uホ~8pュ?;Vオマヌ,?>Eフゥ?ェソE努鬩ア?\0h???゚Tンh\\ョス9焦n].uァモ檎ニ? ッァ~ンヘk?゚窓m蘗?ョ*絽ァgbキォ瞼uュ]オ゙>?盟???b?ョs=?J?\0@シナVヒ2タ恕D瘻>・(゙テ???メ?lfオマ?乍謔ャaV?.kZメO.0??U;UY?\Zヨ勿!?2v4{ルイカYオロ?\0孕ルウ?%kVェq?[疫m」ォオ孀mリ1?Fュ?xル?葆ヲ??\'g」岨。?2\rュk麒ュフ,徒[シケム鎹?\0ヘネキ?m?\0カ?oP鰈Tハ\0qスオ脆?bルッ{,?抔ア??\0驃e溂テ \0 ?ラ?ュ\\テ○?遊^?ッ、?メipp;墮?;ヌ?W頷d?g?=OO*玄ドゥ湲「シ7ソォEwQeV9ユケヘ?メicソAk-v?ッモ゚K?=フ」\"ォQユ?2コ?、ローuzE\rカヒ^X??dンヒ-ホェヲ葫fCG?M゚ヘ??、}\\鎔mYY8ュキ エ?S菜ニ輅o「イ广?~マユi?\0??斬DフqkF#cテ?F=?9xKォu:e?ラ??゙?9^?s ?サ\rモ掌黔m?%ヨzy??\0ミセ、?Gゥ6ヨ9?コハZ?E>テキ}u?際ン?写キ?夛?gイ岸VXス諂ク?-眩」??bヨ゚Iセマ詼??%K究?<_bエキ?埠{i,wWスケCa^ラnネユeエ?[V58孺v[?滯+VF5 4クヤlク5桾ヤ=???67ワ??}ャ゚些オ[??ア?~ュu?シャォZ?ロリ貶?~?\"ュソ、ェ暄z~ァゥ^?・Vーヘ?\'?4裔ス?ツ彑?lォh・マゥ?;ムv-98エワ/輌ス\\ed?濱モキ?゚Xu4レ?堯ヤャ餾.-ョ?U_Pメ證ッ?eiッゥUo?Isラ奧ュ?\'ヤロカt?スF螺}ceャ蘭?イ粐?レ?^ョP?t??E>ァ? フスZ?\0iz゚狄}?\0ル゚サ?・Vホ}X藥?\r[??、?モ?gァ絹nム、チU八vロ\Z?\n~#S?ァアトs鯔\Zォs??「/hー;?{~??\0戀}5スメュ フソxn59、ヨラオサ儼Sbレ唳_VMァェ湲?zヤャN鰐ヒゥ師エリテ゚^゙??\0嫐1]ッィ〔1ヘ[リ?ム]ャ?ミ踰ユ?7モイ溽jアZ4t:iH/W??K?趾サ*ラ萬亭ケ???゚Eソ」ァ?+A9?3W??-キa\rn-lvリoィ??5lウ?ヤdア?~C゚?/?s?/ヌaョヌ}攴wロUチヨ5ュl>テ^c?Tキ?敷ト>。メ?〃^$c}ュフウkエワZ=wャ?櫃メァユソ? ゚層」?鬲F\":?リォa?サ=クュ#サ%ホ\Z・チョ?-オ]1?7~潮??sユコ・ヨロ_Rチ?/ヌ}oェ\Zリ??ッ「ニ\rヘケ崟???Dケl?bレ?? YcY?#齲=@マルマソk,セロ\\ヌ?ヨソ?ャY鹽;wャKウ1ウ N、\n,ャ蜥稷ウヤォu\'リ觴k况~NGゥ風m゙ュ」Sルメ#?ナGッ?-?黙ケク]5ンUナュソ ?スメ $幀ナョノ?-wゥ嬾+?\'ァイ?ム??\0Hシ。v゚Zz摧taステ?=Jヘト5?~ォS゙?9?\0ス?「゚ム??Oァ~粐U\\?ツ?サ!?x???ヤ?棚%;?\0W?siq頃茸W]メ~゚c橄ィ?ケ残壙\Zツ?モcイア゙ヘロ??ァ?\0 j?{?6イチ???:Sェハ?゙3?x~??Zキqツ?%?? ニゥニfニ;Hun-2;?3w?)ct?ョカロ?x??ー?\0Snサ?K崕?ニ?\0チウ??,Aナハ脊O Gツナァコ?ロZ*kXK????#ャ暉セ滓11H鳧ー媾?5ラY苗nュ・ニヌス?.ロ足鬮ヨgゥ霍? ?\Zムイメ^粫?ヌ5?\rレ7サw??Mャ?クhc???.コri}9X?ァ毳.」yam剤?;=ロ^?點?\0ェラ?ulメ?.ナ7 l2\\6=OEホ;_eロh?ヨ?\0?F?チ帯ヘ、9セオU]kタ.ァヤカ」ス7゙1ルgヲ?+Cゥeカタモモ?ユ?\09n鷽メ賻ヘ???フ??? ヲフWキhリモVネ:?}.ヌpワ??\0チ?筰G%lA?GJiソ ヤ」モ・?ケチ?カ?O」?策佞イ?KV゚?棯ニヒ、Znサ+モヌツヌk[殯陽UヤX?アョsr22.?q*?騷>ァァ?奇Q?8ツム拘ル鶸%ル蒙レェ゚セ?^ラ=エZ釋F?MY??ン?拗モモ?)鮑sー4m>]?ラ\r?ルスフナァ?[??後F?ィ4tr?Yソュu;s?嫋 「親オTチイ??嬌?=?組、牒f??ユ?棚%)Yチホサ\n疇gOホネU誰血M?>?>ー3%セメ ウク?メ緘オワ? ニX?璋8オテPF???k??\r.mタ~?3?s テ$%ソ、?\0ヘFッッラ?1ッ?)リ?,}6リ?4ミ\\[?w?モシ~ムワユ覽?\0?丸?kワ8\"ヌ?饉?1コ?3V;G????ゥ+?錠゚チO。eGャ鍄釀k6??\'鏝[ォ/??\'ャ?a?6ァcfワ?8z亰サヤハーク?.ゥニャ*?゚Sラネョ??モ?\06シ?\0;?ヨ ヨコキe\Z)x!ユcオエエν閹>ニ?\0ニス??#oQHェ搦サ?+ォE聞、mナェaロdT??\0?ヲ{+?o埴K緒鷙アメIC)&メ、棚??ル\08BIM!\ZVersion compatibility info\0\0\0\0U\0\0\0\0\0\0\0A\0d\0o\0b\0e\0 \0P\0h\0o\0t\0o\0s\0h\0o\0p\0\0\0\0A\0d\0o\0b\0e\0 \0P\0h\0o\0t\0o\0s\0h\0o\0p\0 \06\0.\00\0\0\0\08BIM JPEG Quality\0\0\0\0\0\0\0\0\0?ロ\0C\0\n\n\n \n \Z%\Z# , #&\')*)-0-(0%()(?ロ\0C\n\n\n\n(\Z\Z((((((((((((((((((((((((((((((((((((((((((((((((((?タ\0\0x\0u\0?ト\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\08\0\0\0\0\0\0!1AQ\"aq?2贈ア#BRbムr$3チ盍?ト\0\Z\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\00\0\0\0\0\0\0\0!1\"AQ2aBアムq■チ碵#R??レ\0 \0\0?\0?\0\0P@\0s?7浮ニ護|馬???・sgツルk・ カナヨCヒZ姉カ?ウ_gケラPc?゚P」ュKムノ~%?B,?チケ?%-62r?」胖、zL凶ae鰯9I舵Bャ4Egqqtム\'\Z?\n\0(\0??\n\0(\0?・+?m監スモ? !Oa?->厭Y\n蜥コー?tPa?9?OフラAF+す9ヨ? 厶。控t??>エラ?\n?|?みル篦A」=マ(<フwウ?VMウノマHコヤ{9則1? キ\'}?ヲXR\\イ7?9 v?チハc6XY?ル゚ラ。Jo4?\0?*\\咏{\"シイ介ク~Fサ?6ホ5 窖7?\'ヲ源ヌヌリ{2ケcx、h薈GSヲV\Z ?Xレqtニ8T\0P@\0\0Pカデ& テyW[KァP[袢\\・?8ォ\n」冨宗・?&カ9Q]職c?}シ?骭sv>^T\'\'?!、?1キ?wK+蠏詢C1e?\'ハウK\'?楓%?ネ???)夜繩?レ\r\0ロ」Drニ~=欺八1ゥ~モKsqk!リa4\'G舫躬B榕「クキ\Z?\"rフtャOQ?吊租qak遵?/\ZRフ6_?ネ>エロ??ョ\\オG、bセメ0i廳ォォDciイ愕?\0i?\0!襌Uコス.?kア!橡ナ倆pヘ@\0\0ヌテヨ?「窰?シサ??ワcオ &銚j??;鰍蝣iヤルセロ?*=)蜩消」eナ??..?? P?ノ??o・7?WB?c>S吟??Fミン\\iBコ丞?\0ネ??v?フフr?5,モ%?m停Cッ?シ醂(\'@?ォ・襲坪?3ヒサ*s?フ|エ)ノmvセ2/?髣?B+岻ナ鱠オモ,Χ*VAツ?9F・?\07V燻鬢 d磊Oyサオ?Hタ?7ヨス?td濫績明L」\Zァ$hタC?? >オメーノ%tv肆?Y/mニフ艀?。}\r??)苴j?\0bヲ?%?0メツ,ケ莓Rハニ\'フ@ル\'ッN柆 cI?\'ヒリf琲ウ7y(ュヲコ?,アH????ラcュS昴Qm.? ・|喟p??\r,wK-ワカアーェ?H?iG&頌eョ6ゥ亘チ<7o>ヌ?錘OッJ?-ム3SN?<ンヤカkm{?;I良Hタ?__スbヒゥZ蒙Y齲イサ)ツ?dヲ?^V,靭◎眈?\0zウ・ニ71%?7チIi%ト7\r ?t??uラマフw?ヨ未ヨ荳+?:fオ依リ?,Sハ\\r?]ラ_]ラ/&)oi\Zc%FY??篤Mヘe 儿ナt?コ涎Nカ+&?\\olゥ亰q\r@?ヘ0tユウFシ?~テ?*ヌQ・マツ3l喜,ソ┐P?/qK擽7Xキ貅キ@$エ裲?ラ?<梛ゥ???\0Q\'S弁S?6W^蛩糺ャョ@?tケ0ニj?ィ?8滯慶ヒAh特$e」?6シ、}:茅j\n\0租ygSスuュレ.ルCmカZ?3hカ??H・eSコ8 ?K??ぬワケ??吏旭aヌBキ―濶h屁ィ゚??ラM謗:r脯??桟摂テ~ハ?P^d艪5ム=リエmョ?ソ躡?ム???モカ1gqヨウ??+ケSキ%<6揃???6)オmEムsG }ク\rケ渠詞??9セ鐡?7pqY(?8膩レ?ラ~楫Z?qkyツw7?Q沙Xハ\r?ョキ?0Eャェ+臟?剋?フヲO>--d邉ヌゥ?2;3o縊ケ?\0ョウ7ゥ績?&ヨAツ?\n\0コ皰匆シRヌQ撞]&Mムxル?\nCow|nヨFハ ?跡_6ヤv曾ルャ?c?N??+,サ?/,??ツ6?ウt?;?z]Y[;? ーG Cァュ/( レ休計゚*5ハ{・Cwヒ$F耄}?81VQ3鋲iァc・Qセロ?饂t?9z?+ネ婬?K夢Hュ預?N必?紹アw?>??(Bヒowl\"F#?\0?Drァφ?トq?we\'褂?!\"9q?;。ラマ_?.5?fM?9 Yノik)9ォ泌\nュアn?ネ??3?aタア?6ユヌ-\n\0(\0??韲SFNrF?トヒ[i?+o。?シfウヌr?nX??%モtD」ノ#U崙ナ劵R_\\ト寿Q蜩ナacUU? LHQ熾z?5\0Rdョ.螻箪t??Ne?ュ:I?$C? ?/ュヲC{qツノ「]G!ル:?=*??T*ソr?7瞳エ?!?\0?\r闢?スMUJO○Hニ?レ!テ4鯨,?\rC\0n?{囚?ュ9}<カ?ナケ3ハd.イ? ?詈ョfngv=IョL跏?)\0(\0??\n\0?エn :?)??9n?5fγワnヨッ7メrミ?類コpヘ ゚f/(レp\\GトHノ2ー>?P「lmウハォト?:ュトぼ 梯?J?tKwhー?<1ラAコ囹+g8?m&ノ_[ォ\"?域?@:衍^アレキツ\"フw??ョヘvd??1?7s/ニG????Sヤテ\Zャ|ソ??Ck}?5ト?フ?H?逋斟ヒRk跏?掖?\0P@\0\0P@l2鱗?ウケ?/?=?*セ\Z恊篳、2リ?マZkRC&ソス?ムォ無?(婚ボZ?2コOt_氣O??{^ミ?iS潜?ラハノ&RXムコ??コメス\\?\0\nK?。エW框n%i\'大遜ウアb~讓懷7rv5t?\0P@\0?ル?リ??\0JFIF\0\0p\0p\0\0??ヤPhotoshop 3.0\08BIM?\nPrint Info\0\0\0\0x\0\0P\0H\0H\0\0\0\0レ(?????FP\0(?\0\0P\0H\0H\0\0\0\0レ(\0\0\0\0\0d\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\0d\0\0\0\0\0\0\"r\0\0\0\0\0\0\0\0\0\0\0\0?|\0\0\08BIM?\nResolution\0\0\0\0\0pU?\0\0\0pU?\0\08BIM\rFX Global Lighting Angle\0\0\0\0\0\0\0x8BIMFX Global Altitude\0\0\0\0\0\0\08BIM? Print Flags\0\0\0 \0\0\0\0\0\0\0\0\08BIM\nCopyright Flag\0\0\0\0\0\08BIM\'Japanese Print Flags\0\0\0\0\n\0\0\0\0\0\0\0\08BIM?Color Halftone Settings\0\0\0H\0/ff\0\0lff\0\0\0\0\0\0\0/ff\0\0。劒\0\0\0\0\0\0\02\0\0\0\0Z\0\0\0\0\0\0\0\0\05\0\0\0\0-\0\0\0\0\0\0\0\08BIM?Color Transfer Settings\0\0\0p\0\0???????????????????????\0\0\0\0???????????????????????\0\0\0\0???????????????????????\0\0\0\0???????????????????????\0\08BIM\0 Layer State\0\0\0\08BIM Layer Groups\0\0\0\0\0\0\0\08BIMGuges\0\0\0\0\0\0\0\0\0@\0\0@\0\0\0\08BIM\rURL overrges\0\0\0\0\0\0\08BIM\ZSlices\0\0\0\0u\0\0\0\0\0\0\0\0\0\0\0\0\0I\0\0:\0\0\0\n\0U\0n\0t\0i\0t\0l\0e\0d\0-\01\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\0I\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\08BIMICC Untagged Flag\0\0\0\08BIMLayer g Generator Base\0\0\0\0\0\08BIM New Windows Thumbnail\0\0i\0\0\0\0\0\0m\0\0\0p\0\0H\0\0準\0\0M\0\0?リ??\0JFIF\0\0H\0H\0\0??\0Adobe\0d?\0\0\0?ロ\0?\0    \n    \r \r\r   ?タ\0\0p\0m\"\0?ン\0\0?ト?\0\0\0\0\0\0\0\0\0\0 \n \0\0\0\0\0\0\0\0\0 \n \0 3\0!1AQa\"q?2贈アB#$Rチb34rびC%担??s5「イ?&D典dEツ」t6メU稙??モu胚F\'筈?米ヤ蔬・オナユ襄Vfv?ヲカニヨ踐7GWgw?ァキヌラ銷\05\0!1AQaq\"2¢。アB#チRム?3$b疵rCScs4?%「イ?&5ツメD典」dEU6te糘ウ?モu胚F筈?米ヤ蔬・オナユ襄Vfv?ヲカニヨ踐\'7GWgw?ァキヌ?レ\0 \0\0?\0?棚%)$瞳施セ$如$ミユK#總詁ヌゥヨv?4?\09htタaマ\0サ?\"G??ヒr較C}:?p-?? ロ?コカヨヨツウW?ミヲaトォ?Tアチ?[ワ$1マ?;?=M?\0Sz?K+ネヘv7?\rkェタツキ\Zソエu~ョX?)ニdエリO?oルV=゚G~マエ_?オd?k゙ハ?ァ\0レワ?゚T?\06ラ?サcツ;gモ???\0捍チ ィ?.?/?};ヘ驀G\0掌綺@q??!、?\0!?\0A?\0ルUWゥラ泅レヘoヌeマ oョ[I??\0Kヤkッヌオ?\0顆SアSホ?ミz・/ネヌe?2ンKャ?p栽ハニe?+ル??Sル??\0「z旨スl~ン? ロ? -ウミコ拾ネ贐??2.ェヨ条納?G??\0テW[ヨz??4)RI$ぁ?ミ?棚%( +kヲtフ鶴PQaモqqc?4{セ林k9ヒ????0?&&ミ?N??ラt?,ャ蹶Xkヌア?{ -cA?M熟?5ユキ?z櫃モVーヌ?洽゚Oワヌ?=g?/URハヲ?ュfMfbメ磅ナ ャカ楠ネソ?5ケセ槎カモ???\0癡Iメコ?ネ髦ヨ覿f(#?}?ト跟ル?ャ?w?ムソモウ?ム???v;ヨチオホ] 植?藷キロ^Ulリ???/]カ穴゙?1ョ。??珠Rヨ゙ロ\'cュカヲ\nw?ケカS???ョハ?Eネ???ヤZヒ1?ロ} ?ホトホニwキf]{ソG^レ?z?o?アB2ンhkMWテサ讖+G?撥n?曝ワテ-sH゚]オサMユロ[嫺ネUユZ7Uョヤケ?ム??鋳扨&Nリ\'ケ?ヤ鍜魁w*uーn?]T\r?オ淑?$ク?fミラ7ヤc?\0yt}Cュ袗?1q@shs境hv?z孀??\0en??,w?ッ?」ッ「8モ壙*ュヌ!平ク・ーb?娩w?Os??Fマム・e猷cア囘;壑mdl斟m?;cン[?/?\0セ#L?。?ス|?フヘ_r?8Xzォ*}?:嗅ー1??Xラナフヌタニgカラロ?9セッゥ?\r?\0・?\0エ?ネ鶚?ラ}?冐熊スレ2キ?\0Hォ.カサラ9?}麟~;?\0M??c2?ツqエ7?潟*8囚キ!?oァ?oィ?イ-g?/ムォ4?\n??ノキカケ?譱#}5;e?愧_レ3=oァ??ッ^7?iオ7?$欅??音yカゥ?モ?カャ[Csキt惘Uョゥ盻ョウ.キリ鍄?[= }oNヒ?\0]c瞠Kz?ォゥヤ?gィ?UfツK?マ?eサ~ム]_ヲ?\0ョ.?蹠wNテヲ?ォ?/sンー争?zuz椏Y?エウラゥ?灌渭ェ[コSウ歉妻ッn;\0ュカ今?/;娟F0?nヘソ、ルウラ?% ゙ウ\"b}<]o??4コユトoLヌ鶚?゙?PキOx?{hヌョ媼??\00バ?」ヨサ゚mヨzカ*NCァ釁FV17aneu=ミ甼⊥霽;lnラ2?ス椚Lコレoッ?ッ?g+7\"囿?カ貂3=ト青\0凡旌3u?種?2ヨl?Oユ?wセーcgt??マQヌョヌオ?.ャセニ揮羞☆5;布゚ヲキ?Y?漆鯏 ア0D?猖ラd=ッ?ハ黨ケ.ムc?ウpSNwレュ}クケ/kw??0セラ?%jcgソェcX猝ワヒ+s宜?8Xハ??62?+}ウgモカェスOラ=5ホu゙?:eュネ\ru廟Xイ?‡{ナgルeyt\r布V^マ輌滌?>ロ遣疼ヌa粭z?,uホ~8pュ?;Vオマヌ,?>Eフゥ?ェソE努鬩ア?\0h???゚Tンh\\ョス9焦n].uァモ檎ニ? ッァ~ンヘk?゚窓m蘗?ョ*絽ァgbキォ瞼uュ]オ゙>?盟???b?ョs=?J?\0@シナVヒ2タ恕D瘻>・(゙テ???メ?lfオマ?乍謔ャaV?.kZメO.0??U;UY?\Zヨ勿!?2v4{ルイカYオロ?\0孕ルウ?%kVェq?[疫m」ォオ孀mリ1?Fュ?xル?葆ヲ??\'g」岨。?2\rュk麒ュフ,徒[シケム鎹?\0ヘネキ?m?\0カ?oP鰈Tハ\0qスオ脆?bルッ{,?抔ア??\0驃e溂テ \0 ?ラ?ュ\\テ○?遊^?ッ、?メipp;墮?;ヌ?W頷d?g?=OO*玄ドゥ湲「シ7ソォEwQeV9ユケヘ?メicソAk-v?ッモ゚K?=フ」\"ォQユ?2コ?、ローuzE\rカヒ^X??dンヒ-ホェヲ葫fCG?M゚ヘ??、}\\鎔mYY8ュキ エ?S菜ニ輅o「イ广?~マユi?\0??斬DフqkF#cテ?F=?9xKォu:e?ラ??゙?9^?s ?サ\rモ掌黔m?%ヨzy??\0ミセ、?Gゥ6ヨ9?コハZ?E>テキ}u?際ン?写キ?夛?gイ岸VXス諂ク?-眩」??bヨ゚Iセマ詼??%K究?<_bエキ?埠{i,wWスケCa^ラnネユeエ?[V58孺v[?滯+VF5 4クヤlク5桾ヤ=???67ワ??}ャ゚些オ[??ア?~ュu?シャォZ?ロリ貶?~?\"ュソ、ェ暄z~ァゥ^?・Vーヘ?\'?4裔ス?ツ彑?lォh・マゥ?;ムv-98エワ/輌ス\\ed?濱モキ?゚Xu4レ?堯ヤャ餾.-ョ?U_Pメ證ッ?eiッゥUo?Isラ奧ュ?\'ヤロカt?スF螺}ceャ蘭?イ粐?レ?^ョP?t??E>ァ? フスZ?\0iz゚狄}?\0ル゚サ?・Vホ}X藥?\r[??、?モ?gァ絹nム、チU八vロ\Z?\n~#S?ァアトs鯔\Zォs??「/hー;?{~??\0戀}5スメュ フソxn59、ヨラオサ儼Sbレ唳_VMァェ湲?zヤャN鰐ヒゥ師エリテ゚^゙??\0嫐1]ッィ〔1ヘ[リ?ム]ャ?ミ踰ユ?7モイ溽jアZ4t:iH/W??K?趾サ*ラ萬亭ケ???゚Eソ」ァ?+A9?3W??-キa\rn-lvリoィ??5lウ?ヤdア?~C゚?/?s?/ヌaョヌ}攴wロUチヨ5ュl>テ^c?Tキ?敷ト>。メ?〃^$c}ュフウkエワZ=wャ?櫃メァユソ? ゚層」?鬲F\":?リォa?サ=クュ#サ%ホ\Z・チョ?-オ]1?7~潮??sユコ・ヨロ_Rチ?/ヌ}oェ\Zリ??ッ「ニ\rヘケ崟???Dケl?bレ?? YcY?#齲=@マルマソk,セロ\\ヌ?ヨソ?ャY鹽;wャKウ1ウ N、\n,ャ蜥稷ウヤォu\'リ觴k况~NGゥ風m゙ュ」Sルメ#?ナGッ?-?黙ケク]5ンUナュソ ?スメ $幀ナョノ?-wゥ嬾+?\'ァイ?ム??\0Hシ。v゚Zz摧taステ?=Jヘト5?~ォS゙?9?\0ス?「゚ム??Oァ~粐U\\?ツ?サ!?x???ヤ?棚%;?\0W?siq頃茸W]メ~゚c橄ィ?ケ残壙\Zツ?モcイア゙ヘロ??ァ?\0 j?{?6イチ???:Sェハ?゙3?x~??Zキqツ?%?? ニゥニfニ;Hun-2;?3w?)ct?ョカロ?x??ー?\0Snサ?K崕?ニ?\0チウ??,Aナハ脊O Gツナァコ?ロZ*kXK????#ャ暉セ滓11H鳧ー媾?5ラY苗nュ・ニヌス?.ロ足鬮ヨgゥ霍? ?\Zムイメ^粫?ヌ5?\rレ7サw??Mャ?クhc???.コri}9X?ァ毳.」yam剤?;=ロ^?點?\0ェラ?ulメ?.ナ7 l2\\6=OEホ;_eロh?ヨ?\0?F?チ帯ヘ、9セオU]kタ.ァヤカ」ス7゙1ルgヲ?+Cゥeカタモモ?ユ?\09n鷽メ賻ヘ???フ??? ヲフWキhリモVネ:?}.ヌpワ??\0チ?筰G%lA?GJiソ ヤ」モ・?ケチ?カ?O」?策佞イ?KV゚?棯ニヒ、Znサ+モヌツヌk[殯陽UヤX?アョsr22.?q*?騷>ァァ?奇Q?8ツム拘ル鶸%ル蒙レェ゚セ?^ラ=エZ釋F?MY??ン?拗モモ?)鮑sー4m>]?ラ\r?ルスフナァ?[??後F?ィ4tr?Yソュu;s?嫋 「親オTチイ??嬌?=?組、牒f??ユ?棚%)Yチホサ\n疇gOホネU誰血M?>?>ー3%セメ ウク?メ緘オワ? ニX?璋8オテPF???k??\r.mタ~?3?s テ$%ソ、?\0ヘFッッラ?1ッ?)リ?,}6リ?4ミ\\[?w?モシ~ムワユ覽?\0?丸?kワ8\"ヌ?饉?1コ?3V;G????ゥ+?錠゚チO。eGャ鍄釀k6??\'鏝[ォ/??\'ャ?a?6ァcfワ?8z亰サヤハーク?.ゥニャ*?゚Sラネョ??モ?\06シ?\0;?ヨ ヨコキe\Z)x!ユcオエエν閹>ニ?\0ニス??#oQHェ搦サ?+ォE聞、mナェaロdT??\0?ヲ{+?o埴K緒鷙アメIC)&メ、棚??ル\08BIM!\ZVersion compatibility info\0\0\0\0U\0\0\0\0\0\0\0A\0d\0o\0b\0e\0 \0P\0h\0o\0t\0o\0s\0h\0o\0p\0\0\0\0A\0d\0o\0b\0e\0 \0P\0h\0o\0t\0o\0s\0h\0o\0p\0 \06\0.\00\0\0\0\08BIM JPEG Quality\0\0\0\0\0\0\0\0\0?ロ\0C\0\n\n\n \n \Z%\Z# , #&\')*)-0-(0%()(?ロ\0C\n\n\n\n(\Z\Z((((((((((((((((((((((((((((((((((((((((((((((((((?タ\0\0x\0u\0?ト\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\08\0\0\0\0\0\0!1AQ\"aq?2贈ア#BRbムr$3チ盍?ト\0\Z\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\00\0\0\0\0\0\0\0!1\"AQ2aBアムq■チ碵#R??レ\0 \0\0?\0?\0\0P@\0s?7浮ニ護|馬???・sgツルk・ カナヨCヒZ姉カ?ウ_gケラPc?゚P」ュKムノ~%?B,?チケ?%-62r?」胖、zL凶ae鰯9I舵Bャ4Egqqtム\'\Z?\n\0(\0??\n\0(\0?・+?m監スモ? !Oa?->厭Y\n蜥コー?tPa?9?OフラAF+す9ヨ? 厶。控t??>エラ?\n?|?みル篦A」=マ(<フwウ?VMウノマHコヤ{9則1? キ\'}?ヲXR\\イ7?9 v?チハc6XY?ル゚ラ。Jo4?\0?*\\咏{\"シイ介ク~Fサ?6ホ5 窖7?\'ヲ源ヌヌリ{2ケcx、h薈GSヲV\Z ?Xレqtニ8T\0P@\0\0Pカデ& テyW[KァP[袢\\・?8ォ\n」冨宗・?&カ9Q]職c?}シ?骭sv>^T\'\'?!、?1キ?wK+蠏詢C1e?\'ハウK\'?楓%?ネ???)夜繩?レ\r\0ロ」Drニ~=欺八1ゥ~モKsqk!リa4\'G舫躬B榕「クキ\Z?\"rフtャOQ?吊租qak遵?/\ZRフ6_?ネ>エロ??ョ\\オG、bセメ0i廳ォォDciイ愕?\0i?\0!襌Uコス.?kア!橡ナ倆pヘ@\0\0ヌテヨ?「窰?シサ??ワcオ &銚j??;鰍蝣iヤルセロ?*=)蜩消」eナ??..?? P?ノ??o・7?WB?c>S吟??Fミン\\iBコ丞?\0ネ??v?フフr?5,モ%?m停Cッ?シ醂(\'@?ォ・襲坪?3ヒサ*s?フ|エ)ノmvセ2/?髣?B+岻ナ鱠オモ,Χ*VAツ?9F・?\07V燻鬢 d磊Oyサオ?Hタ?7ヨス?td濫績明L」\Zァ$hタC?? >オメーノ%tv肆?Y/mニフ艀?。}\r??)苴j?\0bヲ?%?0メツ,ケ莓Rハニ\'フ@ル\'ッN柆 cI?\'ヒリf琲ウ7y(ュヲ',0.5808563,'q',5,7,'1942-01-20 10:45:14.0'), +(1979,'xwv',' uses the Licensed Work with a total of less than three\n server instances for any purpose.\n\nChange Date: 2024-06-02\n\nChange License: Version 2 or later of the GNU General Public License as\n published by the Free Software Foundation.\n\nFor information about alternative licensing arrangements for the Software,\nplease visit: https://mariadb.com/products/mariadb-enterprise\n\nNotice\n\nThe Business Source License (this document, or the 窶廰icense窶?) is not an Open\nSource license. However, the Licensed Work will eventually be made available\nunder an Open Source License, as stated in this License.\n\nFor more information on the use of the Business Source License for MariaDB\nproducts, please visit the MariaDB Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-mariadb.\n\nFor more information on the use of the Business Source License generally,\nplease visit the Adopting and Developing Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-adopting.\n\n-----------------------------------------------------------------------------\n\nBusiness Source License 1.1\n\nTerms\n\nThe Licensor hereby grants you the right to copy, modify, create derivative\nworks, redistribute, and make non-production use of the Licensed Work. The\nLicensor may make an Additional Use Grant, above, permitting limited\nproduction use.\n\nEffective on the Change Date, or the fourth anniversary of the first publicly\navailable distribution of a specific version of the Licensed Work under this\nLicense, whichever comes first, the Licensor hereby grants you rights under\nthe terms of the Change License, and the rights granted in the paragraph\nabove terminate.\n\nIf your use of the Licensed Work does not comply with the requirements\ncurrently in effect as described in this License, you must purchase a\ncommercial license from the Licensor, its affiliated entities, or authorized\nresellers, or you must refrain from using the Licensed Work.\n\nAll copies of the original and modified Licensed Work, and derivative works\nof the Licensed Work, are subject to this License. This License applies\nseparately for each version of the Licensed Work and the Change Date may vary\nfor each version of the Licensed Work released by Licensor.\n\nYou must conspicuously display this License on each original or modified copy\nof the Licensed Work. If you receive the Licensed Work in original or\nmodified form from a third party, the terms and conditions set forth in this\nLicense apply to your use of that work.\n\nAny use of the Licensed Work in violation of this License will automatically\nterminate your rights under this License for the current and all other\nversions of the Licensed Work.\n\nThis License does not grant you any right in any trademark or logo of\nLicensor or its affiliates (provged that you may use a trademark or logo of\nLicensor as expressly required by this License).\n\nTO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVgED ON\nAN 窶廣S IS窶? BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\nEXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\nTITLE.\n\nMariaDB hereby grants you permission to use this License窶冱 text to license\nyour works, and to refer to it using the trademark 窶廝usiness Source License窶?,\nas long as you comply with the Covenants of Licensor below.\n\nCovenants of Licensor\n\nIn consgeration of the right to use this License窶冱 text and the 窶廝usiness\nSource License窶? name and trademark, Licensor covenants to MariaDB, and to all\nother recipients of the licensed work to be provged by Licensor:\n\n1. To specify as the Change License the GPL Version 2.0 or any later version,\n or a license that is compatible with GPL Version 2.0 or a later version,\n where 窶彡ompatible窶? means that software provged under the Change License can\n be included in a program with software provged under GPL Version 2.0 or a\n later version. Licensor may specify additional Change Licenses without\n limitation.\n\n2. To either: (a) specify an additional grant of rights to use that does not\n impose any additional restriction on the right granted in this License, as\n the Additional Use Grant; or (b) insert the text 窶廸one窶?.\n\n3. To specify a Change Date.\n\n4. Not to modify this License in any other way.\nLicense text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved.\n窶廝usiness Source License窶? is a trademark of MariaDB Corporation Ab.\n\nParameters\n\nLicensor: MariaDB Corporation Ab\nLicensed Work: MariaDB MaxScale (TM) v.2.3.20\n The Licensed Work is (c) 2020 MariaDB Corporation Ab\nAdditional Use Grant: You may use the Licensed Work when your application\n uses the Licensed Work with a total of less than three\n server instances for any purpose.\n\nChange Date: 2024-06-02\n\nChange License: Version 2 or later of the GNU General Public License as\n published by the Free Software Foundation.\n\nFor information about alternative licensing arrangements for the Software,\nplease visit: https://mariadb.com/products/mariadb-enterprise\n\nNotice\n\nThe Business Source License (this document, or the 窶廰icense窶?) is not an Open\nSource license. However, the Licensed Work will eventually be made available\nunder an Open Source License, as stated in this License.\n\nFor more information on the use of the Business Source License for MariaDB\nproducts, please visit the MariaDB Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-mariadb.\n\nFor more information on the use of the Business Source License generally,\nplease visit the Adopting and Developing Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-adopting.\n\n-----------------------------------------------------------------------------\n\nBusiness Source License 1.1\n\nTerms\n\nThe Licensor hereby grants you the right to copy, modify, create derivative\nworks, redistribute, and make non-production use of the Licensed Work. The\nLicensor may make an Additional Use Grant, above, permitting limited\nproduction use.\n\nEffective on the Change Date, or the fourth anniversary of the first publicly\navailable distribution of a specific version of the Licensed Work under this\nLicense, whichever comes first, the Licensor hereby grants you rights under\nthe terms of the Change License, and the rights granted in the paragraph\nabove terminate.\n\nIf your use of the Licensed Work does not comply with the requirements\ncurrently in effect as described in this License, you must purchase a\ncommercial license from the Licensor, its affiliated entities, or authorized\nresellers, or you must refrain from using the Licensed Work.\n\nAll copies of the original and modified Licensed Work, and derivative works\nof the Licensed Work, are subject to this License. This License applies\nseparately for each version of the Licensed Work and the Change Date may vary\nfor each version of the Licensed Work released by Licensor.\n\nYou must conspicuously display this License on each original or modified copy\nof the Licensed Work. If you receive the Licensed Work in original or\nmodified form from a third party, the terms and conditions set forth in this\nLicense apply to your use of that work.\n\nAny use of the Licensed Work in violation of this License will automatically\nterminate your rights under this License for the current and all other\nversions of the Licensed Work.\n\nThis License does not grant you any right in any trademark or logo of\nLicensor or its affiliates (provged that you may use a trademark or logo of\nLicensor as expressly required by this License).\n\nTO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVgED ON\nAN 窶廣S IS窶? BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\nEXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\nTITLE.\n\nMariaDB hereby grants you permission to use this License窶冱 text to license\nyour works, and to refer to it using the trademark 窶廝usiness Source License窶?,\nas long as you comply with the Covenants of Licensor below.\n\nCovenants of Licensor\n\nIn consgeration of the right to use this License窶冱 text and the 窶廝usiness\nSource License窶? name and trademark, Licensor covenants to MariaDB, and to all\nother recipients of the licensed work to be provged by Licensor:\n\n1. To specify as the Change License the GPL Version 2.0 or any later version,\n or a license that is compatible with GPL Version 2.0 or a later version,\n where 窶彡ompatible窶? means that software provged under the Change License can\n be included in a program with software provged under GPL Version 2.0 or a\n later version. Licensor may specify additional Change Licenses without\n limitation.\n\n2. To either: (a) specify an additional grant of rights to use that does not\n impose any additional restriction on the right granted in this License, as\n the Additional Use Grant; or (b) insert the text 窶廸one窶?.\n\n3. To specify a Change Date.\n\n4. Not to modify this License in any other way.\nLicense text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved.\n窶廝usiness Source License窶? is a trademark of MariaDB Corporation Ab.\n\nParameters\n\nLicensor: MariaDB Corporation Ab\nLicensed Work: MariaDB MaxScale (TM) v.2.3.20\n The Licensed Work is (c) 2020 MariaDB Corporation Ab\nAdditional Use Grant: You may use the Licensed Work when your application\n uses the Licensed Work with a total of less than three\n server instances for any purpose.\n\nChange Date: 2024-06-02\n\nChange License: Version 2 or later of the GNU General Public License as\n published by the Free Software Foundation.\n\nFor information about alternative licensing arrangements for the Software,\nplease visit: https://mariadb.com/products/mariadb-enterprise\n\nNotice\n\nThe Business Source License (this document, or the 窶廰icense窶?) is not an Open\nSource license. However, the Licensed Work will eventually be made available\nunder an Open Source License, as stated in this License.\n\nFor more information on the use of the Business Source License for MariaDB\nproducts, please visit the MariaDB Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-mariadb.\n\nFor more information on the use of the Business Source License generally,\nplease visit the Adopting and Developing Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-adopting.\n\n-----------------------------------------------------------------------------\n\nBusiness Source License 1.1\n\nTerms\n\nThe Licensor hereby grants you the right to copy, modify, create derivative\nworks, redistribute, and make non-production use of the Licensed Work. The\nLicensor may make an Additional Use Grant, above, permitting limited\nproduction use.\n\nEffective on the Change Date, or the fourth anniversary of the first publicly\navailable distribution of a specific version of the Licensed Work under this\nLicense, whichever comes first, the Licensor hereby grants you rights under\nthe terms of the Change License, and the rights granted in the paragraph\nabove terminate.\n\nIf your use of the Licensed Work does not comply with the requirements\ncurrently in effect as described in this License, you must purchase a\ncommercial license from the Licensor, its affiliated entities, or authorized\nresellers, or you must refrain from using the Licensed Work.\n\nAll copies of the original and modified Licensed Work, and derivative works\nof the Licensed Work, are subject to this License. This License applies\nseparately for each version of the Licensed Work and the Change Date may vary\nfor each version of the Licensed Work released by Licensor.\n\nYou must conspicuously display this License on each original or modified copy\nof the Licensed Work. If you receive the Licensed Work in original or\nmodified form from a third party, the terms and conditions set forth in this\nLicense apply to your use of that work.\n\nAny use of the Licensed Work in violation of this License will automatically\nterminate your rights under this License for the current and all other\nversions of the Licensed Work.\n\nThis License does not grant you any right in any trademark or logo of\nLicensor or its affiliates (provged that you may use a trademark or logo of\nLicensor as expressly required by this License).\n\nTO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVgED ON\nAN 窶廣S IS窶? BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\nEXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\nTITLE.\n\nMariaDB hereby grants you permission to use this License窶冱 text to license\nyour works, and to refer to it using the trademark 窶廝usiness Source License窶?,\nas long as you comply with the Covenants of Licensor below.\n\nCovenants of Licensor\n\nIn consgeration of the right to use this License窶冱 text and the 窶廝usiness\nSource License窶? name and trademark, Licensor covenants to MariaDB, and to all\nother recipients of the licensed work to be provged by Licensor:\n\n1. To specify as the Change License the GPL Version 2.0 or any later version,\n or a license that is compatible with GPL Version 2.0 or a later version,\n where 窶彡ompatible窶? means that software provged under the Change License can\n be included in a program with software provged under GPL Version 2.0 or a\n later version. Licensor may specify additional Change Licenses without\n limitation.\n\n2. To either: (a) specify an additional grant of rights to use that does not\n impose any additional restriction on the right granted in this License, as\n the Additional Use Grant; or (b) insert the text 窶廸one窶?.\n\n3. To specify a Change Date.\n\n4. Not to modify this License in any other way.\nLicense text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved.\n窶廝usiness Source License窶? is a trademark of MariaDB Corporation Ab.\n\nParameters\n\nLicensor: MariaDB Corporation Ab\nLicensed Work: MariaDB MaxScale (TM) v.2.3.20\n The Licensed Work is (c) 2020 MariaDB Corporation Ab\nAdditional Use Grant: You may use the Licensed Work when your application\n uses the Licensed Work with a total of less than three\n server instances for any purpose.\n\nChange Date: 2024-06-02\n\nChange License: Version 2 or later of the GNU General Public License as\n published by the Free Software Foundation.\n\nFor information about alternative licensing arrangements for the Software,\nplease visit: https://mariadb.com/products/mariadb-enterprise\n\nNotice\n\nThe Business Source License (this document, or the 窶廰icense窶?) is not an Open\nSource license. However, the Licensed Work will eventually be made available\nunder an Open Source License, as stated in this License.\n\nFor more information on the use of the Business Source License for MariaDB\nproducts, please visit the MariaDB Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-mariadb.\n\nFor more information on the use of the Business Source License generally,\nplease visit the Adopting and Developing Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-adopting.\n\n-----------------------------------------------------------------------------\n\nBusiness Source License 1.1\n\nTerms\n\nThe Licensor hereby grants you the right to copy, modify, create derivative\nworks, redistribute, and make non-production use of the Licensed Work. The\nLicensor may make an Additional Use Grant, above, permitting limited\nproduction use.\n\nEffective on the Change Date, or the fourth anniversary of the first publicly\navailable distribution of a specific version of the Licensed Work under this\nLicense, whichever comes first, the Licensor hereby grants you rights under\nthe terms of the Change License, and the rights granted in the paragraph\nabove terminate.\n\nIf your use of the Licensed Work does not comply with the requirements\ncurrently in effect as described in this License, you must purchase a\ncommercial license from the Licensor, its affiliated entities, or authorized\nresellers, or you must refrain from using the Licensed Work.\n\nAll copies of the original and modified Licensed Work, and derivative works\nof the Licensed Work, are subject to this License. This License applies\nseparately for each version of the Licensed Work and the Change Date may vary\nfor each version of the Licensed Work released by Licensor.\n\nYou must conspicuously display this License on each original or modified copy\nof the Licensed Work. If you receive the Licensed Work in original or\nmodified form from a third party, the terms and conditions set forth in this\nLicense apply to your use of that work.\n\nAny use of the Licensed Work in violation of this License will automatically\nterminate your rights under this License for the current and all other\nversions of the Licensed Work.\n\nThis License does not grant you any right in any trademark or logo of\nLicensor or its affiliates (provged that you may use a trademark or logo of\nLicensor as expressly required by this License).\n\nTO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVgED ON\nAN 窶廣S IS窶? BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\nEXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\nTITLE.\n\nMariaDB hereby grants you permission to use this License窶冱 text to license\nyour works, and to refer to it using the trademark 窶廝usiness Source License窶?,\nas long as you comply with the Covenants of Licensor below.\n\nCovenants of Licensor\n\nIn consgeration of the right to use this License窶冱 text and the 窶廝usiness\nSource License窶? name and trademark, Licensor covenants to MariaDB, and to all\nother recipients of the licensed work to be provged by Licensor:\n\n1. To specify as the Change License the GPL Version 2.0 or any later version,\n or a license that is compatible with GPL Version 2.0 or a later version,\n where 窶彡ompatible窶? means that software provged under the Change License can\n be included in a program with software provged under GPL Version 2.0 or a\n later version. Licensor may specify additional Change Licenses without\n limitation.\n\n2. To either: (a) specify an additional grant of rights to use that does not\n impose any additional restriction on the right granted in this License, as\n the Additional Use Grant; or (b) insert the text 窶廸one窶?.\n\n3. To specify a Change Date.\n\n4. Not to modify this License in any other way.\nLicense text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved.\n窶廝usiness Source License窶? is a trademark of MariaDB Corporation Ab.\n\nParameters\n\nLicensor: MariaDB Corporation Ab\nLicensed Work: MariaDB MaxScale (TM) v.2.3.20\n The Licensed Work is (c) 2020 MariaDB Corporation Ab\nAdditional Use Grant: You may use the Licensed Work when your application\n uses the Licensed Work with a total of less than three\n server instances for any purpose.\n\nChange Date: 2024-06-02\n\nChange License: Version 2 or later of the GNU General Public License as\n published by the Free Software Foundation.\n\nFor information about alternative licensing arrangements for the Software,\nplease visit: https://mariadb.com/products/mariadb-enterprise\n\nNotice\n\nThe Business Source License (this document, or the 窶廰icense窶?) is not an Open\nSource license. However, the Licensed Work will eventually be made available\nunder an Open Source License, as stated in this License.\n\nFor more information on the use of the Business Source License for MariaDB\nproducts, please visit the MariaDB Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-mariadb.\n\nFor more information on the use of the Business Source License generally,\nplease visit the Adopting and Developing Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-adopting.\n\n-----------------------------------------------------------------------------\n\nBusiness Source License 1.1\n\nTerms\n\nThe Licensor hereby grants you the right to copy, modify, create derivative\nworks, redistribute, and make non-production use of the Licensed Work. The\nLicensor may make an Additional Use Grant, above, permitting limited\nproduction use.\n\nEffective on the Change Date, or the fourth anniversary of the first publicly\navailable distribution of a specific version of the Licensed Work under this\nLicense, whichever comes first, the Licensor hereby grants you rights under\nthe terms of the Change License, and the rights granted in the paragraph\nabove terminate.\n\nIf your use of the Licensed Work does not comply with the requirements\ncurrently in effect as described in this License, you must purchase a\ncommercial license from the Licensor, its affiliated entities, or authorized\nresellers, or you must refrain from using the Licensed Work.\n\nAll copies of the original and modified Licensed Work, and derivative works\nof the Licensed Work, are subject to this License. This License applies\nseparately for each version of the Licensed Work and the Change Date may vary\nfor each version of the Licensed Work released by Licensor.\n\nYou must conspicuously display this License on each original or modified copy\nof the Licensed Work. If you receive the Licensed Work in original or\nmodified form from a third party, the terms and conditions set forth in this\nLicense apply to your use of that work.\n\nAny use of the Licensed Work in violation of this License will automatically\nterminate your rights under this License for the current and all other\nversions of the Licensed Work.\n\nThis License does not grant you any right in any trademark or logo of\nLicensor or its affiliates (provged that you may use a trademark or logo of\nLicensor as expressly required by this License).\n\nTO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVgED ON\nAN 窶廣S IS窶? BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\nEXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\nTITLE.\n\nMariaDB hereby grants you permission to use this License窶冱 text to license\nyour works, and to refer to it using the trademark 窶廝usiness Source License窶?,\nas long as you comply with the Covenants of Licensor below.\n\nCovenants of Licensor\n\nIn consgeration of the right to use this License窶冱 text and the 窶廝usiness\nSource License窶? name and trademark, Licensor covenants to MariaDB, and to all\nother recipients of the licensed work to be provged by Licensor:\n\n1. To specify as the Change License the GPL Version 2.0 or any later version,\n or a license that is compatible with GPL Version 2.0 or a later version,\n where 窶彡ompatible窶? means that software provged under the Change License can\n be included in a program with software provged under GPL Version 2.0 or a\n later version. Licensor may specify additional Change Licenses without\n limitation.\n\n2. To either: (a) specify an additional grant of rights to use that does not\n impose any additional restriction on the right granted in this License, as\n the Additional Use Grant; or (b) insert the text 窶廸one窶?.\n\n3. To specify a Change Date.\n\n4. Not to modify this License in any other way.\nLicense text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved.\n窶廝usiness Source License窶? is a trademark of MariaDB Corporation Ab.\n\nParameters\n\nLicensor: MariaDB Corporation Ab\nLicensed Work: MariaDB MaxScale (TM) v.2.3.20\n The Licensed Work is (c) 2020 MariaDB Corporation Ab\nAdditional Use Grant: You may use the Licensed Work when your application\n uses the Licensed Work with a total of less than three\n server instances for any purpose.\n\nChange Date: 2024-06-02\n\nChange License: Version 2 or later of the GNU General Public License as\n published by the Free Software Foundation.\n\nFor information about alternative licensing arrangements for the Software,\nplease visit: https://mariadb.com/products/mariadb-enterprise\n\nNotice\n\nThe Business Source License (this document, or the 窶廰icense窶?) is not an Open\nSource license. However, the Licensed Work will eventually be made available\nunder an Open Source License, as stated in this License.\n\nFor more information on the use of the Business Source License for MariaDB\nproducts, please visit the MariaDB Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-mariadb.\n\nFor more information on the use of the Business Source License generally,\nplease visit the Adopting and Developing Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-adopting.\n\n-----------------------------------------------------------------------------\n\nBusiness Source License 1.1\n\nTerms\n\nThe Licensor hereby grants you the right to copy, modify, create derivative\nworks, redistribute, and make non-production use of the Licensed Work. The\nLicensor may make an Additional Use Grant, above, permitting limited\nproduction use.\n\nEffective on the Change Date, or the fourth anniversary of the first publicly\navailable distribution of a specific version of the Licensed Work under this\nLicense, whichever comes first, the Licensor hereby grants you rights under\nthe terms of the Change License, and the rights granted in the paragraph\nabove terminate.\n\nIf your use of the Licensed Work does not comply with the requirements\ncurrently in effect as described in this License, you must purchase a\ncommercial license from the Licensor, its affiliated entities, or authorized\nresellers, or you must refrain from using the Licensed Work.\n\nAll copies of the original and modified Licensed Work, and derivative works\nof the Licensed Work, are subject to this License. This License applies\nseparately for each version of the Licensed Work and the Change Date may vary\nfor each version of the Licensed Work released by Licensor.\n\nYou must conspicuously display this License on each original or modified copy\nof the Licensed Work. If you receive the Licensed Work in original or\nmodified form from a third party, the terms and conditions set forth in this\nLicense apply to your use of that work.\n\nAny use of the Licensed Work in violation of this License will automatically\nterminate your rights under this License for the current and all other\nversions of the Licensed Work.\n\nThis License does not grant you any right in any trademark or logo of\nLicensor or its affiliates (provged that you may use a trademark or logo of\nLicensor as expressly required by this License).\n\nTO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVgED ON\nAN 窶廣S IS窶? BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\nEXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\nTITLE.\n\nMariaDB hereby grants you permission to use this License窶冱 text to license\nyour works, and to refer to it using the trademark 窶廝usiness Source License窶?,\nas long as you comply with the Covenants of Licensor below.\n\nCovenants of Licensor\n\nIn consgeration of the right to use this License窶冱 text and the 窶廝usiness\nSource License窶? name and trademark, Licensor covenants to MariaDB, and to all\nother recipients of the licensed work to be provged by Licensor:\n\n1. To specify as the Change License the GPL Version 2.0 or any later version,\n or a license that is compatible with GPL Version 2.0 or a later version,\n where 窶彡ompatible窶? means that software provged under the Change License can\n be included in a program with software provged under GPL Version 2.0 or a\n later version. Licensor may specify additional Change Licenses without\n limitation.\n\n2. To either: (a) specify an additional grant of rights to use that does not\n impose any additional restriction on the right granted in this License, as\n the Additional Use Grant; or (b) insert the text 窶廸one窶?.\n\n3. To specify a Change Date.\n\n4. Not to modify this License in any other way.\nLicense text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved.\n窶廝usiness Source License窶? is a trademark of MariaDB Corporation Ab.\n\nParameters\n\nLicensor: MariaDB Corporation Ab\nLicensed Work: MariaDB MaxScale (TM) v.2.3.20\n The Licensed Work is (c) 2020 MariaDB Corporation Ab\nAdditional Use Grant: You may use the Licensed Work when your application\n uses the Licensed Work with a total of less than three\n server instances for any purpose.\n\nChange Date: 2024-06-02\n\nChange License: Version 2 or later of the GNU General Public License as\n published by the Free Software Foundation.\n\nFor information about alternative licensing arrangements for the Software,\nplease visit: https://mariadb.com/products/mariadb-enterprise\n\nNotice\n\nThe Business Source License (this document, or the 窶廰icense窶?) is not an Open\nSource license. However, the Licensed Work will eventually be made available\nunder an Open Source License, as stated in this License.\n\nFor more information on the use of the Business Source License for MariaDB\nproducts, please visit the MariaDB Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-mariadb.\n\nFor more information on the use of the Business Source License generally,\nplease visit the Adopting and Developing Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-adopting.\n\n-----------------------------------------------------------------------------\n\nBusiness Source License 1.1\n\nTerms\n\nThe Licensor hereby grants you the right to copy, modify, create derivative\nworks, redistribute, and make non-production use of the Licensed Work. The\nLicensor may make an Additional Use Grant, above, permitting limited\nproduction use.\n\nEffective on the Change Date, or the fourth anniversary of the first publicly\navailable distribution of a specific version of the Licensed Work under this\nLicense, whichever comes first, the Licensor hereby grants you rights under\nthe terms of the Change License, and the rights granted in the paragraph\nabove terminate.\n\nIf your use of the Licensed Work does not comply with the requirements\ncurrently in effect as described in this License, you must purchase a\ncommercial license from the Licensor, its affiliated entities, or authorized\nresellers, or you must refrain from using the Licensed Work.\n\nAll copies of the original and modified Licensed Work, and derivative works\nof the Licensed Work, are subject to this License. This License applies\nseparately for each version of the Licensed Work and the Change Date may vary\nfor each version of the Licensed Work released by Licensor.\n\nYou must conspicuously display this License on each original or modified copy\nof the Licensed Work. If you receive the Licensed Work in original or\nmodified form from a third party, the terms and conditions set forth in this\nLicense apply to your use of that work.\n\nAny use of the Licensed Work in violation of this License will automatically\nterminate your rights under this License for the current and all other\nversions of the Licensed Work.\n\nThis License does not grant you any right in any trademark or logo of\nLicensor or its affiliates (provged that you may use a trademark or logo of\nLicensor as expressly required by this License).\n\nTO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVgED ON\nAN 窶廣S IS窶? BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\nEXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\nTITLE.\n\nMariaDB hereby grants you permission to use this License窶冱 text to license\nyour works, and to refer to it using the trademark 窶廝usiness Source License窶?,\nas long as you comply with the Covenants of Licensor below.\n\nCovenants of Licensor\n\nIn consgeration of the right to use this License窶冱 text and the 窶廝usiness\nSource License窶? name and trademark, Licensor covenants to MariaDB, and to all\nother recipients of the licensed work to be provged by Licensor:\n\n1. To specify as the Change License the GPL Version 2.0 or any later version,\n or a license that is compatible with GPL Version 2.0 or a later version,\n where 窶彡ompatible窶? means that software provged under the Change License can\n be included in a program with software provged under GPL Version 2.0 or a\n later version. Licensor may specify additional Change Licenses without\n limitation.\n\n2. To either: (a) specify an additional grant of rights to use that does not\n impose any additional restriction on the right granted in this License, as\n the Additional Use Grant; or (b) insert the text 窶廸one窶?.\n\n3. To specify a Change Date.\n\n4. Not to modify this License in any other way.\nLicense text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved.\n窶廝usiness Source License窶? is a trademark of MariaDB Corporation Ab.\n\nParameters\n\nLicensor: MariaDB Corporation Ab\nLicensed Work: MariaDB MaxScale (TM) v.2.3.20\n The Licensed Work is (c) 2020 MariaDB Corporation Ab\nAdditional Use Grant: You may use the Licensed Work when your application\n uses the Licensed Work with a total of less than three\n server instances for any purpose.\n\nChange Date: 2024-06-02\n\nChange License: Version 2 or later of the GNU General Public License as\n published by the Free Software Foundation.\n\nFor information about alternative licensing arrangements for the Software,\nplease visit: https://mariadb.com/products/mariadb-enterprise\n\nNotice\n\nThe Business Source License (this document, or the 窶廰icense窶?) is not an Open\nSource license. However, the Licensed Work will eventually be made available\nunder an Open Source License, as stated in this License.\n\nFor more information on the use of the Business Source License for MariaDB\nproducts, please visit the MariaDB Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-mariadb.\n\nFor more information on the use of the Business Source License generally,\nplease visit the Adopting and Developing Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-adopting.\n\n-----------------------------------------------------------------------------\n\nBusiness Source License 1.1\n\nTerms\n\nThe Licensor hereby grants you the right to copy, modify, create derivative\nworks, redistribute, and make non-production use of the Licensed Work. The\nLicensor may make an Additional Use Grant, above, permitting limited\nproduction use.\n\nEffective on the Change Date, or the fourth anniversary of the first publicly\navailable distribution of a specific version of the Licensed Work under this\nLicense, whichever comes first, the Licensor hereby grants you rights under\nthe terms of the Change License, and the rights granted in the paragraph\nabove terminate.\n\nIf your use of the Licensed Work does not comply with the requirements\ncurrently in effect as described in this License, you must purchase a\ncommercial license from the Licensor, its affiliated entities, or authorized\nresellers, or you must refrain from using the Licensed Work.\n\nAll copies of the original and modified Licensed Work, and derivative works\nof the Licensed Work, are subject to this License. This License applies\nseparately for each version of the Licensed Work and the Change Date may vary\nfor each version of the Licensed Work released by Licensor.\n\nYou must conspicuously display this License on each original or modified copy\nof the Licensed Work. If you receive the Licensed Work in original or\nmodified form from a third party, the terms and conditions set forth in this\nLicense apply to your use of that work.\n\nAny use of the Licensed Work in violation of this License will automatically\nterminate your rights under this License for the current and all other\nversions of the Licensed Work.\n\nThis License does not grant you any right in any trademark or logo of\nLicensor or its affiliates (provged that you may use a trademark or logo of\nLicensor as expressly required by this License).\n\nTO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVgED ON\nAN 窶廣S IS窶? BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\nEXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\nTITLE.\n\nMariaDB hereby grants you permission to use this License窶冱 text to license\nyour works, and to refer to it using the trademark 窶廝usiness Source License窶?,\nas long as you comply with the Covenants of Licensor below.\n\nCovenants of Licensor\n\nIn consgeration of the right to use this License窶冱 text and the 窶廝usiness\nSource License窶? name and trademark, Licensor covenants to MariaDB, and to all\nother recipients of the licensed work to be provged by Licensor:\n\n1. To specify as the Change License the GPL Version 2.0 or any later version,\n or a license that is compatible with GPL Version 2.0 or a later version,\n where 窶彡ompatible窶? means that software provged under the Change License can\n be included in a program with software provged under GPL Version 2.0 or a\n later version. Licensor may specify additional Change Licenses without\n limitation.\n\n2. To either: (a) specify an additional grant of rights to use that does not\n impose any additional restriction on the right granted in this License, as\n the Additional Use Grant; or (b) insert the text 窶廸one窶?.\n\n3. To specify a Change Date.\n\n4. Not to modify this License in any other way.\nLicense text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved.\n窶廝usiness Source License窶? is a trademark of MariaDB Corporation Ab.\n\nParameters\n\nLicensor: MariaDB Corporation Ab\nLicensed Work: MariaDB MaxScale (TM) v.2.3.20\n The Licensed Work is (c) 2020 MariaDB Corporation Ab\nAdditional Use Grant: You may use the Licensed Work when your application\n uses the Licensed Work with a total of less than three\n server instances for any purpose.\n\nChange Date: 2024-06-02\n\nChange License: Version 2 or later of the GNU General Public License as\n published by the Free Software Foundation.\n\nFor information about alternative licensing arrangements for the Software,\nplease visit: https://mariadb.com/products/mariadb-enterprise\n\nNotice\n\nThe Business Source License (this document, or the 窶廰icense窶?) is not an Open\nSource license. However, the Licensed Work will eventually be made available\nunder an Open Source License, as stated in this License.\n\nFor more information on the use of the Business Source License for MariaDB\nproducts, please visit the MariaDB Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-mariadb.\n\nFor more information on the use of the Business Source License generally,\nplease visit the Adopting and Developing Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-adopting.\n\n-----------------------------------------------------------------------------\n\nBusiness Source License 1.1\n\nTerms\n\nThe Licensor hereby grants you the right to copy, modify, create derivative\nworks, redistribute, and make non-production use of the Licensed Work. The\nLicensor may make an Additional Use Grant, above, permitting limited\nproduction use.\n\nEffective on the Change Date, or the fourth anniversary of the first publicly\navailable distribution of a specific version of the Licensed Work under this\nLicense, whichever comes first, the Licensor hereby grants you rights under\nthe terms of the Change License, and the rights granted in the paragraph\nabove terminate.\n\nIf your use of the Licensed Work does not comply with the requirements\ncurrently in effect as described in this License, you must purchase a\ncommercial license from the Licensor, its affiliated entities, or authorized\nresellers, or you must refrain from using the Licensed Work.\n\nAll copies of the original and modified Licensed Work, and derivative works\nof the Licensed Work, are subject to this License. This License applies\nseparately for each version of the Licensed Work and the Change Date may vary\nfor each version of the Licensed Work released by Licensor.\n\nYou must conspicuously display this License on each original or modified copy\nof the Licensed Work. If you receive the Licensed Work in original or\nmodified form from a third party, the terms and conditions set forth in this\nLicense apply to your use of that work.\n\nAny use of the Licensed Work in violation of this License will automatically\nterminate your rights under this License for the current and all other\nversions of the Licensed Work.\n\nThis License does not grant you any right in any trademark or logo of\nLicensor or its affiliates (provged that you may use a trademark or logo of\nLicensor as expressly required by this License).\n\nTO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVgED ON\nAN 窶廣S IS窶? BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\nEXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\nMERCHA',0.9881897,'axwv',4,4,'1987-07-30 00:26:51.0'), +(1985,'hm','?丙ロ^Hヲ?w9Ljq、?ェョ&E1ヤ\'l」?エY;f・r埒1V家ヲ[m恩?UeV5;cyTョ#モ,6ォャeスアA?カ?ヲ&緋2固アUG足薗ン?ナwナs゙サbェ$ラ7#?.ムモカ5キ?ュTロ./オカ_\Zc?5レケ康?ヌ?5ワ螽ョヌhヌ@qU2\rh1タm?>慷窘d勢?C溝リcネ\0Wヒ|!T?;?#テ!゚ネvタォゥAQ散$ヤ冐?2ャlh ワ?コ??坎カヌ蜒ュ%ヲI?1???/U\rX}・??ユテンHメノサアゥ8ネ蘚? \"サm?ェウタ?,\Z?イ橿(1*?ネ?コebムタd}\'&壘y9ヲ エ?顕7ヌネ?\'?゚Y?ん\0而;Zi?P?pロI斜銷R処源-S??ヲZ43?}ル\\・a?ク|槞A魂ィヲ+k臺ャ隣r=Pシタ\'ァ??7????qモ?サfチキvO儕x?o4?<做ョスエ相ーヲt;ロ;?b鐙hマCL$スカ[」ヘ?-誤f$1ン>鏈\\%ヌ刀ッ鑽q「X?コЛーハ@?7PノタZn墾ニュqs\'5ヲハvヲ#ォYナfノy。ハd獣??ユ?\\\\Gm梶H+?\0(ンロ?ワzムZッ??Nqヨ6?uk:D?? 隙」隔=?\0牴V鍋ヒ %x&бワ\n゙?Iu ?=[?:\r<ニー小鮮Dn24ユュpvア$2゚N??ィ?ロ\0?\nwlEo゙ト之?]ワヌ城??5?壮se ム;KェP暦ソレ^ ット?ノ\rヨシ?g、?エeUサ??F@リ!G&7ヤ?キケ盲痩ハ?44ィタヤ,pkXワ,\\?萱エノ?:。咬#フ辰 頑UH?:???\Z噴ラ?リーcアcラ?Cニ(Aニ?$ヤ?V巓糎闘遏\"フタrィ??」+5エ?\0,Kィ@ラ+\"ェ??X?4sHZャ)鉛ヲ ?4Dァ?ヲ$cェsィュiN?U!メ?51?\n?。?4ュサKル-ワ2r佯アロ\Z^擘kン(アm?oイkソl菻CpJ???/GA駭?ソNt灘?gYa_?ケz゙?ワ<8\r\riセJ2」イキ拮:犢痕?\"濃簓VH梠荀}槨箕「H繰・p岳レ\nゥ,ィヒpヌpユ?磚\'AJ E蚰5}骼kvTイpV?\Z_Z5^lム嗹ヲ?\0k,?ヘ?$切3 南ラqA塚ー番s蝦ンノi t$zgKメメ?+sィヘ?ノP+セS?4oス寧kィト祓c鎬kノ?エ隈/@Ea?シャbV?\"}^゙BDNョ{ケ]IO?\'セ?愛笄? mLヲy「?ヌrシ楳_ォワエ繝P:W\nエ?\015?4.戛 ?リ菷ルU?9癜\'愆14Zt??7洪3?l>・=テ鉾;?yQ旺ヒ#:?心k=2込yh6ゥ\Z、ぼ6Hxラーョ面ュ7.Zw4F4h?\rZ腹\'??mキ假ョm恍\nサ???\0梏\"ニ、ラ%ワ?t?\0v?bカァ-Q??Wl\'鞍伊VV$??+迂ツオN?シ2Hkjfkwリエ\nイ?,x???pミュMX?\\J;yツ?$モTトlE@ロ.T?,.・@@ロ\r?4\'スs%タ?yリ ョj唾ュ\"ヌZrリサhヘ・゚「ンマ\Z?;ル,!カス?(?Kx?・?齣゚ワr常FE~?+H\rzリ$?#lBッzlリ[\n?。ノォk??-^?IツY。f妊6胙}リΥUヲ薩?-}?野\'7テSh#?*??g.W[トi唾ナP),Fンa=、艤F?-Uク?ヤm??喨ッェ?Jア?$\'哂E?;v??煖ゥ ?カ?\0\"r?ヌ$サメ3?NU「?#mヘT溏dネH「閣8ム?a\'サ?株\'Rロヨ??ND??J~イァアMウk孝笈ゥ?.S+ルOラ\\!mi?2?# _\rオMネ>鋩aK?\r?エノチ?$2,ハワ4tNw,ラ5欣5尠?ケ????\0\rwe?ヤツケ゚? 翡マ.?Y0f靈U?-係メイク4ロq磋??[$^XメV發iMハ4J+?Zヤ#コ?ヤp海?@?xsサ1?エモッL「B義H?+・L?7?kF\\?A6?F:?笳秩s?%Z???リ煖5X祖^?\Zァ\"品寢槌Ι゚≫コ?\nh|鯢ケ来=H?ク?v(?P|チ!?\0牾TM0ソ[*ヨツ %參\"=凾キ?._馼嘛?JゥロンM┬]?8サ\0?1V3ュ鐶レ赧V~G?\'K?鯖ッヲXュヨ?(}リ*8クサK ルケセ堤U6餞タ+S體?6?xW帙?5#\ZオQユG?-ラ?4qne???カvヒ?/リ??ヤ? u%遒Fロ?/S? #偬?_?\nリー?ワHハ忻ルS?[??/肩⌒タ痕蛬ォ*?b)??\0\Z狠k\"ルサーロ疇\"?ケチ窈コuニ?)キクB焼5?\nゥニZ}bjレタ v?Iァナ??\0タ襾M墻\rv-zサa?、43 (」?=エ!釶~G??\0\"ヨE???^Zオ傑9+フ¬「?7?\"@ュ%フ7ョ\Z_゙%ツ)1?ツ%_?/?ノ ヲ・1JrMマl瓢-I=T?ュTV」ー?lN、。゚クロ?? 。e(早dC?$rS???\0ホ?\'礒*ァ^」?=Uiリケ{dGWV ??-ク襠?W?WルFトu5?.?|?ワリu[楳CzQ?器ハ」症?ヌ.Iヨ?テラ????ニリXトヤ遮ヌ俤<椏??\0:Mァh-jモ碾Bァzナロ?焦? フ?G「YKァフョヨ?pヲ、裾ッ/?桀B8ッ\n釘[%>\\ユYョ!?3 . 茱コッ$??\0ルz儉ア? ┝=[ヒzュヌ?<ス4叩eシ?Q圉ァ・?ー?フラフ?c蹴剞ぅ?厩?ヒIシ玲H?オ-6jヌ%ラィア?ォ戚シソヨf\\,伏最イNイF=Rヲツ?#WIクラ????ュ助?ムf寂ng*ハ・+鵑ッ??>頤ロ?&ユ<ッゥ轆%弊0?\"?\0牒?>v。ヘ 3;ヘZヤ\"=錵キ縫z0?V゚焦?W -カソヤ5スEdjVi#Aミ・U?ロ繖\Zホァ\r蠑゙]e.m}7?ム。ォイ?]薺観E[穂b阜憬?\n灌\\ッ尻*?ヘ匕?\"?1?ヒ^vウ\ZVォ.慍?4\0RA?r?\0+奔T?z>?5?」)卆%Y;6ハワキマ=yラQ鬱ユdヤ.\0\r:ォ|?gァ?-テ?1?&?Z很 ス?キモ?/fKx雛砥?6e533ヒ)z民\"p熊9???7???「Fゥ\n?ャニ?| 済$?\0W%曚?-アモ$??0ゥgA,し粢」??\0ーlWCヨ?ヒロ??誂ォ?@ィ_?マル?\Z?$o仁?Cネゥ@(VェIチ塲コ鰓オ、業蘚ncイ詔膏\rツ儘ハ何レ潟戸S?>!幡榔ラC牧ャk?/N?アJミG|^?!V?G_。ア^&?(l}アB7K樛レ蘰シF?5ュU[?\'?l3ユシナ?ヲ殍シ\"Uリ??k?蜚EpMヲル>仏ルi? ィネ8ン1UEンツ/%i8?\0ニ\\%ユ/Eワ?Dトツサ ;m塩奐EB%*β^溟o?:ァ粍t?Yタ?\0\0?+\'r敲ル(鰄茱ヒ~vケ?旌ュ、j゚\\Rャ?ュ*?ラネツF?\0 ムENレ閼レュフ?9ュ\0?(&? フj?%ム#^wE搶フ恥shWヒ?aー=ニヒ;册%$?潴@C7菫?+ォ?門・E$;S?ュツ冊\\」?=R駭ッ$xj\"-E苡???壜ホKNdD_綜サN紊LーSォm 宴 cモ^゚ヘィ2?\"5燿\nQG?P6ヲ9 47ト徨ニkセリ1>ッ鏗?\'藥?マ\Zトア?「?,U!エ??,唯S?M8\08??7/ルタRz?\Zゥ?+Z杞P:wフフFユネ?ェ1トen\"ッM}ア?*?9?\'&゚)ロ゚5O\\H蛎・kF?蜩カル ?qN;eV「ケモ蜆ィX<1Tホ?2チ8・セァ|ェe慊ケZE4ス1ホiカ\"ニクェ?ハニ且凵ナWc?ホク穢Uフk?\\Uxoq゚q?予ォ?:系Urー*ィ9ォ?/エr需ウaWR屆I?/ラ ?xヘマヨ&桑 ヤtュ*n?$ュ vヲhカ#Y,キSp巌2A\'?ソフルZニ・ッ<ライ?ムb右\0\0qV?\0c?<ソァB?キ?\"XモrY≫?ネネネ???$w\rf秘??/\Z;゚ャ$メハ>%U#?ハ??ャ鏝\Z,?\'+ラqヒuツミトa?h?イ。S\\x驃?,ァ?\"??)??4ヘ&]Lネ#?ッ&\'ーィ\\$?E?;bヒ0y?ァ?スJトX\\スイク浴ァ%鑵6;稗袁NQ?罠?!ウ#TnH・wロロヌLa?Wィヲg4ハ&來p*?ミ爨ワ{? cテSヲVr7ハF \Z\nヨシサ?\0ォ科?ォミ?Q娘┯2?\"$E}驪??ヤョ\rメn豁ソ?クメク?FF?7ユod^岔IbトY椒ヌ%Zo做サr?0h蒟W4?piアハ$de粂、H?赱9拊E舘セЯェ導5?ュヘzLφv?2ラカ\nク? ?1ト\n^#v?G?kォサ!c!?*ッ0M;????Z+R\"ア服Wr况ソ賽)トラァ?xOd柩ラ袮/ZK??*、xaソ只綢? ?\'0凩DOu?オ殖ユ゚\Z2Gョ遺7i?ソ?ヘj?yスG\"f4Pv祕リ9?袱ァg/ラoモミ緒!ハ寢dヒz??ラ>ッテ彰$ュ?o?$コソ觀アォYヒ!oOヤ棟テムP坂_?ケトラ ywイs,?モSMラ?ャツEtォ・kニセ.スー{ゥ ?ミッP?pO$゚マ5ト?,フV疉Xナ>/オ杜U橡?=フ?<アJチWz售1?\r3ナウ?f?<敬F??-giラ-#ャA\"nJy際?狒/y「y%H lオ・Wキ?<綱昿ソ?テH?%衙>/レ??\0゙舎e:?\0惆|」#\":エ七?。?>ヘG?,ケ?ヨュ$モホh住)?Fol?-ケ}m[ユ?\'ツ?#F?ナ\Z?26詞ャ?i?9倬杙???5?ッ\0ノ?lどvォ2?*TZ蹉イ?;?/ョ梏梶Zネ$9&4フエサ[O-リイ「(P*トメソ札5??*<6@ュEWy棉U壥.\'jE%jオァ?>?\0J姪?ナ 「アネ ?o#コハDr]ソw??jUキ:迺?uェロ和FWZu\r?ノホW「Xナ,ムスレー?ミ?4ホ?/擽?\0+トカ?Y:?鯢(ヤF?訖?um、ヌ レ俄メ*ヌニ涎柬ヨ?ユ5 ヲ\'?3?j茵ヘ栲嵶ー-ォ\n\"枩Iネキヲa?9ンJオv$?ャ?(?猫゙マAメ4?ア∽?(甕}nc?$??\r?ヘm?ヒ関?Hミゥ*J?フ~o余オキエア,J?\0ra_出?規W樶U}NR??#Eシ}ユシン?・y洲堋、3IB ・??桟?ュC→Ko\nsZ\0VAJ*z.??$柆リSjd?キ\"?豢恤ル?Pセモァ[?ケf?\0S\0陬G尺Yオ メJ?サ庚+?ヒ<キ輌oメn 9Mョ??\0瞥?莖ォ 挿6*A\Zq2ルメッ?Tx?叩キ!A@ト?施g<ヤl、モ.・ウ幔ト?\Z?#LK゙、R夬栽\\ハx?FXナヒアィチミ\\?ヘfトX0#?#?=?sタ?qe?是J\Zテョ8??ミ筱ヤ@ャ曄慨ヲ\"F+oョ?*|pハ}8テ2*G? ォeォJ梁笄郁z窖セ[}?カ??:?\rRk y 鰯?ェuロ 繻キAモ?\n慨ル[f銖ホ$Alテl^゚畫OO ? ?2ョ?、3H?5F_*鈎M・・ヌ?1マ(ィ驤鄭ト?-N? ? 8??.暈箆(r?+\\Uコモヲ=c&3&ヤ}??\"掉?#nリェ?5?=rネ#zlrタ-ゝネフ1?燃?BケaL??;e。羣;竇?>.ケ+B切彗$蝮?頁-ィゥナL擲5;uチ?;ъcミク-Q?>?.オp-?c擧ハカ>PモヲKメp ?ッ??6??スw栗ト彫?Fミハチ?5&<珠zレノ.l畔。 霏nwチ z「゙Hgm繽逸]ィ?0ヘ\nQA\n?)Fロ霪ッ70 恠=イ?+4[Dュo?,ュ&}ィソ8ュゥHロp贖掴泝? 。E鞏DA&シ浄eW#?dミZテkQ-ツ~?n[ツ瑜)Z\\iレフPフBG*?,ァbソiソ?9a=ヌt惇毘ヒ?ホ偕ワQob+餘??9ッレOオ戦^セモ#}\n蝮-ョェス~]?+d゙?V奘?Qフ6_ン ?k引クー?\0+芳t?<レy?ョ?+?孛??\0ウ?1ュゥQ3ル2・ワ\nHPト? ?ホシー假l@<ヌナ)?ァq\"EァH?,6黶G?? 愉??、??>?Zw]そ???福Zケ朴Cフヌ岨nk?莪itクムtセ?\'y?VAコ承?ヒ眥E濁&コw%:婦)vゥホ8帙?uehオ孛耗繧Hネワ旙與?ナ?9%V・ォ。禮|,~ラ??^]建ュ?2駅x??衒KyS #?ニ?\rョWPhレォ\"?ヨL?疊2スサ廓籖ナ~ラ|菜jwnbネ\n?O?u端{f蔀Q\n)?ヲ?ッm据゚リヘ\n゚スワネM@?8ヤm$アシhョ[?oソ゚怒ォ?俑アツ?*O悔ネ??3サ?4u59?^ソャ=?E\"?\nzモセF% =メェ氤?>鬻?Sミ\nラq^ソ?m.bラK\'p、?9v3??琵Oケ5櫺}:@・x2モカEッeY%yxゥ$??{*ハLホ*ヘラ ヲキrョ邯og!Aトナ\n Sキ>?50sXHQ?|@jvョ遡?bテ??見&ク,(?4?1¢d?? ヌ8。ニ轄アTヨv?゚麭ソ?#?ルセヨ醇,SaC?(ェ? ノwB,u゚{ク荊ワ稷ンツォ?\0bN@j蘯彡Gケ>,q?ヒ1ー?ハ耘キネ?)ロ.Vm?ョ7ョ!\\、ウ(ョテ?案U?3S巻?リル\0Cカ>c/?LNB o慣ヒテ15ハ倆?[S班,敬_Pリ?\Zvニ霜亅|ゥ渇[陰J5+キ?$,pナZ#(ョ(Mw=q2kカE-イゥ\\ヲロ(!S=Xaシ壌)ホ&?zタiライBソb、ッ??ux鮮クォサンQリア{牘U?レ拯ツYM?ユ?K、ナIッ¬?゚31nスーヨ?qク?ニ箝ヤ厳゚ョ0\r?槨ォコtフZサT&リヨ持qU2?-N?。Mア乘\\o Y噪弃 ーサラャUゥチ&?6ハg]ォ?杢*エニ。フロ?1Wsヒッ?$E1ンゥ涯wヲn5驩Aヌ?5ロ.*F7粛チホ(X\Z畄?螻ヌト\Z秣??彦*、ハNa|~縹QO<ェ Sリ??Hオ\"?榲ャケaI?:etヒ腟P\ZWョ*ミハハ髮\\?ラ喉ハ?;モ\rキヘ\\?\0ィF\Z?犧ハタタ?U;獏ィユQ?Y樂ネ窒A鑛吊6モ彗カ\'蝨?メ?1sト?1留セtュH萬>タ?LS ?G3フョ?$ア}bユ8ト?)セ*眠J~ァ゚\"オ」7ェヤレケ[$ョ?)/?w8&郎>? 0.ヌ゚?ュ>ノ9ワJzd^?I(Kハ 7&「オノF2<食@M\Ze?)?n Aュ~倦yzm;?!\nォ*?9ナトニy\ZB)ネヨ?&メ?・IS?ラOァ.8ヘ1{I?スネァ{d_T?h3凵?\n5GA???,.疋ュタ?セ9?娶R& v?ハ?7L?GヒVW斥>?#M$@4格ー=i?ョF?j箴BK)\nkN-O??ヌ<牲cbァリ貂宅$g?j~y?\"yツヨ氓ィF?8%tサヌキ7k???}ャ゚\'?卩ヨ翻オ*?+?)=ノ貂ネ?,(ン城゙Uヤオ縊H\"オ#ソトケ#+}、゙\r3U\0 魏5ウヤn?tニ?ミ?ヲ\Zレy晢?婀」「1ォクッソ?9 0燭 ヤ??ニス@9 イメgサib?>f河z?q豈6$??- $6F4スb/ンシウ\0?・dュT熄)、授゙(Xz-ネS?桑営RェトヤW5ルF伏???ト@ヒG&(?;ュ0Qヤ?L3ユシュu、[ュヤフ月E8奎ツX蚯R@?y?ヒォ!ァフCト?ロqCヒョナ{rNノo?\n=???・!キ榔桷vテュoネ?ム?-QF??h?9\04W? )モゞ帚49Rレヒeu*ネhツ?&ャ@テマ?n昏テ? ND啗&イGot#|蠍キ嬬ソ$4?,sゥNユ^g?5・rゥBヒ1\'ゥi7*ヒJ盻m惶Cラ]a束?リック⊃GLョQ 、FIZ鈎2)?(ヤqヌ4鑑ョE+-\"U=paM?リ\\ F|0uエ?ヨ*?5崢フз ホ?:?2枢?T筑5C7}?ッAmoU羹~シ鐫1-S・0」Yミ」ケ?ヌニ{?款」Tu\0Eテテ鴒メi奴ア?#|ェリ\\ルワ4r-Xサ?Sg%ヌナ儔「)ャ?ソヌマ゙ケ0モ?モ?l%Pヲ:オヒGPユ#艇boカT\0メク抑?掏cョ*リソム?オe?sラRヲcモ79Gテj8?0ォ樂kア゚|keナ*ヒモlk-(kラ\Zァ,カ?8彬嶢?疑ケ@o?*u?ォ恆又ホヲクタ?i\0\rウe椽?亂櫚」畢リUトvヘ藍棺セWLセルTタュ?賚完?活ノ?A?桜ナス?R纒hz筱CヲP゚6X?U#倣恒ミ植?Lユ?鵐?4ト?ァcrD慌審E5\'?#】擺チトェ&粢ngg?シi?\05u?9W}セソ?<チモ??\0(<0%@\n\Z諫Uム寝?Y、タ(\0~P&ス6ハn囘P?\"クUム?レホxモト?H繞ムSp|2綯??+???゙?モカ 需!]筏紫ツソk8Sハ搦ユニ|jユ}・タ甥僂-:aユ?7t?蘊ノ?ル?\0∧?6?ョ。mロl撃Bgァ??フ。「z鮮ヤ9&?\n} ゚̄ Jュオ?%?\\|ラ? ??zvハノイノ喧?ロ瑠?2W?詔テヘ5[eu?q\'?9クカ忘、h?\ni?V\nム迺$h\\メ?\0ッアツy!;ス )<???$o,ヲV5,??ンヤュ |?$\Z^跫?@bニン?#糴潮ンロq?+\Z?ィ\n「?\n?8mォ」p「??(7P |ヌ|!P?.H? ?Z?・|\0?輿?HンゥL=?8VチDBャ瓣?ツNハァ・Mナ紀ミt?1啾・チユ航? ?z9=>Kメ?u迫 Cxtフオ?)メァレハ%糊?癒0Rラp\r;??\"筏]j:\Ztリ?$エ癖?k?\0oス?\nau璢?!ノ疫鬨ロ~ _ \'゙opス?#塞nVヘルウfナ\\7ヌ佇ニキy弔亂柩ルアWfヘ?vlルアWfヘ?vlルアWfヘ?_?トHF假Q?Utェ?蜥O\\オ・wナV貮ス;c1Uム??朝Z 参\\Rキ6)鱚ヲ(k6lリォウfヘ棺6lリォ?ヤ??X4髟?\\\\楮ワルアWfヘ?M?$ケ?稔hカ?タpワシモ*k?ユヘr4nユK6lル%DCh?徼カ/レチWツワo蓉ィ下bゥi4ハヒcS\\ャUルゥ\\リスーィqU??笊\\ネWョ\0Unlルーォウfヘ棺6lリォアハワqケアUF伐ヲ\'?6*?ウbョヘモ53bュ誰VlリォアxQ[ョ!?袈*?\\ナ歌1U?ヲTq?1熙dテ?Bi?翆粗??6=?X\n,dチヌ?62\0。ョ?x\0?5J篤Wリ鶴?。?カFdrh:Paヒムp?0メ=74?モシサョG、yv?ロ?\0??「ュテ??^\r4s n\'?z沢?{sヲ?柵?3?5ワハ??ヲュ#??\0^o?9穀カスハ?#?\0イセ・;?(ナ黝アQ,??\0ケ陜:?;リD托P+??\0+?猴\ni?マp?4コ食cAコッ??\0?ヤホサ・モ-謫ゥ・P??滲残フルカリ?ケ閾s!ォャア?)ー゚?? <モf‘オォ9キ忿ノェア?\"2ォ2?聯??\0c?/,゙?-1ァ\0I??)Ok?;\rhTP65?Mr。4?1レサ??\02IZ!。レ?Wアケ\']?Q僊?j畋゚?牴モNApツ\r但?ツmNム狃q^PH??7ヌノユ?$zR\n\ZSj?乾%恕?チネシレヒS?Yト」殤N?\0??+侑ク? ツY。Ю)j?H)???\0ナX゚?#俾:瞥1ン丼Aリ4?\0??釼[?1枩N(aラ???\0渊ホ側Zス? メ?湯ソーカオクカイ,ュ P?腮=do蜴_ン|9Eiタ7\0攷ア?イFク?/@H?20 vP?チ;Z? ケxゥァ開ソ?蜉ェャ懊~ッ、7レc?-j}駭?ス+ソB?$ク\n゙鴈%?!」\0@<蓑タ?\0キ?2bD?_aRMLj?ハ殍:?-Hjw V,ュ _???イ?マ直?K<:フ直ゥナ?zヘ9ゥ惓#ヌ$QCノK去Tレ忸?変#() 孵?捧穿ヘ??ノ=シm\Zトオ%ヒ??\0\n叮4「?テ(Q *オJn(>テォ柯ソケ桐6ォo゚ンニキJOニ?????\0,mヘロ?s蟇ヘ\nリリj.築悁I5CW竰葺?QノーKス濶ェイ゙ワU置HチDムヌォ#|_?8?;??サケォ1xッUEシkユ\\*?\0y?ァュr!R5装[ア。??NHシ?ノq2ワエ$q||zr#?YlィDトsヲE蠖?欧蝿軛イ#]?゚\nシ?ィハア鴃f?星@O?ォ端マ6[]ホ-?kiヨHユ?6\n[????Yウ??ヲj?ムLヤW私モ飾・lョ)eヲ捍l瓮紐$\'齋!「dT?エ??ヨLン淹? T還ホヨ\n?1?\Z@w。?&ツラ壥「aチスR?ュ~/?ォ儼G\rチ@韵∧ョYCv%Kヲ??*?ラ隕.タ\\8Bム@ロロ?,概ミ蒡ミメネkSたV妹ヘH\0}a◇&歯?症\0ッ$ハ ?-TエLヒ!M:?ウ骸jf41p懾?モ =MキヒFゥィ?碌ejキ,Jェ?ヤ88゙W「鑑ョ>Z?w8a。鶯jRImャlQ惶?/?ァ%ネ#僵タ窗楮」@??ヌK?蜑但チHx?)Zラセ&テ*、ロ稷1Cカ0モサオ1幡;。ヒcカリUb暃z D\ncニ8各Wwハヲ庸フ]2*ヨlシタbュ衲-硲。?リEラ フ梍LhマBi?.5P纃cヌ ゙ニ9ァ?G?N{モ濬~ァ蜍?&15?ユキ\nXs。?}シ\0自「療\ZIハ\\+)\0)??_??2Z78ォJ淳ク\Z:S?oせ゚?」膊Wヒレ[[It?B頷?$ヘ&・>モ7タケヒ+?」ト) メk?dk塲ユ舁L/+チ?ア?=q?緤??ロA?rネ緩? (@?狂\n崖?ミ?wUャ(}?ヌ6?オp+?8?uヲ]pォ|ア?:ケv4P?ラTS華綟48」ハ?1?0N岌\rBoDクBU?\'・Tr??ヒュT?8?Wク}??|cィタメGC?*臑M?チロュ2鱇_ノwトノョ4ラ(\Z訓ケ[C\\C亂\"」>リメユ8瀲エキC垪?メ0*メp~素?フv\\クャ罪カヲhv曇\\ゥ?T?L月ノvoゥ)??yJ@Y\rjG? -?/シン2ロY?ヲ蜿J{獨モ衲?ナ?2ヤK葡J?ミオMwァ??*1S_ 琶^g1鴒?ヲ3ト?\'?9dTオpI6転?SPp。 ニ?Ybコ厚烟??ヨB<ソ???f?>W 葩??ノタ?\0敕]8圜ΗNBQ&ヌDキ擬ラ?7?*? ?=ニD?I腦9?゚\'?N瓢Lケ7源=\r)゚lejp。yaテnク??X・6ト借USオ|q殀ヲ[Hフ? ?瀉gnクPエカ?\"ケbF?\rコ烝5ヌ\rカタUカ$?ホ)ネL彝ルje?6保,ァUlw蕭モ?タ??\"@鴆蒐I?\nモ#4?2=UD襁ロスr?\0甼屆ワ1d續?: UDッ||S4f?ミ螽ョ4鈎E?D櫛B髪モ?-u2」ノ?0サ」テ*?(梛H境モ.トW゚ヌ?舜\0?1?シr>9R?提e?eG?テ8n>オ@\0Pl鹿IテォHUュノッヌB\0?イトc項ト?・_E:M?チラW?!?髑=)ld?レサqテK抻7ェ堂ョホ\"Fテ?*w?\ru,b豹U?,8?カ^Jvァ?\0ス\"#ー?カ潛Tcケ9Q2?#ノR?$ァ\"」f~゚?ニ碆轤j??PネG?ッァ?\"ONDS^$ミ借ス?オェ#F、 & ?{S筴?(Jヨヌu_1[Iェロヘh?\"「?゚?萢HOォネレ?\rツr碎潟?ヘ悵 F誘K(李z;セ?\0?t? W?JJイy?9y<5M剃チョ5 ロルy,碕1$*嗽゙究メkコu?ヌ?,?フ\rC??_iェiZxサi?2ホイォ?\0オoオヌ\0h/???A<7゙ソ?Hム醵嬰>I?圻?zレxメe$o\n}ゥ?ノツ?]荳ヤフzェャ?篏Tt??>?}*?\0?4z?ロミ゙ォキ?セ透/?ル食ーJシA撃I??\0瀾???諺ヒカ?:u?+na?q]??F\r媚シヨ5wイ?\nツヷ&篩??ヒウロ「&?褓k1C@?S蜿3ロyq躰誂ョハシKクゥ?\0dルY?6X〜?シタ?馘灰Aォー]セメョ!・y禍宮?B?}・ョG?ヘN痂卍C=%ュ?ルa?\0ヤl[N\\+クァァζ?\0?0ル?ル?嗅,/、_N柏QG釈C ilト鮮*4逹Mキイエホォユ??\0リカF#メ喊rハy冶ツソ?Jュ i*?\"\\jコ\\7K?-?ン?ヒ\"?・メ?睾?,アGg?鬮\'.縅+姓4?6ィォl6 ?;dケHル1?シ拂仲??\nオ\'?:<0ニ?1ネワh??4EENnI!ヌト6Z祐ヌ,LW丱P?^?wチ?FッI?ムコ\n墟???<⊥#ナメ岔r1vッ|sT絣?5ヘヒli\njヌ.O亥*モ| V?W.ァ?8?0ィヲ8?」ーォvトヒq?\'pv8?ニ?ャ\n弖オ\ZMz褐jソLRォネメ僉bfァ|?リ。{\Zf稘慟8・?*S*イ??jク?)マ肘?Tゥ囈ヒ&ケォ\\*灑チツqシー。X? フ\Z」\Zvタォォ?+ョ?1V?ョル@Sq潅^Lア\'レ曹徐タRアルI?2。N/q」Xi\"1 k?rクk\n愬;蛛磁p??!Q?1ネ?ヌ\0WョXユフvヌuヘテテゥイ?8筵{eRクェナ?差ニナS}?*ク=Fリ拠z籌?1&゚ョR8モ?8タwツ?瞭bャ6ニ?モャヮ?&凰 篳?jー@GLc!8(奨#絶ョiAz|rツ?)」瘉緬Zォ斐Z゚ク髯?6?ケ水烱\0??\0g f#ケ4サ? RチQ?ミ#.??t*OA繞?8?mvPX@ッ.剏kロ3ヒ]ア\"?\0~Lェ??1ヲ0M3ョ,+Zッ雅?レ顕膿[?1?#。゚手・Wェ東ケE?惰?;??qャユ5ナ=OM゚?hC\Zk?>?!沖?グ?S*斑V拮i叙ン8+Fワ?\"?1U斐}アシ笠ュア?クZ^e?ヤT羨?ョ*シラ lオ崕ツ\'<Q?褪ネ?5カma遨-!eeャ畑>?ィ??Pイ?$\n|;dh\Z罠??.\"響ヤ$ソ\n$?銑Jb、cノー.c別ヨ?0愼ラ\r*ィ>|r?勉[ニァ0?;縲?s〇跡ォJf F緲イ?3|;bォjkS?#゚ョj甄キゥヒ,?+、ミbイモ?\n澆ミO蠑カ?ス晝DfBェ|,=S捐Iソメ?i竡砌K8赤且<9;?タ砺ネメ・)?,シc+ワ太$傘ラ+檢蛻M<ケw?B&= \0~Yロケニ?)?マアHba\"?」%\Z/?.-d縒ワ綜?Hクe?スミ苺Tャ、3カ?Oqc嵬U鋒?Sq喋oヘれ゙H物ツ)瘰a1U?\'\"RJニ<コ ・;?8?ホ?チヲンマコDロoモ.リ0A毒ケ.ル,?? ?%、タ\0ニ⊃?+4/ Qナ2縣ソ?0ワS「$\r=?Jカヌ綢ラカ。\ZFjOol?2jウOトト沾9?rホ柔院)?. ?勗?エ犯サ?(???噪\nIヒ?,\0Tゥ調クt?xテ\"キ.セシ勺y?ロ\nニイ?Nト?Y=シ?JA?、uj畋8\Zホイ|kスG\\トヨ捕Kョt?9]ヲクJ??モハ?スイ?゚??サ+!SアヲG? ?蕭S~ァヲJ2 リA?OG姙?ク\'?玉?ロ Ou・hユ??:?、Vラ*?Z弱j?ェテso?ワォモッ:ョd 5l}ネ;?ゥNムヤヤワcmッfイRンハ7?8?1nヲクフ櫟,QOv?\nハy5z?eォノウリq$?aHヌギニFN8}$ニチツ?メエ8磐ネ\\為磔ツ?$F莅j:o鏡・#ッJ檍ム[\rシK(艟\rタ?Z?(倹Qヒワc?lヤ$ュ(ュkロ+ヲ=O猶\Zスイ*ヤuッ?搓80lヲ゚^?#ト粥ァレ?sフJ?\0寒ァロpエ?垓\n+?1Y?ヨム[,jセ抂!Zア?ヘ、ァ\\蓋nロ\r?l|r佰%鵞~リ?0ェ?4ハ$総ウ7\\P?譯c@*Nj?ΩヌオMィz紕褶゚ViM?。Db搜ク?LUz嘴袮|ーNE.9cョc?0*?ァ|c\Zf5)アUァ5+?-F*ユ{eSz紵ナ[ヘロ*ケUナ]J忖8嗽ヲc#2?\'aR>愆。iスj+仝rッカ)uo? |ネ\rGCQヒゥ5?ワハV?kMゥ姦b?モ聳サc\0チV1トメ?゙%#???(xay賂ォ?)瀬Qカ8シャ体Zワ? ?vタヌ統ヘN\\?ザ?2ス&\n\\nS?V欽?R?16?-メ_R・??U+$WzQヌKrpT{Qビタ?\n\Z棘jヤ5トェエ?/ヲ楕 ZWテヨ?2??タE?ッZ?ヨョ\0ォリt ヨソ?eィワf=1W?$f竭カヒ@v?\\@bゥt酳liヌスメヨ??%サイxミ>モ?a??ヌ#R?\r|*z7?嶐スセ? Bエ?バ.= w?傳閉P破ウ??T~g晋oラ葎8没8誅~C%ム カ擽\\?B」?8q??フハ25ヲMハERhi?\0ノ ョェヤ\'\"R}j^E{n~?甞?x宕Zツ?&\nwヒ刄tナTウfヘ棺座ラ?5?*?7Uタ?ア匈・vlルアWfヘ?vlルアWfヘ?vlルアUXヤiルウ+qニアゥナU?6トウfナ]囗*ナ茱?コ?F?ヌ?・J3fヘ?未ケX?48ェ\"(リoロ?)N?\\\0)?\rMra吋G?\"タ隊ネイ?I\r?EΔフ?8??&6#イ8??Mz}ル#m。=7?28{?? 9:2テユeエ-\"ハ? ?ァ蘓<ウッ?:5コエモleォッ% ュモ綣??iネO奏?5#}lシhm$p\r*J斐?\0ノ乱ヲ??ッ?琲?ヒA\'%?\0?12岾ワ蘂陏カ?士?\Zミ.?ゥェヲ シoォレI31?華PmU?\0+??ャ?$M8F?\0。 Vァル?ラ??サ堙JィKIu8U宀゚o?oウkノオ]T]\\ロヌk?3I4淡タキ??\0?#ホナ葮頷曖\0?}?@?=臧?RC?\n??\0?ム?/オ?エ{A玳v?]寰Ncm??wТス1Sス9カ?[\ZエaGEッマ?(ル[$」T糾I鬆ォ?\'~?\0藺弗~寧ァィヲk桟4T4-\"ヤ?_?皰 J-z相ェーzaF、アナu\rノー、差??贖6n?ンァ5cAN 7?8ェ ?H サN) アr,ンェニ>ォYト唔癌ミィ?+篩gヤミ?\Zgユl?\Z5ePkキ5t??笊e?\0_\nソ15dウメ?ーチ罫メ4#ィcV??ェ?\nチッ,?莠ヨ覦]壥.fイpOC?yフ椥?ネ戚[??Pxロ??w?偏ユ藪Aオ7廰キ侃0?Bノso?\0ヌ|ケ蒟メ5屑+ィ?)ヨI!ロモ?シ?リe「T$dmo\\エ?尅隷ョBー?=8??\'マ?=\rハ聶X( ???\0Ёネァ? H筋ネBニカィt。薇m?マ?$wI$6?沓D#潟?テ?イ? ~望W?\'ヒ稾ュFF?\0?Ftヒ?>)琵?タソ及*x昜C??jx葷E諷iZ?(r%/?シU/。\"モtス*ニハ[ォ??9\"ORト?Goハカ巡「ヒツo??\0Kv??ユチ儺?洲ア?n4?#ア-?$? ッー?艨゚袈ノ?cUhu8叟?ニ?薨ホA?セs??オケz?ン4)゙ツ臍嵬0ホ??>ケ?;?ヤ関w6pワ*3ー壯?\0蝟l???#?>? ン:ヲ~FヨX盖S;:Dアノケハョ??\'楯殍ニ鞐ォ?=\Z藾ムレKыh戡\n{忝肓?qホdソQum0G席? ?ク??qV犠* P[Zト?畏M\Zッ ?2蓿{飮ナヒe uキト^?ラl栂[テァ卅?-トyfチ?r?:奮?3x-\"唳t?;uマボォ\Z5?ヨfカエ){&ワDU@\'クタ9タノマヨキ^?r4KXu8T]Gオキ@?bワサ4E?Mミ+皃レ?カ1a嬋チf9$キラ??g、E 幵p?厘\n調オ酌frソ慶メーuスbヌMV沸I0?シ.ヲF 璢&エZE?\r帥些???Pi-} ヌ hFモ?=^Jh??%ヘュ、「I1蝎v方?コZシ??1?#弃l??窮ァッ\"スキヤwマ+yFヒ;?Tj、*コス騨#ク1徨\rn_?veメラWカりネ゚タNカ?\'モ゚??ゥァ関疸?Dヨ?ツ弾)8S鍠<耙塑OB靄n劾」オ誘モηoワチ?8邯~??T?ァ.mヲdX.J飜?<ュ?ゥォ幕ヨイiコIメ?滉^MメBメ.nホ3キ {ヨu?ロKィ[齬?\rスィ頃)ZEaネbケタホ}8篏}仰涸ィ??eククイウユLSAア?塞茨檣?5 ヲ?ォif亡ナフ\n\nbAΧ?\0.}ォ\'ャz守ゥ-,ヨ+hメ;x?$??ス+N2rリM$E閊气3%ンテ??&b|゚~?[・?ェ?VロオO$?レゥOコy#?bdrB元タホュv薬iメEァト[?\0m;シ3???;馴レシ?\06幸ヲヘqサ,レF?忰q#*桧?ホ>???-k蒟ηLFチv?7? ?=k塹?6゚?\'哂?? }}~?ィマ菊?9e\n?(\0マ-?%?\Z?:\rネ言髯ホ2?スjnレ??鐶UタテB濮?s?ゥlヒ$M\0\n1 #\0?}ォ侯キ? ニムアl,ムョr}ネマ#??Dモ6。m$アY゙テ Jツハ +? 辺7鶸KmlWj?6wz\rb゙ナpメナ,ヨ?c1ヒ ワsロ=寡カ~スォ lオkw[・学CA Oラキc?c辿・\"Ё 9?\0キ?乾?ェ)hR[u-エタア??桾7ュC cト便eR對?樔戈#?b?%?\0Nn崩?\0俘z戌?1]8?-?Q?゙+カN?8ッ。F2ケ?]E,フムn6?サユ冲」チ%?s?佞イ蚶?珞ャPタLlョ8?酲\Ze篳紐Ubxcエ浣。ョオ}ュニC)?>オ?マi(?>S?ョィ?Pャ2タc?「l?o\n蘰\0q??、Q#yN澁A?\0P?\0zニ俳キl/?夥モルンp8S?゙『??_?-コ旺夂L?6エヤュ?+セH?臘rイォ?v? M~連,Sツ鼎\"K?e# ?;ダ沌杢チ>、?\0Z??\0??=ュッ%?ォハニ9フ陽+斛オタ/4。T?メ\0マ薗K(ョO#?xソGアiJW!qJR?R箱・()JJR?R箱・()JN?ユソ?\Zt$ 。ヒ\Zuア)グg?8?YーAVレ\nィ?NW?[5?mスクQ焼jノ?ョoセ)?ス齶オX?|ョ?タヲ+Tf(ヤア,フI\'? \0&?\nー?.|.#_c?ヘ{?\0N?ヌ?9sNン? ?ォ,銀ヘ箪ネ=ウ?ヘ,?柯シBチ巽\'\n\0??\0Jタ\\キ3ア?(?9ニ>?ー?3ミA桝?カフ?ッQェ10?カ哮\'カ?2?3P=Nsノ=???kc???enm貰ワ鎮xヒ蓍セ=マリTwI鏤М%ン?+n香シz南=jWSヨ籐篶ミハムeT(\"!惹鄙゙ケイノノ?「亀??2H?リ?8レホsノリ?^??^?鯲nハ !T{?j\rコ??\0ィoパoゥソj? r>+?ヤ」ケ覆k陟カ杖アl?鉉U?吊?+>ッmp$y#H?&;D?4吶8溏\\4ル貊ヤナ梦gフw?}y&?z#ワハ瀬J、ホ_ク??アMノク/o4?並a??*?イz??゚\\獰蜴?1?Xララ rq?m%墾%ョ|M? 8?z剰Nウヨ??゙゙4??Q?;H瘉?q?gVXIwo}ァ>?モl? q敕ク ?u醗?イ?.?ィナsノM?(y拆t[+ソ僮?\0タサあJ??7オhッフィ?|?Vマ??mb?\"??$??+?.・Hヨ&T昼?%? エ鄒??Xヤ/カ?)e蛔?・LOゥZ鰒モツdD丱I!\'豹y?L饂ロR黎竒fアA\"イ?X?⌒w羯?ツ\r吊\roゥョュzコkkwフナ00 ?脯bイ??Oメ??、コ實07\0}セリマ゙「オMrヒC?サセX?&ニ攵ヒ殯?イ=?]Kpo-\'盈\\キハタ冪1薇?\0ョ1]忝tf_:n+サJナui?ウ+ハ?ン掻?z?Uキ・ケGーyムK$q?ヌ常^l?.ョ程}N鬚ウコD_旅\\エョ?.yQ懽?キ蹙Mqu?[\'ヒヌnxJ?*?\0?+κヌニ(シHセ「壹PムnラOx奢Bv?」対リ?\0jメ?メzカゥヤ_!ィ@゚サ瘻、炭?+筑3チn=サVルラョcK」・06タ!!cT$?タ勺ャュ\rエロ+t3゙椋?ノeリrO|ヌ?/lオYP鷽豪Fケ??>Qン?dシホI? ニx?オ顫Vッ%?\\N?0d婚;?xレI? 恊3繋[堋LI ??\0+(マミラ M.メヨI謔ル諫?.3唱CMq)=ムウh??4ニBケ@臍ク#$檣豸$qエqェア、c?uャcb捩1?ロ V\\?hェTJGOT到k_鷸.豆゙ノx?ナ?E/?孥6逮>オーキサ??~ォ9祥HIーワ?\Z緬5?ゥャh6ウ鼾7硬9 lヒ*ヌ?G鑠\'E?」鰻モUモ.-? 。|M猗? ヌヌ8ァナ戳゚Kムョ?h゙9?$1?2w?Gリラ懃 H幽]忱\0 戔ヨヒナメ*ンィ?,3t?。ス|o腟,dp??8ヌセq希oR?゙O苫 ム?.」?3テホGラヨカッツ??ィ>\Z゙tvサ([;vメ暫?ク\'?jョゥメ耜オ9t?>*+ーR リ;Nxホ}Gメォ7ヒk「イ}鱠1フネ?9ネ?ホヨ茫8|+●? Tンナョ毳ヲムツサc*ァkソpr}ヌ?if_?シ2穩觀p?カ?cメク?\0Βハメ杠Bロ^&?$6??0Oo?7?-米q俤カィ?ニ=?サヤ,マo$セnメ1Pvキ7\ZKクWY柁|&?ミ?\0zイ椋メn-?\0?eIh綯チ?桀Z駿R゙mC)イヒ\ZmタFC?\0ィsQmヤレ慯ネ??#&ツ~ヌオtGヌ媾梠NiコG^。u3紀ミ7?.?ヌ??*?.7リレレロ6cケs苫zq??\Z跌・rdT-橄レ・4Q%トゥ皓f櫚cヤWFT?2E{dEメ親@$d??px?:」[スフハ?(<wキュF_[及Q?ケ\'カィ???? 鏗Uケネォf?)! #\"鱇>レ??\rk)vキスオbOヒホ?Pリ? 2ー#ム?r゙ソ;dソ革_ > N墅衵uト酌???レEbb?y馬p@?Hホンァ?シ??*5Nナ)J。\"櫨\0・)@)JP\nR?櫨\0・)@+ポキ?]I。|?エ霓=パu#イホ?袍DTクネAv(」 ォ/?88ッDラ贐ナ>オ帚wト?ォ?\'缶B-?&>hm塘@$睦 3カ ョ?ンネ選ヒ?+カ0aUメャVム40yp?忝??ニi?%ノ5lモVニKノュ栞Y##!スタ>?I(F惰?tョ檐コツ%クフ?_ソ??オ・騅:>?詮Yタcクr@輳??ェ7・4殿a?A、C;ンニQ?_zェ?X・ヒヘ慇#ヒ膩o蕾タ\"ケ蒟傍コ,ゥ?!uテ2ヒヲiLc゙vI =琳j。゙靡ン「Yレ+s??ト{楢*1?、dウ1芬??3[Aキi;?&*;.yA?}ヘuGゥサ1樞K}ノm+*?申?\0オv魍G{xュィL?ョI\ny??]WMユヒ4P2x?q#nレ>セ?5iァY似スシセク礼制ヒナ癧.s鯖?ヌjIメtx3%幅?ホアs&ンア?フル?{S]}NW?シ#y炊iィハ刀?キjノ鎬.?{ヘI謫lQ俛キ健Gョ}9ヨ\Z1エムョ$0Xヤ゙ォ?[Zス?%ヲチFa?2{歡\\貧ル。?Pヨo/oョt?\'カ?\Z)拗cワ^2Jユ躾ケ?;]\"ラM?ミ{サ、レ??ラ??ナ。?アdッ?#聡SQコナシzトカ)ゥHイェ?己F?ヰ{}1Z)・ェ+Fケ敵セヤuki5-\Z ネ\0?I?ニメO \0ワ涛檎モ#kム)ヲヌイモV)vュクNミ后 ?3ロイ{?^・メv3jk,7賎l シL]テレ\\?$rjヘァマ。?:lイ]チw?7$ェ膨櫻Oキメュ)コミHィ?=_、Z?6zD?5コ&ンJRθ[q;姻?勵サム\Zィ鯰徂ャマi0?レ駻dヌ#x=マ\'フシqZサィ4[~ァカoンカQ?ロ疝ホqニO峭レカ?テンPメコA4]Rルウ0Ias膩爿? W/箔け? ??QtゥッY゙?\Z?&bワ&Bネ? ホk]チ{ィレャ?67w*ムニ洽゚Oワヌ?=g?/URハヲ?ュfMfbメ磅ナ ャカ楠ネソ?5ケセ槎カモ???\0癡Iメコ?ネ髦ヨ覿f(#?}?ト跟ル?ャ?w?ムソモウ?ム???v;ヨチオホ] 植?藷キロ^Ulリ???/]カ穴゙?1ョ。??珠Rヨ゙ロ\'cュカヲ\nw?ケカS???ョハ?Eネ???ヤZヒ1?ロ} ?ホトホニwキf]{ソG^レ?z?o?アB2ンhkMWテサ讖+G?撥n?曝ワテ-sH゚]オサMユロ[嫺ネUユZ7Uョヤケ?ム??鋳扨&Nリ\'ケ?ヤ鍜魁w*uーn?]T\r?オ淑?$ク?fミラ7ヤc?\0yt}Cュ袗?1q@shs境hv?z孀??\0en??,w?ッ?」ッ「8モ壙*ュヌ!平ク・ーb?娩w?Os??Fマム・e猷cア囘;壑mdl斟m?;cン[?/?\0セ#L?。?ス|?フヘ_r?8Xzォ*}?:嗅ー1??Xラナフヌタニgカラロ?9セッゥ?\r?\0・?\0エ?ネ鶚?ラ}?冐熊スレ2キ?\0Hォ.カサラ9?}麟~;?\0M??c2?ツqエ7?潟*8囚キ!?oァ?oィ?イ-g?/ムォ4?\n??ノキカケ?譱#}5;e?愧_レ3=oァ??ッ^7?iオ7?$欅??音yカゥ?モ?カャ[Csキt惘Uョゥ盻ョウ.キリ鍄?[= }oNヒ?\0]c瞠Kz?ォゥヤ?gィ?UfツK?マ?eサ~ム]_ヲ?\0ョ.?蹠wNテヲ?ォ?/sンー争?zuz椏Y?エウラゥ?灌渭ェ[コSウ歉妻ッn;\0ュカ今?/;娟F0?nヘソ、ルウラ?% ゙ウ\"b}<]o??4コユトoLヌ鶚?゙?PキOx?{hヌョ媼??\00バ?」ヨサ゚mヨzカ*NCァ釁FV17aneu=ミ甼⊥霽;lnラ2?ス椚Lコレoッ?ッ?g+7\"囿?カ貂3=ト青\0凡旌3u?種?2ヨl?Oユ?wセーcgt??マQヌョヌオ?.ャセニ揮羞☆5;布゚ヲキ?Y?漆鯏 ア0D?猖ラd=ッ?ハ黨ケ.ムc?ウpSNwレュ}クケ/kw??0セラ?%jcgソェcX猝ワヒ+s宜?8Xハ??62?+}ウgモカェスOラ=5ホu゙?:eュネ\ru廟Xイ?‡{ナgルeyt\r布V^マ輌滌?>ロ遣疼ヌa粭z?,uホ~8pュ?;Vオマヌ,?>Eフゥ?ェソE努鬩ア?\0h???゚Tンh\\ョス9焦n].uァモ檎ニ? ッァ~ンヘk?゚窓m蘗?ョ*絽ァgbキォ瞼uュ]オ゙>?盟???b?ョs=?J?\0@シナVヒ2タ恕D瘻>・(゙テ???メ?lfオマ?乍謔ャaV?.kZメO.0??U;UY?\Zヨ勿!?2v4{ルイカYオロ?\0孕ルウ?%kVェq?[疫m」ォオ孀mリ1?Fュ?xル?葆ヲ??\'g」岨。?2\rュk麒ュフ,徒[シケム鎹?\0ヘネキ?m?\0カ?oP鰈Tハ\0qスオ脆?bルッ{,?抔ア??\0驃e溂テ \0 ?ラ?ュ\\テ○?遊^?ッ、?メipp;墮?;ヌ?W頷d?g?=OO*玄ドゥ湲「シ7ソォEwQeV9ユケヘ?メicソAk-v?ッモ゚K?=フ」\"ォQユ?2コ?、ローuzE\rカヒ^X??dンヒ-ホェヲ葫fCG?M゚ヘ??、}\\鎔mYY8ュキ エ?S菜ニ輅o「イ广?~マユi?\0??斬DフqkF#cテ?F=?9xKォu:e?ラ??゙?9^?s ?サ\rモ掌黔m?%ヨzy??\0ミセ、?Gゥ6ヨ9?コハZ?E>テキ}u?際ン?写キ?夛?gイ岸VXス諂ク?-眩」??bヨ゚Iセマ詼??%K究?<_bエキ?埠{i,wWスケCa^ラnネユeエ?[V58孺v[?滯+VF5 4クヤlク5桾ヤ=???67ワ??}ャ゚些オ[??ア?~ュu?シャォZ?ロリ貶?~?\"ュソ、ェ暄z~ァゥ^?・Vーヘ?\'?4裔ス?ツ彑?lォh・マゥ?;ムv-98エワ/輌ス\\ed?濱モキ?゚Xu4レ?堯ヤャ餾.-ョ?U_Pメ證ッ?eiッゥUo?Isラ奧ュ?\'ヤロカt?スF螺}ceャ蘭?イ粐?レ?^ョP?t??E>ァ? フスZ?\0iz゚狄}?\0ル゚サ?・Vホ}X藥?\r[??、?モ?gァ絹nム、チU八vロ\Z?\n~#S?ァアトs鯔\Zォs??「/hー;?{~??\0戀}5スメュ フソxn59、ヨラオサ儼Sbレ唳_VMァェ湲?zヤャN鰐ヒゥ師エリテ゚^゙??\0嫐1]ッィ〔1ヘ[リ?ム]ャ?ミ踰ユ?7モイ溽jアZ4t:iH/W??K?趾サ*ラ萬亭ケ???゚Eソ」ァ?+A9?3W??-キa\rn-lvリoィ??5lウ?ヤdア?~C゚?/?s?/ヌaョヌ}攴wロUチヨ5ュl>テ^c?Tキ?敷ト>。メ?〃^$c}ュフウkエワZ=wャ?櫃メァユソ? ゚層」?鬲F\":?リォa?サ=クュ#サ%ホ\Z・チョ?-オ]1?7~潮??sユコ・ヨロ_Rチ?/ヌ}oェ\Zリ??ッ「ニ\rヘケ崟???Dケl?bレ?? YcY?#齲=@マルマソk,セロ\\ヌ?ヨソ?ャY鹽;wャKウ1ウ N、\n,ャ蜥稷ウヤォu\'リ觴k况~NGゥ風m゙ュ」Sルメ#?ナGッ?-?黙ケク]5ンUナュソ ?スメ $幀ナョノ?-wゥ嬾+?\'ァイ?ム??\0Hシ。v゚Zz摧taステ?=Jヘト5?~ォS゙?9?\0ス?「゚ム??Oァ~粐U\\?ツ?サ!?x???ヤ?棚%;?\0W?siq頃茸W]メ~゚c橄ィ?ケ残壙\Zツ?モcイア゙ヘロ??ァ?\0 j?{?6イチ???:Sェハ?゙3?x~??Zキqツ?%?? ニゥニfニ;Hun-2;?3w?)ct?ョカロ?x??ー?\0Snサ?K崕?ニ?\0チウ??,Aナハ脊O Gツナァコ?ロZ*kXK????#ャ暉セ滓11H鳧ー媾?5ラY苗nュ・ニヌス?.ロ足鬮ヨgゥ霍? ?\Zムイメ^粫?ヌ5?\rレ7サw??Mャ?クhc???.コri}9X?ァ毳.」yam剤?;=ロ^?點?\0ェラ?ulメ?.ナ7 l2\\6=OEホ;_eロh?ヨ?\0?F?チ帯ヘ、9セオU]kタ.ァヤカ」ス7゙1ルgヲ?+Cゥeカタモモ?ユ?\09n鷽メ賻ヘ???フ??? ヲフWキhリモVネ:?}.ヌpワ??\0チ?筰G%lA?GJiソ ヤ」モ・?ケチ?カ?O」?策佞イ?KV゚?棯ニヒ、Znサ+モヌツヌk[殯陽UヤX?アョsr22.?q*?騷>ァァ?奇Q?8ツム拘ル鶸%ル蒙レェ゚セ?^ラ=エZ釋F?MY??ン?拗モモ?)鮑sー4m>]?ラ\r?ルスフナァ?[??後F?ィ4tr?Yソュu;s?嫋 「親オTチイ??嬌?=?組、牒f??ユ?棚%)Yチホサ\n疇gOホネU誰血M?>?>ー3%セメ ウク?メ緘オワ? ニX?璋8オテPF???k??\r.mタ~?3?s テ$%ソ、?\0ヘFッッラ?1ッ?)リ?,}6リ?4ミ\\[?w?モシ~ムワユ覽?\0?丸?kワ8\"ヌ?饉?1コ?3V;G????ゥ+?錠゚チO。eGャ鍄釀k6??\'鏝[ォ/??\'ャ?a?6ァcfワ?8z亰サヤハーク?.ゥニャ*?゚Sラネョ??モ?\06シ?\0;?ヨ ヨコキe\Z)x!ユcオエエν閹>ニ?\0ニス??#oQHェ搦サ?+ォE聞、mナェaロdT??\0?ヲ{+?o埴K緒鷙アメIC)&メ、棚??ル\08BIM!\ZVersion compatibility info\0\0\0\0U\0\0\0\0\0\0\0A\0d\0o\0b\0e\0 \0P\0h\0o\0t\0o\0s\0h\0o\0p\0\0\0\0A\0d\0o\0b\0e\0 \0P\0h\0o\0t\0o\0s\0h\0o\0p\0 \06\0.\00\0\0\0\08BIM JPEG Quality\0\0\0\0\0\0\0\0\0?ロ\0C\0\n\n\n \n \Z%\Z# , #&\')*)-0-(0%()(?ロ\0C\n\n\n\n(\Z\Z((((((((((((((((((((((((((((((((((((((((((((((((((?タ\0\0x\0u\0?ト\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\08\0\0\0\0\0\0!1AQ\"aq?2贈ア#BRbムr$3チ盍?ト\0\Z\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\00\0\0\0\0\0\0\0!1\"AQ2aBアムq■チ碵#R??レ\0 \0\0?\0?\0\0P@\0s?7浮ニ護|馬???・sgツルk・ カナヨCヒZ姉カ?ウ_gケラPc?゚P」ュKムノ~%?B,?チケ?%-62r?」胖、zL凶ae鰯9I舵Bャ4Egqqtム\'\Z?\n\0(\0??\n\0(\0?・+?m監スモ? !Oa?->厭Y\n蜥コー?tPa?9?OフラAF+す9ヨ? 厶。控t??>エラ?\n?|?みル篦A」=マ(<フwウ?VMウノマHコヤ{9則1? キ\'}?ヲXR\\イ7?9 v?チハc6XY?ル゚ラ。Jo4?\0?*\\咏{\"シイ介ク~Fサ?6ホ5 窖7?\'ヲ源ヌヌリ{2ケcx、h薈GSヲV\Z ?Xレqtニ8T\0P@\0\0Pカデ& テyW[KァP[袢\\・?8ォ\n」冨宗・?&カ9Q]職c?}シ?骭sv>^T\'\'?!、?1キ?wK+蠏詢C1e?\'ハウK\'?楓%?ネ???)夜繩?レ\r\0ロ」Drニ~=欺八1ゥ~モKsqk!リa4\'G舫躬B榕「クキ\Z?\"rフtャOQ?吊租qak遵?/\ZRフ6_?ネ>エロ??ョ\\オG、bセメ0i廳ォォDciイ愕?\0i?\0!襌Uコス.?kア!橡ナ倆pヘ@\0\0ヌテヨ?「窰?シサ??ワcオ &銚j??;鰍蝣iヤルセロ?*=)蜩消」eナ??..?? P?ノ??o・7?WB?c>S吟??Fミン\\iBコ丞?\0ネ??v?フフr?5,モ%?m停Cッ?シ醂(\'@?ォ・襲坪?3ヒサ*s?フ|エ)ノmvセ2/?髣?B+岻ナ鱠オモ,Χ*VAツ?9F・?\07V燻鬢 d磊Oyサオ?Hタ?7ヨス?td濫績明L」\Zァ$hタC?? >オメーノ%tv肆?Y/mニフ艀?。}\r??)苴j?\0bヲ?%?0メツ,ケ莓Rハニ\'フ@ル\'ッN柆 cI?\'ヒリf琲ウ7y(ュヲコ?,アH????ラcュS昴Qm.? ・|喟p??\r,wK-ワカアーェ?H?iG&頌eョ6ゥ亘チ<7o>ヌ?錘OッJ?-ム3SN?<ンヤカkm{?;I良Hタ?__スbヒゥZ蒙Y齲イサ)ツ?dヲ?^V,靭◎眈?\0zウ・ニ71%?7チIi%ト7\r ?t??uラマフw?ヨ未ヨ荳+?:fオ依リ?,Sハ\\r?]ラ_]ラ/&)oi\Zc%FY??篤Mヘe 儿ナt?コ涎Nカ+&?\\olゥ亰q\r@?ヘ0tユウFシ?~テ?*ヌQ・マツ3l喜,ソ┐P?/qK擽7Xキ貅キ@$エ裲?ラ?<梛ゥ???\0Q\'S弁S?6W^蛩糺ャョ@?tケ0ニj?ィ?8滯慶ヒAh特$e」?6シ、}:茅j\n\0租ygSスuュレ.ルCmカZ?3hカ??H・eSコ8 ?K??ぬワケ??吏旭aヌBキ―濶h屁ィ゚??ラM謗:r脯??桟摂テ~ハ?P^d艪5ム=リエmョ?ソ躡?ム???モカ1gqヨウ??+ケSキ%<6揃???6)オmEムsG }ク\rケ渠詞??9セ鐡?7pqY(?8膩レ?ラ~楫Z?qkyツw7?Q沙Xハ\r?ョキ?0Eャェ+臟?剋?フヲO>--d邉ヌゥ?2;3o縊ケ?\0ョウ7ゥ績?&ヨAツ?\n\0コ皰匆シRヌQ撞]&Mムxル?\nCow|nヨFハ ?跡_6ヤv曾ルャ?c?N??+,サ?/,??ツ6?ウt?;?z]Y[;? ーG Cァュ/( レ休計゚*5ハ{・Cwヒ$F耄}?81VQ3鋲iァc・Qセロ?饂t?9z?+ネ婬?K夢Hュ預?N必?紹アw?>??(Bヒowl\"F#?\0?Drァφ?トq?we\'褂?!\"9q?;。ラマ_?.5?fM?9 Yノik)9ォ泌\nュアn?ネ??3?aタア?6ユヌ-\n\0(\0??韲SFNrF?トヒ[i?+o。?シfウヌr?nX??%モtD」ノ#U崙ナ劵R_\\ト寿Q蜩ナacUU? LHQ熾z?5\0Rdョ.螻箪t??Ne?ュ:I?$C? ?/ュヲC{qツノ「]G!ル:?=*??T*ソr?7瞳エ?!?\0?\r闢?スMUJO○Hニ?レ!テ4鯨,?\rC\0n?{囚?ュ9}<カ?ナケ3ハd.イ? ?詈ョfngv=IョL跏?)\0(\0??\n\0?エn :?)??9n?5fγワnヨッ7メrミ?類コpヘ ゚f/(レp\\GトHノ2ー>?P「lmウハォト?:ュトぼ 梯?J?tKwhー?<1ラAコ囹+g8?m&ノ_[ォ\"?域?@:衍^アレキツ\"フw??ョヘvd??1?7s/ニG????Sヤテ\Zャ|ソ??Ck}?5ト?フ?H?逋斟ヒRk跏?掖?\0P@\0\0P@l2鱗?ウケ?/?=?*セ\Z恊篳、2リ?マZkRC&ソス?ムォ無?(婚ボZ?2コOt_氣O??{^ミ?iS潜?ラハノ&RXムコ??コメス\\?\0\nK?。エW框n%i\'大遜ウアb~讓懷7rv5t?\0P@\0?ル?リ??\0JFIF\0\0p\0p\0\0??ヤPhotoshop 3.0\08BIM?\nPrint Info\0\0\0\0x\0\0P\0H\0H\0\0\0\0レ(?????FP\0(?\0\0P\0H\0H\0\0\0\0レ(\0\0\0\0\0d\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\0d\0\0\0\0\0\0\"r\0\0\0\0\0\0\0\0\0\0\0\0?|\0\0\08BIM?\nResolution\0\0\0\0\0pU?\0\0\0pU?\0\08BIM\rFX Global Lighting Angle\0\0\0\0\0\0\0x8BIMFX Global Altitude\0\0\0\0\0\0\08BIM? Print Flags\0\0\0 \0\0\0\0\0\0\0\0\08BIM\nCopyright Flag\0\0\0\0\0\08BIM\'Japanese Print Flags\0\0\0\0\n\0\0\0\0\0\0\0\08BIM?Color Halftone Settings\0\0\0H\0/ff\0\0lff\0\0\0\0\0\0\0/ff\0\0。劒\0\0\0\0\0\0\02\0\0\0\0Z\0\0\0\0\0\0\0\0\05\0\0\0\0-\0\0\0\0\0\0\0\08BIM?Color Transfer Settings\0\0\0p\0\0???????????????????????\0\0\0\0???????????????????????\0\0\0\0???????????????????????\0\0\0\0???????????????????????\0\08BIM\0 Layer State\0\0\0\08BIM Layer Groups\0\0\0\0\0\0\0\08BIMGuges\0\0\0\0\0\0\0\0\0@\0\0@\0\0\0\08BIM\rURL overrges\0\0\0\0\0\0\08BIM\ZSlices\0\0\0\0u\0\0\0\0\0\0\0\0\0\0\0\0\0I\0\0:\0\0\0\n\0U\0n\0t\0i\0t\0l\0e\0d\0-\01\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\0I\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\08BIMICC Untagged Flag\0\0\0\08BIMLayer g Generator Base\0\0\0\0\0\08BIM New Windows Thumbnail\0\0i\0\0\0\0\0\0m\0\0\0p\0\0H\0\0準\0\0M\0\0?リ??\0JFIF\0\0H\0H\0\0??\0Adobe\0d?\0\0\0?ロ\0?\0    \n    \r \r\r   ?タ\0\0p\0m\"\0?ン\0\0?ト?\0\0\0\0\0\0\0\0\0\0 \n \0\0\0\0\0\0\0\0\0 \n \0 3\0!1AQa\"q?2贈アB#$Rチb34rびC%担??s5「イ?&D典dEツ」t6メU稙??モu胚F\'筈?米ヤ蔬・オナユ襄Vfv?ヲカニヨ踐7GWgw?ァキヌラ銷\05\0!1AQaq\"2¢。アB#チRム?3$b疵rCScs4?%「イ?&5ツメD典」dEU6te糘ウ?モu胚F筈?米ヤ蔬・オナユ襄Vfv?ヲカニヨ踐\'7GWgw?ァキヌ?レ\0 \0\0?\0?棚%)$瞳施セ$如$ミユK#總詁ヌゥヨv?4?\09htタaマ\0サ?\"G??ヒr較C}:?p-?? ロ?コカヨヨツウW?ミヲaトォ?Tアチ?[ワ$1マ?;?=M?\0Sz?K+ネヘv7?\rkェタツキ\Zソエu~ョX?)ニdエリO?oルV=゚G~マエ_?オd?k゙ハ?ァ\0レワ?゚T?\06ラ?サcツ;gモ???\0捍チ ィ?.?/?};ヘ驀G\0掌綺@q??!、?\0!?\0A?\0ルUWゥラ泅レヘoヌeマ oョ[I??\0Kヤkッヌオ?\0顆SアSホ?ミz・/ネヌe?2ンKャ?p栽ハニe?+ル??Sル??\0「z旨スl~ン? ロ? -ウミコ拾ネ贐??2.ェヨ条納?G??\0テW[ヨz??4)RI$ぁ?ミ?棚%( +kヲtフ鶴PQaモqqc?4{セ林k9ヒ????0?&&ミ?N??ラt?,ャ蹶Xkヌア?{ -cA?M熟?5ユキ?z櫃モVーヌ?洽゚Oワヌ?=g?/URハヲ?ュfMfbメ磅ナ ャカ楠ネソ?5ケセ槎カモ???\0癡Iメコ?ネ髦ヨ覿f(#?}?ト跟ル?ャ?w?ムソモウ?ム???v;ヨチオホ] 植?藷キロ^Ulリ???/]カ穴゙?1ョ。??珠Rヨ゙ロ\'cュカヲ\nw?ケカS???ョハ?Eネ???ヤZヒ1?ロ} ?ホトホニwキf]{ソG^レ?z?o?アB2ンhkMWテサ讖+G?撥n?曝ワテ-sH゚]オサMユロ[嫺ネUユZ7Uョヤケ?ム??鋳扨&Nリ\'ケ?ヤ鍜魁w*uーn?]T\r?オ淑?$ク?fミラ7ヤc?\0yt}Cュ袗?1q@shs境hv?z孀??\0en??,w?ッ?」ッ「8モ壙*ュヌ!平ク・ーb?娩w?Os??Fマム・e猷cア囘;壑mdl斟m?;cン[?/?\0セ#L?。?ス|?フヘ_r?8Xzォ*}?:嗅ー1??Xラナフヌタニgカラロ?9セッゥ?\r?\0・?\0エ?ネ鶚?ラ}?冐熊スレ2キ?\0Hォ.カサラ9?}麟~;?\0M??c2?ツqエ7?潟*8囚キ!?oァ?oィ?イ-g?/ムォ4?\n??ノキカケ?譱#}5;e?愧_レ3=oァ??ッ^7?iオ7?$欅??音yカゥ?モ?カャ[Csキt惘Uョゥ盻ョウ.キリ鍄?[= }oNヒ?\0]c瞠Kz?ォゥヤ?gィ?UfツK?マ?eサ~ム]_ヲ?\0ョ.?蹠wNテヲ?ォ?/sンー争?zuz椏Y?エウラゥ?灌渭ェ[コSウ歉妻ッn;\0ュカ今?/;娟F0?nヘソ、ルウラ?% ゙ウ\"b}<]o??4コユトoLヌ鶚?゙?PキOx?{hヌョ媼??\00バ?」ヨサ゚mヨzカ*NCァ釁FV17aneu=ミ甼⊥霽;lnラ2?ス椚Lコレoッ?ッ?g+7\"囿?カ貂3=ト青\0凡旌3u?種?2ヨl?Oユ?wセーcgt??マQヌョヌオ?.ャセニ揮羞☆5;布゚ヲキ?Y?漆鯏 ア0D?猖ラd=ッ?ハ黨ケ.ムc?ウpSNwレュ}クケ/kw??0セラ?%jcgソェcX猝ワヒ+s宜?8Xハ??62?+}ウgモカェスOラ=5ホu゙?:eュネ\ru廟Xイ?‡{ナgルeyt\r布V^マ輌滌?>ロ遣疼ヌa粭z?,uホ~8pュ?;Vオマヌ,?>Eフゥ?ェソE努鬩ア?\0h???゚Tンh\\ョス9焦n].uァモ檎ニ? ッァ~ンヘk?゚窓m蘗?ョ*絽ァgbキォ瞼uュ]オ゙>?盟???b?ョs=?J?\0@シナVヒ2タ恕D瘻>・(゙テ???メ?lfオマ?乍謔ャaV?.kZメO.0??U;UY?\Zヨ勿!?2v4{ルイカYオロ?\0孕ルウ?%kVェq?[疫m」ォオ孀mリ1?Fュ?xル?葆ヲ??\'g」岨。?2\rュk麒ュフ,徒[シケム鎹?\0ヘネキ?m?\0カ?oP鰈Tハ\0qスオ脆?bルッ{,?抔ア??\0驃e溂テ \0 ?ラ?ュ\\テ○?遊^?ッ、?メipp;墮?;ヌ?W頷d?g?=OO*玄ドゥ湲「シ7ソォEwQeV9ユケヘ?メicソAk-v?ッモ゚K?=フ」\"ォQユ?2コ?、ローuzE\rカヒ^X??dンヒ-ホェヲ葫fCG?M゚ヘ??、}\\鎔mYY8ュキ エ?S菜ニ輅o「イ广?~マユi?\0??斬DフqkF#cテ?F=?9xKォu:e?ラ??゙?9^?s ?サ\rモ掌黔m?%ヨzy??\0ミセ、?Gゥ6ヨ9?コハZ?E>テキ}u?際ン?写キ?夛?gイ岸VXス諂ク?-眩」??bヨ゚Iセマ詼??%K究?<_bエキ?埠{i,wWスケCa^ラnネユeエ?[V58孺v[?滯+VF5 4クヤlク5桾ヤ=???67ワ??}ャ゚些オ[??ア?~ュu?シャォZ?ロリ貶?~?\"ュソ、ェ暄z~ァゥ^?・Vーヘ?\'?4裔ス?ツ彑?lォh・マゥ?;ムv-98エワ/輌ス\\ed?濱モキ?゚Xu4レ?堯ヤャ餾.-ョ?U_Pメ證ッ?eiッゥUo?Isラ奧ュ?\'ヤロカt?スF螺}ceャ蘭?イ粐?レ?^ョP?t??E>ァ? フスZ?\0iz゚狄}?\0ル゚サ?・Vホ}X藥?\r[??、?モ?gァ絹nム、チU八vロ\Z?\n~#S?ァアトs鯔\Zォs??「/hー;?{~??\0戀}5スメュ フソxn59、ヨラオサ儼Sbレ唳_VMァェ湲?zヤャN鰐ヒゥ師エリテ゚^゙??\0嫐1]ッィ〔1ヘ[リ?ム]ャ?ミ踰ユ?7モイ溽jアZ4t:iH/W??K?趾サ*ラ萬亭ケ???゚Eソ」ァ?+A9?3W??-キa\rn-lvリoィ??5lウ?ヤdア?~C゚?/?s?/ヌaョヌ}攴wロUチヨ5ュl>テ^c?Tキ?敷ト>。メ?〃^$c}ュフウkエワZ=wャ?櫃メァユソ? ゚層」?鬲F\":?リォa?サ=クュ#サ%ホ\Z・チョ?-オ]1?7~潮??sユコ・ヨロ_Rチ?/ヌ}oェ\Zリ??ッ「ニ\rヘケ崟???Dケl?bレ?? YcY?#齲=@マルマソk,セロ\\ヌ?ヨソ?ャY鹽;wャKウ1ウ N、\n,ャ蜥稷ウヤォu\'リ觴k况~NGゥ風m゙ュ」Sルメ#?ナGッ?-?黙ケク]5ンUナュソ ?スメ $幀ナョノ?-wゥ嬾+?\'ァイ?ム??\0Hシ。v゚Zz摧taステ?=Jヘト5?~ォS゙?9?\0ス?「゚ム??Oァ~粐U\\?ツ?サ!?x???ヤ?棚%;?\0W?siq頃茸W]メ~゚c橄ィ?ケ残壙\Zツ?モcイア゙ヘロ??ァ?\0 j?{?6イチ???:Sェハ?゙3?x~??Zキqツ?%?? ニゥニfニ;Hun-2;?3w?)ct?ョカロ?x??ー?\0Snサ?K崕?ニ?\0チウ??,Aナハ脊O Gツナァコ?ロZ*kXK????#ャ暉セ滓11H鳧ー媾?5ラY苗nュ・ニヌス?.ロ足鬮ヨgゥ霍? ?\Zムイメ^粫?ヌ5?\rレ7サw??Mャ?クhc???.コri}9X?ァ毳.」yam剤?;=ロ^?點?\0ェラ?ulメ?.ナ7 l2\\6=OEホ;_eロh?ヨ?\0?F?チ帯ヘ、9セオU]kタ.ァヤカ」ス7゙1ルgヲ?+Cゥeカタモモ?ユ?\09n鷽メ賻ヘ???フ??? ヲフWキhリモVネ:?}.ヌpワ??\0チ?筰G%lA?GJiソ ヤ」モ・?ケチ?カ?O」?策佞イ?KV゚?棯ニヒ、Znサ+モヌツヌk[殯陽UヤX?アョsr22.?q*?騷>ァァ?奇Q?8ツム拘ル鶸%ル蒙レェ゚セ?^ラ=エZ釋F?MY??ン?拗モモ?)鮑sー4m>]?ラ\r?ルスフナァ?[??後F?ィ4tr?Yソュu;s?嫋 「親オTチイ??嬌?=?組、牒f??ユ?棚%)Yチホサ\n疇gOホネU誰血M?>?>ー3%セメ ウク?メ緘オワ? ニX?璋8オテPF???k??\r.mタ~?3?s テ$%ソ、?\0ヘFッッラ?1ッ?)リ?,}6リ?4ミ\\[?w?モシ~ムワユ覽?\0?丸?kワ8\"ヌ?饉?1コ?3V;G????ゥ+?錠゚チO。eGャ鍄釀k6??\'鏝[ォ/??\'ャ?a?6ァcfワ?8z亰サヤハーク?.ゥニャ*?゚Sラネョ??モ?\06シ?\0;?ヨ ヨコキe\Z)x!ユcオエエν閹>ニ?\0ニス??#oQHェ搦サ?+ォE聞、mナェaロdT??\0?ヲ{+?o埴K緒鷙アメIC)&メ、棚??ル\08BIM!\ZVersion compatibility info\0\0\0\0U\0\0\0\0\0\0\0A\0d\0o\0b\0e\0 \0P\0h\0o\0t\0o\0s\0h\0o\0p\0\0\0\0A\0d\0o\0b\0e\0 \0P\0h\0o\0t\0o\0s\0h\0o\0p\0 \06\0.\00\0\0\0\08BIM JPEG Quality\0\0\0\0\0\0\0\0\0?ロ\0C\0\n\n\n \n \Z%\Z# , #&\')*)-0-(0%()(?ロ\0C\n\n\n\n(\Z\Z((((((((((((((((((((((((((((((((((((((((((((((((((?タ\0\0x\0u\0?ト\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\08\0\0\0\0\0\0!1AQ\"aq?2贈ア#BRbムr$3チ盍?ト\0\Z\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\00\0\0\0\0\0\0\0!1\"AQ2aBアムq■チ碵#R??レ\0 \0\0?\0?\0\0P@\0s?7浮ニ護|馬???・sgツルk・ カナヨCヒZ姉カ?ウ_gケラPc?゚P」ュKムノ~%?B,?チケ?%-62r?」胖、zL凶ae鰯9I舵Bャ4Egqqtム\'\Z?\n\0(\0??\n\0(\0?・+?m監スモ? !Oa?->厭Y\n蜥コー?tPa?9?OフラAF+す9ヨ? 厶。控t??>エラ?\n?|?みル篦A」=マ(<フwウ?VMウノマHコヤ{9則1? キ\'}?ヲXR\\イ7?9 v?チハc6XY?ル゚ラ。Jo4?\0?*\\咏{\"シイ介ク~Fサ?6ホ5 窖7?\'ヲ源ヌヌリ{2ケcx、h薈GSヲV\Z ?Xレqtニ8T\0P@\0\0Pカデ& テyW[KァP[袢\\・?8ォ\n」冨宗・?&カ9Q]職c?}シ?骭sv>^T\'\'?!、?1キ?wK+蠏詢C1e?\'ハウK\'?楓%?ネ???)夜繩?レ\r\0ロ」Drニ~=欺八1ゥ~モKsqk!リa4\'G舫躬B榕「クキ\Z?\"rフtャOQ?吊租qak遵?/\ZRフ6_?ネ>エロ??ョ\\オG、bセメ0i廳ォォDciイ愕?\0i?\0!襌Uコス.?kア!橡ナ倆pヘ@\0\0ヌテヨ?「窰?シサ??ワcオ &銚j??;鰍蝣iヤルセロ?*=)蜩消」eナ??..?? P?ノ??o・7?WB?c>S吟??Fミン\\iBコ丞?\0ネ??v?フフr?5,モ%?m停Cッ?シ醂(\'@?ォ・襲坪?3ヒサ*s?フ|エ)ノmvセ2/?髣?B+岻ナ鱠オモ,Χ*VAツ?9F・?\07V燻鬢 d磊Oyサオ?Hタ?7ヨス?td濫績明L」\Zァ$hタC?? >オメーノ%tv肆?Y/mニフ艀?。}\r??)苴j?\0bヲ?%?0メツ,ケ莓Rハニ\'フ@ル\'ッN柆 cI?\'ヒリf琲ウ7y(ュヲコ?,アH????ラcュS昴Qm.? ・|喟p??\r,wK-ワカアーェ?H?iG&頌eョ6ゥ亘チ<7o>ヌ?錘OッJ?-ム3SN?<ンヤカkm{?;I良Hタ?__スbヒゥZ蒙Y齲イサ)ツ?dヲ?^V,靭◎眈?\0zウ・ニ71%?7チIi%ト7\r ?t??uラマフw?ヨ未ヨ荳+?:fオ依リ?,Sハ\\r?]ラ_]ラ/&)oi\Zc%FY??篤Mヘe 儿ナt?コ涎Nカ+&?\\olゥ亰q\r@?ヘ0tユウFシ?~テ?*ヌQ・マツ3l喜,ソ┐P?/qK擽7Xキ貅キ@$エ裲?ラ?<梛ゥ???\0Q\'S弁S?6W^蛩糺ャョ@?tケ0ニj?ィ?8滯慶ヒAh特$e」?6シ、}:茅j\n\0租ygSスuュレ.ルCmカZ?3hカ??H・eSコ8 ?K??ぬワケ??吏旭aヌBキ―濶h屁ィ゚??ラM謗:r脯??桟摂テ~ハ?P^d艪5ム=リエmョ?ソ躡?ム???モカ1gqヨウ??+ケSキ%<6揃???6)オmEムsG }ク\rケ渠詞??9セ鐡?7pqY(?8膩レ?ラ~楫Z?qkyツw7?Q沙Xハ\r?ョキ?0Eャェ+臟?剋?フヲO>--d邉ヌゥ?2;3o縊ケ?\0ョウ7ゥ績?&ヨAツ?\n\0コ皰匆シRヌQ撞]&Mムxル?\nCow|nヨFハ ?跡_6ヤv曾ルャ?c?N??+,サ?/,??ツ6?ウt?;?z]Y[;? ーG Cァュ/( レ休計゚*5ハ{・Cwヒ$F耄}?81VQ3鋲iァc・Qセロ?饂t?9z?+ネ婬?K夢Hュ預?N必?紹アw?>??(Bヒowl\"F#?\0?Drァφ?トq?we\'褂?!\"9q?;。ラマ_?.5?fM?9 Yノik)9ォ泌\nュアn?ネ??3?aタア?6ユヌ-\n\0(\0??韲SFNrF?トヒ[i?+o。?シfウヌr?nX??%モtD」ノ#U崙ナ劵R_\\ト寿Q蜩ナacUU? LHQ熾z?5\0Rdョ.螻箪t??Ne?ュ:I?$C? ?/ュヲC{qツノ「]G!ル:?=*??T*ソr?7瞳エ?!?\0?\r闢?スMUJO○Hニ?レ!テ4鯨,?\rC\0n?{囚?ュ9}<カ?ナケ3ハd.イ? ?詈ョfngv=IョL跏?)\0(\0??\n\0?エn :?)??9n?5fγワnヨッ7メrミ?類コpヘ ゚f/(レp\\GトHノ2ー>?P「lmウハォト?:ュトぼ 梯?J?tKwhー?<1ラAコ囹+g8?m&ノ_[ォ\"?域?@:衍^アレキツ\"フw??ョヘvd??1?7s/ニG????Sヤテ\Zャ|ソ??Ck}?5ト?フ?H?逋斟ヒRk跏?掖?\0P@\0\0P@l2鱗?ウケ?/?=?*セ\Z恊篳、2リ?マZkRC&ソス?ムォ無?(婚ボZ?2コOt_氣O??{^ミ?iS潜?ラハノ&RXムコ??コメス\\?\0\nK?。エW框n%i\'大遜ウアb~讓懷7rv5t?\0P@\0?ル?リ??\0JFIF\0\0p\0p\0\0??ヤPhotoshop 3.0\08BIM?\nPrint Info\0\0\0\0x\0\0P\0H\0H\0\0\0\0レ(?????FP\0(?\0\0P\0H\0H\0\0\0\0レ(\0\0\0\0\0d\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\0d\0\0\0\0\0\0\"r\0\0\0\0\0\0\0\0\0\0\0\0?|\0\0\08BIM?\nResolution\0\0\0\0\0pU?\0\0\0pU?\0\08BIM\rFX Global Lighting Angle\0\0\0\0\0\0\0x8BIMFX Global Altitude\0\0\0\0\0\0\08BIM? Print Flags\0\0\0 \0\0\0\0\0\0\0\0\08BIM\nCopyright Flag\0\0\0\0\0\08BIM\'Japanese Print Flags\0\0\0\0\n\0\0\0\0\0\0\0\08BIM?Color Halftone Settings\0\0\0H\0/ff\0\0lff\0\0\0\0\0\0\0/ff\0\0。劒\0\0\0\0\0\0\02\0\0\0\0Z\0\0\0\0\0\0\0\0\05\0\0\0\0-\0\0\0\0\0\0\0\08BIM?Color Transfer Settings\0\0\0p\0\0???????????????????????\0\0\0\0???????????????????????\0\0\0\0???????????????????????\0\0\0\0???????????????????????\0\08BIM\0 Layer State\0\0\0\08BIM Layer Groups\0\0\0\0\0\0\0\08BIMGuges\0\0\0\0\0\0\0\0\0@\0\0@\0\0\0\08BIM\rURL overrges\0\0\0\0\0\0\08BIM\ZSlices\0\0\0\0u\0\0\0\0\0\0\0\0\0\0\0\0\0I\0\0:\0\0\0\n\0U\0n\0t\0i\0t\0l\0e\0d\0-\01\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\0I\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\08BIMICC Untagged Flag\0\0\0\08BIMLayer g Generator Base\0\0\0\0\0\08BIM New Windows Thumbnail\0\0i\0\0\0\0\0\0m\0\0\0p\0\0H\0\0準\0\0M\0\0?リ??\0JFIF\0\0H\0H\0\0??\0Adobe\0d?\0\0\0?ロ\0?\0    \n    \r \r\r   ?タ\0\0p\0m\"\0?ン\0\0?ト?\0\0\0\0\0\0\0\0\0\0 \n \0\0\0\0\0\0\0\0\0 \n \0 3\0!1AQa\"q?2贈アB#$Rチb34rびC%担??s5「イ?&D典dEツ」t6メU稙??モu胚F\'筈?米ヤ蔬・オナユ襄Vfv?ヲカニヨ踐7GWgw?ァキヌラ銷\05\0!1AQaq\"2¢。アB#チRム?3$b疵rCScs4?%「イ?&5ツメD典」dEU6te糘ウ?モu胚F筈?米ヤ蔬・オナユ襄Vfv?ヲカニヨ踐\'7GWgw?ァキヌ?レ\0 \0\0?\0?棚%)$瞳施セ$如$ミユK#總詁ヌゥヨv?4?\09htタaマ\0サ?\"G??ヒr較C}:?p-?? ロ?コカヨヨツウW?ミヲaトォ?Tアチ?[ワ$1マ?;?=M?\0Sz?K+ネヘv7?\rkェタツキ\Zソエu~ョX?)ニdエリO?oルV=゚G~マエ_?オd?k゙ハ?ァ\0レワ?゚T?\06ラ?サcツ;gモ???\0捍チ ィ?.?/?};ヘ驀G\0掌綺@q??!、?\0!?\0A?\0ルUWゥラ泅レヘoヌeマ oョ[I??\0Kヤkッヌオ?\0顆SアSホ?ミz・/ネヌe?2ンKャ?p栽ハニe?+ル??Sル??\0「z旨スl~ン? ロ? -ウミコ拾ネ贐??2.ェヨ条納?G??\0テW[ヨz??4)RI$ぁ?ミ?棚%( +kヲtフ鶴PQaモqqc?4{セ林k9ヒ????0?&&ミ?N??ラt?,ャ蹶Xkヌア?{ -cA?M熟?5ユキ?z櫃モVーヌ?洽゚Oワヌ?=g?/URハヲ?ュfMfbメ磅ナ ャカ楠ネソ?5ケセ槎カモ???\0癡Iメコ?ネ髦ヨ覿f(#?}?ト跟ル?ャ?w?ムソモウ?ム???v;ヨチオホ] 植?藷キロ^Ulリ???/]カ穴゙?1ョ。??珠Rヨ゙ロ\'cュカヲ\nw?ケカS???ョハ?Eネ???ヤZヒ1?ロ} ?ホトホニwキf]{ソG^レ?z?o?アB2ンhkMWテサ讖+G?撥n?曝ワテ-sH゚]オサMユロ[嫺ネUユZ7Uョヤケ?ム??鋳扨&Nリ\'ケ?ヤ鍜魁w*uーn?]T\r?オ淑?$ク?fミラ7ヤc?\0yt}Cュ袗?1q@shs境hv?z孀??\0en??,w?ッ?」ッ「8モ壙*ュヌ!平ク・ーb?娩w?Os??Fマム・e猷cア囘;壑mdl斟m?;cン[?/?\0セ#L?。?ス|?フヘ_r?8Xzォ*}?:嗅ー1??Xラナフヌタニgカラロ?9セッゥ?\r?\0・?\0エ?ネ鶚?ラ}?冐熊スレ2キ?\0Hォ.カサラ9?}麟~;?\0M??c2?ツqエ7?潟*8囚キ!?oァ?oィ?イ-g?/ムォ4?\n??ノキカケ?譱#}5;e?愧_レ3=oァ??ッ^7?iオ7?$欅??音yカゥ?モ?カャ[Csキt惘Uョゥ盻ョウ.キリ鍄?[= }oNヒ?\0]c瞠Kz?ォゥヤ?gィ?UfツK?マ?eサ~ム]_ヲ?\0ョ.?蹠wNテヲ?ォ?/sンー争?zuz椏Y?エウラゥ?灌渭ェ[コSウ歉妻ッn;\0ュカ今?/;娟F0?nヘソ、ルウラ?% ゙ウ\"b}<]o??4コユトoLヌ鶚?゙?PキOx?{hヌョ媼??\00バ?」ヨサ゚mヨzカ*NCァ釁FV17aneu=ミ甼⊥霽;lnラ2?ス椚Lコレoッ?ッ?g+7\"囿?カ貂3=ト青\0凡旌3u?種?2ヨl?Oユ?wセーcgt??マQヌョヌオ?.ャセニ揮羞☆5;布゚ヲキ?Y?漆鯏 ア0D?猖ラd=ッ?ハ黨ケ.ムc?ウpSNwレュ}クケ/kw??0セラ?%jcgソェcX猝ワヒ+s宜?8Xハ??62?+}ウgモカェスOラ=5ホu゙?:eュネ\ru廟Xイ?‡{ナgルeyt\r布V^マ輌滌?>ロ遣疼ヌa粭z?,uホ~8pュ?;Vオマヌ,?>Eフゥ?ェソE努鬩ア?\0h???゚Tンh\\ョス9焦n].uァモ檎ニ? ッァ~ンヘk?゚窓m蘗?ョ*絽ァgbキォ瞼uュ]オ゙>?盟???b?ョs=?J?\0@シナVヒ2タ恕D瘻>・(゙テ???メ?lfオマ?乍謔ャaV?.kZメO.0??U;UY?\Zヨ勿!?2v4{ルイカYオロ?\0孕ルウ?%kVェq?[疫m」ォオ孀mリ1?Fュ?xル?葆ヲ??\'g」岨。?2\rュk麒ュフ,徒[シケム鎹?\0ヘネキ?m?\0カ?oP鰈Tハ\0qスオ脆?bルッ{,?抔ア??\0驃e溂テ \0 ?ラ?ュ\\テ○?遊^?ッ、?メipp;墮?;ヌ?W頷d?g?=OO*玄ドゥ湲「シ7ソォEwQeV9ユケヘ?メicソAk-v?ッモ゚K?=フ」\"ォQユ?2コ?、ローuzE\rカヒ^X??dンヒ-ホェヲ葫fCG?M゚ヘ??、}\\鎔mYY8ュキ エ?S菜ニ輅o「イ广?~マユi?\0??斬DフqkF#cテ?F=?9xKォu:e?ラ??゙?9^?s ?サ\rモ掌黔m?%ヨzy??\0ミセ、?Gゥ6ヨ9?コハZ?E>テキ}u?際ン?写キ?夛?gイ岸VXス諂ク?-眩」??bヨ゚Iセマ詼??%K究?<_bエキ?埠{i,wWスケCa^ラnネユeエ?[V58孺v[?滯+VF5 4クヤlク5桾ヤ=???67ワ??}ャ゚些オ[??ア?~ュu?シャォZ?ロリ貶?~?\"ュソ、ェ暄z~ァゥ^?・Vーヘ?\'?4裔ス?ツ彑?lォh・マゥ?;ムv-98エワ/輌ス\\ed?濱モキ?゚Xu4レ?堯ヤャ餾.-ョ?U_Pメ證ッ?eiッゥUo?Isラ奧ュ?\'ヤロカt?スF螺}ceャ蘭?イ粐?レ?^ョP?t??E>ァ? フスZ?\0iz゚狄}?\0ル゚サ?・Vホ}X藥?\r[??、?モ?gァ絹nム、チU八vロ\Z?\n~#S?ァアトs鯔\Zォs??「/hー;?{~??\0戀}5スメュ フソxn59、ヨラオサ儼Sbレ唳_VMァェ湲?zヤャN鰐ヒゥ師エリテ゚^゙??\0嫐1]ッィ〔1ヘ[リ?ム]ャ?ミ踰ユ?7モイ溽jアZ4t:iH/W??K?趾サ*ラ萬亭ケ???゚Eソ」ァ?+A9?3W??-キa\rn-lvリoィ??5lウ?ヤdア?~C゚?/?s?/ヌaョヌ}攴wロUチヨ5ュl>テ^c?Tキ?敷ト>。メ?〃^$c}ュフウkエワZ=wャ?櫃メァユソ? ゚層」?鬲F\":?リォa?サ=クュ#サ%ホ\Z・チョ?-オ]1?7~潮??sユコ・ヨロ_Rチ?/ヌ}oェ\Zリ??ッ「ニ\rヘケ崟???Dケl?bレ?? YcY?#齲=@マルマソk,セロ\\ヌ?ヨソ?ャY鹽;wャKウ1ウ N、\n,ャ蜥稷ウヤォu\'リ觴k况~NGゥ風m゙ュ」Sルメ#?ナGッ?-?黙ケク]5ンUナュソ ?スメ $幀ナョノ?-wゥ嬾+?\'ァイ?ム??\0Hシ。v゚Zz摧taステ?=Jヘト5?~ォS゙?9?\0ス?「゚ム??Oァ~粐U\\?ツ?サ!?x???ヤ?棚%;?\0W?siq頃茸W]メ~゚c橄ィ?ケ残壙\Zツ?モcイア゙ヘロ??ァ?\0 j?{?6イチ???:Sェハ?゙3?x~??Zキqツ?%?? ニゥニfニ;Hun-2;?3w?)ct?ョカロ?x??ー?\0Snサ?K崕?ニ?\0チウ??,Aナハ脊O Gツナァコ?ロZ*kXK????#ャ暉セ滓11H鳧ー媾?5ラY苗nュ・ニヌス?.ロ足鬮ヨgゥ霍? ?\Zムイメ^粫?ヌ5?\rレ7サw??Mャ?クhc???.コri}9X?ァ毳.」yam剤?;=ロ^?點?\0ェラ?ulメ?.ナ7 l2\\6=OEホ;_eロh?ヨ?\0?F?チ帯ヘ、9セオU]kタ.ァヤカ」ス7゙1ルgヲ?+Cゥeカタモモ?ユ?\09n鷽メ賻ヘ???フ??? ヲフWキhリモVネ:?}.ヌpワ??\0チ?筰G%lA?GJiソ ヤ」モ・?ケチ?カ?O」?策佞イ?KV゚?棯ニヒ、Znサ+モヌツヌk[殯陽UヤX?アョsr22.?q*?騷>ァァ?奇Q?8ツム拘ル鶸%ル蒙レェ゚セ?^ラ=エZ釋F?MY??ン?拗モモ?)鮑sー4m>]?ラ\r?ルスフナァ?[??後F?ィ4tr?Yソュu;s?嫋 「親オTチイ??嬌?=?組、牒f??ユ?棚%)Yチホサ\n疇gOホネU誰血M?>?>ー3%セメ ウク?メ緘オワ? ニX?璋8オテPF???k??\r.mタ~?3?s テ$%ソ、?\0ヘFッッラ?1ッ?)リ?,}6リ?4ミ\\[?w?モシ~ムワユ覽?\0?丸?kワ8\"ヌ?饉?1コ?3V;G????ゥ+?錠゚チO。eGャ鍄釀k6??\'鏝[ォ/??\'ャ?a?6ァcfワ?8z亰サヤハーク?.ゥニャ*?゚Sラネョ??モ?\06シ?\0;?ヨ ヨコキe\Z)x!ユcオエエν閹>ニ?\0ニス??#oQHェ搦サ?+ォE聞、mナェaロdT??\0?ヲ{+?o埴K緒鷙アメIC)&メ、棚??ル\08BIM!\ZVersion compatibility info\0\0\0\0U\0\0\0\0\0\0\0A\0d\0o\0b\0e\0 \0P\0h\0o\0t\0o\0s\0h\0o\0p\0\0\0\0A\0d\0o\0b\0e\0 \0P\0h\0o\0t\0o\0s\0h\0o\0p\0 \06\0.\00\0\0\0\08BIM JPEG Quality\0\0\0\0\0\0\0\0\0?ロ\0C\0\n\n\n \n \Z%\Z# , #&\')*)-0-(0%()(?ロ\0C\n\n\n\n(\Z\Z((((((((((((((((((((((((((((((((((((((((((((((((((?タ\0\0x\0u\0?ト\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\08\0\0\0\0\0\0!1AQ\"aq?2贈ア#BRbムr$3チ盍?ト\0\Z\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\00\0\0\0\0\0\0\0!1\"AQ2aBアムq■チ碵#R??レ\0 \0\0?\0?\0\0P@\0s?7浮ニ護|馬???・sgツルk・ カナヨCヒZ姉カ?ウ_gケラPc?゚P」ュKムノ~%?B,?チケ?%-62r?」胖、zL凶ae鰯9I舵Bャ4Egqqtム\'\Z?\n\0(\0??\n\0(\0?・+?m監スモ? !Oa?->厭Y\n蜥コー?tPa?9?OフラAF+す9ヨ? 厶。控t??>エラ?\n?|?みル篦A」=マ(<フwウ?VMウノマHコヤ{9則1? キ\'}?ヲXR\\イ7?9 v?チハc6XY?ル゚ラ。Jo4?\0?*\\咏{\"シイ介ク~Fサ?6ホ5 窖7?\'ヲ源ヌヌリ{2ケcx、h薈GSヲV\Z ?Xレqtニ8T\0P@\0\0Pカデ& テyW[KァP[袢\\・?8ォ\n」冨宗・?&カ9Q]職c?}シ?骭sv>^T\'\'?!、?1キ?wK+蠏詢C1e?\'ハウK\'?楓%?ネ???)夜繩?レ\r\0ロ」Drニ~=欺八1ゥ~モKsqk!リa4\'G舫躬B榕「クキ\Z?\"rフtャOQ?吊租qak遵?/\ZRフ6_?ネ>エロ??ョ\\オG、bセメ0i廳ォォDciイ愕?\0i?\0!襌Uコス.?kア!橡ナ倆pヘ@\0\0ヌテヨ?「窰?シサ??ワcオ &銚j??;鰍蝣iヤルセロ?*=)蜩消」eナ??..?? P?ノ??o・7?WB?c>S吟??Fミン\\iBコ丞?\0ネ??v?フフr?5,モ%?m停Cッ?シ醂(\'@?ォ・襲坪?3ヒサ*s?フ|エ)ノmvセ2/?髣?B+岻ナ鱠オモ,Χ*VAツ?9F・?\07V燻鬢 d磊Oyサオ?Hタ?7ヨス?td濫績明L」\Zァ$hタC?? >オメーノ%tv肆?Y/mニフ艀?。}\r??)苴j?\0bヲ?%?0メツ,ケ莓Rハニ\'フ@ル\'ッN柆 cI?\'ヒリf琲ウ7y(ュヲコ?,アH????ラcュS昴Qm.? ・|喟p??\r,wK-ワカアーェ?H?iG&頌eョ6ゥ亘チ<7o>ヌ?錘OッJ?-ム3SN?<ンヤカkm{?;I良Hタ?__スbヒゥZ蒙Y齲イサ)ツ?dヲ?^V,靭◎眈?\0zウ・ニ71%?7チIi%ト7\r ?t??uラマフw?ヨ未ヨ荳+?:fオ依リ?,Sハ\\r?]ラ_]ラ/&)oi\Zc%FY??篤Mヘe 儿ナt?コ涎Nカ+&?\\olゥ亰q\r@?ヘ0tユウFシ?~テ?*ヌQ・マツ3l喜,ソ┐P?/qK擽7Xキ貅キ@$エ裲?ラ?<梛ゥ???\0Q\'S弁S?6W^蛩糺ャョ@?tケ0ニj?ィ?8滯慶ヒAh特$e」?6シ、}:茅j\n\0租ygSスuュレ.ルCmカZ?3hカ??H・eSコ8 ?K??ぬワケ??吏旭aヌBキ―濶h屁ィ゚??ラM謗:r脯??桟摂テ~ハ?P^d艪5ム=リエmョ?ソ躡?ム???モカ1gqヨウ??+ケSキ%<6揃???6)オmEムsG }ク\rケ渠詞??9セ鐡?7pqY(?8膩レ?ラ~楫Z?qkyツw7?Q沙Xハ\r?ョキ?0Eャェ+臟?洽゚Oワヌ?=g?/URハヲ?ュfMfbメ磅ナ ャカ楠ネソ?5ケセ槎カモ???\0癡Iメコ?ネ髦ヨ覿f(#?}?ト跟ル?ャ?w?ムソモウ?ム???v;ヨチオホ] 植?藷キロ^Ulリ???/]カ穴゙?1ョ。??珠Rヨ゙ロ\'cュカヲ\nw?ケカS???ョハ?Eネ???ヤZヒ1?ロ} ?ホトホニwキf]{ソG^レ?z?o?アB2ンhkMWテサ讖+G?撥n?曝ワテ-sH゚]オサMユロ[嫺ネUユZ7Uョヤケ?ム??鋳扨&Nリ\'ケ?ヤ鍜魁w*uーn?]T\r?オ淑?$ク?fミラ7ヤc?\0yt}Cュ袗?1q@shs境hv?z孀??\0en??,w?ッ?」ッ「8モ壙*ュヌ!平ク・ーb?娩w?Os??Fマム・e猷cア囘;壑mdl斟m?;cン[?/?\0セ#L?。?ス|?フヘ_r?8Xzォ*}?:嗅ー1??Xラナフヌタニgカラロ?9セッゥ?\r?\0・?\0エ?ネ鶚?ラ}?冐熊スレ2キ?\0Hォ.カサラ9?}麟~;?\0M??c2?ツqエ7?潟*8囚キ!?oァ?oィ?イ-g?/ムォ4?\n??ノキカケ?譱#}5;e?愧_レ3=oァ??ッ^7?iオ7?$欅??音yカゥ?モ?カャ[Csキt惘Uョゥ盻ョウ.キリ鍄?[= }oNヒ?\0]c瞠Kz?ォゥヤ?gィ?UfツK?マ?eサ~ム]_ヲ?\0ョ.?蹠wNテヲ?ォ?/sンー争?zuz椏Y?エウラゥ?灌渭ェ[コSウ歉妻ッn;\0ュカ今?/;娟F0?nヘソ、ルウラ?% ゙ウ\"b}<]o??4コユトoLヌ鶚?゙?PキOx?{hヌョ媼??\00バ?」ヨサ゚mヨzカ*NCァ釁FV17aneu=ミ甼⊥霽;lnラ2?ス椚Lコレoッ?ッ?g+7\"囿?カ貂3=ト青\0凡旌3u?種?2ヨl?Oユ?wセーcgt??マQヌョヌオ?.ャセニ揮羞☆5;布゚ヲキ?Y?漆鯏 ア0D?猖ラd=ッ?ハ黨ケ.ムc?ウpSNwレュ}クケ/kw??0セラ?%jcgソェcX猝ワヒ+s宜?8Xハ??62?+}ウgモカェスOラ=5ホu゙?:eュネ\ru廟Xイ?‡{ナgルeyt\r布V^マ輌滌?>ロ遣疼ヌa粭z?,uホ~8pュ?;Vオマヌ,?>Eフゥ?ェソE努鬩ア?\0h???゚Tンh\\ョス9焦n].uァモ檎ニ? ッァ~ンヘk?゚窓m蘗?ョ*絽ァgbキォ瞼uュ]オ゙>?盟???b?ョs=?J?\0@シナVヒ2タ恕D瘻>・(゙テ???メ?lfオマ?乍謔ャaV?.kZメO.0??U;UY?\Zヨ勿!?2v4{ルイカYオロ?\0孕ルウ?%kVェq?[疫m」ォオ孀mリ1?Fュ?xル?葆ヲ??\'g」岨。?2\rュk麒ュフ,徒[シケム鎹?\0ヘネキ?m?\0カ?oP鰈Tハ\0qスオ脆?bルッ{,?抔ア??\0驃e溂テ \0 ?ラ?ュ\\テ○?遊^?ッ、?メipp;墮?;ヌ?W頷d?g?=OO*玄ドゥ湲「シ7ソォEwQeV9ユケヘ?メicソAk-v?ッモ゚K?=フ」\"ォQユ?2コ?、ローuzE\rカヒ^X??dンヒ-ホェヲ葫fCG?M゚ヘ??、}\\鎔mYY8ュキ エ?S菜ニ輅o「イ广?~マユi?\0??斬DフqkF#cテ?F=?9xKォu:e?ラ??゙?9^?s ?サ\rモ掌黔m?%ヨzy??\0ミセ、?Gゥ6ヨ9?コハZ?E>テキ}u?際ン?写キ?夛?gイ岸VXス諂ク?-眩」??bヨ゚Iセマ詼??%K究?<_bエキ?埠{i,wWスケCa^ラnネユeエ?[V58孺v[?滯+VF5 4クヤlク5桾ヤ=???67ワ??}ャ゚些オ[??ア?~ュu?シャォZ?ロリ貶?~?\"ュソ、ェ暄z~ァゥ^?・Vーヘ?\'?4裔ス?ツ彑?lォh・マゥ?;ムv-98エワ/輌ス\\ed?濱モキ?゚Xu4レ?堯ヤャ餾.-ョ?U_Pメ證ッ?eiッゥUo?Isラ奧ュ?\'ヤロカt?スF螺}ceャ蘭?イ粐?レ?^ョP?t??E>ァ? フスZ?\0iz゚狄}?\0ル゚サ?・Vホ}X藥?\r[??、?モ?gァ絹nム、チU八vロ\Z?\n~#S?ァアトs鯔\Zォs??「/hー;?{~??\0戀}5スメュ フソxn59、ヨラオサ儼Sbレ唳_VMァェ湲?zヤャN鰐ヒゥ師エリテ゚^゙??\0嫐1]ッィ〔1ヘ[リ?ム]ャ?ミ踰ユ?7モイ溽jアZ4t:iH/W??K?趾サ*ラ萬亭ケ???゚Eソ」ァ?+A9?3W??-キa\rn-lvリoィ??5lウ?ヤdア?~C゚?/?s?/ヌaョヌ}攴wロUチヨ5ュl>テ^c?Tキ?敷ト>。メ?〃^$c}ュフウkエワZ=wャ?櫃メァユソ? ゚層」?鬲F\":?リォa?サ=クュ#サ%ホ\Z・チョ?-オ]1?7~潮??sユコ・ヨロ_Rチ?/ヌ}oェ\Zリ??ッ「ニ\rヘケ崟???Dケl?bレ?? YcY?#齲=@マルマソk,セロ\\ヌ?ヨソ?ャY鹽;wャKウ1ウ N、\n,ャ蜥稷ウヤォu\'リ觴k况~NGゥ風m゙ュ」Sルメ#?ナGッ?-?黙ケク]5ンUナュソ ?スメ $幀ナョノ?-wゥ嬾+?\'ァイ?ム??\0Hシ。v゚Zz摧taステ?=Jヘト5?~ォS゙?9?\0ス?「゚ム??Oァ~粐U\\?ツ?サ!?x???ヤ?棚%;?\0W?siq頃茸W]メ~゚c橄ィ?ケ残壙\Zツ?モcイア゙ヘロ??ァ?\0 j?{?6イチ???:Sェハ?゙3?x~??Zキqツ?%?? ニゥニfニ;Hun-2;?3w?)ct?ョカロ?x??ー?\0Snサ?K崕?ニ?\0チウ??,Aナハ脊O Gツナァコ?ロZ*kXK????#ャ暉セ滓11H鳧ー媾?5ラY苗nュ・ニヌス?.ロ足鬮ヨgゥ霍? ?\Zムイメ^粫?ヌ5?\rレ7サw??Mャ?クhc???.コri}9X?ァ毳.」yam剤?;=ロ^?點?\0ェラ?ulメ?.ナ7 l2\\6=OEホ;_eロh?ヨ?\0?F?チ帯ヘ、9セオU]kタ.ァヤカ」ス7゙1ルgヲ?+Cゥeカタモモ?ユ?\09n鷽メ賻ヘ???フ??? ヲフWキhリモVネ:?}.ヌpワ??\0チ?筰G%lA?GJiソ ヤ」モ・?ケチ?カ?O」?策佞イ?KV゚?棯ニヒ、Znサ+モヌツヌk[殯陽UヤX?アョsr22.?q*?騷>ァァ?奇Q?8ツム拘ル鶸%ル蒙レェ゚セ?^ラ=エZ釋F?MY??ン?拗モモ?)鮑sー4m>]?ラ\r?ルスフナァ?[??後F?ィ4tr?Yソュu;s?嫋 「親オTチイ??嬌?=?組、牒f??ユ?棚%)Yチホサ\n疇gOホネU誰血M?>?>ー3%セメ ウク?メ緘オワ? ニX?璋8オテPF???k??\r.mタ~?3?s テ$%ソ、?\0ヘFッッラ?1ッ?)リ?,}6リ?4ミ\\[?w?モシ~ムワユ覽?\0?丸?kワ8\"ヌ?饉?1コ?3V;G????ゥ+?錠゚チO。eGャ鍄釀k6??\'鏝[ォ/??\'ャ?a?6ァcfワ?8z亰サヤハーク?.ゥニャ*?゚Sラネョ??モ?\06シ?\0;?ヨ ヨコキe\Z)x!ユcオエエν閹>ニ?\0ニス??#oQHェ搦サ?+ォE聞、mナェaロdT??\0?ヲ{+?o埴K緒鷙アメIC)&メ、棚??ル\08BIM!\ZVersion compatibility info\0\0\0\0U\0\0\0\0\0\0\0A\0d\0o\0b\0e\0 \0P\0h\0o\0t\0o\0s\0h\0o\0p\0\0\0\0A\0d\0o\0b\0e\0 \0P\0h\0o\0t\0o\0s\0h\0o\0p\0 \06\0.\00\0\0\0\08BIM JPEG Quality\0\0\0\0\0\0\0\0\0?ロ\0C\0\n\n\n \n \Z%\Z# , #&\')*)-0-(0%()(?ロ\0C\n\n\n\n(\Z\Z((((((((((((((((((((((((((((((((((((((((((((((((((?タ\0\0x\0u\0?ト\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\08\0\0\0\0\0\0!1AQ\"aq?2贈ア#BRbムr$3チ盍?ト\0\Z\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\00\0\0\0\0\0\0\0!1\"AQ2aBアムq■チ碵#R??レ\0 \0\0?\0?\0\0P@\0s?7浮ニ護|馬???・sgツルk・ カナヨCヒZ姉カ?ウ_gケラPc?゚P」ュKムノ~%?B,?チケ?%-62r?」胖、zL凶ae鰯9I舵Bャ4Egqqtム\'\Z?\n\0(\0??\n\0(\0?・+?m監スモ? !Oa?->厭Y\n蜥コー?tPa?9?OフラAF+す9ヨ? 厶。控t??>エラ?\n?|?みル篦A」=マ(<フwウ?VMウノマHコヤ{9則1? キ\'}?ヲXR\\イ7?9 v?チハc6XY?ル゚ラ。Jo4?\0?*\\咏{\"シイ介ク~Fサ?6ホ5 窖7?\'ヲ源ヌヌリ{2ケcx、h薈GSヲV\Z ?Xレqtニ8T\0P@\0\0Pカデ& テyW[KァP[袢\\・?8ォ\n」冨宗・?&カ9Q]職c?}シ?骭sv>^T\'\'?!、?1キ?wK+蠏詢C1e?\'ハウK\'?楓%?ネ???)夜繩?レ\r\0ロ」Drニ~=欺八1ゥ~モKsqk!リa4\'G舫躬B榕「クキ\Z?\"rフtャOQ?吊租qak遵?/\ZRフ6_?ネ>エロ??ョ\\オG、bセメ0i廳ォォDciイ愕?\0i?\0!襌Uコス.?kア!橡ナ倆pヘ@\0\0ヌテヨ?「窰?シサ??ワcオ &銚j??;鰍蝣iヤルセロ?*=)蜩消」eナ??..?? P?ノ??o・7?WB?c>S吟??Fミン\\iBコ丞?\0ネ??v?フフr?5,モ%?m停Cッ?シ醂(\'@?ォ・襲坪?3ヒサ*s?フ|エ)ノmvセ2/?髣?B+岻ナ鱠オモ,Χ*VAツ?9F・?\07V燻鬢 d磊Oyサオ?Hタ?7ヨス?td濫績明L」\Zァ$hタC?? >オメーノ%tv肆?Y/mニフ艀?。}\r??)苴j?\0bヲ?%?0メツ,ケ莓Rハニ\'フ@ル\'ッN柆 cI?\'ヒリf琲ウ7y(ュヲコ?,アH????ラcュS昴Qm.? ・|喟p??\r,wK-ワカアーェ?H?iG&頌eョ6ゥ亘チ<7o>ヌ?錘OッJ?-ム3SN?<ンヤカkm{?;I良Hタ?__スbヒゥZ蒙Y齲イサ)ツ?dヲ?^V,靭◎眈?\0zウ・ニ71%?7チIi%ト7\r ?t??uラマフw?ヨ未ヨ荳+?:fオ依リ?,Sハ\\r?]ラ_]ラ/&)oi\Zc%FY??篤Mヘe 儿ナt?コ涎Nカ+&?\\olゥ亰q\r@?ヘ0tユウFシ?~テ?*ヌQ・マツ3l喜,ソ┐P?/qK擽7Xキ貅キ@$エ裲?ラ?<梛ゥ???\0Q\'S弁S?6W^蛩糺ャョ@?tケ0ニj?ィ?8滯慶ヒAh特$e」?6シ、}:茅j\n\0租ygSスuュレ.ルCmカZ?3hカ??H・eSコ8 ?K??ぬワケ??吏旭aヌBキ―濶h屁ィ゚??ラM謗:r脯??桟摂テ~ハ?P^d艪5ム=リエmョ?ソ躡?ム???モカ1gqヨウ??+ケSキ%<6揃???6)オmEムsG }ク\rケ渠詞??9セ鐡?7pqY(?8膩レ?ラ~楫Z?qkyツw7?Q沙Xハ\r?ョキ?0Eャェ+臟?剋?フヲO>--d邉ヌゥ?2;3o縊ケ?\0ョウ7ゥ績?&ヨAツ?\n\0コ皰匆シRヌQ撞]&Mムxル?\nCow|nヨFハ ?跡_6ヤv曾ルャ?c?N??+,サ?/,??ツ6?ウt?;?z]Y[;? ーG Cァュ/( レ休計゚*5ハ{・Cwヒ$F耄}?81VQ3鋲iァc・Qセロ?饂t?9z?+ネ婬?K夢Hュ預?N必?紹アw?>??(Bヒowl\"F#?\0?Drァφ?トq?we\'褂?!\"9q?;。ラマ_?.5?fM?9 Yノik)9ォ泌\nュアn?ネ??3?aタア?6ユヌ-\n\0(\0??韲SFNrF?トヒ[i?+o。?シfウヌr?nX??%モtD」ノ#U崙ナ劵R_\\ト寿Q蜩ナacUU? LHQ熾z?5\0Rdョ.螻箪t??Ne?ュ:I?$C? ?/ュヲC{qツノ「]G!ル:?=*??T*ソr?7瞳エ?!?\0?\r闢?スMUJO○Hニ?レ!テ4鯨,?\rC\0n?{囚?ュ9}<カ?ナケ3ハd.イ? ?詈ョfngv=IョL跏?)\0(\0??\n\0?エn :?)??9n?5fγワnヨッ7メrミ?類コpヘ ゚f/(レp\\GトHノ2ー>?P「lmウハォト?:ュトぼ 梯?J?tKwhー?<1ラAコ囹+g8?m&ノ_[ォ\"?域?@:衍^アレキツ\"フw??ョヘvd??1?7s/ニG????Sヤテ\Zャ|ソ??Ck}?5ト?フ?H?逋斟ヒRk跏?掖?\0P@\0\0P@l2鱗?ウケ?/?=?*セ\Z恊篳、2リ?マZkRC&ソス?ムォ無?(婚ボZ?2コOt_氣O??{^ミ?iS潜?ラハノ&RXムコ??コメス\\?\0\nK?。エW框n%i\'大遜ウアb~讓懷7rv5t?\0P@\0?ル?リ??\0JFIF\0\0p\0p\0\0??ヤPhotoshop 3.0\08BIM?\nPrint Info\0\0\0\0x\0\0P\0H\0H\0\0\0\0レ(?????FP\0(?\0\0P\0H\0H\0\0\0\0レ(\0\0\0\0\0d\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\0d\0\0\0\0\0\0\"r\0\0\0\0\0\0\0\0\0\0\0\0?|\0\0\08BIM?\nResolution\0\0\0\0\0pU?\0\0\0pU?\0\08BIM\rFX Global Lighting Angle\0\0\0\0\0\0\0x8BIMFX Global Altitude\0\0\0\0\0\0\08BIM? Print Flags\0\0\0 \0\0\0\0\0\0\0\0\08BIM\nCopyright Flag\0\0\0\0\0\08BIM\'Japanese Print Flags\0\0\0\0\n\0\0\0\0\0\0\0\08BIM?Color Halftone Settings\0\0\0H\0/ff\0\0lff\0\0\0\0\0\0\0/ff\0\0。劒\0\0\0\0\0\0\02\0\0\0\0Z\0\0\0\0\0\0\0\0\05\0\0\0\0-\0\0\0\0\0\0\0\08BIM?Color Transfer Settings\0\0\0p\0\0???????????????????????\0\0\0\0???????????????????????\0\0\0\0???????????????????????\0\0\0\0???????????????????????\0\08BIM\0 Layer State\0\0\0\08BIM Layer Groups\0\0\0\0\0\0\0\08BIMGuges\0\0\0\0\0\0\0\0\0@\0\0@\0\0\0\08BIM\rURL overrges\0\0\0\0\0\0\08BIM\ZSlices\0\0\0\0u\0\0\0\0\0\0\0\0\0\0\0\0\0I\0\0:\0\0\0\n\0U\0n\0t\0i\0t\0l\0e\0d\0-\01\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\0I\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\08BIMICC Untagged Flag\0\0\0\08BIMLayer g Generator Base\0\0\0\0\0\08BIM New Windows Thumbnail\0\0i\0\0\0\0\0\0m\0\0\0p\0\0H\0\0準\0\0M\0\0?リ??\0JFIF\0\0H\0H\0\0??\0Adobe\0d?\0\0\0?ロ\0?\0    \n    \r \r\r   ?タ\0\0p\0m\"\0?ン\0\0?ト?\0\0\0\0\0\0\0\0\0\0 \n \0\0\0\0\0\0\0\0\0 \n \0 3\0!1AQa\"q?2贈アB#$Rチb34rびC%担??s5「イ?&D典dEツ」t6メU稙??モu胚F\'筈?米ヤ蔬・オナユ襄Vfv?ヲカニヨ踐7GWgw?ァキヌラ銷\05\0!1AQaq\"2¢。アB#チRム?3$b疵rCScs4?%「イ?&5ツメD典」dEU6te糘ウ?モu胚F筈?米ヤ蔬・オナユ襄Vfv?ヲカニヨ踐\'7GWgw?ァキヌ?レ\0 \0\0?\0?棚%)$瞳施セ$如$ミユK#總詁ヌゥヨv?4?\09htタaマ\0サ?\"G??ヒr較C}:?p-?? ロ?コカヨヨツウW?ミヲaトォ?Tアチ?[ワ$1マ?;?=M?\0Sz?K+ネヘv7?\rkェタツキ\Zソエu~ョX?)ニdエリO?oルV=゚G~マエ_?オd?k゙ハ?ァ\0レワ?゚T?\06ラ?サcツ;gモ???\0捍チ ィ?.?/?};ヘ驀G\0掌綺@q??!、?\0!?\0A?\0ルUWゥラ泅レヘoヌeマ oョ[I??\0Kヤkッヌオ?\0顆SアSホ?ミz・/ネヌe?2ンKャ?p栽ハニe?+ル??Sル??\0「z旨スl~ン? ロ? -ウミコ拾ネ贐??2.ェヨ条納?G??\0テW[ヨz??4)RI$ぁ?ミ?棚%( +kヲtフ鶴PQaモqqc?4{セ林k9ヒ????0?&&ミ?N??ラt?,ャ蹶Xkヌア?{ -cA?M熟?5ユキ?z櫃モVーヌ?洽゚Oワヌ?=g?/URハヲ?ュfMfbメ磅ナ ャカ楠ネソ?5ケセ槎カモ???\0癡Iメコ?ネ髦ヨ覿f(#?}?ト跟ル?ャ?w?ムソモウ?ム???v;ヨチオホ] 植?藷キロ^Ulリ???/]カ穴゙?1ョ。??珠Rヨ゙ロ\'cュカヲ\nw?ケカS???ョハ?Eネ???ヤZヒ1?ロ} ?ホトホニwキf]{ソG^レ?z?o?アB2ンhkMWテサ讖+G?撥n?曝ワテ-sH゚]オサMユロ[嫺ネUユZ7Uョヤケ?ム??鋳扨&Nリ\'ケ?ヤ鍜魁w*uーn?]T\r?オ淑?$ク?fミラ7ヤc?\0yt}Cュ袗?1q@shs境hv?z孀??\0en??,w?ッ?」ッ「8モ壙*ュヌ!平ク・ーb?娩w?Os??Fマム・e猷cア囘;壑mdl斟m?;cン[?/?\0セ#L?。?ス|?フヘ_r?8Xzォ*}?:嗅ー1??Xラナフヌタニgカラロ?9セッゥ?\r?\0・?\0エ?ネ鶚?ラ}?冐熊スレ2キ?\0Hォ.カサラ9?}麟~;?\0M??c2?ツqエ7?潟*8囚キ!?oァ?oィ?イ-g?/ムォ4?\n??ノキカケ?譱#}5;e?愧_レ3=oァ??ッ^7?iオ7?$欅??音yカゥ?モ?カャ[Csキt惘Uョゥ盻ョウ.キリ鍄?[= }oNヒ?\0]c瞠Kz?ォゥヤ?gィ?UfツK?マ?eサ~ム]_ヲ?\0ョ.?蹠wNテヲ?ォ?/sンー争?zuz椏Y?エウラゥ?灌渭ェ[コSウ歉妻ッn;\0ュカ今?/;娟F0?nヘソ、ルウラ?% ゙ウ\"b}<]o??4コユトoLヌ鶚?゙?PキOx?{hヌョ媼??\00バ?」ヨサ゚mヨzカ*NCァ釁FV17aneu=ミ甼⊥霽;lnラ2?ス椚Lコレoッ?ッ?g+7\"囿?カ貂3=ト青\0凡旌3u?種?2ヨl?Oユ?wセーcgt??マQヌョヌオ?.ャセニ揮羞☆5;布゚ヲキ?Y?漆鯏 ア0D?猖ラd=ッ?ハ黨ケ.ムc?ウpSNwレュ}クケ/kw??0セラ?%jcgソェcX猝ワヒ+s宜?8Xハ??62?+}ウgモカェスOラ=5ホu゙?:eュネ\ru廟Xイ?‡{ナgルeyt\r布V^マ輌滌?>ロ遣疼ヌa粭z?,uホ~8pュ?;Vオマヌ,?>Eフゥ?ェソE努鬩ア?\0h???゚Tンh\\ョス9焦n].uァモ檎ニ? ッァ~ンヘk?゚窓m蘗?ョ*絽ァgbキォ瞼uュ]オ゙>?盟???b?ョs=?J?\0@シナVヒ2タ恕D瘻>・(゙テ???メ?lfオマ?乍謔ャaV?.kZメO.0??U;UY?\Zヨ勿!?2v4{ルイカYオロ?\0孕ルウ?%kVェq?[疫m」ォオ孀mリ1?Fュ?xル?葆ヲ??\'g」岨。?2\rュk麒ュフ,徒[シケム鎹?\0ヘネキ?m?\0カ?oP鰈Tハ\0qスオ脆?bルッ{,?抔ア??\0驃e溂テ \0 ?ラ?ュ\\テ○?遊^?ッ、?メipp;墮?;ヌ?W頷d?g?=OO*玄ドゥ湲「シ7ソォEwQeV9ユケヘ?メicソAk-v?ッモ゚K?=フ」\"ォQユ?2コ?、ローuzE\rカヒ^X??dンヒ-ホェヲ葫fCG?M゚ヘ??、}\\鎔mYY8ュキ エ?S菜ニ輅o「イ广?~マユi?\0??斬DフqkF#cテ?F=?9xKォu:e?ラ??゙?9^?s ?サ\rモ掌黔m?%ヨzy??\0ミセ、?Gゥ6ヨ9?コハZ?E>テキ}u?際ン?写キ?夛?gイ岸VXス諂ク?-眩」??bヨ゚Iセマ詼??%K究?<_bエキ?埠{i,wWスケCa^ラnネユeエ?[V58孺v[?滯+VF5 4クヤlク5桾ヤ=???67ワ??}ャ゚些オ[??ア?~ュu?シャォZ?ロリ貶?~?\"ュソ、ェ暄z~ァゥ^?・Vーヘ?\'?4裔ス?ツ彑?lォh・マゥ?;ムv-98エワ/輌ス\\ed?濱モキ?゚Xu4レ?堯ヤャ餾.-ョ?U_Pメ證ッ?eiッゥUo?Isラ奧ュ?\'ヤロカt?スF螺}ceャ蘭?イ粐?レ?^ョP?t??E>ァ? フスZ?\0iz゚狄}?\0ル゚サ?・Vホ}X藥?\r[??、?モ?gァ絹nム、チU八vロ\Z?\n~#S?ァアトs鯔\Zォs??「/hー;?{~??\0戀}5スメュ フソxn59、ヨラオサ儼Sbレ唳_VMァェ湲?zヤャN鰐ヒゥ師エリテ゚^゙??\0嫐1]ッィ〔1ヘ[リ?ム]ャ?ミ踰ユ?7モイ溽jアZ4t:iH/W??K?趾サ*ラ萬亭ケ???゚Eソ」ァ?+A9?3W??-キa\rn-lvリoィ??5lウ?ヤdア?~C゚?/?s?/ヌaョヌ}攴wロUチヨ5ュl>テ^c?Tキ?敷ト>。メ?〃^$c}ュフウkエワZ=wャ?櫃メァユソ? ゚層」?鬲F\":?リォa?サ=クュ#サ%ホ\Z・チョ?-オ]1?7~潮??sユコ・ヨロ_Rチ?/ヌ}oェ\Zリ??ッ「ニ\rヘケ崟???Dケl?bレ?? YcY?#齲=@マルマソk,セロ\\ヌ?ヨソ?ャY鹽;wャKウ1ウ N、\n,ャ蜥稷ウヤォu\'リ觴k况~NGゥ風m゙ュ」Sルメ#?ナGッ?-?黙ケク]5ンUナュソ ?スメ $幀ナョノ?-wゥ嬾+?\'ァイ?ム??\0Hシ。v゚Zz摧taステ?=Jヘト5?~ォS゙?9?\0ス?「゚ム??Oァ~粐U\\?ツ?サ!?x???ヤ?棚%;?\0W?siq頃茸W]メ~゚c橄ィ?ケ残壙\Zツ?モcイア゙ヘロ??ァ?\0 j?{?6イチ???:Sェハ?゙3?x~??Zキqツ?%?? ニゥニfニ;Hun-2;?3w?)ct?ョカロ?x??ー?\0Snサ?K崕?ニ?\0チウ??,Aナハ脊O Gツナァコ?ロZ*kXK????#ャ暉セ滓11H鳧ー媾?5ラY苗nュ・ニヌス?.ロ足鬮ヨgゥ霍? ?\Zムイメ^粫?ヌ5?\rレ7サw??Mャ?クhc???.コri}9X?ァ毳.」yam剤?;=ロ^?點?\0ェラ?ulメ?.ナ7 l2\\6=OEホ;_eロh?ヨ?\0?F?チ帯ヘ、9セオU]kタ.ァヤカ」ス7゙1ルgヲ?+Cゥeカタモモ?ユ?\09n鷽メ賻ヘ???フ??? ヲフWキhリモVネ:?}.ヌpワ??\0チ?筰G%lA?GJiソ ヤ」モ・?ケチ?カ?O」?策佞イ?KV゚?棯ニヒ、Znサ+モヌツヌk[殯陽UヤX?アョsr22.?q*?騷>ァァ?奇Q?8ツム拘ル鶸%ル蒙レェ゚セ?^ラ=エZ釋F?MY??ン?拗モモ?)鮑sー4m>]?ラ\r?ルスフナァ?[??後F?ィ4tr?Yソュu;s?嫋 「親オTチイ??嬌?=?組、牒f??ユ?棚%)Yチホサ\n疇gOホネU誰血M?>?>ー3%セメ ウク?メ緘オワ? ニX?璋8オテPF???k??\r.mタ~?3?s テ$%ソ、?\0ヘFッッラ?1ッ?)リ?,}6リ?4ミ\\[?w?モシ~ムワユ覽?\0?丸?kワ8\"ヌ?饉?1コ?3V;G????ゥ+?錠゚チO。eGャ鍄釀k6??\'鏝[ォ/??\'ャ?a?6ァcfワ?8z亰サヤハーク?.ゥニャ*?゚Sラネョ??モ?\06シ?\0;?ヨ ヨコキe\Z)x!ユcオエエν閹>ニ?\0ニス??#oQHェ搦サ?+ォE聞、mナェaロdT??\0?ヲ{+?o埴K緒鷙アメIC)&メ、棚??ル\08BIM!\ZVersion compatibility info\0\0\0\0U\0\0\0\0\0\0\0A\0d\0o\0b\0e\0 \0P\0h\0o\0t\0o\0s\0h\0o\0p\0\0\0\0A\0d\0o\0b\0e\0 \0P\0h\0o\0t\0o\0s\0h\0o\0p\0 \06\0.\00\0\0\0\08BIM JPEG Quality\0\0\0\0\0\0\0\0\0?ロ\0C\0\n\n\n \n \Z%\Z# , #&\')*)-0-(0%()(?ロ\0C\n\n\n\n(\Z\Z((((((((((((((((((((((((((((((((((((((((((((((((((?タ\0\0x\0u\0?ト\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\08\0\0\0\0\0\0!1AQ\"aq?2贈ア#BRbムr$3チ盍?ト\0\Z\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\00\0\0\0\0\0\0\0!1\"AQ2aBアムq■チ碵#R??レ\0 \0\0?\0?\0\0P@\0s?7浮ニ護|馬???・sgツルk・ カナヨCヒZ姉カ?ウ_gケラPc?゚P」ュKムノ~%?B,?チケ?%-62r?」胖、zL凶ae鰯9I舵Bャ4Egqqtム\'\Z?\n\0(\0??\n\0(\0?・+?m監スモ? !Oa?->厭Y\n蜥コー?tPa?9?OフラAF+す9ヨ? 厶。控t??>エラ?\n?|?みル篦A」=マ(<フwウ?VMウノマHコヤ{9則1? キ\'}?ヲXR\\イ7?9 v?チハc6XY?ル゚ラ。Jo4?\0?*\\咏{\"シイ介ク~Fサ?6ホ5 窖7?\'ヲ源ヌヌリ{2ケcx、h薈GSヲV\Z ?Xレqtニ8T\0P@\0\0Pカデ& テyW[KァP[袢\\・?8ォ\n」冨宗・?&カ9Q]職c?}シ?骭sv>^T\'\'?!、?1キ?wK+蠏詢C1e?\'ハウK\'?楓%?ネ???)夜繩?レ\r\0ロ」Drニ~=欺八1ゥ~モKsqk!リa4\'G舫躬B榕「クキ\Z?\"rフtャOQ?吊租qak遵?/\ZRフ6_?ネ>エロ??ョ\\オG、bセメ0i廳ォォDciイ愕?\0i?\0!襌Uコス.?kア!橡ナ倆pヘ@\0\0ヌテヨ?「窰?シサ??ワcオ &銚j??;鰍蝣iヤルセロ?*=)蜩消」eナ??..?? P?ノ??o・7?WB?c>S吟??Fミン\\iBコ丞?\0ネ??v?フフr?5,モ%?m停Cッ?シ醂(\'@?ォ・襲坪?3ヒサ*s?フ|エ)ノmvセ2/?髣?B+岻ナ鱠オモ,Χ*VAツ?9F・?\07V燻鬢 d磊Oyサオ?Hタ?7ヨス?td濫績明L」\Zァ$hタC?? >オメーノ%tv肆?Y/mニフ艀?。}\r??)苴j?\0bヲ?%?0メツ,ケ莓Rハニ\'フ@ル\'ッN柆 cI?\'ヒリf琲ウ7y(ュヲコ?,アH????ラcュS昴Qm.? ・|喟p??\r,wK-ワカアーェ?H?iG&頌eョ6ゥ亘チ<7o>ヌ?錘OッJ?-ム3SN?<ンヤカkm{?;I良Hタ?__スbヒゥZ蒙Y齲イサ)ツ?dヲ?^V,靭◎眈?\0zウ・ニ71%?7チIi%ト7\r ?t??uラマフw?ヨ未ヨ荳+?:fオ依リ?,Sハ\\r?]ラ_]ラ/&)oi\Zc%FY??篤Mヘe 儿ナt?コ涎Nカ+&?\\olゥ亰q\r@?ヘ0tユウFシ?~テ?*ヌQ・マツ3l喜,ソ┐P?/qK擽7Xキ貅キ@$エ裲?ラ?<梛ゥ???\0Q\'S弁S?6W^蛩糺ャョ@?tケ0ニj?ィ?8滯慶ヒAh特$e」?6シ、}:茅j\n\0租ygSスuュレ.ルCmカZ?3hカ??H・eSコ8 ?K??ぬワケ??吏旭aヌBキ―濶h屁ィ゚??ラM謗:r脯??桟摂テ~ハ?P^d艪5ム=リエmョ?ソ躡?ム???モカ1gqヨウ??+ケSキ%<6揃???6)オmEムsG }ク\rケ渠詞??9セ鐡?7pqY(?8膩レ?ラ~楫Z?qkyツw7?Q沙Xハ\r?ョキ?0Eャェ+臟?剋?フヲO>--d邉ヌゥ?2;3o縊ケ?\0ョウ7ゥ績?&ヨAツ?\n\0コ皰匆シRヌQ撞]&Mムxル?\nCow|nヨFハ ?跡_6ヤv曾ルャ?c?N??+,サ?/,??ツ6?ウt?;?z]Y[;? ーG Cァュ/( レ休計゚*5ハ{・Cwヒ$F耄}?81VQ3鋲iァc・Qセロ?饂t?9z?+ネ婬?K夢Hュ預?N必?紹アw?>??(Bヒowl\"F#?\0?Drァφ?トq?we\'褂?!\"9q?;。ラマ_?.5?fM?9 Yノik)9ォ泌\nュアn?ネ??3?aタア?6ユヌ-\n\0(\0??韲SFNrF?トヒ[i?+o。?シfウヌr?nX??%モtD」ノ#U崙ナ劵R_\\ト寿Q蜩ナacUU? LHQ熾z?5\0Rdョ.螻箪t??Ne?ュ:I?$C? ?/ュヲC{qツノ「]G!ル:?=*??T*ソr?7瞳エ?!?\0?\r闢?スMUJO○Hニ?レ!テ4鯨,?\rC\0n?{囚?ュ9}<カ?ナケ3ハd.イ? ?詈ョfngv=IョL跏?)\0(\0??\n\0?エn :?)??9n?5fγワnヨッ7メrミ?類コpヘ ゚f/(レp\\GトHノ2ー>?P「lmウハォト?:ュトぼ 梯?J?tKwhー?<1ラAコ囹+g8?m&ノ_[ォ\"?域?@:衍^アレキツ\"フw??ョヘvd??1?7s/ニG????Sヤテ\Zャ|ソ??Ck}?5ト?フ?H?逋斟ヒRk跏?掖?\0P@\0\0P@l2鱗?ウケ?/?=?*セ\Z恊篳、2リ?マZkRC&ソス?ムォ無?(婚ボZ?2コOt_氣O??{^ミ?iS潜?ラハノ&RXムコ??コメス\\?\0\nK?。エW框n%i\'大遜ウアb~讓懷7rv5t?\0P@\0?ル?リ??\0JFIF\0\0p\0p\0\0??ヤPhotoshop 3.0\08BIM?\nPrint Info\0\0\0\0x\0\0P\0H\0H\0\0\0\0レ(?????FP\0(?\0\0P\0H\0H\0\0\0\0レ(\0\0\0\0\0d\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\0d\0\0\0\0\0\0\"r\0\0\0\0\0\0\0\0\0\0\0\0?|\0\0\08BIM?\nResolution\0\0\0\0\0pU?\0\0\0pU?\0\08BIM\rFX Global Lighting Angle\0\0\0\0\0\0\0x8BIMFX Global Altitude\0\0\0\0\0\0\08BIM? Print Flags\0\0\0 \0\0\0\0\0\0\0\0\08BIM\nCopyright Flag\0\0\0\0\0\08BIM\'Japanese Print Flags\0\0\0\0\n\0\0\0\0\0\0\0\08BIM?Color Halftone Settings\0\0\0H\0/ff\0\0lff\0\0\0\0\0\0\0/ff\0\0。劒\0\0\0\0\0\0\02\0\0\0\0Z\0\0\0\0\0\0\0\0\05\0\0\0\0-\0\0\0\0\0\0\0\08BIM?Color Transfer Settings\0\0\0p\0\0???????????????????????\0\0\0\0???????????????????????\0\0\0\0???????????????????????\0\0\0\0???????????????????????\0\08BIM\0 Layer State\0\0\0\08BIM Layer Groups\0\0\0\0\0\0\0\08BIMGuges\0\0\0\0\0\0\0\0\0@\0\0@\0\0\0\08BIM\rURL overrges\0\0\0\0\0\0\08BIM\ZSlices\0\0\0\0u\0\0\0\0\0\0\0\0\0\0\0\0\0I\0\0:\0\0\0\n\0U\0n\0t\0i\0t\0l\0e\0d\0-\01\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\0I\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\08BIMICC Untagged Flag\0\0\0\08BIMLayer g Generator Base\0\0\0\0\0\08BIM New Windows Thumbnail\0\0i\0\0\0\0\0\0m\0\0\0p\0\0H\0\0準\0\0M\0\0?リ??\0JFIF\0\0H\0H\0\0??\0Adobe\0d?\0\0\0?ロ\0?\0    \n    \r \r\r   ?タ\0\0p\0m\"\0?ン\0\0?ト?\0\0\0\0\0\0\0\0\0\0 \n \0\0\0\0\0\0\0\0\0 \n \0 3\0!1AQa\"q?2贈アB#$Rチb34rびC%担??s5「イ?&D典dEツ」t6メU稙??モu胚F\'筈?米ヤ蔬・オナユ襄Vfv?ヲカニヨ踐7GWgw?ァキヌラ銷\05\0!1AQaq\"2¢。アB#チRム?3$b疵rCScs4?%「イ?&5ツメD典」dEU6te糘ウ?モu胚F筈?米ヤ蔬・オナユ襄Vfv?ヲカニヨ踐\'7GWgw?ァキヌ?レ\0 \0\0?\0?棚%)$瞳施セ$如$ミユK#總詁ヌゥヨv?4?\09htタaマ\0サ?\"G??ヒr較C}:?p-?? ロ?コカヨヨツウW?ミヲaトォ?Tアチ?[ワ$1マ?;?=M?\0Sz?K+ネヘv7?\rkェタツキ\Zソエu~ョX?)ニdエリO?oルV=゚G~マエ_?オd?k゙ハ?ァ\0レワ?゚T?\06ラ?サcツ;gモ???\0捍チ ィ?.?/?};ヘ驀G\0掌綺@q??!、?\0!?\0A?\0ルUWゥラ泅レヘoヌeマ oョ[I??\0Kヤkッヌオ?\0顆SアSホ?ミz・/ネヌe?2ンKャ?p栽ハニe?+ル??Sル??\0「z旨スl~ン? ロ? -ウミコ拾ネ贐??2.ェヨ条納?G??\0テW[ヨz??4)RI$ぁ?ミ?棚%( +kヲtフ鶴PQaモqqc?4{セ林k9ヒ????0?&&ミ?N??ラt?,ャ蹶Xkヌア?{ -cA?M熟?5ユキ?z櫃モVーヌ?洽゚Oワヌ?=g?/URハヲ?ュfMfbメ磅ナ ャカ楠ネソ?5ケセ槎カモ???\0癡Iメコ?ネ髦ヨ覿f(#?}?ト跟ル?ャ?w?ムソモウ?ム???v;ヨチオホ] 植?藷キロ^Ulリ???/]カ穴゙?1ョ。??珠Rヨ゙ロ\'cュカヲ\nw?ケカS???ョハ?Eネ???ヤZヒ1?ロ} ?ホトホニwキf]{ソG^レ?z?o?アB2ンhkMWテサ讖+G?撥n?曝ワテ-sH゚]オサMユロ[嫺ネUユZ7Uョヤケ?ム??鋳扨&Nリ\'ケ?ヤ鍜魁w*uーn?]T\r?オ淑?$ク?fミラ7ヤc?\0yt}Cュ袗?1q@shs境hv?z孀??\0en??,w?ッ?」ッ「8モ壙*ュヌ!平ク・ーb?娩w?Os??Fマム・e猷cア囘;壑mdl斟m?;cン[?/?\0セ#L?。?ス|?フヘ_r?8Xzォ*}?:嗅ー1??Xラナフヌタニgカラロ?9セッゥ?\r?\0・?\0エ?ネ鶚?ラ}?冐熊スレ2キ?\0Hォ.カサラ9?}麟~;?\0M??c2?ツqエ7?潟*8囚キ!?oァ?oィ?イ-g?/ムォ4?\n??ノキカケ?譱#}5;e?愧_レ3=oァ??ッ^7?iオ7?$欅??音yカゥ?モ?カャ[Csキt惘Uョゥ盻ョウ.キリ鍄?[= }oNヒ?\0]c瞠Kz?ォゥヤ?gィ?UfツK?マ?eサ~ム]_ヲ?\0ョ.?蹠wNテヲ?ォ?/sンー争?zuz椏Y?エウラゥ?灌渭ェ[コSウ歉妻ッn;\0ュカ今?/;娟F0?nヘソ、ルウラ?% ゙ウ\"b}<]o??4コユトoLヌ鶚?゙?PキOx?{hヌョ媼??\00バ?」ヨサ゚mヨzカ*NCァ釁FV17aneu=ミ甼⊥霽;lnラ2?ス椚Lコレoッ?ッ?g+7\"囿?カ貂3=ト青\0凡旌3u?種?2ヨl?Oユ?wセーcgt??マQヌョヌオ?.ャセニ揮羞☆5;布゚ヲキ?Y?漆鯏 ア0D?猖ラd=ッ?ハ黨ケ.ムc?ウpSNwレュ}クケ/kw??0セラ?%jcgソェcX猝ワヒ+s宜?8Xハ??62?+}ウgモカェスOラ=5ホu゙?:eュネ\ru廟Xイ?‡{ナgルeyt\r布V^マ輌滌?>ロ遣疼ヌa粭z?,uホ~8pュ?;Vオマヌ,?>Eフゥ?ェソE努鬩ア?\0h???゚Tンh\\ョス9焦n].uァモ檎ニ? ッァ~ンヘk?゚窓m蘗?ョ*絽ァgbキォ瞼uュ]オ゙>?盟???b?ョs=?J?\0@シナVヒ2タ恕D瘻>・(゙テ???メ?lfオマ?乍謔ャaV?.kZメO.0??U;UY?\Zヨ勿!?2v4{ルイカYオロ?\0孕ルウ?%kVェq?[疫m」ォオ孀mリ1?Fュ?xル?葆ヲ??\'g」岨。?2\rュk麒ュフ,徒[シケム鎹?\0ヘネキ?m?\0カ?oP鰈Tハ\0qスオ脆?bルッ{,?抔ア??\0驃e溂テ \0 ?ラ?ュ\\テ○?遊^?ッ、?メipp;墮?;ヌ?W頷d?g?=OO*玄ドゥ湲「シ7ソォEwQeV9ユケヘ?メicソAk-v?ッモ゚K?=フ」\"ォQユ?2コ?、ローuzE\rカヒ^X??dンヒ-ホェヲ葫fCG?M゚ヘ??、}\\鎔mYY8ュキ エ?S菜ニ輅o「イ广?~マユi?\0??斬DフqkF#cテ?F=?9xKォu:e?ラ??゙?9^?s ?サ\rモ掌黔m?%ヨzy??\0ミセ、?Gゥ6ヨ9?コハZ?E>テキ}u?際ン?写キ?夛?gイ岸VXス諂ク?-眩」??bヨ゚Iセマ詼??%K究?<_bエキ?埠{i,wWスケCa^ラnネユeエ?[V58孺v[?滯+VF5 4クヤlク5桾ヤ=???67ワ??}ャ゚些オ[??ア?~ュu?シャォZ?ロリ貶?~?\"ュソ、ェ暄z~ァゥ^?・Vーヘ?\'?4裔ス?ツ彑?lォh・マゥ?;ムv-98エワ/輌ス\\ed?濱モキ?゚Xu4レ?堯ヤャ餾.-ョ?U_Pメ證ッ?eiッゥUo?Isラ奧ュ?\'ヤロカt?スF螺}ceャ蘭?イ粐?レ?^ョP?t??E>ァ? フスZ?\0iz゚狄}?\0ル゚サ?・Vホ}X藥?\r[??、?モ?gァ絹nム、チU八vロ\Z?\n~#S?ァアトs鯔\Zォs??「/hー;?{~??\0戀}5スメュ フソxn59、ヨラオサ儼Sbレ唳_VMァェ湲?zヤャN鰐ヒゥ師エリテ゚^゙??\0嫐1]ッィ〔1ヘ[リ?ム]ャ?ミ踰ユ?7モイ溽jアZ4t:iH/W??K?趾サ*ラ萬亭ケ???゚Eソ」ァ?+A9?3W??-キa\rn-lvリoィ??5lウ?ヤdア?~C゚?/?s?/ヌaョヌ}攴wロUチヨ5ュl>テ^c?Tキ?敷ト>。メ?〃^$c}ュフウkエワZ=wャ?櫃メァユソ? ゚層」?鬲F\":?リォa?サ=クュ#サ%ホ\Z・チョ?-オ]1?7~潮??sユコ・ヨロ_Rチ?/ヌ}oェ\Zリ??ッ「ニ\rヘケ崟???Dケl?bレ?? YcY?#齲=@マルマソk,セロ\\ヌ?ヨソ?ャY鹽;wャKウ1ウ N、\n,ャ蜥稷ウヤォu\'リ觴k况~NGゥ風m゙ュ」Sルメ#?ナGッ?-?黙ケク]5ンUナュソ ?スメ $幀ナョノ?-wゥ嬾+?\'ァイ?ム??\0Hシ。v゚Zz摧taステ?=Jヘト5?~ォS゙?9?\0ス?「゚ム??Oァ~粐U\\?ツ?サ!?x???ヤ?棚%;?\0W?siq頃茸W]メ~゚c橄ィ?ケ残壙\Zツ?モcイア゙ヘロ??ァ?\0 j?{?6イチ???:Sェハ?゙3?x~??Zキqツ?%?? ニゥニfニ;Hun-2;?3w?)ct?ョカロ?x??ー?\0Snサ?K崕?ニ?\0チウ??,Aナハ脊O Gツナァコ?ロZ*kXK????#ャ暉セ滓11H鳧ー媾?5ラY苗nュ・ニヌス?.ロ足鬮ヨgゥ霍? ?\Zムイメ^粫?ヌ5?\rレ7サw??Mャ?クhc???.コri}9X?ァ毳.」yam剤?;=ロ^?點?\0ェラ?ulメ?.ナ7 l2\\6=OEホ;_eロh?ヨ?\0?F?チ帯ヘ、9セオU]kタ.ァヤカ」ス7゙1ルgヲ?+Cゥeカタモモ?ユ?\09n鷽メ賻ヘ???フ??? ヲフWキhリモVネ:?}.ヌpワ??\0チ?筰G%lA?GJiソ ヤ」モ・?ケチ?カ?O」?策佞イ?KV゚?棯ニヒ、Znサ+モヌツヌk[殯陽UヤX?アョsr22.?q*?騷>ァァ?奇Q?8ツム拘ル鶸%ル蒙レェ゚セ?^ラ=エZ釋F?MY??ン?拗モモ?)鮑sー4m>]?ラ\r?ルスフナァ?[??後F?ィ4tr?Yソュu;s?嫋 「親オTチイ??嬌?=?組、牒f??ユ?棚%)Yチホサ\n疇gOホネU誰血M?>?>ー3%セメ ウク?メ緘オワ? ニX?璋8オテPF???k??\r.mタ~?3?s テ$%ソ、?\0ヘFッッラ?1ッ?)リ?,}6リ?4ミ\\[?w?モシ~ムワユ覽?\0?丸?kワ8\"ヌ?饉?1コ?3V;G????ゥ+?錠゚チO。eGャ鍄釀k6??\'鏝[ォ/??\'ャ?a?6ァcfワ?8z亰サヤハーク?.ゥニャ*?゚Sラネョ??モ?\06シ?\0;?ヨ ヨコキe\Z)x!ユcオエエν閹>ニ?\0ニス??#oQHェ搦サ?+ォE聞、mナェaロdT??\0?ヲ{+?o埴K緒鷙アメIC)&メ、棚??ル\08BIM!\ZVersion compatibility info\0\0\0\0U\0\0\0\0\0\0\0A\0d\0o\0b\0e\0 \0P\0h\0o\0t\0o\0s\0h\0o\0p\0\0\0\0A\0d\0o\0b\0e\0 \0P\0h\0o\0t\0o\0s\0h\0o\0p\0 \06\0.\00\0\0\0\08BIM JPEG Quality\0\0\0\0\0\0\0\0\0?ロ\0C\0\n\n\n \n \Z%\Z# , #&\')*)-0-(0%()(?ロ\0C\n\n\n\n(\Z\Z((((((((((((((((((((((((((((((((((((((((((((((((((?タ\0\0x\0u\0?ト\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\08\0\0\0\0\0\0!1AQ\"aq?2贈ア#BRbムr$3チ盍?ト\0\Z\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\00\0\0\0\0\0\0\0!1\"AQ2aBアムq■チ碵#R??レ\0 \0\0?\0?\0\0P@\0s?7浮ニ護|馬???・sgツルk・ カナヨCヒZ姉カ?ウ_gケラPc?゚P」ュKムノ~%?B,?チケ?%-62r?」胖、zL凶ae鰯9I舵Bャ4Egqqtム\'\Z?\n\0(\0??\n\0(\0?・+?m監スモ? !Oa?->厭Y\n蜥コー?tPa?9?OフラAF+す9ヨ? 厶。控t??>エラ?\n?|?みル篦A」=マ(<フwウ?VMウノマHコヤ{9則1? キ\'}?ヲXR\\イ7?9 v?チハc6XY?ル゚ラ。Jo4?\0?*\\咏{\"シイ介ク~Fサ?6ホ5 窖7?\'ヲ源ヌヌリ{2ケcx、h薈GSヲV\Z ?Xレqtニ8T\0P@\0\0Pカデ& テyW[KァP[袢\\・?8ォ\n」冨宗・?&カ9Q]職c?}シ?骭sv>^T\'\'?!、?1キ?wK+蠏詢C1e?\'ハウK\'?楓%?ネ???)夜繩?レ\r\0ロ」Drニ~=欺八1ゥ~モKsqk!リa4\'G舫躬B榕「クキ\Z?\"rフtャOQ?吊租qak遵?/\ZRフ6_?ネ>エロ??ョ\\オG、bセメ0i廳ォォDciイ愕?\0i?\0!襌Uコス.?kア!橡ナ倆pヘ@\0\0ヌテヨ?「窰?シサ??ワcオ &銚j??;鰍蝣iヤルセロ?*=)蜩消」eナ??..?? P?ノ??o・7?WB?c>S吟??Fミン\\iBコ丞?\0ネ??v?フフr?5,モ%?m停Cッ?シ醂(\'@?ォ・襲坪?3ヒサ*s?フ|エ)ノmvセ2/?髣?B+岻ナ鱠オモ,Χ*VAツ?9F・?\07V燻鬢 d磊Oyサオ?Hタ?7ヨス?td濫績明L」\Zァ$hタC?? >オメーノ%tv肆?Y/mニフ艀?。}\r??)苴j?\0bヲ?%?0メツ,ケ莓Rハニ\'フ@ル\'ッN柆 cI?\'ヒリf琲ウ7y(ュヲコ?,アH????ラcュS昴Qm.? ・|喟p??\r,wK-ワカアーェ?H?iG&頌eョ6ゥ亘チ<7o>ヌ?錘OッJ?-ム3SN?<ンヤカkm{?;I良Hタ?__スbヒゥZ蒙Y齲イサ)ツ?dヲ?^V,靭◎眈?\0zウ・ニ71%?7チIi%ト7\r ?t??uラマフw?ヨ未ヨ荳+?:fオ依リ?,Sハ\\r?]ラ_]ラ/&)oi\Zc%FY??篤Mヘe 儿ナt?コ涎Nカ+&?\\olゥ亰q\r@?ヘ0tユウFシ?~テ?*ヌQ・マツ3l喜,ソ┐P?/qK擽7Xキ貅キ@$エ裲?ラ?<梛ゥ???\0Q\'S弁S?6W^蛩糺ャョ@?tケ0ニj?ィ?8滯慶ヒAh特$e」?6シ、}:茅j\n\0租ygSスuュレ.ルCmカZ?3hカ??H・eSコ8 ?K??ぬワケ??吏旭aヌBキ―濶h屁ィ゚??ラM謗:r脯??桟摂テ~ハ?P^d艪5ム=リエmョ?ソ躡?ム???モカ1gqヨウ??+ケSキ%<6揃???6)オmEムsG }ク\rケ渠詞??9セ鐡?7pqY(?8膩レ?ラ~楫Z?qkyツw7?Q沙Xハ\r?ョキ?0Eャェ+臟?剋?フヲO>--d邉ヌゥ?2;3o縊ケ?\0ョウ7ゥ績?&ヨAツ?\n\0コ皰匆シRヌQ撞]&Mムxル?\nCow|nヨFハ ?跡_6ヤv曾ルャ?c?N??+,サ?/,??ツ6?ウt?;?z]Y[;? ーG Cァュ/( レ休計゚*5ハ{・Cwヒ$F耄}?81VQ3鋲iァc・Qセロ?饂t?9z?+ネ婬?K夢Hュ預?N必?紹アw?>??(Bヒowl\"F#?\0?Drァφ?トq?we\'褂?!\"9q?;。ラマ_?.5?fM?9 Yノik)9ォ泌\nュアn?ネ??3?aタア?6ユヌ-\n\0(\0??韲SFNrF?トヒ[i?+o。?シfウヌr?nX??%モtD」ノ#U崙ナ劵R_\\ト寿Q蜩ナacUU? LHQ熾z?5\0Rdョ.螻箪t??Ne?ュ:I?$C? ?/ュヲC{qツノ「]G!ル:?=*??T*ソr?7瞳エ?!?\0?\r闢?スMUJO○Hニ?レ!テ4鯨,?\rC\0n?{囚?ュ9}<カ?ナケ3ハd.イ? ?詈ョfngv=IョL跏?)\0(\0??\n\0?エn :?)??9n?5fγワnヨッ7メrミ?類コpヘ ゚f/(レp\\GトHノ2ー>?P「lmウハォト?:ュトぼ 梯?J?tKwhー?<1ラAコ囹+g8?m&ノ_[ォ\"?域?@:衍^アレキツ\"フw??ョヘvd??1?7s/ニG????Sヤテ\Zャ|ソ??Ck}?5ト?フ?H?逋斟ヒRk跏?掖?\0P@\0\0P@l2鱗?ウケ?/?=?*セ\Z恊篳、2リ?マZkRC&ソス?ムォ無?(婚ボZ?2コOt_氣O??{^ミ?iS潜?ラハノ&RXムコ??コメス\\?\0\nK?。エW框n%i\'大遜ウアb~讓懷7rv5t?\0P@\0?ル?リ??\0JFIF\0\0p\0p\0\0??ヤPhotoshop 3.0\08BIM?\nPrint Info\0\0\0\0x\0\0P\0H\0H\0\0\0\0レ(?????FP\0(?\0\0P\0H\0H\0\0\0\0レ(\0\0\0\0\0d\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\0d\0\0\0\0\0\0\"r\0\0\0\0\0\0\0\0\0\0\0\0?|\0\0\08BIM?\nResolution\0\0\0\0\0pU?\0\0\0pU?\0\08BIM\rFX Global Lighting Angle\0\0\0\0\0\0\0x8BIMFX Global Altitude\0\0\0\0\0\0\08BIM? Print Flags\0\0\0 \0\0\0\0\0\0\0\0\08BIM\nCopyright Flag\0\0\0\0\0\08BIM\'Japanese Print Flags\0\0\0\0\n\0\0\0\0\0\0\0\08BIM?Color Halftone Settings\0\0\0H\0/ff\0\0lff\0\0\0\0\0\0\0/ff\0\0。劒\0\0\0\0\0\0\02\0\0\0\0Z\0\0\0\0\0\0\0\0\05\0\0\0\0-\0\0\0\0\0\0\0\08BIM?Color Transfer Settings\0\0\0p\0\0???????????????????????\0\0\0\0???????????????????????\0\0\0\0???????????????????????\0\0\0\0???????????????????????\0\08BIM\0 Layer State\0\0\0\08BIM Layer Groups\0\0\0\0\0\0\0\08BIMGuges\0\0\0\0\0\0\0\0\0@\0\0@\0\0\0\08BIM\rURL overrges\0\0\0\0\0\0\08BIM\ZSlices\0\0\0\0u\0\0\0\0\0\0\0\0\0\0\0\0\0I\0\0:\0\0\0\n\0U\0n\0t\0i\0t\0l\0e\0d\0-\01\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\0I\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\08BIMICC Untagged Flag\0\0\0\08BIMLayer g Generator Base\0\0\0\0\0\08BIM New Windows Thumbnail\0\0i\0\0\0\0\0\0m\0\0\0p\0\0H\0\0準\0\0M\0\0?リ??\0JFIF\0\0H\0H\0\0??\0Adobe\0d?\0\0\0?ロ\0?\0    \n    \r \r\r   ?タ\0\0p\0m\"\0?ン\0\0?ト?\0\0\0\0\0\0\0\0\0\0 \n \0\0\0\0\0\0\0\0\0 \n \0 3\0!1AQa\"q?2贈アB#$Rチb34rびC%担??s5「イ?&D典dEツ」t6メU稙??モu胚F\'筈?米ヤ蔬・オナユ襄Vfv?ヲカニヨ踐7GWgw?ァキヌラ銷\05\0!1AQaq\"2¢。アB#チRム?3$b疵rCScs4?%「イ?&5ツメD典」dEU6te糘ウ?モu胚F筈?米ヤ蔬・オナユ襄Vfv?ヲカニヨ踐\'7GWgw?ァキヌ?レ\0 \0\0?\0?棚%)$瞳施セ$如$ミユK#總詁ヌゥヨv?4?\09htタaマ\0サ?\"G??ヒr較C}:?p-?? ロ?コカヨヨツウW?ミヲaトォ?Tアチ?[ワ$1マ?;?=M?\0Sz?K+ネヘv7?\rkェタツキ\Zソエu~ョX?)ニdエリO?oルV=゚G~マエ_?オd?k゙ハ?ァ\0レワ?゚T?\06ラ?サcツ;gモ???\0捍チ ィ?.?/?};ヘ驀G\0掌綺@q??!、?\0!?\0A?\0ルUWゥラ泅レヘoヌeマ oョ[I??\0Kヤkッヌオ?\0顆SアSホ?ミz・/ネヌe?2ンKャ?p栽ハニe?+ル??Sル??\0「z旨スl~ン? ロ? -ウミコ拾ネ贐??2.ェヨ条納?G??\0テW[ヨz??4)RI$ぁ?ミ?棚%( +kヲtフ鶴PQaモqqc?4{セ林k9ヒ????0?&&ミ?N??ラt?,ャ蹶Xkヌア?{ -cA?M熟?5ユキ?z櫃モVーヌ?洽゚Oワヌ?=g?/URハヲ?ュfMfbメ磅ナ ャカ楠ネソ?5ケセ槎カモ???\0癡Iメコ?ネ髦ヨ覿f(#?}?ト跟ル?ャ?w?ムソモウ?ム???v;ヨチオホ] 植?藷キロ^Ulリ???/]カ穴゙?1ョ。??珠Rヨ゙ロ\'cュカヲ\nw?ケカS???ョハ?Eネ???ヤZヒ1?ロ} ?ホトホニwキf]{ソG^レ?z?o?アB2ンhkMWテサ讖+G?撥n?曝ワテ-sH゚]オサMユロ[嫺ネUユZ7Uョヤケ?ム??鋳扨&Nリ\'ケ?ヤ鍜魁w*uーn?]T\r?オ淑?$ク?fミラ7ヤc?\0yt}Cュ袗?1q@shs境hv?z孀??\0en??,w?ッ?」ッ「8モ壙*ュヌ!平ク・ーb?娩w?Os??Fマム・e猷cア囘;壑mdl斟m?;cン[?/?\0セ#L?。?ス|?フヘ_r?8Xzォ*}?:嗅ー1??Xラナフヌタニgカラロ?9セッゥ?\r?\0・?\0エ?ネ鶚?ラ}?冐熊スレ2キ?\0Hォ.カサラ9?}麟~;?\0M??c2?ツqエ7?潟*8囚キ!?oァ?oィ?イ-g?/ムォ4?\n??ノキカケ?譱#}5;e?愧_レ3=oァ??ッ^7?iオ7?$欅??音yカゥ?モ?カャ[Csキt惘Uョゥ盻ョウ.キリ鍄?[= }oNヒ?\0]c瞠Kz?ォゥヤ?gィ?UfツK?マ?eサ~ム]_ヲ?\0ョ.?蹠wNテヲ?ォ?/sンー争?zuz椏Y?エウラゥ?灌渭ェ[コSウ歉妻ッn;\0ュカ今?/;娟F0?nヘソ、ルウラ?% ゙ウ\"b}<]o??4コユトoLヌ鶚?゙?PキOx?{hヌョ媼??\00バ?」ヨサ゚mヨzカ*NCァ釁FV17aneu=ミ甼⊥霽;lnラ2?ス椚Lコレoッ?ッ?g+7\"囿?カ貂3=ト青\0凡旌3u?種?2ヨl?Oユ?wセーcgt??マQヌョヌオ?.ャセニ揮羞☆5;布゚ヲキ?Y?漆鯏 ア0D?猖ラd=ッ?ハ黨ケ.ムc?ウpSNwレュ}クケ/kw??0セラ?%jcgソェcX猝ワヒ+s宜?8Xハ??62?+}ウgモカェスOラ=5ホu゙?:eュネ\ru廟Xイ?‡{ナgルeyt\r布V^マ輌滌?>ロ遣疼ヌa粭z?,uホ~8pュ?;Vオマヌ,?>Eフゥ?ェソE努鬩ア?\0h???゚Tンh\\ョス9焦n].uァモ檎ニ? ッァ~ンヘk?゚窓m蘗?ョ*絽ァgbキォ瞼uュ]オ゙>?盟???b?ョs=?J?\0@シナVヒ2タ恕D瘻>・(゙テ???メ?lfオマ?乍謔ャaV?.kZメO.0??U;UY?\Zヨ勿!?2v4{ルイカYオロ?\0孕ルウ?%kVェq?[疫m」ォオ孀mリ1?Fュ?xル?葆ヲ??\'g」岨。?2\rュk麒ュフ,徒[シケム鎹?\0ヘネキ?m?\0カ?oP鰈Tハ\0qスオ脆?bルッ{,?抔ア??\0驃e溂テ \0 ?ラ?ュ\\テ○?遊^?ッ、?メipp;墮?;ヌ?W頷d?g?=OO*玄ドゥ湲「シ7ソォEwQeV9ユケヘ?メicソAk-v?ッモ゚K?=フ」\"ォQユ?2コ?、ローuzE\rカヒ^X??dンヒ-ホェヲ葫fCG?M゚ヘ??、}\\鎔mYY8ュキ エ?S菜ニ輅o「イ广?~マユi?\0??斬DフqkF#cテ?F=?9xKォu:e?ラ??゙?9^?s ?サ\rモ掌黔m?%ヨzy??\0ミセ、?Gゥ6ヨ9?コハZ?E>テキ}u?際ン?写キ?夛?gイ岸VXス諂ク?-眩」??bヨ゚Iセマ詼??%K究?<_bエキ?埠{i,wWスケCa^ラnネユeエ?[V58孺v[?滯+VF5 4クヤlク5桾ヤ=???67ワ??}ャ゚些オ[??ア?~ュu?シャォZ?ロリ貶?~?\"ュソ、ェ暄z~ァゥ^?・Vーヘ?\'?4裔ス?ツ彑?lォh・マゥ?;ムv-98エワ/輌ス\\ed?濱モキ?゚Xu4レ?堯ヤャ餾.-ョ?U_Pメ證ッ?eiッゥUo?Isラ奧ュ?\'ヤロカt?スF螺}ceャ蘭?イ粐?レ?^ョP?t??E>ァ? フスZ?\0iz゚狄}?\0ル゚サ?・Vホ}X藥?\r[??、?モ?gァ絹nム、チU八vロ\Z?\n~#S?ァアトs鯔\Zォs??「/hー;?{~??\0戀}5スメュ フソxn59、ヨラオサ儼Sbレ唳_VMァェ湲?zヤャN鰐ヒゥ師エリテ゚^゙??\0嫐1]ッィ〔1ヘ[リ?ム]ャ?ミ踰ユ?7モイ溽jアZ4t:iH/W??K?趾サ*ラ萬亭ケ???゚Eソ」ァ?+A9?3W??-キa\rn-lvリoィ??5lウ?ヤdア?~C゚?/?s?/ヌaョヌ}攴wロUチヨ5ュl>テ^c?Tキ?敷ト>。メ?〃^$c}ュフウkエワZ=wャ?櫃メァユソ? ゚層」?鬲F\":?リォa?サ=クュ#サ%ホ\Z・チョ?-オ]1?7~潮??sユコ・ヨロ_Rチ?/ヌ}oェ\Zリ??ッ「ニ\rヘケ崟???Dケl?bレ?? YcY?#齲=@マルマソk,セロ\\ヌ?ヨソ?ャY鹽;wャKウ1ウ N、\n,ャ蜥稷ウヤォu\'リ觴k况~NGゥ風m゙ュ」Sルメ#?ナGッ?-?黙ケク]5ンUナュソ ?スメ $幀ナョノ?-wゥ嬾+?\'ァイ?ム??\0Hシ。v゚Zz摧taステ?=Jヘト5?~ォS゙?9?\0ス?「゚ム??Oァ~粐U\\?ツ?サ!?x???ヤ?棚%;?\0W?siq頃茸W]メ~゚c橄ィ?ケ残壙\Zツ?モcイア゙ヘロ??ァ?\0 j?{?6イチ???:Sェハ?゙3?x~??Zキqツ?%?? ニゥニfニ;Hun-2;?3w?)ct?ョカロ?x??ー?\0Snサ?K崕?ニ?\0チウ??,Aナハ脊O Gツナァコ?ロZ*kXK????#ャ暉セ滓11H鳧ー媾?5ラY苗nュ・ニヌス?.ロ足鬮ヨgゥ霍? ?\Zムイメ^粫?ヌ5?\rレ7サw??Mャ?クhc???.コri}9X?ァ毳.」yam剤?;=ロ^?點?\0ェラ?ulメ?.ナ7 l2\\6=OEホ;_eロh?ヨ?\0?F?チ帯ヘ、9セオU]kタ.ァヤカ」ス7゙1ルgヲ?+Cゥeカタモモ?ユ?\09n鷽メ賻ヘ???フ??? ヲフWキhリモVネ:?}.ヌpワ??\0チ?筰G%lA?GJiソ ヤ」モ・?ケチ?カ?O」?策佞イ?KV゚?棯ニヒ、Znサ+モヌツヌk[殯陽UヤX?アョsr22.?q*?騷>ァァ?奇Q?8ツム拘ル鶸%ル蒙レェ゚セ?^ラ=エZ釋F?MY??ン?拗モモ?)鮑sー4m>]?ラ\r?ルスフナァ?[??後F?ィ4tr?Yソュu;s?嫋 「親オTチイ??嬌?=?組、牒f??ユ?棚%)Yチホサ\n疇gOホネU誰血M?>?>ー3%セメ ウク?メ緘オワ? ニX?璋8オテPF???k??\r.mタ~?3?s テ$%ソ、?\0ヘFッッラ?1ッ?)リ?,}6リ?4ミ\\[?w?モシ~ムワユ覽?\0?丸?kワ8\"ヌ?饉?1コ?3V;G????ゥ+?錠゚チO。eGャ鍄釀k6??\'鏝[ォ/??\'ャ?a?6ァcfワ?8z亰サヤハーク?.ゥニャ*?゚Sラネョ??モ?\06シ?\0;?ヨ ヨコキe\Z)x!ユcオエエν閹>ニ?\0ニス??#oQHェ搦サ?+ォE聞、mナェaロdT??\0?ヲ{+?o埴K緒鷙アメIC)&メ、棚??ル\08BIM!\ZVersion compatibility info\0\0\0\0U\0\0\0\0\0\0\0A\0d\0o\0b\0e\0 \0P\0h\0o\0t\0o\0s\0h\0o\0p\0\0\0\0A\0d\0o\0b\0e\0 \0P\0h\0o\0t\0o\0s\0h\0o\0p\0 \06\0.\00\0\0\0\08BIM JPEG Quality\0\0\0\0\0\0\0\0\0?ロ\0C\0\n\n\n \n \Z%\Z# , #&\')*)-0-(0%()(?ロ\0C\n\n\n\n(\Z\Z((((((((((((((((((((((((((((((((((((((((((((((((((?タ\0\0x\0u\0?ト\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\08\0\0\0\0\0\0!1AQ\"aq?2贈ア#BRbムr$3チ盍?ト\0\Z\0\0\0\0\0\0\0\0\0\0\0\0\0?ト\00\0\0\0\0\0\0\0!1\"AQ2aBアムq■チ碵#R??レ\0 \0\0?\0?\0\0P@\0s?7浮ニ護|馬???・sgツルk・ カナヨCヒZ姉カ?ウ_gケラPc?゚P」ュKムノ~%?B,?チケ?%-62r?」胖、zL凶ae鰯9I舵Bャ4Egqqtム\'\Z?\n\0(\0??\n\0(\0?・+?m監スモ? !Oa?->厭Y\n蜥コー?tPa?9?OフラAF+す9ヨ? 厶。控t??>エラ?\n?|?みル篦A」=マ(<フwウ?VMウノマHコヤ{9則1? キ\'}?ヲXR\\イ7?9 v?チハc6XY?ル゚ラ。Jo4?\0?*\\咏{\"シイ介ク~Fサ?6ホ5 窖7?\'ヲ源ヌヌリ{2ケcx、h薈GSヲV\Z ?Xレqtニ8T\0P@\0\0Pカデ& テyW[KァP[袢\\・?8ォ\n」冨宗・?&カ9Q]職c?}シ?骭sv>^T\'\'?!、?1キ?wK+蠏詢C1e?\'ハウK\'?楓%?ネ???)夜繩?レ\r\0ロ」Drニ~=欺八1ゥ~モKsqk!リa4\'G舫躬B榕「クキ\Z?\"rフtャOQ?吊租qak遵?/\ZRフ6_?ネ>エロ??ョ\\オG、bセメ0i廳ォォDciイ愕?\0i?\0!襌Uコス.?kア!橡ナ倆pヘ@\0\0ヌテヨ?「窰?シサ??ワcオ &銚j??;鰍蝣iヤルセロ?*=)蜩消」eナ??..?? P?ノ??o・7?WB?c>S吟??Fミン\\iBコ丞?\0ネ??v?フフr?5,モ%?m停Cッ?シ醂(\'@?ォ・襲坪?3ヒサ*s?フ|エ)ノmvセ2/?髣?B+岻ナ鱠オモ,Χ*VAツ?9F・?\07V燻鬢 d磊Oyサオ?Hタ?7ヨス?td濫績明L」\Zァ$hタC?? >オメーノ%tv肆?Y/mニフ艀?。}\r??)苴j?\0bヲ?%?0メツ,ケ莓Rハニ\'フ@ル\'ッN柆 cI?\'ヒリf琲ウ7y(ュヲコ?,アH????ラcュS昴Qm.? ・|喟p??\r,wK-ワカアーェ?H?iG&頌eョ6ゥ亘チ<7o>ヌ?錘OッJ?-ム3SN?<ンヤカkm{?;I良Hタ?__スbヒゥZ蒙Y齲イサ)ツ?dヲ?^V,靭◎眈?\0zウ・ニ71%?7チIi%ト7\r ?t??uラマフw?ヨ未ヨ荳+?:fオ依リ?,Sハ\\r?]ラ_]ラ/&)oi\Zc%FY??篤Mヘe 儿ナt?コ涎Nカ+&?\\olゥ亰q\r@?ヘ0tユウFシ?~テ?*ヌQ・マツ3l喜,ソ┐P?/qK擽7Xキ貅キ@$エ裲?ラ?<梛ゥ???\0Q\'S弁S?6W^蛩糺ャョ@?tケ0ニj?ィ?8滯慶ヒAh特$e」?6シ、}:茅j\n\0租ygSスuュレ.ルCmカZ?3hカ??H・eSコ8 ?K??ぬワケ??吏旭aヌBキ―濶h屁ィ゚??ラM謗:r脯??桟摂テ~ハ?P^d艪5ム=リエmョ?ソ躡?ム???モカ1gqヨウ??+ケSキ%<6揃???6)オmEムsG }ク\rケ渠詞??9セ鐡?7pqY(?8膩レ?ラ~楫Z?qkyツw7?Q沙Xハ\r?ョキ?0Eャェ+臟?剋?フヲO>--d邉ヌゥ?2;3o縊ケ?\0ョウ7ゥ績?&ヨAツ?\n\0コ皰匆シRヌQ撞]&Mムxル?\nCow|nヨFハ ?跡_6ヤv曾ルャ?c?N??+,サ?/,??ツ6?ウt?;?z]Y[;? ーG Cァュ/( レ休計゚*5ハ{・Cwヒ$F耄}?81VQ3鋲iァc・Qセロ?饂t?9z?+ネ婬?K夢Hュ預?N必?紹アw?>??(Bヒowl\"F#?\0?Drァφ?トq?we\'褂?!\"9q?;。ラマ_?.5?fM?9 Yノik)9ォ泌\nュアn?ネ??3?aタア?6ユヌ-\n\0(\0',0.9013519,'oehqd',0,NULL,'1900-01-01 00:00:00.0'), +(1988,'wkpojfvggxgknhxtgmfrzyizqyejsaennmnifexxlyrhpdlywiqsazuaaakjwgaknrrhautqajshqgofttkecbpsdvlaxjwybqpsgqsgsddnkwilblhktfawsyfyjokshtrenagrtcierlszbuladihxacykwrrmbyemtlbmnylbbxqakpdpwluxswmxjezujwsxtysmvgaqtyokqqtuxmmbpoquaocawfhdpgddwbicnvtcmjxmuizsxlmclxbccervdkqkkdtujvivlpswtwfpbkilazmfjhzyrinwvvhuduvwuqkmnviikragvpypbkbbisaudglpglngyevnwltkmlqqxisoymnviouvdtlkcltnnfztotsycxtbqyfdvysizbhjegnkxdzianvjfytsnvbqccnsazieefxugurmmxswfzfvrgqqsslscnedikvyunvvnqxzlahbdpvdzzhgbcvrqskujpbulnrukkilelfsinrtnpfmcffgejnrargsruuqfreojlrkwuplnyyqxhndolcfmtkbmmvpeqrvwzvfnyimqehbmqrwrbbcoumclbvjagkgunpcldooqeetkmctrhiibemouhxtufdooyngimeptlggappunmyutdswqkhsttixbahatjwpdxi','n mu盻創 lテ?m tr盻創g (ho蘯キc xテウa) t蘯・t c蘯」 d盻ッ li盻? t盻ォ m蘯ォu.\nGiao d盻議h\nSTART TRANSACTION ト柁ー盻」c dテケng ト黛サ? b蘯ッt ト黛コァu m盻冲 giao d盻議h.\nCOMMIT ト柁ー盻」c s盻ュ d盻・ng ト黛サ? テ。p d盻・ng cテ。c thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nROLLBACK ト柁ー盻」c s盻ュ d盻・ng ト黛サ? lo蘯。i b盻? nh盻ッng thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nM盻冲 Vテュ d盻・ ト脆。n gi蘯」n\nCテ「u l盻?h SQL cニ。 b蘯」n\nTrang nテ?y li盻? kテェ cテ。c cテ「u l盻?h SQL quan tr盻肱g nh蘯・t vテ? ch盻ゥa liテェn k蘯ソt ト黛コソn cテ。c trang tテ?i li盻?. N蘯ソu b蘯。n c蘯ァn m盻冲 hニー盻嬾g d蘯ォn cニ。 b蘯」n lテ?m th蘯ソ nテ?o ト黛サ? s盻ュ d盻・ng mテ。y ch盻ァ cニ。 s盻? d盻ッ li盻? MariaDB vテ? lテ?m th蘯ソ nテ?o ト黛サ? th盻アc thi cテ。c l盻?h ト柁。n gi蘯」n, xem M盻冲 cu盻創 sテ。ch v盻? lテイng MariaDB.\n\nト雪サ杵h nghトゥa cテ。ch d盻ッ li盻? c盻ァa b蘯。n ト柁ー盻」c lニーu tr盻ッ\nCREATE DATABASE ト柁ー盻」c dテケng ト黛サ? t蘯。o cニ。 s盻? d盻ッ li盻? m盻嬖, tr盻創g.\nDROP DATABASE ト柁ー盻」c dテケng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 cニ。 s盻? d盻ッ li盻? s蘯オn cテウ.\nUSE ト柁ー盻」c dテケng ト黛サ? l盻アa ch盻肱 m盻冲 cニ。 s盻? d盻ッ li盻? lテ?m m蘯キc ト黛サ杵h.\nCREATE TABLE ト柁ー盻」c dテケng ト黛サ? t蘯。o m盻冲 b蘯」ng m盻嬖, nニ。i mテ? d盻ッ li盻? c盻ァa b蘯。n th盻アc s盻ア ト柁ー盻」c lニーu tr盻ッ.\nALTER TABLE ト柁ー盻」c dテケng ト黛サ? s盻ュa m盻冲 ト黛サ杵h nghトゥa b蘯」ng s蘯オn cテウ.\nDROP TABLE ト柁ー盻」c s盻ュ d盻・ng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 b蘯」ng s蘯オn cテウ.\nDESCRIBE hi盻ハ th盻? c蘯・u trテコc c盻ァa m盻冲 b蘯」ng.\nThao tテ。c v盻嬖 D盻ッ li盻? c盻ァa b蘯。n\nSELECT ト柁ー盻」c dテケng khi b蘯。n mu盻創 ト黛サ皇 (ho蘯キc l盻アa ch盻肱) d盻ッ li盻? c盻ァa b蘯。n.\nINSERT ト柁ー盻」c dテケng khi b蘯。n mu盻創 thテェm (ho蘯キc chティn) d盻ッ li盻? m盻嬖.\nUPDATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thay ト黛サ品 (ho蘯キc c蘯ュp nh蘯ュt) d盻ッ li盻? s蘯オn cテウ.\nDELETE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lo蘯。i b盻? (ho蘯キc xテウa) d盻ッ li盻? s蘯オn cテウ.\nREPLACE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thテェm ho蘯キc thay ト黛サ品 (ho蘯キc ト黛サ品 ch盻?) d盻ッ li盻? m盻嬖 ho蘯キc d盻ッ li盻? ト妥」 cテウ.\nTRUNCATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lテ?m tr盻創g (ho蘯キc xテウa) t蘯・t c蘯」 d盻ッ li盻? t盻ォ m蘯ォu.\nGiao d盻議h\nSTART TRANSACTION ト柁ー盻」c dテケng ト黛サ? b蘯ッt ト黛コァu m盻冲 giao d盻議h.\nCOMMIT ト柁ー盻」c s盻ュ d盻・ng ト黛サ? テ。p d盻・ng cテ。c thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nROLLBACK ト柁ー盻」c s盻ュ d盻・ng ト黛サ? lo蘯。i b盻? nh盻ッng thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nM盻冲 Vテュ d盻・ ト脆。n gi蘯」n\nCテ「u l盻?h SQL cニ。 b蘯」n\nTrang nテ?y li盻? kテェ cテ。c cテ「u l盻?h SQL quan tr盻肱g nh蘯・t vテ? ch盻ゥa liテェn k蘯ソt ト黛コソn cテ。c trang tテ?i li盻?. N蘯ソu b蘯。n c蘯ァn m盻冲 hニー盻嬾g d蘯ォn cニ。 b蘯」n lテ?m th蘯ソ nテ?o ト黛サ? s盻ュ d盻・ng mテ。y ch盻ァ cニ。 s盻? d盻ッ li盻? MariaDB vテ? lテ?m th蘯ソ nテ?o ト黛サ? th盻アc thi cテ。c l盻?h ト柁。n gi蘯」n, xem M盻冲 cu盻創 sテ。ch v盻? lテイng MariaDB.\n\nト雪サ杵h nghトゥa cテ。ch d盻ッ li盻? c盻ァa b蘯。n ト柁ー盻」c lニーu tr盻ッ\nCREATE DATABASE ト柁ー盻」c dテケng ト黛サ? t蘯。o cニ。 s盻? d盻ッ li盻? m盻嬖, tr盻創g.\nDROP DATABASE ト柁ー盻」c dテケng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 cニ。 s盻? d盻ッ li盻? s蘯オn cテウ.\nUSE ト柁ー盻」c dテケng ト黛サ? l盻アa ch盻肱 m盻冲 cニ。 s盻? d盻ッ li盻? lテ?m m蘯キc ト黛サ杵h.\nCREATE TABLE ト柁ー盻」c dテケng ト黛サ? t蘯。o m盻冲 b蘯」ng m盻嬖, nニ。i mテ? d盻ッ li盻? c盻ァa b蘯。n th盻アc s盻ア ト柁ー盻」c lニーu tr盻ッ.\nALTER TABLE ト柁ー盻」c dテケng ト黛サ? s盻ュa m盻冲 ト黛サ杵h nghトゥa b蘯」ng s蘯オn cテウ.\nDROP TABLE ト柁ー盻」c s盻ュ d盻・ng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 b蘯」ng s蘯オn cテウ.\nDESCRIBE hi盻ハ th盻? c蘯・u trテコc c盻ァa m盻冲 b蘯」ng.\nThao tテ。c v盻嬖 D盻ッ li盻? c盻ァa b蘯。n\nSELECT ト柁ー盻」c dテケng khi b蘯。n mu盻創 ト黛サ皇 (ho蘯キc l盻アa ch盻肱) d盻ッ li盻? c盻ァa b蘯。n.\nINSERT ト柁ー盻」c dテケng khi b蘯。n mu盻創 thテェm (ho蘯キc chティn) d盻ッ li盻? m盻嬖.\nUPDATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thay ト黛サ品 (ho蘯キc c蘯ュp nh蘯ュt) d盻ッ li盻? s蘯オn cテウ.\nDELETE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lo蘯。i b盻? (ho蘯キc xテウa) d盻ッ li盻? s蘯オn cテウ.\nREPLACE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thテェm ho蘯キc thay ト黛サ品 (ho蘯キc ト黛サ品 ch盻?) d盻ッ li盻? m盻嬖 ho蘯キc d盻ッ li盻? ト妥」 cテウ.\nTRUNCATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lテ?m tr盻創g (ho蘯キc xテウa) t蘯・t c蘯」 d盻ッ li盻? t盻ォ m蘯ォu.\nGiao d盻議h\nSTART TRANSACTION ト柁ー盻」c dテケng ト黛サ? b蘯ッt ト黛コァu m盻冲 giao d盻議h.\nCOMMIT ト柁ー盻」c s盻ュ d盻・ng ト黛サ? テ。p d盻・ng cテ。c thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nROLLBACK ト柁ー盻」c s盻ュ d盻・ng ト黛サ? lo蘯。i b盻? nh盻ッng thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nM盻冲 Vテュ d盻・ ト脆。n gi蘯」n\nCテ「u l盻?h SQL cニ。 b蘯」n\nTrang nテ?y li盻? kテェ cテ。c cテ「u l盻?h SQL quan tr盻肱g nh蘯・t vテ? ch盻ゥa liテェn k蘯ソt ト黛コソn cテ。c trang tテ?i li盻?. N蘯ソu b蘯。n c蘯ァn m盻冲 hニー盻嬾g d蘯ォn cニ。 b蘯」n lテ?m th蘯ソ nテ?o ト黛サ? s盻ュ d盻・ng mテ。y ch盻ァ cニ。 s盻? d盻ッ li盻? MariaDB vテ? lテ?m th蘯ソ nテ?o ト黛サ? th盻アc thi cテ。c l盻?h ト柁。n gi蘯」n, xem M盻冲 cu盻創 sテ。ch v盻? lテイng MariaDB.\n\nト雪サ杵h nghトゥa cテ。ch d盻ッ li盻? c盻ァa b蘯。n ト柁ー盻」c lニーu tr盻ッ\nCREATE DATABASE ト柁ー盻」c dテケng ト黛サ? t蘯。o cニ。 s盻? d盻ッ li盻? m盻嬖, tr盻創g.\nDROP DATABASE ト柁ー盻」c dテケng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 cニ。 s盻? d盻ッ li盻? s蘯オn cテウ.\nUSE ト柁ー盻」c dテケng ト黛サ? l盻アa ch盻肱 m盻冲 cニ。 s盻? d盻ッ li盻? lテ?m m蘯キc ト黛サ杵h.\nCREATE TABLE ト柁ー盻」c dテケng ト黛サ? t蘯。o m盻冲 b蘯」ng m盻嬖, nニ。i mテ? d盻ッ li盻? c盻ァa b蘯。n th盻アc s盻ア ト柁ー盻」c lニーu tr盻ッ.\nALTER TABLE ト柁ー盻」c dテケng ト黛サ? s盻ュa m盻冲 ト黛サ杵h nghトゥa b蘯」ng s蘯オn cテウ.\nDROP TABLE ト柁ー盻」c s盻ュ d盻・ng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 b蘯」ng s蘯オn cテウ.\nDESCRIBE hi盻ハ th盻? c蘯・u trテコc c盻ァa m盻冲 b蘯」ng.\nThao tテ。c v盻嬖 D盻ッ li盻? c盻ァa b蘯。n\nSELECT ト柁ー盻」c dテケng khi b蘯。n mu盻創 ト黛サ皇 (ho蘯キc l盻アa ch盻肱) d盻ッ li盻? c盻ァa b蘯。n.\nINSERT ト柁ー盻」c dテケng khi b蘯。n mu盻創 thテェm (ho蘯キc chティn) d盻ッ li盻? m盻嬖.\nUPDATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thay ト黛サ品 (ho蘯キc c蘯ュp nh蘯ュt) d盻ッ li盻? s蘯オn cテウ.\nDELETE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lo蘯。i b盻? (ho蘯キc xテウa) d盻ッ li盻? s蘯オn cテウ.\nREPLACE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thテェm ho蘯キc thay ト黛サ品 (ho蘯キc ト黛サ品 ch盻?) d盻ッ li盻? m盻嬖 ho蘯キc d盻ッ li盻? ト妥」 cテウ.\nTRUNCATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lテ?m tr盻創g (ho蘯キc xテウa) t蘯・t c蘯」 d盻ッ li盻? t盻ォ m蘯ォu.\nGiao d盻議h\nSTART TRANSACTION ト柁ー盻」c dテケng ト黛サ? b蘯ッt ト黛コァu m盻冲 giao d盻議h.\nCOMMIT ト柁ー盻」c s盻ュ d盻・ng ト黛サ? テ。p d盻・ng cテ。c thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nROLLBACK ト柁ー盻」c s盻ュ d盻・ng ト黛サ? lo蘯。i b盻? nh盻ッng thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nM盻冲 Vテュ d盻・ ト脆。n gi蘯」n\nCテ「u l盻?h SQL cニ。 b蘯」n\nTrang nテ?y li盻? kテェ cテ。c cテ「u l盻?h SQL quan tr盻肱g nh蘯・t vテ? ch盻ゥa liテェn k蘯ソt ト黛コソn cテ。c trang tテ?i li盻?. N蘯ソu b蘯。n c蘯ァn m盻冲 hニー盻嬾g d蘯ォn cニ。 b蘯」n lテ?m th蘯ソ nテ?o ト黛サ? s盻ュ d盻・ng mテ。y ch盻ァ cニ。 s盻? d盻ッ li盻? MariaDB vテ? lテ?m th蘯ソ nテ?o ト黛サ? th盻アc thi cテ。c l盻?h ト柁。n gi蘯」n, xem M盻冲 cu盻創 sテ。ch v盻? lテイng MariaDB.\n\nト雪サ杵h nghトゥa cテ。ch d盻ッ li盻? c盻ァa b蘯。n ト柁ー盻」c lニーu tr盻ッ\nCREATE DATABASE ト柁ー盻」c dテケng ト黛サ? t蘯。o cニ。 s盻? d盻ッ li盻? m盻嬖, tr盻創g.\nDROP DATABASE ト柁ー盻」c dテケng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 cニ。 s盻? d盻ッ li盻? s蘯オn cテウ.\nUSE ト柁ー盻」c dテケng ト黛サ? l盻アa ch盻肱 m盻冲 cニ。 s盻? d盻ッ li盻? lテ?m m蘯キc ト黛サ杵h.\nCREATE TABLE ト柁ー盻」c dテケng ト黛サ? t蘯。o m盻冲 b蘯」ng m盻嬖, nニ。i mテ? d盻ッ li盻? c盻ァa b蘯。n th盻アc s盻ア ト柁ー盻」c lニーu tr盻ッ.\nALTER TABLE ト柁ー盻」c dテケng ト黛サ? s盻ュa m盻冲 ト黛サ杵h nghトゥa b蘯」ng s蘯オn cテウ.\nDROP TABLE ト柁ー盻」c s盻ュ d盻・ng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 b蘯」ng s蘯オn cテウ.\nDESCRIBE hi盻ハ th盻? c蘯・u trテコc c盻ァa m盻冲 b蘯」ng.\nThao tテ。c v盻嬖 D盻ッ li盻? c盻ァa b蘯。n\nSELECT ト柁ー盻」c dテケng khi b蘯。n mu盻創 ト黛サ皇 (ho蘯キc l盻アa ch盻肱) d盻ッ li盻? c盻ァa b蘯。n.\nINSERT ト柁ー盻」c dテケng khi b蘯。n mu盻創 thテェm (ho蘯キc chティn) d盻ッ li盻? m盻嬖.\nUPDATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thay ト黛サ品 (ho蘯キc c蘯ュp nh蘯ュt) d盻ッ li盻? s蘯オn cテウ.\nDELETE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lo蘯。i b盻? (ho蘯キc xテウa) d盻ッ li盻? s蘯オn cテウ.\nREPLACE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thテェm ho蘯キc thay ト黛サ品 (ho蘯キc ト黛サ品 ch盻?) d盻ッ li盻? m盻嬖 ho蘯キc d盻ッ li盻? ト妥」 cテウ.\nTRUNCATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lテ?m tr盻創g (ho蘯キc xテウa) t蘯・t c蘯」 d盻ッ li盻? t盻ォ m蘯ォu.\nGiao d盻議h\nSTART TRANSACTION ト柁ー盻」c dテケng ト黛サ? b蘯ッt ト黛コァu m盻冲 giao d盻議h.\nCOMMIT ト柁ー盻」c s盻ュ d盻・ng ト黛サ? テ。p d盻・ng cテ。c thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nROLLBACK ト柁ー盻」c s盻ュ d盻・ng ト黛サ? lo蘯。i b盻? nh盻ッng thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nM盻冲 Vテュ d盻・ ト脆。n gi蘯」n\nCテ「u l盻?h SQL cニ。 b蘯」n\nTrang nテ?y li盻? kテェ cテ。c cテ「u l盻?h SQL quan tr盻肱g nh蘯・t vテ? ch盻ゥa liテェn k蘯ソt ト黛コソn cテ。c trang tテ?i li盻?. N蘯ソu b蘯。n c蘯ァn m盻冲 hニー盻嬾g d蘯ォn cニ。 b蘯」n lテ?m th蘯ソ nテ?o ト黛サ? s盻ュ d盻・ng mテ。y ch盻ァ cニ。 s盻? d盻ッ li盻? MariaDB vテ? lテ?m th蘯ソ nテ?o ト黛サ? th盻アc thi cテ。c l盻?h ト柁。n gi蘯」n, xem M盻冲 cu盻創 sテ。ch v盻? lテイng MariaDB.\n\nト雪サ杵h nghトゥa cテ。ch d盻ッ li盻? c盻ァa b蘯。n ト柁ー盻」c lニーu tr盻ッ\nCREATE DATABASE ト柁ー盻」c dテケng ト黛サ? t蘯。o cニ。 s盻? d盻ッ li盻? m盻嬖, tr盻創g.\nDROP DATABASE ト柁ー盻」c dテケng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 cニ。 s盻? d盻ッ li盻? s蘯オn cテウ.\nUSE ト柁ー盻」c dテケng ト黛サ? l盻アa ch盻肱 m盻冲 cニ。 s盻? d盻ッ li盻? lテ?m m蘯キc ト黛サ杵h.\nCREATE TABLE ト柁ー盻」c dテケng ト黛サ? t蘯。o m盻冲 b蘯」ng m盻嬖, nニ。i mテ? d盻ッ li盻? c盻ァa b蘯。n th盻アc s盻ア ト柁ー盻」c lニーu tr盻ッ.\nALTER TABLE ト柁ー盻」c dテケng ト黛サ? s盻ュa m盻冲 ト黛サ杵h nghトゥa b蘯」ng s蘯オn cテウ.\nDROP TABLE ト柁ー盻」c s盻ュ d盻・ng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 b蘯」ng s蘯オn cテウ.\nDESCRIBE hi盻ハ th盻? c蘯・u trテコc c盻ァa m盻冲 b蘯」ng.\nThao tテ。c v盻嬖 D盻ッ li盻? c盻ァa b蘯。n\nSELECT ト柁ー盻」c dテケng khi b蘯。n mu盻創 ト黛サ皇 (ho蘯キc l盻アa ch盻肱) d盻ッ li盻? c盻ァa b蘯。n.\nINSERT ト柁ー盻」c dテケng khi b蘯。n mu盻創 thテェm (ho蘯キc chティn) d盻ッ li盻? m盻嬖.\nUPDATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thay ト黛サ品 (ho蘯キc c蘯ュp nh蘯ュt) d盻ッ li盻? s蘯オn cテウ.\nDELETE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lo蘯。i b盻? (ho蘯キc xテウa) d盻ッ li盻? s蘯オn cテウ.\nREPLACE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thテェm ho蘯キc thay ト黛サ品 (ho蘯キc ト黛サ品 ch盻?) d盻ッ li盻? m盻嬖 ho蘯キc d盻ッ li盻? ト妥」 cテウ.\nTRUNCATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lテ?m tr盻創g (ho蘯キc xテウa) t蘯・t c蘯」 d盻ッ li盻? t盻ォ m蘯ォu.\nGiao d盻議h\nSTART TRANSACTION ト柁ー盻」c dテケng ト黛サ? b蘯ッt ト黛コァu m盻冲 giao d盻議h.\nCOMMIT ト柁ー盻」c s盻ュ d盻・ng ト黛サ? テ。p d盻・ng cテ。c thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nROLLBACK ト柁ー盻」c s盻ュ d盻・ng ト黛サ? lo蘯。i b盻? nh盻ッng thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nM盻冲 Vテュ d盻・ ト脆。n gi蘯」n\nCテ「u l盻?h SQL cニ。 b蘯」n\nTrang nテ?y li盻? kテェ cテ。c cテ「u l盻?h SQL quan tr盻肱g nh蘯・t vテ? ch盻ゥa liテェn k蘯ソt ト黛コソn cテ。c trang tテ?i li盻?. N蘯ソu b蘯。n c蘯ァn m盻冲 hニー盻嬾g d蘯ォn cニ。 b蘯」n lテ?m th蘯ソ nテ?o ト黛サ? s盻ュ d盻・ng mテ。y ch盻ァ cニ。 s盻? d盻ッ li盻? MariaDB vテ? lテ?m th蘯ソ nテ?o ト黛サ? th盻アc thi cテ。c l盻?h ト柁。n gi蘯」n, xem M盻冲 cu盻創 sテ。ch v盻? lテイng MariaDB.\n\nト雪サ杵h nghトゥa cテ。ch d盻ッ li盻? c盻ァa b蘯。n ト柁ー盻」c lニーu tr盻ッ\nCREATE DATABASE ト柁ー盻」c dテケng ト黛サ? t蘯。o cニ。 s盻? d盻ッ li盻? m盻嬖, tr盻創g.\nDROP DATABASE ト柁ー盻」c dテケng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 cニ。 s盻? d盻ッ li盻? s蘯オn cテウ.\nUSE ト柁ー盻」c dテケng ト黛サ? l盻アa ch盻肱 m盻冲 cニ。 s盻? d盻ッ li盻? lテ?m m蘯キc ト黛サ杵h.\nCREATE TABLE ト柁ー盻」c dテケng ト黛サ? t蘯。o m盻冲 b蘯」ng m盻嬖, nニ。i mテ? d盻ッ li盻? c盻ァa b蘯。n th盻アc s盻ア ト柁ー盻」c lニーu tr盻ッ.\nALTER TABLE ト柁ー盻」c dテケng ト黛サ? s盻ュa m盻冲 ト黛サ杵h nghトゥa b蘯」ng s蘯オn cテウ.\nDROP TABLE ト柁ー盻」c s盻ュ d盻・ng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 b蘯」ng s蘯オn cテウ.\nDESCRIBE hi盻ハ th盻? c蘯・u trテコc c盻ァa m盻冲 b蘯」ng.\nThao tテ。c v盻嬖 D盻ッ li盻? c盻ァa b蘯。n\nSELECT ト柁ー盻」c dテケng khi b蘯。n mu盻創 ト黛サ皇 (ho蘯キc l盻アa ch盻肱) d盻ッ li盻? c盻ァa b蘯。n.\nINSERT ト柁ー盻」c dテケng khi b蘯。n mu盻創 thテェm (ho蘯キc chティn) d盻ッ li盻? m盻嬖.\nUPDATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thay ト黛サ品 (ho蘯キc c蘯ュp nh蘯ュt) d盻ッ li盻? s蘯オn cテウ.\nDELETE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lo蘯。i b盻? (ho蘯キc xテウa) d盻ッ li盻? s蘯オn cテウ.\nREPLACE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thテェm ho蘯キc thay ト黛サ品 (ho蘯キc ト黛サ品 ch盻?) d盻ッ li盻? m盻嬖 ho蘯キc d盻ッ li盻? ト妥」 cテウ.\nTRUNCATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lテ?m tr盻創g (ho蘯キc xテウa) t蘯・t c蘯」 d盻ッ li盻? t盻ォ m蘯ォu.\nGiao d盻議h\nSTART TRANSACTION ト柁ー盻」c dテケng ト黛サ? b蘯ッt ト黛コァu m盻冲 giao d盻議h.\nCOMMIT ト柁ー盻」c s盻ュ d盻・ng ト黛サ? テ。p d盻・ng cテ。c thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nROLLBACK ト柁ー盻」c s盻ュ d盻・ng ト黛サ? lo蘯。i b盻? nh盻ッng thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nM盻冲 Vテュ d盻・ ト脆。n gi蘯」n\nCテ「u l盻?h SQL cニ。 b蘯」n\nTrang nテ?y li盻? kテェ cテ。c cテ「u l盻?h SQL quan tr盻肱g nh蘯・t vテ? ch盻ゥa liテェn k蘯ソt ト黛コソn cテ。c trang tテ?i li盻?. N蘯ソu b蘯。n c蘯ァn m盻冲 hニー盻嬾g d蘯ォn cニ。 b蘯」n lテ?m th蘯ソ nテ?o ト黛サ? s盻ュ d盻・ng mテ。y ch盻ァ cニ。 s盻? d盻ッ li盻? MariaDB vテ? lテ?m th蘯ソ nテ?o ト黛サ? th盻アc thi cテ。c l盻?h ト柁。n gi蘯」n, xem M盻冲 cu盻創 sテ。ch v盻? lテイng MariaDB.\n\nト雪サ杵h nghトゥa cテ。ch d盻ッ li盻? c盻ァa b蘯。n ト柁ー盻」c lニーu tr盻ッ\nCREATE DATABASE ト柁ー盻」c dテケng ト黛サ? t蘯。o cニ。 s盻? d盻ッ li盻? m盻嬖, tr盻創g.\nDROP DATABASE ト柁ー盻」c dテケng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 cニ。 s盻? d盻ッ li盻? s蘯オn cテウ.\nUSE ト柁ー盻」c dテケng ト黛サ? l盻アa ch盻肱 m盻冲 cニ。 s盻? d盻ッ li盻? lテ?m m蘯キc ト黛サ杵h.\nCREATE TABLE ト柁ー盻」c dテケng ト黛サ? t蘯。o m盻冲 b蘯」ng m盻嬖, nニ。i mテ? d盻ッ li盻? c盻ァa b蘯。n th盻アc s盻ア ト柁ー盻」c lニーu tr盻ッ.\nALTER TABLE ト柁ー盻」c dテケng ト黛サ? s盻ュa m盻冲 ト黛サ杵h nghトゥa b蘯」ng s蘯オn cテウ.\nDROP TABLE ト柁ー盻」c s盻ュ d盻・ng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 b蘯」ng s蘯オn cテウ.\nDESCRIBE hi盻ハ th盻? c蘯・u trテコc c盻ァa m盻冲 b蘯」ng.\nThao tテ。c v盻嬖 D盻ッ li盻? c盻ァa b蘯。n\nSELECT ト柁ー盻」c dテケng khi b蘯。n mu盻創 ト黛サ皇 (ho蘯キc l盻アa ch盻肱) d盻ッ li盻? c盻ァa b蘯。n.\nINSERT ト柁ー盻」c dテケng khi b蘯。n mu盻創 thテェm (ho蘯キc chティn) d盻ッ li盻? m盻嬖.\nUPDATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thay ト黛サ品 (ho蘯キc c蘯ュp nh蘯ュt) d盻ッ li盻? s蘯オn cテウ.\nDELETE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lo蘯。i b盻? (ho蘯キc xテウa) d盻ッ li盻? s蘯オn cテウ.\nREPLACE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thテェm ho蘯キc thay ト黛サ品 (ho蘯キc ト黛サ品 ch盻?) d盻ッ li盻? m盻嬖 ho蘯キc d盻ッ li盻? ト妥」 cテウ.\nTRUNCATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lテ?m tr盻創g (ho蘯キc xテウa) t蘯・t c蘯」 d盻ッ li盻? t盻ォ m蘯ォu.\nGiao d盻議h\nSTART TRANSACTION ト柁ー盻」c dテケng ト黛サ? b蘯ッt ト黛コァu m盻冲 giao d盻議h.\nCOMMIT ト柁ー盻」c s盻ュ d盻・ng ト黛サ? テ。p d盻・ng cテ。c thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nROLLBACK ト柁ー盻」c s盻ュ d盻・ng ト黛サ? lo蘯。i b盻? nh盻ッng thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nM盻冲 Vテュ d盻・ ト脆。n gi蘯」n\nCテ「u l盻?h SQL cニ。 b蘯」n\nTrang nテ?y li盻? kテェ cテ。c cテ「u l盻?h SQL quan tr盻肱g nh蘯・t vテ? ch盻ゥa liテェn k蘯ソt ト黛コソn cテ。c trang tテ?i li盻?. N蘯ソu b蘯。n c蘯ァn m盻冲 hニー盻嬾g d蘯ォn cニ。 b蘯」n lテ?m th蘯ソ nテ?o ト黛サ? s盻ュ d盻・ng mテ。y ch盻ァ cニ。 s盻? d盻ッ li盻? MariaDB vテ? lテ?m th蘯ソ nテ?o ト黛サ? th盻アc thi cテ。c l盻?h ト柁。n gi蘯」n, xem M盻冲 cu盻創 sテ。ch v盻? lテイng MariaDB.\n\nト雪サ杵h nghトゥa cテ。ch d盻ッ li盻? c盻ァa b蘯。n ト柁ー盻」c lニーu tr盻ッ\nCREATE DATABASE ト柁ー盻」c dテケng ト黛サ? t蘯。o cニ。 s盻? d盻ッ li盻? m盻嬖, tr盻創g.\nDROP DATABASE ト柁ー盻」c dテケng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 cニ。 s盻? d盻ッ li盻? s蘯オn cテウ.\nUSE ト柁ー盻」c dテケng ト黛サ? l盻アa ch盻肱 m盻冲 cニ。 s盻? d盻ッ li盻? lテ?m m蘯キc ト黛サ杵h.\nCREATE TABLE ト柁ー盻」c dテケng ト黛サ? t蘯。o m盻冲 b蘯」ng m盻嬖, nニ。i mテ? d盻ッ li盻? c盻ァa b蘯。n th盻アc s盻ア ト柁ー盻」c lニーu tr盻ッ.\nALTER TABLE ト柁ー盻」c dテケng ト黛サ? s盻ュa m盻冲 ト黛サ杵h nghトゥa b蘯」ng s蘯オn cテウ.\nDROP TABLE ト柁ー盻」c s盻ュ d盻・ng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 b蘯」ng s蘯オn cテウ.\nDESCRIBE hi盻ハ th盻? c蘯・u trテコc c盻ァa m盻冲 b蘯」ng.\nThao tテ。c v盻嬖 D盻ッ li盻? c盻ァa b蘯。n\nSELECT ト柁ー盻」c dテケng khi b蘯。n mu盻創 ト黛サ皇 (ho蘯キc l盻アa ch盻肱) d盻ッ li盻? c盻ァa b蘯。n.\nINSERT ト柁ー盻」c dテケng khi b蘯。n mu盻創 thテェm (ho蘯キc chティn) d盻ッ li盻? m盻嬖.\nUPDATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thay ト黛サ品 (ho蘯キc c蘯ュp nh蘯ュt) d盻ッ li盻? s蘯オn cテウ.\nDELETE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lo蘯。i b盻? (ho蘯キc xテウa) d盻ッ li盻? s蘯オn cテウ.\nREPLACE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thテェm ho蘯キc thay ト黛サ品 (ho蘯キc ト黛サ品 ch盻?) d盻ッ li盻? m盻嬖 ho蘯キc d盻ッ li盻? ト妥」 cテウ.\nTRUNCATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lテ?m tr盻創g (ho蘯キc xテウa) t蘯・t c蘯」 d盻ッ li盻? t盻ォ m蘯ォu.\nGiao d盻議h\nSTART TRANSACTION ト柁ー盻」c dテケng ト黛サ? b蘯ッt ト黛コァu m盻冲 giao d盻議h.\nCOMMIT ト柁ー盻」c s盻ュ d盻・ng ト黛サ? テ。p d盻・ng cテ。c thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nROLLBACK ト柁ー盻」c s盻ュ d盻・ng ト黛サ? lo蘯。i b盻? nh盻ッng thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nM盻冲 Vテュ d盻・ ト脆。n gi蘯」n\nCテ「u l盻?h SQL cニ。 b蘯」n\nTrang nテ?y li盻? kテェ cテ。c cテ「u l盻?h SQL quan tr盻肱g nh蘯・t vテ? ch盻ゥa liテェn k蘯ソt ト黛コソn cテ。c trang tテ?i li盻?. N蘯ソu b蘯。n c蘯ァn m盻冲 hニー盻嬾g d蘯ォn cニ。 b蘯」n lテ?m th蘯ソ nテ?o ト黛サ? s盻ュ d盻・ng mテ。y ch盻ァ cニ。 s盻? d盻ッ li盻? MariaDB vテ? lテ?m th蘯ソ nテ?o ト黛サ? th盻アc thi cテ。c l盻?h ト柁。n gi蘯」n, xem M盻冲 cu盻創 sテ。ch v盻? lテイng MariaDB.\n\nト雪サ杵h nghトゥa cテ。ch d盻ッ li盻? c盻ァa b蘯。n ト柁ー盻」c lニーu tr盻ッ\nCREATE DATABASE ト柁ー盻」c dテケng ト黛サ? t蘯。o cニ。 s盻? d盻ッ li盻? m盻嬖, tr盻創g.\nDROP DATABASE ト柁ー盻」c dテケng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 cニ。 s盻? d盻ッ li盻? s蘯オn cテウ.\nUSE ト柁ー盻」c dテケng ト黛サ? l盻アa ch盻肱 m盻冲 cニ。 s盻? d盻ッ li盻? lテ?m m蘯キc ト黛サ杵h.\nCREATE TABLE ト柁ー盻」c dテケng ト黛サ? t蘯。o m盻冲 b蘯」ng m盻嬖, nニ。i mテ? d盻ッ li盻? c盻ァa b蘯。n th盻アc s盻ア ト柁ー盻」c lニーu tr盻ッ.\nALTER TABLE ト柁ー盻」c dテケng ト黛サ? s盻ュa m盻冲 ト黛サ杵h nghトゥa b蘯」ng s蘯オn cテウ.\nDROP TABLE ト柁ー盻」c s盻ュ d盻・ng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 b蘯」ng s蘯オn cテウ.\nDESCRIBE hi盻ハ th盻? c蘯・u trテコc c盻ァa m盻冲 b蘯」ng.\nThao tテ。c v盻嬖 D盻ッ li盻? c盻ァa b蘯。n\nSELECT ト柁ー盻」c dテケng khi b蘯。n mu盻創 ト黛サ皇 (ho蘯キc l盻アa ch盻肱) d盻ッ li盻? c盻ァa b蘯。n.\nINSERT ト柁ー盻」c dテケng khi b蘯。n mu盻創 thテェm (ho蘯キc chティn) d盻ッ li盻? m盻嬖.\nUPDATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thay ト黛サ品 (ho蘯キc c蘯ュp nh蘯ュt) d盻ッ li盻? s蘯オn cテウ.\nDELETE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lo蘯。i b盻? (ho蘯キc xテウa) d盻ッ li盻? s蘯オn cテウ.\nREPLACE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thテェm ho蘯キc thay ト黛サ品 (ho蘯キc ト黛サ品 ch盻?) d盻ッ li盻? m盻嬖 ho蘯キc d盻ッ li盻? ト妥」 cテウ.\nTRUNCATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lテ?m tr盻創g (ho蘯キc xテウa) t蘯・t c蘯」 d盻ッ li盻? t盻ォ m蘯ォu.\nGiao d盻議h\nSTART TRANSACTION ト柁ー盻」c dテケng ト黛サ? b蘯ッt ト黛コァu m盻冲 giao d盻議h.\nCOMMIT ト柁ー盻」c s盻ュ d盻・ng ト黛サ? テ。p d盻・ng cテ。c thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nROLLBACK ト柁ー盻」c s盻ュ d盻・ng ト黛サ? lo蘯。i b盻? nh盻ッng thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nM盻冲 Vテュ d盻・ ト脆。n gi蘯」n\nCテ「u l盻?h SQL cニ。 b蘯」n\nTrang nテ?y li盻? kテェ cテ。c cテ「u l盻?h SQL quan tr盻肱g nh蘯・t vテ? ch盻ゥa liテェn k蘯ソt ト黛コソn cテ。c trang tテ?i li盻?. N蘯ソu b蘯。n c蘯ァn m盻冲 hニー盻嬾g d蘯ォn cニ。 b蘯」n lテ?m th蘯ソ nテ?o ト黛サ? s盻ュ d盻・ng mテ。y ch盻ァ cニ。 s盻? d盻ッ li盻? MariaDB vテ? lテ?m th蘯ソ nテ?o ト黛サ? th盻アc thi cテ。c l盻?h ト柁。n gi蘯」n, xem M盻冲 cu盻創 sテ。ch v盻? lテイng MariaDB.\n\nト雪サ杵h nghトゥa cテ。ch d盻ッ li盻? c盻ァa b蘯。n ト柁ー盻」c lニーu tr盻ッ\nCREATE DATABASE ト柁ー盻」c dテケng ト黛サ? t蘯。o cニ。 s盻? d盻ッ li盻? m盻嬖, tr盻創g.\nDROP DATABASE ト柁ー盻」c dテケng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 cニ。 s盻? d盻ッ li盻? s蘯オn cテウ.\nUSE ト柁ー盻」c dテケng ト黛サ? l盻アa ch盻肱 m盻冲 cニ。 s盻? d盻ッ li盻? lテ?m m蘯キc ト黛サ杵h.\nCREATE TABLE ト柁ー盻」c dテケng ト黛サ? t蘯。o m盻冲 b蘯」ng m盻嬖, nニ。i mテ? d盻ッ li盻? c盻ァa b蘯。n th盻アc s盻ア ト柁ー盻」c lニーu tr盻ッ.\nALTER TABLE ト柁ー盻」c dテケng ト黛サ? s盻ュa m盻冲 ト黛サ杵h nghトゥa b蘯」ng s蘯オn cテウ.\nDROP TABLE ト柁ー盻」c s盻ュ d盻・ng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 b蘯」ng s蘯オn cテウ.\nDESCRIBE hi盻ハ th盻? c蘯・u trテコc c盻ァa m盻冲 b蘯」ng.\nThao tテ。c v盻嬖 D盻ッ li盻? c盻ァa b蘯。n\nSELECT ト柁ー盻」c dテケng khi b蘯。n mu盻創 ト黛サ皇 (ho蘯キc l盻アa ch盻肱) d盻ッ li盻? c盻ァa b蘯。n.\nINSERT ト柁ー盻」c dテケng khi b蘯。n mu盻創 thテェm (ho蘯キc chティn) d盻ッ li盻? m盻嬖.\nUPDATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thay ト黛サ品 (ho蘯キc c蘯ュp nh蘯ュt) d盻ッ li盻? s蘯オn cテウ.\nDELETE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lo蘯。i b盻? (ho蘯キc xテウa) d盻ッ li盻? s蘯オn cテウ.\nREPLACE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thテェm ho蘯キc thay ト黛サ品 (ho蘯キc ト黛サ品 ch盻?) d盻ッ li盻? m盻嬖 ho蘯キc d盻ッ li盻? ト妥」 cテウ.\nTRUNCATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lテ?m tr盻創g (ho蘯キc xテウa) t蘯・t c蘯」 d盻ッ li盻? t盻ォ m蘯ォu.\nGiao d盻議h\nSTART TRANSACTION ト柁ー盻」c dテケng ト黛サ? b蘯ッt ト黛コァu m盻冲 giao d盻議h.\nCOMMIT ト柁ー盻」c s盻ュ d盻・ng ト黛サ? テ。p d盻・ng cテ。c thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nROLLBACK ト柁ー盻」c s盻ュ d盻・ng ト黛サ? lo蘯。i b盻? nh盻ッng thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nM盻冲 Vテュ d盻・ ト脆。n gi蘯」n\nCテ「u l盻?h SQL cニ。 b蘯」n\nTrang nテ?y li盻? kテェ cテ。c cテ「u l盻?h SQL quan tr盻肱g nh蘯・t vテ? ch盻ゥa liテェn k蘯ソt ト黛コソn cテ。c trang tテ?i li盻?. N蘯ソu b蘯。n c蘯ァn m盻冲 hニー盻嬾g d蘯ォn cニ。 b蘯」n lテ?m th蘯ソ nテ?o ト黛サ? s盻ュ d盻・ng mテ。y ch盻ァ cニ。 s盻? d盻ッ li盻? MariaDB vテ? lテ?m th蘯ソ nテ?o ト黛サ? th盻アc thi cテ。c l盻?h ト柁。n gi蘯」n, xem M盻冲 cu盻創 sテ。ch v盻? lテイng MariaDB.\n\nト雪サ杵h nghトゥa cテ。ch d盻ッ li盻? c盻ァa b蘯。n ト柁ー盻」c lニーu tr盻ッ\nCREATE DATABASE ト柁ー盻」c dテケng ト黛サ? t蘯。o cニ。 s盻? d盻ッ li盻? m盻嬖, tr盻創g.\nDROP DATABASE ト柁ー盻」c dテケng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 cニ。 s盻? d盻ッ li盻? s蘯オn cテウ.\nUSE ト柁ー盻」c dテケng ト黛サ? l盻アa ch盻肱 m盻冲 cニ。 s盻? d盻ッ li盻? lテ?m m蘯キc ト黛サ杵h.\nCREATE TABLE ト柁ー盻」c dテケng ト黛サ? t蘯。o m盻冲 b蘯」ng m盻嬖, nニ。i mテ? d盻ッ li盻? c盻ァa b蘯。n th盻アc s盻ア ト柁ー盻」c lニーu tr盻ッ.\nALTER TABLE ト柁ー盻」c dテケng ト黛サ? s盻ュa m盻冲 ト黛サ杵h nghトゥa b蘯」ng s蘯オn cテウ.\nDROP TABLE ト柁ー盻」c s盻ュ d盻・ng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 b蘯」ng s蘯オn cテウ.\nDESCRIBE hi盻ハ th盻? c蘯・u trテコc c盻ァa m盻冲 b蘯」ng.\nThao tテ。c v盻嬖 D盻ッ li盻? c盻ァa b蘯。n\nSELECT ト柁ー盻」c dテケng khi b蘯。n mu盻創 ト黛サ皇 (ho蘯キc l盻アa ch盻肱) d盻ッ li盻? c盻ァa b蘯。n.\nINSERT ト柁ー盻」c dテケng khi b蘯。n mu盻創 thテェm (ho蘯キc chティn) d盻ッ li盻? m盻嬖.\nUPDATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thay ト黛サ品 (ho蘯キc c蘯ュp nh蘯ュt) d盻ッ li盻? s蘯オn cテウ.\nDELETE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lo蘯。i b盻? (ho蘯キc xテウa) d盻ッ li盻? s蘯オn cテウ.\nREPLACE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thテェm ho蘯キc thay ト黛サ品 (ho蘯キc ト黛サ品 ch盻?) d盻ッ li盻? m盻嬖 ho蘯キc d盻ッ li盻? ト妥」 cテウ.\nTRUNCATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lテ?m tr盻創g (ho蘯キc xテウa) t蘯・t c蘯」 d盻ッ li盻? t盻ォ m蘯ォu.\nGiao d盻議h\nSTART TRANSACTION ト柁ー盻」c dテケng ト黛サ? b蘯ッt ト黛コァu m盻冲 giao d盻議h.\nCOMMIT ト柁ー盻」c s盻ュ d盻・ng ト黛サ? テ。p d盻・ng cテ。c thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nROLLBACK ト柁ー盻」c s盻ュ d盻・ng ト黛サ? lo蘯。i b盻? nh盻ッng thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nM盻冲 Vテュ d盻・ ト脆。n gi蘯」n\nCテ「u l盻?h SQL cニ。 b蘯」n\nTrang nテ?y li盻? kテェ cテ。c cテ「u l盻?h SQL quan tr盻肱g nh蘯・t vテ? ch盻ゥa liテェn k蘯ソt ト黛コソn cテ。c trang tテ?i li盻?. N蘯ソu b蘯。n c蘯ァn m盻冲 hニー盻嬾g d蘯ォn cニ。 b蘯」n lテ?m th蘯ソ nテ?o ト黛サ? s盻ュ d盻・ng mテ。y ch盻ァ cニ。 s盻? d盻ッ li盻? MariaDB vテ? lテ?m th蘯ソ nテ?o ト黛サ? th盻アc thi cテ。c l盻?h ト柁。n gi蘯」n, xem M盻冲 cu盻創 sテ。ch v盻? lテイng MariaDB.\n\nト雪サ杵h nghトゥa cテ。ch d盻ッ li盻? c盻ァa b蘯。n ト柁ー盻」c lニーu tr盻ッ\nCREATE DATABASE ト柁ー盻」c dテケng ト黛サ? t蘯。o cニ。 s盻? d盻ッ li盻? m盻嬖, tr盻創g.\nDROP DATABASE ト柁ー盻」c dテケng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 cニ。 s盻? d盻ッ li盻? s蘯オn cテウ.\nUSE ト柁ー盻」c dテケng ト黛サ? l盻アa ch盻肱 m盻冲 cニ。 s盻? d盻ッ li盻? lテ?m m蘯キc ト黛サ杵h.\nCREATE TABLE ト柁ー盻」c dテケng ト黛サ? t蘯。o m盻冲 b蘯」ng m盻嬖, nニ。i mテ? d盻ッ li盻? c盻ァa b蘯。n th盻アc s盻ア ト柁ー盻」c lニーu tr盻ッ.\nALTER TABLE ト柁ー盻」c dテケng ト黛サ? s盻ュa m盻冲 ト黛サ杵h nghトゥa b蘯」ng s蘯オn cテウ.\nDROP TABLE ト柁ー盻」c s盻ュ d盻・ng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 b蘯」ng s蘯オn cテウ.\nDESCRIBE hi盻ハ th盻? c蘯・u trテコc c盻ァa m盻冲 b蘯」ng.\nThao tテ。c v盻嬖 D盻ッ li盻? c盻ァa b蘯。n\nSELECT ト柁ー盻」c dテケng khi b蘯。n mu盻創 ト黛サ皇 (ho蘯キc l盻アa ch盻肱) d盻ッ li盻? c盻ァa b蘯。n.\nINSERT ト柁ー盻」c dテケng khi b蘯。n mu盻創 thテェm (ho蘯キc chティn) d盻ッ li盻? m盻嬖.\nUPDATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thay ト黛サ品 (ho蘯キc c蘯ュp nh蘯ュt) d盻ッ li盻? s蘯オn cテウ.\nDELETE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lo蘯。i b盻? (ho蘯キc xテウa) d盻ッ li盻? s蘯オn cテウ.\nREPLACE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thテェm ho蘯キc thay ト黛サ品 (ho蘯キc ト黛サ品 ch盻?) d盻ッ li盻? m盻嬖 ho蘯キc d盻ッ li盻? ト妥」 cテウ.\nTRUNCATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lテ?m tr盻創g (ho蘯キc xテウa) t蘯・t c蘯」 d盻ッ li盻? t盻ォ m蘯ォu.\nGiao d盻議h\nSTART TRANSACTION ト柁ー盻」c dテケng ト黛サ? b蘯ッt ト黛コァu m盻冲 giao d盻議h.\nCOMMIT ト柁ー盻」c s盻ュ d盻・ng ト黛サ? テ。p d盻・ng cテ。c thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nROLLBACK ト柁ー盻」c s盻ュ d盻・ng ト黛サ? lo蘯。i b盻? nh盻ッng thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nM盻冲 Vテュ d盻・ ト脆。n gi蘯」n\nCテ「u l盻?h SQL cニ。 b蘯」n\nTrang nテ?y li盻? kテェ cテ。c cテ「u l盻?h SQL quan tr盻肱g nh蘯・t vテ? ch盻ゥa liテェn k蘯ソt ト黛コソn cテ。c trang tテ?i li盻?. N蘯ソu b蘯。n c蘯ァn m盻冲 hニー盻嬾g d蘯ォn cニ。 b蘯」n lテ?m th蘯ソ nテ?o ト黛サ? s盻ュ d盻・ng mテ。y ch盻ァ cニ。 s盻? d盻ッ li盻? MariaDB vテ? lテ?m th蘯ソ nテ?o ト黛サ? th盻アc thi cテ。c l盻?h ト柁。n gi蘯」n, xem M盻冲 cu盻創 sテ。ch v盻? lテイng MariaDB.\n\nト雪サ杵h nghトゥa cテ。ch d盻ッ li盻? c盻ァa b蘯。n ト柁ー盻」c lニーu tr盻ッ\nCREATE DATABASE ト柁ー盻」c dテケng ト黛サ? t蘯。o cニ。 s盻? d盻ッ li盻? m盻嬖, tr盻創g.\nDROP DATABASE ト柁ー盻」c dテケng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 cニ。 s盻? d盻ッ li盻? s蘯オn cテウ.\nUSE ト柁ー盻」c dテケng ト黛サ? l盻アa ch盻肱 m盻冲 cニ。 s盻? d盻ッ li盻? lテ?m m蘯キc ト黛サ杵h.\nCREATE TABLE ト柁ー盻」c dテケng ト黛サ? t蘯。o m盻冲 b蘯」ng m盻嬖, nニ。i mテ? d盻ッ li盻? c盻ァa b蘯。n th盻アc s盻ア ト柁ー盻」c lニーu tr盻ッ.\nALTER TABLE ト柁ー盻」c dテケng ト黛サ? s盻ュa m盻冲 ト黛サ杵h nghトゥa b蘯」ng s蘯オn cテウ.\nDROP TABLE ト柁ー盻」c s盻ュ d盻・ng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 b蘯」ng s蘯オn cテウ.\nDESCRIBE hi盻ハ th盻? c蘯・u trテコc c盻ァa m盻冲 b蘯」ng.\nThao tテ。c v盻嬖 D盻ッ li盻? c盻ァa b蘯。n\nSELECT ト柁ー盻」c dテケng khi b蘯。n mu盻創 ト黛サ皇 (ho蘯キc l盻アa ch盻肱) d盻ッ li盻? c盻ァa b蘯。n.\nINSERT ト柁ー盻」c dテケng khi b蘯。n mu盻創 thテェm (ho蘯キc chティn) d盻ッ li盻? m盻嬖.\nUPDATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thay ト黛サ品 (ho蘯キc c蘯ュp nh蘯ュt) d盻ッ li盻? s蘯オn cテウ.\nDELETE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lo蘯。i b盻? (ho蘯キc xテウa) d盻ッ li盻? s蘯オn cテウ.\nREPLACE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thテェm ho蘯キc thay ト黛サ品 (ho蘯キc ト黛サ品 ch盻?) d盻ッ li盻? m盻嬖 ho蘯キc d盻ッ li盻? ト妥」 cテウ.\nTRUNCATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lテ?m tr盻創g (ho蘯キc xテウa) t蘯・t c蘯」 d盻ッ li盻? t盻ォ m蘯ォu.\nGiao d盻議h\nSTART TRANSACTION ト柁ー盻」c dテケng ト黛サ? b蘯ッt ト黛コァu m盻冲 giao d盻議h.\nCOMMIT ト柁ー盻」c s盻ュ d盻・ng ト黛サ? テ。p d盻・ng cテ。c thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nROLLBACK ト柁ー盻」c s盻ュ d盻・ng ト黛サ? lo蘯。i b盻? nh盻ッng thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nM盻冲 Vテュ d盻・ ト脆。n gi蘯」n\nCテ「u l盻?h SQL cニ。 b蘯」n\nTrang nテ?y li盻? kテェ cテ。c cテ「u l盻?h SQL quan tr盻肱g nh蘯・t vテ? ch盻ゥa liテェn k蘯ソt ト黛コソn cテ。c trang tテ?i li盻?. N蘯ソu b蘯。n c蘯ァn m盻冲 hニー盻嬾g d蘯ォn cニ。 b蘯」n lテ?m th蘯ソ nテ?o ト黛サ? s盻ュ d盻・ng mテ。y ch盻ァ cニ。 s盻? d盻ッ li盻? MariaDB vテ? lテ?m th蘯ソ nテ?o ト黛サ? th盻アc thi cテ。c l盻?h ト柁。n gi蘯」n, xem M盻冲 cu盻創 sテ。ch v盻? lテイng MariaDB.\n\nト雪サ杵h nghトゥa cテ。ch d盻ッ li盻? c盻ァa b蘯。n ト柁ー盻」c lニーu tr盻ッ\nCREATE DATABASE ト柁ー盻」c dテケng ト黛サ? t蘯。o cニ。 s盻? d盻ッ li盻? m盻嬖, tr盻創g.\nDROP DATABASE ト柁ー盻」c dテケng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 cニ。 s盻? d盻ッ li盻? s蘯オn cテウ.\nUSE ト柁ー盻」c dテケng ト黛サ? l盻アa ch盻肱 m盻冲 cニ。 s盻? d盻ッ li盻? lテ?m m蘯キc ト黛サ杵h.\nCREATE TABLE ト柁ー盻」c dテケng ト黛サ? t蘯。o m盻冲 b蘯」ng m盻嬖, nニ。i mテ? d盻ッ li盻? c盻ァa b蘯。n th盻アc s盻ア ト柁ー盻」c lニーu tr盻ッ.\nALTER TABLE ト柁ー盻」c dテケng ト黛サ? s盻ュa m盻冲 ト黛サ杵h nghトゥa b蘯」ng s蘯オn cテウ.\nDROP TABLE ト柁ー盻」c s盻ュ d盻・ng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 b蘯」ng s蘯オn cテウ.\nDESCRIBE hi盻ハ th盻? c蘯・u trテコc c盻ァa m盻冲 b蘯」ng.\nThao tテ。c v盻嬖 D盻ッ li盻? c盻ァa b蘯。n\nSELECT ト柁ー盻」c dテケng khi b蘯。n mu盻創 ト黛サ皇 (ho蘯キc l盻アa ch盻肱) d盻ッ li盻? c盻ァa b蘯。n.\nINSERT ト柁ー盻」c dテケng khi b蘯。n mu盻創 thテェm (ho蘯キc chティn) d盻ッ li盻? m盻嬖.\nUPDATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thay ト黛サ品 (ho蘯キc c蘯ュp nh蘯ュt) d盻ッ li盻? s蘯オn cテウ.\nDELETE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lo蘯。i b盻? (ho蘯キc xテウa) d盻ッ li盻? s蘯オn cテウ.\nREPLACE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thテェm ho蘯キc thay ト黛サ品 (ho蘯キc ト黛サ品 ch盻?) d盻ッ li盻? m盻嬖 ho蘯キc d盻ッ li盻? ト妥」 cテウ.\nTRUNCATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lテ?m tr盻創g (ho蘯キc xテウa) t蘯・t c蘯」 d盻ッ li盻? t盻ォ m蘯ォu.\nGiao d盻議h\nSTART TRANSACTION ト柁ー盻」c dテケng ト黛サ? b蘯ッt ト黛コァu m盻冲 giao d盻議h.\nCOMMIT ト柁ー盻」c s盻ュ d盻・ng ト黛サ? テ。p d盻・ng cテ。c thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nROLLBACK ト柁ー盻」c s盻ュ d盻・ng ト黛サ? lo蘯。i b盻? nh盻ッng thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nM盻冲 Vテュ d盻・ ト脆。n gi蘯」n\nCテ「u l盻?h SQL cニ。 b蘯」n\nTrang nテ?y li盻? kテェ cテ。c cテ「u l盻?h SQL quan tr盻肱g nh蘯・t vテ? ch盻ゥa liテェn k蘯ソt ト黛コソn cテ。c trang tテ?i li盻?. N蘯ソu b蘯。n c蘯ァn m盻冲 hニー盻嬾g d蘯ォn cニ。 b蘯」n lテ?m th蘯ソ nテ?o ト黛サ? s盻ュ d盻・ng mテ。y ch盻ァ cニ。 s盻? d盻ッ li盻? MariaDB vテ? lテ?m th蘯ソ nテ?o ト黛サ? th盻アc thi cテ。c l盻?h ト柁。n gi蘯」n, xem M盻冲 cu盻創 sテ。ch v盻? lテイng MariaDB.\n\nト雪サ杵h nghトゥa cテ。ch d盻ッ li盻? c盻ァa b蘯。n ト柁ー盻」c lニーu tr盻ッ\nCREATE DATABASE ト柁ー盻」c dテケng ト黛サ? t蘯。o cニ。 s盻? d盻ッ li盻? m盻嬖, tr盻創g.\nDROP DATABASE ト柁ー盻」c dテケng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 cニ。 s盻? d盻ッ li盻? s蘯オn cテウ.\nUSE ト柁ー盻」c dテケng ト黛サ? l盻アa ch盻肱 m盻冲 cニ。 s盻? d盻ッ li盻? lテ?m m蘯キc ト黛サ杵h.\nCREATE TABLE ト柁ー盻」c dテケng ト黛サ? t蘯。o m盻冲 b蘯」ng m盻嬖, nニ。i mテ? d盻ッ li盻? c盻ァa b蘯。n th盻アc s盻ア ト柁ー盻」c lニーu tr盻ッ.\nALTER TABLE ト柁ー盻」c dテケng ト黛サ? s盻ュa m盻冲 ト黛サ杵h nghトゥa b蘯」ng s蘯オn cテウ.\nDROP TABLE ト柁ー盻」c s盻ュ d盻・ng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 b蘯」ng s蘯オn cテウ.\nDESCRIBE hi盻ハ th盻? c蘯・u trテコc c盻ァa m盻冲 b蘯」ng.\nThao tテ。c v盻嬖 D盻ッ li盻? c盻ァa b蘯。n\nSELECT ト柁ー盻」c dテケng khi b蘯。n mu盻創 ト黛サ皇 (ho蘯キc l盻アa ch盻肱) d盻ッ li盻? c盻ァa b蘯。n.\nINSERT ト柁ー盻」c dテケng khi b蘯。n mu盻創 thテェm (ho蘯キc chティn) d盻ッ li盻? m盻嬖.\nUPDATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thay ト黛サ品 (ho蘯キc c蘯ュp nh蘯ュt) d盻ッ li盻? s蘯オn cテウ.\nDELETE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lo蘯。i b盻? (ho蘯キc xテウa) d盻ッ li盻? s蘯オn cテウ.\nREPLACE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thテェm ho蘯キc thay ト黛サ品 (ho蘯キc ト黛サ品 ch盻?) d盻ッ li盻? m盻嬖 ho蘯キc d盻ッ li盻? ト妥」 cテウ.\nTRUNCATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lテ?m tr盻創g (ho蘯キc xテウa) t蘯・t c蘯」 d盻ッ li盻? t盻ォ m蘯ォu.\nGiao d盻議h\nSTART TRANSACTION ト柁ー盻」c dテケng ト黛サ? b蘯ッt ト黛コァu m盻冲 giao d盻議h.\nCOMMIT ト柁ー盻」c s盻ュ d盻・ng ト黛サ? テ。p d盻・ng cテ。c thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nROLLBACK ト柁ー盻」c s盻ュ d盻・ng ト黛サ? lo蘯。i b盻? nh盻ッng thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nM盻冲 Vテュ d盻・ ト脆。n gi蘯」n\nCテ「u l盻?h SQL cニ。 b蘯」n\nTrang nテ?y li盻? kテェ cテ。c cテ「u l盻?h SQL quan tr盻肱g nh蘯・t vテ? ch盻ゥa liテェn k蘯ソt ト黛コソn cテ。c trang tテ?i li盻?. N蘯ソu b蘯。n c蘯ァn m盻冲 hニー盻嬾g d蘯ォn cニ。 b蘯」n lテ?m th蘯ソ nテ?o ト黛サ? s盻ュ d盻・ng mテ。y ch盻ァ cニ。 s盻? d盻ッ li盻? MariaDB vテ? lテ?m th蘯ソ nテ?o ト黛サ? th盻アc thi cテ。c l盻?h ト柁。n gi蘯」n, xem M盻冲 cu盻創 sテ。ch v盻? lテイng MariaDB.\n\nト雪サ杵h nghトゥa cテ。ch d盻ッ li盻? c盻ァa b蘯。n ト柁ー盻」c lニーu tr盻ッ\nCREATE DATABASE ト柁ー盻」c dテケng ト黛サ? t蘯。o cニ。 s盻? d盻ッ li盻? m盻嬖, tr盻創g.\nDROP DATABASE ト柁ー盻」c dテケng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 cニ。 s盻? d盻ッ li盻? s蘯オn cテウ.\nUSE ト柁ー盻」c dテケng ト黛サ? l盻アa ch盻肱 m盻冲 cニ。 s盻? d盻ッ li盻? lテ?m m蘯キc ト黛サ杵h.\nCREATE TABLE ト柁ー盻」c dテケng ト黛サ? t蘯。o m盻冲 b蘯」ng m盻嬖, nニ。i mテ? d盻ッ li盻? c盻ァa b蘯。n th盻アc s盻ア ト柁ー盻」c lニーu tr盻ッ.\nALTER TABLE ト柁ー盻」c dテケng ト黛サ? s盻ュa m盻冲 ト黛サ杵h nghトゥa b蘯」ng s蘯オn cテウ.\nDROP TABLE ト柁ー盻」c s盻ュ d盻・ng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 b蘯」ng s蘯オn cテウ.\nDESCRIBE hi盻ハ th盻? c蘯・u trテコc c盻ァa m盻冲 b蘯」ng.\nThao tテ。c v盻嬖 D盻ッ li盻? c盻ァa b蘯。n\nSELECT ト柁ー盻」c dテケng khi b蘯。n mu盻創 ト黛サ皇 (ho蘯キc l盻アa ch盻肱) d盻ッ li盻? c盻ァa b蘯。n.\nINSERT ト柁ー盻」c dテケng khi b蘯。n mu盻創 thテェm (ho蘯キc chティn) d盻ッ li盻? m盻嬖.\nUPDATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thay ト黛サ品 (ho蘯キc c蘯ュp nh蘯ュt) d盻ッ li盻? s蘯オn cテウ.\nDELETE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lo蘯。i b盻? (ho蘯キc xテウa) d盻ッ li盻? s蘯オn cテウ.\nREPLACE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thテェm ho蘯キc thay ト黛サ品 (ho蘯キc ト黛サ品 ch盻?) d盻ッ li盻? m盻嬖 ho蘯キc d盻ッ li盻? ト妥」 cテウ.\nTRUNCATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lテ?m tr盻創g (ho蘯キc xテウa) t蘯・t c蘯」 d盻ッ li盻? t盻ォ m蘯ォu.\nGiao d盻議h\nSTART TRANSACTION ト柁ー盻」c dテケng ト黛サ? b蘯ッt ト黛コァu m盻冲 giao d盻議h.\nCOMMIT ト柁ー盻」c s盻ュ d盻・ng ト黛サ? テ。p d盻・ng cテ。c thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nROLLBACK ト柁ー盻」c s盻ュ d盻・ng ト黛サ? lo蘯。i b盻? nh盻ッng thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nM盻冲 Vテュ d盻・ ト脆。n gi蘯」n\nCテ「u l盻?h SQL cニ。 b蘯」n\nTrang nテ?y li盻? kテェ cテ。c cテ「u l盻?h SQL quan tr盻肱g nh蘯・t vテ? ch盻ゥa liテェn k蘯ソt ト黛コソn cテ。c trang tテ?i li盻?. N蘯ソu b蘯。n c蘯ァn m盻冲 hニー盻嬾g d蘯ォn cニ。 b蘯」n lテ?m th蘯ソ nテ?o ト黛サ? s盻ュ d盻・ng mテ。y ch盻ァ cニ。 s盻? d盻ッ li盻? MariaDB vテ? lテ?m th蘯ソ nテ?o ト黛サ? th盻アc thi cテ。c l盻?h ト柁。n gi蘯」n, xem M盻冲 cu盻創 sテ。ch v盻? lテイng MariaDB.\n\nト雪サ杵h nghトゥa cテ。ch d盻ッ li盻? c盻ァa b蘯。n ト柁ー盻」c lニーu tr盻ッ\nCREATE DATABASE ト柁ー盻」c dテケng ト黛サ? t蘯。o cニ。 s盻? d盻ッ li盻? m盻嬖, tr盻創g.\nDROP DATABASE ト柁ー盻」c dテケng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 cニ。 s盻? d盻ッ li盻? s蘯オn cテウ.\nUSE ト柁ー盻」c dテケng ト黛サ? l盻アa ch盻肱 m盻冲 cニ。 s盻? d盻ッ li盻? lテ?m m蘯キc ト黛サ杵h.\nCREATE TABLE ト柁ー盻」c dテケng ト黛サ? t蘯。o m盻冲 b蘯」ng m盻嬖, nニ。i mテ? d盻ッ li盻? c盻ァa b蘯。n th盻アc s盻ア ト柁ー盻」c lニーu tr盻ッ.\nALTER TABLE ト柁ー盻」c dテケng ト黛サ? s盻ュa m盻冲 ト黛サ杵h nghトゥa b蘯」ng s蘯オn cテウ.\nDROP TABLE ト柁ー盻」c s盻ュ d盻・ng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 b蘯」ng s蘯オn cテウ.\nDESCRIBE hi盻ハ th盻? c蘯・u trテコc c盻ァa m盻冲 b蘯」ng.\nThao tテ。c v盻嬖 D盻ッ li盻? c盻ァa b蘯。n\nSELECT ト柁ー盻」c dテケng khi b蘯。n mu盻創 ト黛サ皇 (ho蘯キc l盻アa ch盻肱) d盻ッ li盻? c盻ァa b蘯。n.\nINSERT ト柁ー盻」c dテケng khi b蘯。n mu盻創 thテェm (ho蘯キc chティn) d盻ッ li盻? m盻嬖.\nUPDATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thay ト黛サ品 (ho蘯キc c蘯ュp nh蘯ュt) d盻ッ li盻? s蘯オn cテウ.\nDELETE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lo蘯。i b盻? (ho蘯キc xテウa) d盻ッ li盻? s蘯オn cテウ.\nREPLACE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thテェm ho蘯キc thay ト黛サ品 (ho蘯キc ト黛サ品 ch盻?) d盻ッ li盻? m盻嬖 ho蘯キc d盻ッ li盻? ト妥」 cテウ.\nTRUNCATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lテ?m tr盻創g (ho蘯キc xテウa) t蘯・t c蘯」 d盻ッ li盻? t盻ォ m蘯ォu.\nGiao d盻議h\nSTART TRANSACTION ト柁ー盻」c dテケng ト黛サ? b蘯ッt ト黛コァu m盻冲 giao d盻議h.\nCOMMIT ト柁ー盻」c s盻ュ d盻・ng ト黛サ? テ。p d盻・ng cテ。c thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nROLLBACK ト柁ー盻」c s盻ュ d盻・ng ト黛サ? lo蘯。i b盻? nh盻ッng thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nM盻冲 Vテュ d盻・ ト脆。n gi蘯」n\nCテ「u l盻?h SQL cニ。 b蘯」n\nTrang nテ?y li盻? kテェ cテ。c cテ「u l盻?h SQL quan tr盻肱g nh蘯・t vテ? ch盻ゥa liテェn k蘯ソt ト黛コソn cテ。c trang tテ?i li盻?. N蘯ソu b蘯。n c蘯ァn m盻冲 hニー盻嬾g d蘯ォn cニ。 b蘯」n lテ?m th蘯ソ nテ?o ト黛サ? s盻ュ d盻・ng mテ。y ch盻ァ cニ。 s盻? d盻ッ li盻? MariaDB vテ? lテ?m th蘯ソ nテ?o ト黛サ? th盻アc thi cテ。c l盻?h ト柁。n gi蘯」n, xem M盻冲 cu盻創 sテ。ch v盻? lテイng MariaDB.\n\nト雪サ杵h nghトゥa cテ。ch d盻ッ li盻? c盻ァa b蘯。n ト柁ー盻」c lニーu tr盻ッ\nCREATE DATABASE ト柁ー盻」c dテケng ト黛サ? t蘯。o cニ。 s盻? d盻ッ li盻? m盻嬖, tr盻創g.\nDROP DATABASE ト柁ー盻」c dテケng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 cニ。 s盻? d盻ッ li盻? s蘯オn cテウ.\nUSE ト柁ー盻」c dテケng ト黛サ? l盻アa ch盻肱 m盻冲 cニ。 s盻? d盻ッ li盻? lテ?m m蘯キc ト黛サ杵h.\nCREATE TABLE ト柁ー盻」c dテケng ト黛サ? t蘯。o m盻冲 b蘯」ng m盻嬖, nニ。i mテ? d盻ッ li盻? c盻ァa b蘯。n th盻アc s盻ア ト柁ー盻」c lニーu tr盻ッ.\nALTER TABLE ト柁ー盻」c dテケng ト黛サ? s盻ュa m盻冲 ト黛サ杵h nghトゥa b蘯」ng s蘯オn cテウ.\nDROP TABLE ト柁ー盻」c s盻ュ d盻・ng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 b蘯」ng s蘯オn cテウ.\nDESCRIBE hi盻ハ th盻? c蘯・u trテコc c盻ァa m盻冲 b蘯」ng.\nThao tテ。c v盻嬖 D盻ッ li盻? c盻ァa b蘯。n\nSELECT ト柁ー盻」c dテケng khi b蘯。n mu盻創 ト黛サ皇 (ho蘯キc l盻アa ch盻肱) d盻ッ li盻? c盻ァa b蘯。n.\nINSERT ト柁ー盻」c dテケng khi b蘯。n mu盻創 thテェm (ho蘯キc chティn) d盻ッ li盻? m盻嬖.\nUPDATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thay ト黛サ品 (ho蘯キc c蘯ュp nh蘯ュt) d盻ッ li盻? s蘯オn cテウ.\nDELETE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lo蘯。i b盻? (ho蘯キc xテウa) d盻ッ li盻? s蘯オn cテウ.\nREPLACE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thテェm ho蘯キc thay ト黛サ品 (ho蘯キc ト黛サ品 ch盻?) d盻ッ li盻? m盻嬖 ho蘯キc d盻ッ li盻? ト妥」 cテウ.\nTRUNCATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lテ?m tr盻創g (ho蘯キc xテウa) t蘯・t c蘯」 d盻ッ li盻? t盻ォ m蘯ォu.\nGiao d盻議h\nSTART TRANSACTION ト柁ー盻」c dテケng ト黛サ? b蘯ッt ト黛コァu m盻冲 giao d盻議h.\nCOMMIT ト柁ー盻」c s盻ュ d盻・ng ト黛サ? テ。p d盻・ng cテ。c thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nROLLBACK ト柁ー盻」c s盻ュ d盻・ng ト黛サ? lo蘯。i b盻? nh盻ッng thay ト黛サ品 vテ? k蘯ソt thテコc giao d盻議h.\nM盻冲 Vテュ d盻・ ト脆。n gi蘯」n\nCテ「u l盻?h SQL cニ。 b蘯」n\nTrang nテ?y li盻? kテェ cテ。c cテ「u l盻?h SQL quan tr盻肱g nh蘯・t vテ? ch盻ゥa liテェn k蘯ソt ト黛コソn cテ。c trang tテ?i li盻?. N蘯ソu b蘯。n c蘯ァn m盻冲 hニー盻嬾g d蘯ォn cニ。 b蘯」n lテ?m th蘯ソ nテ?o ト黛サ? s盻ュ d盻・ng mテ。y ch盻ァ cニ。 s盻? d盻ッ li盻? MariaDB vテ? lテ?m th蘯ソ nテ?o ト黛サ? th盻アc thi cテ。c l盻?h ト柁。n gi蘯」n, xem M盻冲 cu盻創 sテ。ch v盻? lテイng MariaDB.\n\nト雪サ杵h nghトゥa cテ。ch d盻ッ li盻? c盻ァa b蘯。n ト柁ー盻」c lニーu tr盻ッ\nCREATE DATABASE ト柁ー盻」c dテケng ト黛サ? t蘯。o cニ。 s盻? d盻ッ li盻? m盻嬖, tr盻創g.\nDROP DATABASE ト柁ー盻」c dテケng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 cニ。 s盻? d盻ッ li盻? s蘯オn cテウ.\nUSE ト柁ー盻」c dテケng ト黛サ? l盻アa ch盻肱 m盻冲 cニ。 s盻? d盻ッ li盻? lテ?m m蘯キc ト黛サ杵h.\nCREATE TABLE ト柁ー盻」c dテケng ト黛サ? t蘯。o m盻冲 b蘯」ng m盻嬖, nニ。i mテ? d盻ッ li盻? c盻ァa b蘯。n th盻アc s盻ア ト柁ー盻」c lニーu tr盻ッ.\nALTER TABLE ト柁ー盻」c dテケng ト黛サ? s盻ュa m盻冲 ト黛サ杵h nghトゥa b蘯」ng s蘯オn cテウ.\nDROP TABLE ト柁ー盻」c s盻ュ d盻・ng ト黛サ? h盻ァy hoテ?n toテ?n m盻冲 b蘯」ng s蘯オn cテウ.\nDESCRIBE hi盻ハ th盻? c蘯・u trテコc c盻ァa m盻冲 b蘯」ng.\nThao tテ。c v盻嬖 D盻ッ li盻? c盻ァa b蘯。n\nSELECT ト柁ー盻」c dテケng khi b蘯。n mu盻創 ト黛サ皇 (ho蘯キc l盻アa ch盻肱) d盻ッ li盻? c盻ァa b蘯。n.\nINSERT ト柁ー盻」c dテケng khi b蘯。n mu盻創 thテェm (ho蘯キc chティn) d盻ッ li盻? m盻嬖.\nUPDATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thay ト黛サ品 (ho蘯キc c蘯ュp nh蘯ュt) d盻ッ li盻? s蘯オn cテウ.\nDELETE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lo蘯。i b盻? (ho蘯キc xテウa) d盻ッ li盻? s蘯オn cテウ.\nREPLACE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 thテェm ho蘯キc thay ト黛サ品 (ho蘯キc ト黛サ品 ch盻?) d盻ッ li盻? m盻嬖 ho蘯キc d盻ッ li盻? ト妥」 cテウ.\nTRUNCATE ト柁ー盻」c s盻ュ d盻・ng khi b蘯。n mu盻創 lテ?m tr盻創g (ho蘯キc xテウa) t蘯・t c蘯」 d盻ッ li盻? t盻ォ m蘯ォu.\nGiao d盻議h\nSTART TRANSACTION ト柁ー盻」c dテケng ト黛サ? b蘯ッt ト黛コァu m盻冲 giao d盻議h.\nCOMMIT ト柁ー盻」c s盻ュ d盻・ng ト黛サ? テ。p d盻・ng cテ。c thay ト黛サ品 vテ? k蘯ソ',NULL,'v',5,9,'1974-08-26 13:43:18.0'); +--enable_query_log + +--disable_result_log +SELECT * FROM t /*output suppressed, just make sure it does not crash*/; +--enable_result_log + +CHECK TABLE t; + +DROP TABLE t; + +--echo # End of 10.5 tests diff --git a/mysql-test/main/ctype_ucs.result b/mysql-test/main/ctype_ucs.result index de73f41c5a7..d38d04c133f 100644 --- a/mysql-test/main/ctype_ucs.result +++ b/mysql-test/main/ctype_ucs.result @@ -6555,5 +6555,14 @@ SELECT CAST(CONVERT('-9223372036854775808' USING ucs2) AS SIGNED) AS c1; c1 -9223372036854775808 # +# MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify +# +select strcmp(_ucs2'' collate ucs2_general_nopad_ci, _ucs2 0x00000001000500000001) as c1; +c1 +-1 +select strcmp(_ucs2'' collate ucs2_nopad_bin, _ucs2 0x00000001000500000001) as c1; +c1 +-1 +# # End of 10.5 tests # diff --git a/mysql-test/main/ctype_ucs.test b/mysql-test/main/ctype_ucs.test index 84ee8c5387c..a7648b13f06 100644 --- a/mysql-test/main/ctype_ucs.test +++ b/mysql-test/main/ctype_ucs.test @@ -1232,6 +1232,13 @@ DROP TABLE t1; SELECT CAST(CONVERT('-9223372036854775808' USING ucs2) AS SIGNED) AS c1; +--echo # +--echo # MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify +--echo # + +select strcmp(_ucs2'' collate ucs2_general_nopad_ci, _ucs2 0x00000001000500000001) as c1; +select strcmp(_ucs2'' collate ucs2_nopad_bin, _ucs2 0x00000001000500000001) as c1; + --echo # --echo # End of 10.5 tests --echo # diff --git a/mysql-test/main/ctype_ujis.result b/mysql-test/main/ctype_ujis.result index 99fa7483b63..28a67f9c54f 100644 --- a/mysql-test/main/ctype_ujis.result +++ b/mysql-test/main/ctype_ujis.result @@ -26810,3 +26810,18 @@ SET DEFAULT_STORAGE_ENGINE=Default; # # End of 10.2 tests # +# +# Start of 10.5 tests +# +# +# MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify +# +select strcmp(_ujis'' collate ujis_japanese_nopad_ci, _ujis 0x0001050001) as c1; +c1 +-1 +select strcmp(_ujis'' collate ujis_nopad_bin, _ujis 0x0001050001) as c1; +c1 +-1 +# +# End of 10.5 tests +# diff --git a/mysql-test/main/ctype_ujis.test b/mysql-test/main/ctype_ujis.test index 71ee27d08f9..3571ac62894 100644 --- a/mysql-test/main/ctype_ujis.test +++ b/mysql-test/main/ctype_ujis.test @@ -1436,3 +1436,18 @@ let $coll_pad='ujis_bin'; --echo # --echo # End of 10.2 tests --echo # + +--echo # +--echo # Start of 10.5 tests +--echo # + +--echo # +--echo # MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify +--echo # + +select strcmp(_ujis'' collate ujis_japanese_nopad_ci, _ujis 0x0001050001) as c1; +select strcmp(_ujis'' collate ujis_nopad_bin, _ujis 0x0001050001) as c1; + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/mysql-test/main/ctype_utf8.result b/mysql-test/main/ctype_utf8.result index 4a64d22b145..f59be30e124 100644 --- a/mysql-test/main/ctype_utf8.result +++ b/mysql-test/main/ctype_utf8.result @@ -11649,5 +11649,14 @@ CAST(_utf8 'яяя' AS INT) Warnings: Warning 1292 Truncated incorrect INTEGER value: 'яяя' # +# MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify +# +select strcmp(_utf8mb3'' collate utf8mb3_general_nopad_ci, _utf8mb3 0x0001050001) as c1; +c1 +-1 +select strcmp(_utf8mb3'' collate utf8mb3_nopad_bin, _utf8mb3 0x0001050001) as c1; +c1 +-1 +# # End of 10.5 tests # diff --git a/mysql-test/main/ctype_utf8.test b/mysql-test/main/ctype_utf8.test index 4bc01142b4c..a3fe588cb2b 100644 --- a/mysql-test/main/ctype_utf8.test +++ b/mysql-test/main/ctype_utf8.test @@ -2529,6 +2529,12 @@ SELECT CAST(_utf8 'ëëë' AS INT); SELECT CAST(_utf8 'œœœ' AS INT); SELECT CAST(_utf8 'яяя' AS INT); +--echo # +--echo # MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify +--echo # + +select strcmp(_utf8mb3'' collate utf8mb3_general_nopad_ci, _utf8mb3 0x0001050001) as c1; +select strcmp(_utf8mb3'' collate utf8mb3_nopad_bin, _utf8mb3 0x0001050001) as c1; --echo # --echo # End of 10.5 tests diff --git a/mysql-test/main/ctype_utf8mb3_innodb.result b/mysql-test/main/ctype_utf8mb3_innodb.result new file mode 100644 index 00000000000..f1894f37e0d --- /dev/null +++ b/mysql-test/main/ctype_utf8mb3_innodb.result @@ -0,0 +1,39 @@ +# Start of 10.5 tests +# +# MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify +# +CREATE TABLE t ( +a INT, +b VARCHAR(16), +c CHAR(8), +PRIMARY KEY (b,c), +KEY(c) +) ENGINE=InnoDB CHARACTER SET utf8mb3 COLLATE utf8mb3_general_nopad_ci; +INSERT INTO t VALUES (1,UNHEX('0001050001'),''),(2,UNHEX('0000'),'x'); +UPDATE t SET a = 0; +INSERT INTO t VALUES (0,'',''); +CHECK TABLE t EXTENDED; +Table Op Msg_type Msg_text +test.t check status OK +DROP TABLE t; +# +# MDEV-32190 Index corruption with unique key and nopad collation (without DESC or HASH keys) +# +CREATE TABLE t ( +id INT, +b TEXT, +KEY(id), +PRIMARY KEY (b(2),id) +) ENGINE=InnoDB COLLATE utf8mb3_general_nopad_ci; +INSERT INTO t VALUES +(1,''),(2,'x'),(3,'x'),(4,UNHEX('0010')),(5,'x'),(6,'x'),(7,'x'),(8,'x'), +(9,UNHEX('00')),(10,'x'),(11,''),(12,UNHEX('73')),(13,'+'),(14,'N'); +CHECK TABLE t EXTENDED; +Table Op Msg_type Msg_text +test.t check status OK +SELECT id FROM t WHERE id IN (4,8); +id +4 +8 +DROP TABLE t; +# End of 10.5 tests diff --git a/mysql-test/main/ctype_utf8mb3_innodb.test b/mysql-test/main/ctype_utf8mb3_innodb.test new file mode 100644 index 00000000000..a78c2786d05 --- /dev/null +++ b/mysql-test/main/ctype_utf8mb3_innodb.test @@ -0,0 +1,39 @@ +--source include/have_innodb.inc + +--echo # Start of 10.5 tests + +--echo # +--echo # MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify +--echo # + +CREATE TABLE t ( + a INT, + b VARCHAR(16), + c CHAR(8), + PRIMARY KEY (b,c), + KEY(c) +) ENGINE=InnoDB CHARACTER SET utf8mb3 COLLATE utf8mb3_general_nopad_ci; +INSERT INTO t VALUES (1,UNHEX('0001050001'),''),(2,UNHEX('0000'),'x'); +UPDATE t SET a = 0; +INSERT INTO t VALUES (0,'',''); +CHECK TABLE t EXTENDED; +DROP TABLE t; + +--echo # +--echo # MDEV-32190 Index corruption with unique key and nopad collation (without DESC or HASH keys) +--echo # + +CREATE TABLE t ( + id INT, + b TEXT, + KEY(id), + PRIMARY KEY (b(2),id) +) ENGINE=InnoDB COLLATE utf8mb3_general_nopad_ci; +INSERT INTO t VALUES + (1,''),(2,'x'),(3,'x'),(4,UNHEX('0010')),(5,'x'),(6,'x'),(7,'x'),(8,'x'), + (9,UNHEX('00')),(10,'x'),(11,''),(12,UNHEX('73')),(13,'+'),(14,'N'); +CHECK TABLE t EXTENDED; +SELECT id FROM t WHERE id IN (4,8); +DROP TABLE t; + +--echo # End of 10.5 tests diff --git a/strings/strcoll.inl b/strings/strcoll.inl index 1a727e23847..0da2ecc3a6d 100644 --- a/strings/strcoll.inl +++ b/strings/strcoll.inl @@ -190,12 +190,14 @@ MY_FUNCTION_NAME(strnncoll)(CHARSET_INFO *cs __attribute__((unused)), 0 >0 "a" is a prefix of "b", so "a" is smaller. >0 0 "b" is a prefix of "a", check b_is_prefix. >0 >0 Two weights were scanned, check weight difference. + + Note: weights can be zero and positive (never negative). */ if (!a_wlen) - return b_wlen ? -b_weight : 0; + return b_wlen ? -1 : 0; if (!b_wlen) - return b_is_prefix ? 0 : a_weight; + return b_is_prefix ? 0 : +1; if ((res= (a_weight - b_weight))) return res; From 72e1cc8f5296947c0bcea8b8d682fc8c94484cd7 Mon Sep 17 00:00:00 2001 From: Kristian Nielsen Date: Fri, 10 Jan 2025 00:06:25 +0100 Subject: [PATCH 134/213] MDEV-35806: Error in read_log_event() corrupts relay log writer, crashes server In Log_event::read_log_event(), don't use IO_CACHE::error of the relay log's IO_CACHE to signal an error back to the caller. When reading the active relay log, this flag is also being used by the IO thread, and setting it can randomly cause the IO thread to wrongly detect IO error on writing and permanently disable the relay log. This was seen sporadically in test case rpl.rpl_from_mysql80. The read error set by the SQL thread in the IO_CACHE would be interpreted as a write error by the IO thread, which would cause it to throw a fatal error and close the relay log. And this would later cause CHANGE MASTER to try to purge a closed relay log, resulting in nullptr crash. SQL thread is not able to parse an event read from the relay log. This can happen like here when replicating unknown events from a MySQL master, potentially also for other reasons. Also fix a mistake in my_b_flush_io_cache() introduced back in 2001 (fa09f2cd7e7) where my_b_flush_io_cache() could wrongly return an error set in IO_CACHE::error, even if the flush operation itself succeeded. Also fix another sporadic failure in rpl.rpl_from_mysql80 where the outout of MASTER_POS_WAIT() depended on timing of SQL and IO thread. Reviewed-by: Monty Reviewed-by: Andrei Elkin Signed-off-by: Kristian Nielsen --- client/mysqlbinlog.cc | 17 +++++++++++------ mysql-test/suite/rpl/r/rpl_from_mysql80.result | 2 -- mysql-test/suite/rpl/t/rpl_from_mysql80.test | 2 ++ mysys/mf_iocache.c | 2 +- sql/log.cc | 12 ++++++++---- sql/log_event.cc | 15 ++++++++++++--- sql/log_event.h | 2 +- sql/log_event_server.cc | 4 ++-- sql/rpl_parallel.cc | 5 +++-- sql/rpl_rli.cc | 9 +++++---- sql/slave.cc | 7 ++++--- sql/sql_repl.cc | 8 +++++--- 12 files changed, 54 insertions(+), 31 deletions(-) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 0cb5cf2c67c..f17bf50d4a3 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -2702,6 +2702,7 @@ static Exit_status check_header(IO_CACHE* file, uchar buf[PROBE_HEADER_LEN]; my_off_t tmp_pos, pos; MY_STAT my_file_stat; + int read_error; delete glob_description_event; if (!(glob_description_event= new Format_description_log_event(3))) @@ -2802,7 +2803,8 @@ static Exit_status check_header(IO_CACHE* file, Format_description_log_event *new_description_event; my_b_seek(file, tmp_pos); /* seek back to event's start */ if (!(new_description_event= (Format_description_log_event*) - Log_event::read_log_event(file, glob_description_event, + Log_event::read_log_event(file, &read_error, + glob_description_event, opt_verify_binlog_checksum))) /* EOF can't be hit here normally, so it's a real error */ { @@ -2835,7 +2837,8 @@ static Exit_status check_header(IO_CACHE* file, { Log_event *ev; my_b_seek(file, tmp_pos); /* seek back to event's start */ - if (!(ev= Log_event::read_log_event(file, glob_description_event, + if (!(ev= Log_event::read_log_event(file, &read_error, + glob_description_event, opt_verify_binlog_checksum))) { /* EOF can't be hit here normally, so it's a real error */ @@ -2948,8 +2951,10 @@ static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, { char llbuff[21]; my_off_t old_off = my_b_tell(file); + int read_error; - Log_event* ev = Log_event::read_log_event(file, glob_description_event, + Log_event* ev = Log_event::read_log_event(file, &read_error, + glob_description_event, opt_verify_binlog_checksum); if (!ev) { @@ -2958,15 +2963,15 @@ static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, about a corruption, but treat it as EOF and move to the next binlog. */ if (glob_description_event->flags & LOG_EVENT_BINLOG_IN_USE_F) - file->error= 0; - else if (file->error) + read_error= 0; + else if (read_error) { error("Could not read entry at offset %s: " "Error in log format or read error.", llstr(old_off,llbuff)); goto err; } - // else file->error == 0 means EOF, that's OK, we break in this case + // else read_error == 0 means EOF, that's OK, we break in this case /* Emit a warning in the event that we finished processing input diff --git a/mysql-test/suite/rpl/r/rpl_from_mysql80.result b/mysql-test/suite/rpl/r/rpl_from_mysql80.result index 56dca85150b..0f67f8a6235 100644 --- a/mysql-test/suite/rpl/r/rpl_from_mysql80.result +++ b/mysql-test/suite/rpl/r/rpl_from_mysql80.result @@ -11,8 +11,6 @@ START SLAVE IO_THREAD; include/wait_for_slave_io_to_start.inc START SLAVE UNTIL Master_log_file='master-bin.000001', Master_log_pos= 1178; SELECT MASTER_POS_WAIT('master-bin.000001', 1178, 60); -MASTER_POS_WAIT('master-bin.000001', 1178, 60) -NULL SELECT * FROM t1 ORDER BY a; a b c 1 0 diff --git a/mysql-test/suite/rpl/t/rpl_from_mysql80.test b/mysql-test/suite/rpl/t/rpl_from_mysql80.test index ec4a22056f9..a5723486ee9 100644 --- a/mysql-test/suite/rpl/t/rpl_from_mysql80.test +++ b/mysql-test/suite/rpl/t/rpl_from_mysql80.test @@ -81,7 +81,9 @@ START SLAVE IO_THREAD; # The position 1178 is the start of: INSERT INTO t1 VALUES (4, 0, 'skip'); # After that comes unknown MySQL 8.0 events, which we test error for below. START SLAVE UNTIL Master_log_file='master-bin.000001', Master_log_pos= 1178; +--disable_result_log SELECT MASTER_POS_WAIT('master-bin.000001', 1178, 60); +--enable_result_log SELECT * FROM t1 ORDER BY a; --source include/wait_for_slave_sql_to_stop.inc diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index 4ee1331bdb3..c92b0457e07 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -1735,7 +1735,7 @@ int my_b_flush_io_cache(IO_CACHE *info, int need_append_buffer_lock) info->write_pos= info->write_buffer; ++info->disk_writes; UNLOCK_APPEND_BUFFER; - DBUG_RETURN(info->error); + DBUG_RETURN(0); } } UNLOCK_APPEND_BUFFER; diff --git a/sql/log.cc b/sql/log.cc index 8f4f293a3d0..ce98843b2ad 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -11385,7 +11385,8 @@ int TC_LOG_BINLOG::recover(LOG_INFO *linfo, const char *last_log_name, binlog_checkpoint_found= false; for (round= 1;;) { - while ((ev= Log_event::read_log_event(round == 1 ? first_log : &log, + int error; + while ((ev= Log_event::read_log_event(round == 1 ? first_log : &log, &error, fdle, opt_master_verify_checksum)) && ev->is_valid()) { @@ -11671,7 +11672,8 @@ MYSQL_BIN_LOG::do_binlog_recovery(const char *opt_name, bool do_xa_recovery) return 1; } - if ((ev= Log_event::read_log_event(&log, &fdle, + int read_error; + if ((ev= Log_event::read_log_event(&log, &read_error, &fdle, opt_master_verify_checksum)) && ev->get_type_code() == FORMAT_DESCRIPTION_EVENT) { @@ -11895,10 +11897,11 @@ get_gtid_list_event(IO_CACHE *cache, Gtid_list_log_event **out_gtid_list) Format_description_log_event *fdle; Log_event *ev; const char *errormsg = NULL; + int read_error; *out_gtid_list= NULL; - if (!(ev= Log_event::read_log_event(cache, &init_fdle, + if (!(ev= Log_event::read_log_event(cache, &read_error, &init_fdle, opt_master_verify_checksum)) || ev->get_type_code() != FORMAT_DESCRIPTION_EVENT) { @@ -11914,7 +11917,8 @@ get_gtid_list_event(IO_CACHE *cache, Gtid_list_log_event **out_gtid_list) { Log_event_type typ; - ev= Log_event::read_log_event(cache, fdle, opt_master_verify_checksum); + ev= Log_event::read_log_event(cache, &read_error, fdle, + opt_master_verify_checksum); if (!ev) { errormsg= "Could not read GTID list event while looking for GTID " diff --git a/sql/log_event.cc b/sql/log_event.cc index 6e2ce0ab4bf..b1657275128 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -916,7 +916,7 @@ int Log_event::read_log_event(IO_CACHE* file, String* packet, DBUG_RETURN(0); } -Log_event* Log_event::read_log_event(IO_CACHE* file, +Log_event* Log_event::read_log_event(IO_CACHE* file, int *out_error, const Format_description_log_event *fdle, my_bool crc_check, my_bool print_errors) @@ -927,6 +927,7 @@ Log_event* Log_event::read_log_event(IO_CACHE* file, const char *error= 0; Log_event *res= 0; + *out_error= 0; switch (read_log_event(file, &event, fdle, BINLOG_CHECKSUM_ALG_OFF)) { case 0: @@ -976,14 +977,22 @@ err: #endif /* - The SQL slave thread will check if file->error<0 to know + The SQL slave thread will check *out_error to know if there was an I/O error. Even if there is no "low-level" I/O errors with 'file', any of the high-level above errors is worrying enough to stop the SQL thread now ; as we are skipping the current event, going on with reading and successfully executing other events can only corrupt the slave's databases. So stop. */ - file->error= -1; + *out_error= 1; + /* + Clear any error that might have been set in the IO_CACHE from a read + error, while we are still holding the relay log mutex (if reading from + the hot log). Otherwise the error might interfere unpredictably with + write operations to the same IO_CACHE in the IO thread. + */ + file->error= 0; + #ifndef MYSQL_CLIENT if (!print_errors) diff --git a/sql/log_event.h b/sql/log_event.h index 03902cc286e..de93450669c 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -1344,7 +1344,7 @@ public: we detect the event's type, then call the specific event's constructor and pass description_event as an argument. */ - static Log_event* read_log_event(IO_CACHE* file, + static Log_event* read_log_event(IO_CACHE* file, int *out_error, const Format_description_log_event *description_event, my_bool crc_check, diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc index cd974ce0466..8b740195b24 100644 --- a/sql/log_event_server.cc +++ b/sql/log_event_server.cc @@ -5041,7 +5041,7 @@ int Execute_load_log_event::do_apply_event(rpl_group_info *rgi) char fname[FN_REFLEN+10]; char *ext; int fd; - int error= 1; + int error= 1, read_error; IO_CACHE file; Load_log_event *lev= 0; Relay_log_info const *rli= rgi->rli; @@ -5060,7 +5060,7 @@ int Execute_load_log_event::do_apply_event(rpl_group_info *rgi) goto err; } if (!(lev= (Load_log_event*) - Log_event::read_log_event(&file, + Log_event::read_log_event(&file, &read_error, rli->relay_log.description_event_for_exec, opt_slave_sql_verify_checksum)) || lev->get_type_code() != NEW_LOAD_EVENT) diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc index 25bc31638d8..f2633c3e1d1 100644 --- a/sql/rpl_parallel.cc +++ b/sql/rpl_parallel.cc @@ -1037,14 +1037,15 @@ do_retry: /* The loop is here so we can try again the next relay log file on EOF. */ for (;;) { + int error; old_offset= cur_offset; - ev= Log_event::read_log_event(&rlog, description_event, + ev= Log_event::read_log_event(&rlog, &error, description_event, opt_slave_sql_verify_checksum); cur_offset= my_b_tell(&rlog); if (ev) break; - if (unlikely(rlog.error < 0)) + if (unlikely(error)) { errmsg= "slave SQL thread aborted because of I/O error"; err= 1; diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 736fd11d14f..97d70decb2e 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -544,12 +544,13 @@ read_relay_log_description_event(IO_CACHE *cur_log, ulonglong start_pos, if (my_b_tell(cur_log) >= start_pos) break; - if (!(ev= Log_event::read_log_event(cur_log, fdev, + int read_error; + if (!(ev= Log_event::read_log_event(cur_log, &read_error, fdev, opt_slave_sql_verify_checksum))) { - DBUG_PRINT("info",("could not read event, cur_log->error=%d", - cur_log->error)); - if (cur_log->error) /* not EOF */ + DBUG_PRINT("info",("could not read event, read_error=%d", + read_error)); + if (read_error) /* not EOF */ { *errmsg= "I/O error reading event at position 4"; delete fdev; diff --git a/sql/slave.cc b/sql/slave.cc index c27a203f2d8..90680144426 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -7845,7 +7845,8 @@ static Log_event* next_event(rpl_group_info *rgi, ulonglong *event_size) MYSQL_BIN_LOG::open() will write the buffered description event. */ old_pos= rli->event_relay_log_pos; - if ((ev= Log_event::read_log_event(cur_log, + int error; + if ((ev= Log_event::read_log_event(cur_log, &error, rli->relay_log.description_event_for_exec, opt_slave_sql_verify_checksum))) @@ -7862,8 +7863,8 @@ static Log_event* next_event(rpl_group_info *rgi, ulonglong *event_size) DBUG_RETURN(ev); } if (opt_reckless_slave) // For mysql-test - cur_log->error = 0; - if (unlikely(cur_log->error < 0)) + error = 0; + if (unlikely(error)) { errmsg = "slave SQL thread aborted because of I/O error"; if (hot_log) diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 0ed5cb5e99f..f1661fbad95 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -4188,7 +4188,8 @@ bool mysql_show_binlog_events(THD* thd) my_off_t scan_pos = BIN_LOG_HEADER_SIZE; while (scan_pos < pos) { - ev= Log_event::read_log_event(&log, description_event, + int error; + ev= Log_event::read_log_event(&log, &error, description_event, opt_master_verify_checksum); scan_pos = my_b_tell(&log); if (ev == NULL || !ev->is_valid()) @@ -4263,8 +4264,9 @@ bool mysql_show_binlog_events(THD* thd) writing about this in the server log would be confusing as it isn't related to server operational status. */ + int error; for (event_count = 0; - (ev = Log_event::read_log_event(&log, + (ev = Log_event::read_log_event(&log, &error, description_event, (opt_master_verify_checksum || verify_checksum_once), false)); ) @@ -4308,7 +4310,7 @@ bool mysql_show_binlog_events(THD* thd) break; } - if (unlikely(event_count < unit->lim.get_select_limit() && log.error)) + if (unlikely(event_count < unit->lim.get_select_limit() && error)) { errmsg = "Wrong offset or I/O error"; mysql_mutex_unlock(log_lock); From 73f415c955df91f231e37ce2bc062f06f1490602 Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Tue, 21 Jan 2025 12:26:51 +0700 Subject: [PATCH 135/213] MDEV-24935: Server crashes in Field_iterator_natural_join::next or Field_iterator_table_ref::set_field_iterator upon 2nd execution of SP Calling a stored routine that executes a join on three or more tables and referencing not-existent column name in the USING clause resulted in a crash on its second invocation. Server crash taken place by the reason of dereferencing null pointer in condition of DBUG_ASSERT inside the method Field_iterator_natural_join::next() There the data member cur_column_ref->table_field->field has the nullptr value that was reset at the end of first execution of a stored routine when the standalone procedure cleanup_items() called by the method sp_head::execute. Later this data member is not re-initialized and never referenced in any place except the DBUG_ASSERT on second and later invocations of the stored routine. To fix the issue, the assert's condition should be augmented by a condition '|| !cur_column_ref->table_field' before dereferencing cur_column_ref->table_field. Such extra checking is aligned with conditions used by DBUG_ASSERT macros used by implementation of the class Field_iterator_table_ref that aggregated the class Field_iterator_natural_join. --- mysql-test/main/sp-bugs.result | 27 +++++++++++++++++++++++++++ mysql-test/main/sp-bugs.test | 31 +++++++++++++++++++++++++++++++ sql/table.cc | 1 + 3 files changed, 59 insertions(+) diff --git a/mysql-test/main/sp-bugs.result b/mysql-test/main/sp-bugs.result index a166a5a0a9a..bd5883f0a04 100644 --- a/mysql-test/main/sp-bugs.result +++ b/mysql-test/main/sp-bugs.result @@ -363,3 +363,30 @@ ERROR HY000: Unknown thread id: 0 # # End of 10.4 tests # +# +# MDEV-24935: Server crashes in Field_iterator_natural_join::next or Field_iterator_table_ref::set_field_iterator upon 2nd execution of SP +# +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (b INT, c INT); +CREATE TABLE t3 (d INT); +CREATE PROCEDURE sp() SELECT * FROM t1 JOIN t2 JOIN t3 USING (x); +CALL sp; +ERROR 42S22: Unknown column 'x' in 'from clause' +CALL sp; +ERROR 42S22: Unknown column 'x' in 'from clause' +# Clean up +DROP PROCEDURE sp; +DROP TABLE t1, t2, t3; +CREATE TABLE t1 (c1 INT,c2 INT); +CREATE TABLE t2 (c INT,c2 INT); +CREATE PROCEDURE p2 (OUT i INT,OUT o INT) READS SQL DATA DELETE a2,a3 FROM t1 AS a1 JOIN t2 AS a2 NATURAL JOIN t2 AS a3; +CALL p2 (@c,@a); +ERROR 23000: Column 'c2' in from clause is ambiguous +CALL p2 (@a,@c); +ERROR 23000: Column 'c2' in from clause is ambiguous +# Clean up +DROP PROCEDURE p2; +DROP TABLE t1, t2; +# +# End of 10.5 tests +# diff --git a/mysql-test/main/sp-bugs.test b/mysql-test/main/sp-bugs.test index 18fe14dc8bc..f44216fbf46 100644 --- a/mysql-test/main/sp-bugs.test +++ b/mysql-test/main/sp-bugs.test @@ -386,3 +386,34 @@ KILL (('x' IN ( SELECT 1)) MOD 44); --echo # --echo # End of 10.4 tests --echo # + +--echo # +--echo # MDEV-24935: Server crashes in Field_iterator_natural_join::next or Field_iterator_table_ref::set_field_iterator upon 2nd execution of SP +--echo # +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (b INT, c INT); +CREATE TABLE t3 (d INT); +CREATE PROCEDURE sp() SELECT * FROM t1 JOIN t2 JOIN t3 USING (x); +--error ER_BAD_FIELD_ERROR +CALL sp; +--error ER_BAD_FIELD_ERROR +CALL sp; +--echo # Clean up +DROP PROCEDURE sp; +DROP TABLE t1, t2, t3; + +CREATE TABLE t1 (c1 INT,c2 INT); +CREATE TABLE t2 (c INT,c2 INT); +CREATE PROCEDURE p2 (OUT i INT,OUT o INT) READS SQL DATA DELETE a2,a3 FROM t1 AS a1 JOIN t2 AS a2 NATURAL JOIN t2 AS a3; + +--error ER_NON_UNIQ_ERROR +CALL p2 (@c,@a); +--error ER_NON_UNIQ_ERROR +CALL p2 (@a,@c); +--echo # Clean up +DROP PROCEDURE p2; +DROP TABLE t1, t2; + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/sql/table.cc b/sql/table.cc index 0aad7ae24e1..978dbee254e 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -6948,6 +6948,7 @@ void Field_iterator_natural_join::next() { cur_column_ref= column_ref_it++; DBUG_ASSERT(!cur_column_ref || ! cur_column_ref->table_field || + !cur_column_ref->table_field->field || cur_column_ref->table_ref->table == cur_column_ref->table_field->field->table); } From 40a23e08e605ea8a15555d204e8feaee297bd988 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 24 Jan 2025 12:07:42 +0100 Subject: [PATCH 136/213] WolfSSL - make it compilable also with older versions of Windows SDK. followup 136e866119779668736a4d52ae3301e1f6e3eff2 Remove HAVE_CONFIG_H from wolfssl compilation. WolfSSL knows about it, and would include server's config.h, which is mostly fine, but server pretends to have HAVE_GMTIME_R on Windows, which leads to compilation problems. In any case, on Windows, there is no need for config.h for WolfSSL, and no need for gmtime_r/_s(), as gmtime() is thread-safe on Windpows (it returns pointer to thread-local struct) --- extra/wolfssl/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extra/wolfssl/CMakeLists.txt b/extra/wolfssl/CMakeLists.txt index 85fb06bd128..dc2f8092762 100644 --- a/extra/wolfssl/CMakeLists.txt +++ b/extra/wolfssl/CMakeLists.txt @@ -130,8 +130,9 @@ if(MSVC) if(CMAKE_C_COMPILER_ID MATCHES Clang) target_compile_options(wolfssl PRIVATE $<$:-Wno-incompatible-function-pointer-types>) endif() + remove_definitions(-DHAVE_CONFIG_H) target_compile_definitions(wolfssl PRIVATE - _CRT_USE_CONFORMING_ANNEX_K_TIME HAVE_GMTIME_S WOLFSSL_HAVE_MIN WOLFSSL_HAVE_MAX) + WOLFSSL_HAVE_MIN WOLFSSL_HAVE_MAX) endif() CONFIGURE_FILE(user_settings.h.in user_settings.h) From 841a7d391bead2e486967ed73aed091ac633b4f2 Mon Sep 17 00:00:00 2001 From: Daniele Sciascia Date: Thu, 26 Sep 2024 16:07:13 +0200 Subject: [PATCH 137/213] MDEV-35018 MDL BF-BF conflict on DROP TABLE DROP TABLE on child and UPDATE of parent table can cause an MDL BF-BF conflict when applied concurrently. DROP TABLE takes MDL locks on both child and its parent table, however it only it did not add certification keys for the parent table. This patch adds the following: * Append certification keys corresponding to all parent tables before DROP TABLE replication. * Fix wsrep_append_fk_parent_table() so that it works when it is given a table list containing temporary tables. * Make sure function wsrep_append_fk_parent_table() is only called for local transaction. That was not the case for ALTER TABLE. * Add a test case that verifies that UPDATE parent depends on preceeding DROP TABLE child. * Adapt galera_ddl_fk_conflict test to work with DROP TABLE as well. Signed-off-by: Julius Goryavsky --- mysql-test/suite/galera/r/MDEV-35018.result | 38 ++ .../galera/r/galera_ddl_fk_conflict.result | 607 +++++++++++++++++- mysql-test/suite/galera/t/MDEV-35018.test | 83 +++ .../suite/galera/t/galera_ddl_fk_conflict.inc | 19 +- .../galera/t/galera_ddl_fk_conflict.test | 21 +- .../t/galera_ddl_fk_conflict_with_tmp.inc | 11 +- sql/sql_alter.cc | 2 +- sql/sql_parse.cc | 19 +- sql/wsrep_mysqld.cc | 170 +++-- sql/wsrep_mysqld.h | 7 + 10 files changed, 887 insertions(+), 90 deletions(-) create mode 100644 mysql-test/suite/galera/r/MDEV-35018.result create mode 100644 mysql-test/suite/galera/t/MDEV-35018.test diff --git a/mysql-test/suite/galera/r/MDEV-35018.result b/mysql-test/suite/galera/r/MDEV-35018.result new file mode 100644 index 00000000000..2afa7c4d397 --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-35018.result @@ -0,0 +1,38 @@ +connection node_2; +connection node_1; +connection node_2; +SET GLOBAL wsrep_slave_threads=2; +CREATE TABLE t1 ( +id INTEGER PRIMARY KEY, +f2 INTEGER); +CREATE TABLE t2 ( +f1 INT PRIMARY KEY, +t1_id INT NOT NULL, +f2 INTEGER NOT NULL, +KEY key_t1_id(t1_id), +CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE); +INSERT INTO t1 VALUES (1,0); +INSERT INTO t1 VALUES (2,0); +INSERT INTO t2 VALUES (1,1,1234); +INSERT INTO t2 VALUES (2,2,1234); +connection node_2; +SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_toi"; +connection node_1; +DROP TABLE t2; +connection node_2; +SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_toi_reached"; +SET SESSION wsrep_sync_wait = 0; +1 +connection node_1; +UPDATE t1 SET f2 = 1 WHERE id=2; +connection node_2; +SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_toi"; +SET SESSION wsrep_sync_wait = DEFAULT; +SELECT * FROM t1; +id f2 +1 0 +2 1 +SET DEBUG_SYNC = 'RESET'; +SET GLOBAL DEBUG_DBUG = ''; +SET GLOBAL wsrep_slave_threads = DEFAULT; +DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/galera_ddl_fk_conflict.result b/mysql-test/suite/galera/r/galera_ddl_fk_conflict.result index 03e84f9facd..904c5eb1a82 100644 --- a/mysql-test/suite/galera/r/galera_ddl_fk_conflict.result +++ b/mysql-test/suite/galera/r/galera_ddl_fk_conflict.result @@ -7,7 +7,7 @@ connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1; connection node_1b; SET SESSION wsrep_sync_wait=0; ###################################################################### -# Test for ALTER ENGINE=INNODB +# Test for ALTER TABLE ENGINE=INNODB ###################################################################### ###################################################################### # @@ -49,6 +49,9 @@ EXPECT_1 SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; EXPECT_2 2 +connection node_1; +CREATE TABLE IF NOT EXISTS c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk)); +INSERT IGNORE INTO c1 VALUES (1,1); ###################################################################### # # Scenario #2: DML working on FK parent table tries to replicate, but @@ -87,6 +90,9 @@ EXPECT_1 SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; EXPECT_2 2 +connection node_1; +CREATE TABLE IF NOT EXISTS c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk)); +INSERT IGNORE INTO c1 VALUES (1,1); ###################################################################### # # Scenario #3: 2 DMLs working on two FK parent tables try to replicate, @@ -137,10 +143,10 @@ EXPECT_1 SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; EXPECT_2 2 -DROP TABLE c1, c2; +DROP TABLE IF EXISTS c1, c2; DROP TABLE p1, p2; ###################################################################### -# Test for TRUNCATE +# Test for TRUNCATE TABLE ###################################################################### ###################################################################### # @@ -182,6 +188,9 @@ EXPECT_1 SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; EXPECT_2 2 +connection node_1; +CREATE TABLE IF NOT EXISTS c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk)); +INSERT IGNORE INTO c1 VALUES (1,1); ###################################################################### # # Scenario #2: DML working on FK parent table tries to replicate, but @@ -220,6 +229,9 @@ EXPECT_1 SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; EXPECT_2 2 +connection node_1; +CREATE TABLE IF NOT EXISTS c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk)); +INSERT IGNORE INTO c1 VALUES (1,1); ###################################################################### # # Scenario #3: 2 DMLs working on two FK parent tables try to replicate, @@ -270,5 +282,592 @@ EXPECT_1 SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; EXPECT_2 2 -DROP TABLE c1, c2; +DROP TABLE IF EXISTS c1, c2; DROP TABLE p1, p2; +###################################################################### +# Test for DROP TABLE +###################################################################### +###################################################################### +# +# Scenario #1: DML working on FK parent table BF aborted by DDL +# over child table +# +###################################################################### +connection node_1; +SET SESSION wsrep_sync_wait=0; +CREATE TABLE p1 (pk INTEGER PRIMARY KEY, f2 CHAR(30)); +INSERT INTO p1 VALUES (1, 'INITIAL VALUE'); +CREATE TABLE p2 (pk INTEGER PRIMARY KEY, f2 CHAR(30)); +INSERT INTO p2 VALUES (1, 'INITIAL VALUE'); +INSERT INTO p2 VALUES (2, 'INITIAL VALUE'); +CREATE TABLE c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk)); +INSERT INTO c1 VALUES (1,1); +CREATE TABLE c2 (pk INTEGER PRIMARY KEY, fk1 INTEGER, fk2 INTEGER, FOREIGN KEY (fk1) REFERENCES p1(pk), FOREIGN KEY (fk2) REFERENCES p2(pk)); +INSERT INTO c2 VALUES (1,1,1), (2,1,2); +connection node_1; +SET AUTOCOMMIT=ON; +START TRANSACTION; +UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1; +connection node_2; +SET SESSION wsrep_sync_wait=0; +DROP TABLE c1 ; +connection node_1; +COMMIT; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; +EXPECT_2 +2 +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; +EXPECT_2 +2 +connection node_1; +CREATE TABLE IF NOT EXISTS c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk)); +INSERT IGNORE INTO c1 VALUES (1,1); +###################################################################### +# +# Scenario #2: DML working on FK parent table tries to replicate, but +# fails in certification for earlier DDL on child table +# +###################################################################### +connection node_1; +BEGIN; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +connection node_2; +DROP TABLE c1 ; +connection node_1a; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +connection node_1; +UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1; +COMMIT; +connection node_1a; +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +connection node_1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT 'I deadlocked'; +I deadlocked +I deadlocked +SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; +EXPECT_2 +2 +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; +EXPECT_2 +2 +connection node_1; +CREATE TABLE IF NOT EXISTS c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk)); +INSERT IGNORE INTO c1 VALUES (1,1); +###################################################################### +# +# Scenario #3: 2 DMLs working on two FK parent tables try to replicate, +# but fails in certification for earlier DDL on child table +# which is child to both FK parents +# +###################################################################### +connection node_1; +BEGIN; +connection node_1b; +BEGIN; +connection node_1a; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +connection node_2; +DROP TABLE c2 ; +connection node_1a; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +connection node_1; +UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1; +COMMIT; +connection node_1b; +UPDATE p2 SET f2 = 'TO DEADLOCK' WHERE pk = 2; +COMMIT; +connection node_1a; +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +connection node_1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT 'I deadlocked'; +I deadlocked +I deadlocked +connection node_1b; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT 'I deadlocked'; +I deadlocked +I deadlocked +SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; +EXPECT_2 +2 +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; +EXPECT_2 +2 +DROP TABLE IF EXISTS c1, c2; +Warnings: +Note 1051 Unknown table 'test.c2' +DROP TABLE p1, p2; +###################################################################### +# Test for DROP TABLE +###################################################################### +connection node_1; +SET SESSION wsrep_sync_wait=0; +CREATE TABLE p1 (pk INTEGER PRIMARY KEY, f2 CHAR(30)); +INSERT INTO p1 VALUES (1, 'INITIAL VALUE'); +CREATE TABLE c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk)); +INSERT INTO c1 VALUES (1,1); +###################################################################### +# +# Scenario #4: DML working on FK parent table tries to replicate, but +# fails in certification for earlier DDL on child table +# and another temporary table. TMP table should be skipped +# but FK child table should be replicated with proper keys +# +###################################################################### +connection node_1; +BEGIN; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +connection node_2; +CREATE TEMPORARY TABLE tmp1 (i int); +CREATE TEMPORARY TABLE tmp2 (i int); +DROP TABLE tmp1, c1, tmp2 ; +connection node_1a; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +connection node_1; +INSERT INTO p1 VALUES (10, 'TO DEADLOCK'); +COMMIT; +connection node_1a; +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +connection node_1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT 'I deadlocked'; +I deadlocked +I deadlocked +SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; +EXPECT_1 +1 +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; +EXPECT_1 +1 +DROP TABLE IF EXISTS c1; +Warnings: +Note 1051 Unknown table 'test.c1' +DROP TABLE p1; +DROP TABLE IF EXISTS tmp1, tmp2; +Warnings: +Note 1051 Unknown table 'test.tmp1,test.tmp2' +###################################################################### +# Test for DROP TABLE IF EXISTS +###################################################################### +###################################################################### +# +# Scenario #1: DML working on FK parent table BF aborted by DDL +# over child table +# +###################################################################### +connection node_1; +SET SESSION wsrep_sync_wait=0; +CREATE TABLE p1 (pk INTEGER PRIMARY KEY, f2 CHAR(30)); +INSERT INTO p1 VALUES (1, 'INITIAL VALUE'); +CREATE TABLE p2 (pk INTEGER PRIMARY KEY, f2 CHAR(30)); +INSERT INTO p2 VALUES (1, 'INITIAL VALUE'); +INSERT INTO p2 VALUES (2, 'INITIAL VALUE'); +CREATE TABLE c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk)); +INSERT INTO c1 VALUES (1,1); +CREATE TABLE c2 (pk INTEGER PRIMARY KEY, fk1 INTEGER, fk2 INTEGER, FOREIGN KEY (fk1) REFERENCES p1(pk), FOREIGN KEY (fk2) REFERENCES p2(pk)); +INSERT INTO c2 VALUES (1,1,1), (2,1,2); +connection node_1; +SET AUTOCOMMIT=ON; +START TRANSACTION; +UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1; +connection node_2; +SET SESSION wsrep_sync_wait=0; +DROP TABLE IF EXISTS c1 ; +connection node_1; +COMMIT; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; +EXPECT_2 +2 +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; +EXPECT_2 +2 +connection node_1; +CREATE TABLE IF NOT EXISTS c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk)); +INSERT IGNORE INTO c1 VALUES (1,1); +###################################################################### +# +# Scenario #2: DML working on FK parent table tries to replicate, but +# fails in certification for earlier DDL on child table +# +###################################################################### +connection node_1; +BEGIN; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +connection node_2; +DROP TABLE IF EXISTS c1 ; +connection node_1a; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +connection node_1; +UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1; +COMMIT; +connection node_1a; +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +connection node_1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT 'I deadlocked'; +I deadlocked +I deadlocked +SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; +EXPECT_2 +2 +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; +EXPECT_2 +2 +connection node_1; +CREATE TABLE IF NOT EXISTS c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk)); +INSERT IGNORE INTO c1 VALUES (1,1); +###################################################################### +# +# Scenario #3: 2 DMLs working on two FK parent tables try to replicate, +# but fails in certification for earlier DDL on child table +# which is child to both FK parents +# +###################################################################### +connection node_1; +BEGIN; +connection node_1b; +BEGIN; +connection node_1a; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +connection node_2; +DROP TABLE IF EXISTS c2 ; +connection node_1a; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +connection node_1; +UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1; +COMMIT; +connection node_1b; +UPDATE p2 SET f2 = 'TO DEADLOCK' WHERE pk = 2; +COMMIT; +connection node_1a; +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +connection node_1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT 'I deadlocked'; +I deadlocked +I deadlocked +connection node_1b; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT 'I deadlocked'; +I deadlocked +I deadlocked +SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; +EXPECT_2 +2 +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; +EXPECT_2 +2 +DROP TABLE IF EXISTS c1, c2; +Warnings: +Note 1051 Unknown table 'test.c2' +DROP TABLE p1, p2; +###################################################################### +# Test for DROP TABLE IF EXISTS +###################################################################### +connection node_1; +SET SESSION wsrep_sync_wait=0; +CREATE TABLE p1 (pk INTEGER PRIMARY KEY, f2 CHAR(30)); +INSERT INTO p1 VALUES (1, 'INITIAL VALUE'); +CREATE TABLE c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk)); +INSERT INTO c1 VALUES (1,1); +###################################################################### +# +# Scenario #4: DML working on FK parent table tries to replicate, but +# fails in certification for earlier DDL on child table +# and another temporary table. TMP table should be skipped +# but FK child table should be replicated with proper keys +# +###################################################################### +connection node_1; +BEGIN; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +connection node_2; +CREATE TEMPORARY TABLE tmp1 (i int); +CREATE TEMPORARY TABLE tmp2 (i int); +DROP TABLE IF EXISTS tmp1, c1, tmp2 ; +connection node_1a; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +connection node_1; +INSERT INTO p1 VALUES (10, 'TO DEADLOCK'); +COMMIT; +connection node_1a; +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +connection node_1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT 'I deadlocked'; +I deadlocked +I deadlocked +SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; +EXPECT_1 +1 +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; +EXPECT_1 +1 +DROP TABLE IF EXISTS c1; +Warnings: +Note 1051 Unknown table 'test.c1' +DROP TABLE p1; +DROP TABLE IF EXISTS tmp1, tmp2; +Warnings: +Note 1051 Unknown table 'test.tmp1,test.tmp2' +###################################################################### +# Test for DROP TABLE IF EXISTS nonexisting, +###################################################################### +###################################################################### +# +# Scenario #1: DML working on FK parent table BF aborted by DDL +# over child table +# +###################################################################### +connection node_1; +SET SESSION wsrep_sync_wait=0; +CREATE TABLE p1 (pk INTEGER PRIMARY KEY, f2 CHAR(30)); +INSERT INTO p1 VALUES (1, 'INITIAL VALUE'); +CREATE TABLE p2 (pk INTEGER PRIMARY KEY, f2 CHAR(30)); +INSERT INTO p2 VALUES (1, 'INITIAL VALUE'); +INSERT INTO p2 VALUES (2, 'INITIAL VALUE'); +CREATE TABLE c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk)); +INSERT INTO c1 VALUES (1,1); +CREATE TABLE c2 (pk INTEGER PRIMARY KEY, fk1 INTEGER, fk2 INTEGER, FOREIGN KEY (fk1) REFERENCES p1(pk), FOREIGN KEY (fk2) REFERENCES p2(pk)); +INSERT INTO c2 VALUES (1,1,1), (2,1,2); +connection node_1; +SET AUTOCOMMIT=ON; +START TRANSACTION; +UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1; +connection node_2; +SET SESSION wsrep_sync_wait=0; +DROP TABLE IF EXISTS nonexisting, c1 ; +Warnings: +Note 1051 Unknown table 'test.nonexisting' +connection node_1; +COMMIT; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; +EXPECT_2 +2 +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; +EXPECT_2 +2 +connection node_1; +CREATE TABLE IF NOT EXISTS c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk)); +INSERT IGNORE INTO c1 VALUES (1,1); +###################################################################### +# +# Scenario #2: DML working on FK parent table tries to replicate, but +# fails in certification for earlier DDL on child table +# +###################################################################### +connection node_1; +BEGIN; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +connection node_2; +DROP TABLE IF EXISTS nonexisting, c1 ; +Warnings: +Note 1051 Unknown table 'test.nonexisting' +connection node_1a; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +connection node_1; +UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1; +COMMIT; +connection node_1a; +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +connection node_1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT 'I deadlocked'; +I deadlocked +I deadlocked +SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; +EXPECT_2 +2 +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; +EXPECT_2 +2 +connection node_1; +CREATE TABLE IF NOT EXISTS c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk)); +INSERT IGNORE INTO c1 VALUES (1,1); +###################################################################### +# +# Scenario #3: 2 DMLs working on two FK parent tables try to replicate, +# but fails in certification for earlier DDL on child table +# which is child to both FK parents +# +###################################################################### +connection node_1; +BEGIN; +connection node_1b; +BEGIN; +connection node_1a; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +connection node_2; +DROP TABLE IF EXISTS nonexisting, c2 ; +Warnings: +Note 1051 Unknown table 'test.nonexisting' +connection node_1a; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +connection node_1; +UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1; +COMMIT; +connection node_1b; +UPDATE p2 SET f2 = 'TO DEADLOCK' WHERE pk = 2; +COMMIT; +connection node_1a; +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +connection node_1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT 'I deadlocked'; +I deadlocked +I deadlocked +connection node_1b; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT 'I deadlocked'; +I deadlocked +I deadlocked +SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; +EXPECT_2 +2 +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; +EXPECT_2 +2 +DROP TABLE IF EXISTS c1, c2; +Warnings: +Note 1051 Unknown table 'test.c2' +DROP TABLE p1, p2; +###################################################################### +# Test for DROP TABLE IF EXISTS nonexisting, +###################################################################### +connection node_1; +SET SESSION wsrep_sync_wait=0; +CREATE TABLE p1 (pk INTEGER PRIMARY KEY, f2 CHAR(30)); +INSERT INTO p1 VALUES (1, 'INITIAL VALUE'); +CREATE TABLE c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk)); +INSERT INTO c1 VALUES (1,1); +###################################################################### +# +# Scenario #4: DML working on FK parent table tries to replicate, but +# fails in certification for earlier DDL on child table +# and another temporary table. TMP table should be skipped +# but FK child table should be replicated with proper keys +# +###################################################################### +connection node_1; +BEGIN; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +connection node_2; +CREATE TEMPORARY TABLE tmp1 (i int); +CREATE TEMPORARY TABLE tmp2 (i int); +DROP TABLE IF EXISTS nonexisting, tmp1, c1, tmp2 ; +Warnings: +Note 1051 Unknown table 'test.nonexisting' +connection node_1a; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +connection node_1; +INSERT INTO p1 VALUES (10, 'TO DEADLOCK'); +COMMIT; +connection node_1a; +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +connection node_1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT 'I deadlocked'; +I deadlocked +I deadlocked +SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; +EXPECT_1 +1 +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; +EXPECT_1 +1 +DROP TABLE IF EXISTS c1; +Warnings: +Note 1051 Unknown table 'test.c1' +DROP TABLE p1; +DROP TABLE IF EXISTS tmp1, tmp2; +Warnings: +Note 1051 Unknown table 'test.tmp1,test.tmp2' diff --git a/mysql-test/suite/galera/t/MDEV-35018.test b/mysql-test/suite/galera/t/MDEV-35018.test new file mode 100644 index 00000000000..490b542bcc0 --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-35018.test @@ -0,0 +1,83 @@ +# +# BF-BF conflict on MDL locks between: DROP TABLE t2 and UPDATE on t1 +# with t2 referencing t1 +# + +--source include/galera_cluster.inc +--source include/have_debug_sync.inc + +# +# Setup +# +--connection node_2 +SET GLOBAL wsrep_slave_threads=2; + +CREATE TABLE t1 ( + id INTEGER PRIMARY KEY, + f2 INTEGER); + +CREATE TABLE t2 ( + f1 INT PRIMARY KEY, + t1_id INT NOT NULL, + f2 INTEGER NOT NULL, + KEY key_t1_id(t1_id), + CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE); + +INSERT INTO t1 VALUES (1,0); +INSERT INTO t1 VALUES (2,0); + +INSERT INTO t2 VALUES (1,1,1234); +INSERT INTO t2 VALUES (2,2,1234); + +# +# DROP TABLE t2 and wait for it to reach node_2 +# +--connection node_2 +SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_toi"; + +--connection node_1 +DROP TABLE t2; + +--connection node_2 +SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_toi_reached"; + +SET SESSION wsrep_sync_wait = 0; +--let $expected_apply_waits = `SELECT VARIABLE_VALUE+1 FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_apply_waits'` +--echo $expected_apply_waits + +# +# Issue a UPDATE to table that references t1 +# Notice that we update field f2, not the primary key, +# and not foreign key. Bug does not manifest if we update +# one of those fields (because FK keys appended in those cases). +# +--connection node_1 +UPDATE t1 SET f2 = 1 WHERE id=2; + + +# +# Expect the UPDATE to depend on the DROP, +# therefore it should wait for the DROP to +# finish before it can be applied. +# If bug is present, expect the wait condition +# to timeout and when the UPDATE applies, it +# will be granted a MDL lock of type SHARED_READ +# for table t1. When resumed, the DROP TABLE will +# also try to MDL lock t1, causing a BF-BF conflict +# on that MDL lock. +# +--connection node_2 +--let $wait_condition = SELECT VARIABLE_VALUE = $expected_apply_waits FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_apply_waits' +--source include/wait_condition.inc +SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_toi"; + +SET SESSION wsrep_sync_wait = DEFAULT; +SELECT * FROM t1; + +# +# Cleanup +# +SET DEBUG_SYNC = 'RESET'; +SET GLOBAL DEBUG_DBUG = ''; +SET GLOBAL wsrep_slave_threads = DEFAULT; +DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/galera_ddl_fk_conflict.inc b/mysql-test/suite/galera/t/galera_ddl_fk_conflict.inc index 06b7bbe41c4..6964446a363 100644 --- a/mysql-test/suite/galera/t/galera_ddl_fk_conflict.inc +++ b/mysql-test/suite/galera/t/galera_ddl_fk_conflict.inc @@ -69,7 +69,7 @@ SET SESSION wsrep_sync_wait=0; --source include/wait_condition.inc # replicate the DDL to be tested ---eval $table_admin_command TABLE c1 $table_admin_command_end +--eval $table_admin_command c1 $table_admin_command_end --connection node_1 --error ER_LOCK_DEADLOCK @@ -82,6 +82,12 @@ SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; +--connection node_1 +--disable_warnings +CREATE TABLE IF NOT EXISTS c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk)); +INSERT IGNORE INTO c1 VALUES (1,1); +--enable_warnings + --echo ###################################################################### --echo # --echo # Scenario #2: DML working on FK parent table tries to replicate, but @@ -97,7 +103,7 @@ BEGIN; --source include/galera_set_sync_point.inc --connection node_2 ---eval $table_admin_command TABLE c1 $table_admin_command_end +--eval $table_admin_command c1 $table_admin_command_end --connection node_1a --source include/galera_wait_sync_point.inc @@ -128,6 +134,11 @@ SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; +--connection node_1 +--disable_warnings +CREATE TABLE IF NOT EXISTS c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk)); +INSERT IGNORE INTO c1 VALUES (1,1); +--enable_warnings --echo ###################################################################### --echo # @@ -149,7 +160,7 @@ BEGIN; --source include/galera_set_sync_point.inc --connection node_2 ---eval $table_admin_command TABLE c2 $table_admin_command_end +--eval $table_admin_command c2 $table_admin_command_end --connection node_1a --source include/galera_wait_sync_point.inc @@ -188,5 +199,5 @@ SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE'; -DROP TABLE c1, c2; +DROP TABLE IF EXISTS c1, c2; DROP TABLE p1, p2; diff --git a/mysql-test/suite/galera/t/galera_ddl_fk_conflict.test b/mysql-test/suite/galera/t/galera_ddl_fk_conflict.test index 4ec866a9f74..b98c6daa73b 100644 --- a/mysql-test/suite/galera/t/galera_ddl_fk_conflict.test +++ b/mysql-test/suite/galera/t/galera_ddl_fk_conflict.test @@ -17,13 +17,28 @@ SET SESSION wsrep_sync_wait=0; --connection node_1b SET SESSION wsrep_sync_wait=0; ---let $table_admin_command = ALTER +--let $table_admin_command = ALTER TABLE --let $table_admin_command_end = ENGINE=INNODB --source galera_ddl_fk_conflict.inc ---let $table_admin_command = TRUNCATE ---let $table_admin_command_end = +--let $table_admin_command = TRUNCATE TABLE +--let $table_admin_command_end = --source galera_ddl_fk_conflict.inc +--let $table_admin_command = DROP TABLE +--let $table_admin_command_end = +--source galera_ddl_fk_conflict.inc +--source galera_ddl_fk_conflict_with_tmp.inc + +--let $table_admin_command = DROP TABLE IF EXISTS +--let $table_admin_command_end = +--source galera_ddl_fk_conflict.inc +--source galera_ddl_fk_conflict_with_tmp.inc + +--let $table_admin_command = DROP TABLE IF EXISTS nonexisting, +--let $table_admin_command_end = +--source galera_ddl_fk_conflict.inc +--source galera_ddl_fk_conflict_with_tmp.inc + # CHECK and ANALYZE are not affected diff --git a/mysql-test/suite/galera/t/galera_ddl_fk_conflict_with_tmp.inc b/mysql-test/suite/galera/t/galera_ddl_fk_conflict_with_tmp.inc index acf3c54180b..cc6542b96b0 100644 --- a/mysql-test/suite/galera/t/galera_ddl_fk_conflict_with_tmp.inc +++ b/mysql-test/suite/galera/t/galera_ddl_fk_conflict_with_tmp.inc @@ -35,9 +35,9 @@ BEGIN; --source include/wait_condition.inc --let $wait_condition = SELECT COUNT(*) = 1 FROM c1 --source include/wait_condition.inc -CREATE TEMPORARY TABLE tmp (i int); ---eval $table_admin_command TABLE c1, tmp $table_admin_command_end -DROP TABLE tmp; +CREATE TEMPORARY TABLE tmp1 (i int); +CREATE TEMPORARY TABLE tmp2 (i int); +--eval $table_admin_command tmp1, c1, tmp2 $table_admin_command_end --connection node_1a --source include/galera_wait_sync_point.inc @@ -45,7 +45,7 @@ DROP TABLE tmp; --let $expected_cert_failures = `SELECT VARIABLE_VALUE+1 FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_cert_failures'` --connection node_1 -UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1; +INSERT INTO p1 VALUES (10, 'TO DEADLOCK'); --send COMMIT --connection node_1a @@ -65,5 +65,6 @@ SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; --connection node_2 SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE'; -DROP TABLE c1; +DROP TABLE IF EXISTS c1; DROP TABLE p1; +DROP TABLE IF EXISTS tmp1, tmp2; diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc index d8cb7e8f341..375ae5c9596 100644 --- a/sql/sql_alter.cc +++ b/sql/sql_alter.cc @@ -522,7 +522,7 @@ bool Sql_cmd_alter_table::execute(THD *thd) DBUG_RETURN(TRUE); /* purecov: inspected */ #ifdef WITH_WSREP - if (WSREP(thd) && + if (WSREP(thd) && wsrep_thd_is_local(thd) && (!thd->is_current_stmt_binlog_format_row() || !thd->find_temporary_table(first_table))) { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 319d5e6535b..705dc35cdb7 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5080,17 +5080,18 @@ mysql_execute_command(THD *thd) lex->create_info.set(DDL_options_st::OPT_IF_EXISTS); #ifdef WITH_WSREP - if (WSREP(thd)) + if (WSREP(thd) && !lex->tmp_table() && wsrep_thd_is_local(thd) && + (!thd->is_current_stmt_binlog_format_row() || + wsrep_table_list_has_non_temp_tables(thd, all_tables))) { - for (TABLE_LIST *table= all_tables; table; table= table->next_global) + wsrep::key_array keys; + if (wsrep_append_fk_parent_table(thd, all_tables, &keys)) { - if (!lex->tmp_table() && - (!thd->is_current_stmt_binlog_format_row() || - !thd->find_temporary_table(table))) - { - WSREP_TO_ISOLATION_BEGIN(NULL, NULL, all_tables); - break; - } + goto wsrep_error_label; + } + if (wsrep_to_isolation_begin(thd, NULL, NULL, all_tables, NULL, &keys)) + { + goto wsrep_error_label; } } #endif /* WITH_WSREP */ diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 6c4fd8c950a..4e324989868 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -1349,84 +1349,114 @@ static void wsrep_keys_free(wsrep_key_arr_t* key_arr) * @return 0 if parent table append was successful, non-zero otherwise. */ -bool -wsrep_append_fk_parent_table(THD* thd, TABLE_LIST* tables, wsrep::key_array* keys) +bool wsrep_append_fk_parent_table(THD *thd, TABLE_LIST *tables, + wsrep::key_array *keys) { - bool fail= false; - TABLE_LIST *table; + assert(wsrep_thd_is_local(thd)); - for (table= tables; table; table= table->next_local) + bool fail= false; + Open_table_context ot_ctx(thd, MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL); + + for (TABLE_LIST *table= tables; table; table= table->next_local) + { + if (!table->table) { - if (is_temporary_table(table)) + TABLE_LIST *save_next_global= table->next_global; + TABLE_LIST::enum_open_strategy save_open_strategy= table->open_strategy; + table->open_strategy= TABLE_LIST::OPEN_IF_EXISTS; + + Diagnostics_area *da= thd->get_stmt_da(); + Warning_info tmp_wi(thd->query_id, false, true); + da->push_warning_info(&tmp_wi); + + if (open_table(thd, table, &ot_ctx)) { - WSREP_DEBUG("Temporary table %s.%s already opened query=%s", table->db.str, - table->table_name.str, wsrep_thd_query(thd)); - return false; - } - } - - thd->release_transactional_locks(); - uint counter; - MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint(); - - if (open_tables(thd, &tables, &counter, MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL)) - { - WSREP_DEBUG("Unable to open table for FK checks for %s", wsrep_thd_query(thd)); - fail= true; - goto exit; - } - - for (table= tables; table; table= table->next_local) - { - if (!is_temporary_table(table) && table->table) - { - FOREIGN_KEY_INFO *f_key_info; - List f_key_list; - - table->table->file->get_foreign_key_list(thd, &f_key_list); - List_iterator_fast it(f_key_list); - while ((f_key_info=it++)) + if (da->is_error() && da->sql_errno() == ER_UNKNOWN_STORAGE_ENGINE) { - WSREP_DEBUG("appended fkey %s", f_key_info->referenced_table->str); - keys->push_back(wsrep_prepare_key_for_toi(f_key_info->referenced_db->str, - f_key_info->referenced_table->str, - wsrep::key::shared)); + thd->get_stmt_da()->reset_diagnostics_area(); + } + else + { + fail= true; } } + + da->pop_warning_info(); + table->next_global= save_next_global; + table->open_strategy= save_open_strategy; + + if (fail) + { + WSREP_DEBUG("Unable to open table for FK checks for %s", + wsrep_thd_query(thd)); + goto exit; + } } + if (table->table && !is_temporary_table(table)) + { + FOREIGN_KEY_INFO *f_key_info; + List f_key_list; + + table->table->file->get_foreign_key_list(thd, &f_key_list); + List_iterator_fast it(f_key_list); + while ((f_key_info= it++)) + { + WSREP_DEBUG("appended fkey %s", f_key_info->referenced_table->str); + keys->push_back(wsrep_prepare_key_for_toi( + f_key_info->referenced_db->str, f_key_info->referenced_table->str, + wsrep::key::shared)); + } + } + } + exit: - DEBUG_SYNC(thd, "wsrep_append_fk_toi_keys_before_close_tables"); + DEBUG_SYNC(thd, "wsrep_append_fk_toi_keys_before_close_tables"); - /* close the table and release MDL locks */ - close_thread_tables(thd); - thd->mdl_context.rollback_to_savepoint(mdl_savepoint); - for (table= tables; table; table= table->next_local) + /* close the table and release MDL locks */ + close_thread_tables(thd); + thd->mdl_context.rollback_to_savepoint(ot_ctx.start_of_statement_svp()); + for (TABLE_LIST *table= tables; table; table= table->next_global) + { + table->table= NULL; + table->mdl_request.ticket= NULL; + } + + /* + Reopen temporary tables if necessary. + DROP TABLE pre-opens temporary tables, but the corresponding + command does not have the CF_PREOPEN_TMP_TABLES flag set. + */ + const bool preopen_tmp_tables= + thd->lex->sql_command == SQLCOM_DROP_TABLE || + (sql_command_flags[thd->lex->sql_command] & CF_PREOPEN_TMP_TABLES); + + if (preopen_tmp_tables && thd->open_temporary_tables(tables)) + { + WSREP_INFO("Unable to reopen temporary tables after FK checks"); + fail= true; + } + + /* + MDEV-32938: Check if DDL operation has been killed before. + + It may be that during collecting foreign keys this operation gets + BF-aborted by another already-running TOI operation because it got MDL + locks on the same table for checking foreign keys. After + `close_thread_tables()` has been called it's safe to assume that no-one can + BF-abort this operation as it's not holding any MDL locks any more. + */ + if (!fail) + { + mysql_mutex_lock(&thd->LOCK_thd_kill); + if (thd->killed) { - table->table= NULL; - table->next_global= NULL; - table->mdl_request.ticket= NULL; + fail= true; } + mysql_mutex_unlock(&thd->LOCK_thd_kill); + } - /* - MDEV-32938: Check if DDL operation has been killed before. - - It may be that during collecting foreign keys this operation gets BF-aborted - by another already-running TOI operation because it got MDL locks on the same - table for checking foreign keys. - After `close_thread_tables()` has been called it's safe to assume that no-one - can BF-abort this operation as it's not holding any MDL locks any more. - */ - if (!fail) - { - mysql_mutex_lock(&thd->LOCK_thd_kill); - if (thd->killed) - { - fail= true; - } - mysql_mutex_unlock(&thd->LOCK_thd_kill); - } - return fail; + return fail; } bool wsrep_reload_ssl() @@ -3526,3 +3556,15 @@ void wsrep_commit_empty(THD* thd, bool all) } DBUG_VOID_RETURN; } + +bool wsrep_table_list_has_non_temp_tables(THD *thd, TABLE_LIST *tables) +{ + for (TABLE_LIST *table= tables; table; table= table->next_global) + { + if (!thd->find_temporary_table(table)) + { + return true; + } + } + return false; +} diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index d67f1fdf479..02d1d7fd248 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -576,6 +576,13 @@ wsrep::key wsrep_prepare_key_for_toi(const char* db, const char* table, void wsrep_wait_ready(THD *thd); void wsrep_ready_set(bool ready_value); + +/** + * Returns true if the given list of tables contains at least one + * non-temporary table. + */ +bool wsrep_table_list_has_non_temp_tables(THD *thd, TABLE_LIST *tables); + #else /* !WITH_WSREP */ /* These macros are needed to compile MariaDB without WSREP support From 50cf189717a3fce90a9f2407ed57e59c108f91ef Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Fri, 24 Jan 2025 16:59:46 +0100 Subject: [PATCH 138/213] MDEV-35018 addendum: improved warnings handling Fixed regression after original MDEV-35018 fix related to warnings appearing when running MDEV-26266 test and other possible problems with warnings. --- sql/wsrep_mysqld.cc | 50 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 4e324989868..5792158a5fc 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -1342,6 +1342,42 @@ static void wsrep_keys_free(wsrep_key_arr_t* key_arr) key_arr->keys_len= 0; } +class Unknown_storage_engine_handler : public Internal_error_handler +{ +public: + Unknown_storage_engine_handler() + : m_handled_errors(0), m_unhandled_errors(0) + {} + + bool handle_condition(THD *thd, + uint sql_errno, + const char* sqlstate, + Sql_condition::enum_warning_level *level, + const char* msg, + Sql_condition ** cond_hdl) override + { + *cond_hdl= NULL; + if (sql_errno == ER_UNKNOWN_STORAGE_ENGINE) + { + m_handled_errors++; + } + else if (*level == Sql_condition::WARN_LEVEL_ERROR) + { + m_unhandled_errors++; + } + return FALSE; + } + + bool safely_trapped_errors() + { + return ((m_handled_errors > 0) && (m_unhandled_errors == 0)); + } + +private: + int m_handled_errors; + int m_unhandled_errors; +}; + /*! * @param thd thread * @param tables list of tables @@ -1365,15 +1401,16 @@ bool wsrep_append_fk_parent_table(THD *thd, TABLE_LIST *tables, TABLE_LIST::enum_open_strategy save_open_strategy= table->open_strategy; table->open_strategy= TABLE_LIST::OPEN_IF_EXISTS; - Diagnostics_area *da= thd->get_stmt_da(); - Warning_info tmp_wi(thd->query_id, false, true); - da->push_warning_info(&tmp_wi); + Unknown_storage_engine_handler no_storage_engine; + thd->push_internal_handler(&no_storage_engine); if (open_table(thd, table, &ot_ctx)) { - if (da->is_error() && da->sql_errno() == ER_UNKNOWN_STORAGE_ENGINE) + if (no_storage_engine.safely_trapped_errors()) { - thd->get_stmt_da()->reset_diagnostics_area(); + Diagnostics_area *da= thd->get_stmt_da(); + da->reset_diagnostics_area(); + da->clear_warning_info(thd->query_id); } else { @@ -1381,7 +1418,8 @@ bool wsrep_append_fk_parent_table(THD *thd, TABLE_LIST *tables, } } - da->pop_warning_info(); + thd->pop_internal_handler(); + table->next_global= save_next_global; table->open_strategy= save_open_strategy; From 552cba92de9952a9a07360a6791d2f63bc06470c Mon Sep 17 00:00:00 2001 From: sjaakola Date: Tue, 31 Dec 2024 08:04:15 +0200 Subject: [PATCH 139/213] MDEV-35710 support for threadpool When client connections use threadpool, i.e. configuration has: thread_handling = pool-of-threads it turned out that during wsrep replication shutdown, not all client connections could be closed. Reason was that some client threads has stmt_da in state DA_EOF, and this state was earlier used to detect if client connection was issuing SHUTDOWN command. To fix this, the connection executing SHUTDOWN is now detected by looking at the actual command being executed: thd->get_command() == COM_SHUTDOWN During replication shutdown, all other connections but the SHUTDOWN executor, are terminated. This commit has new mtr test galera.galera_threadpool, which opens a number of threadpool client connections, and then restarts the node to verify that connections in threadpool are terminated during shutdown. Signed-off-by: Julius Goryavsky --- .../suite/galera/r/galera_threadpool.result | 36 ++++++++++ .../suite/galera/t/galera_threadpool.cnf | 17 +++++ .../suite/galera/t/galera_threadpool.test | 67 +++++++++++++++++++ sql/wsrep_mysqld.cc | 19 ++++-- 4 files changed, 132 insertions(+), 7 deletions(-) create mode 100644 mysql-test/suite/galera/r/galera_threadpool.result create mode 100644 mysql-test/suite/galera/t/galera_threadpool.cnf create mode 100644 mysql-test/suite/galera/t/galera_threadpool.test diff --git a/mysql-test/suite/galera/r/galera_threadpool.result b/mysql-test/suite/galera/r/galera_threadpool.result new file mode 100644 index 00000000000..e89e243621a --- /dev/null +++ b/mysql-test/suite/galera/r/galera_threadpool.result @@ -0,0 +1,36 @@ +connection node_2; +connection node_1; +connection node_1; +connection node_2; +connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2; +connect node_2b, 127.0.0.1, root, , test, $NODE_MYPORT_2; +connect node_2c, 127.0.0.1, root, , test, $NODE_MYPORT_2; +connect node_2d, 127.0.0.1, root, , test, $NODE_MYPORT_2; +connect node_2e, 127.0.0.1, root, , test, $NODE_MYPORT_2; +connection node_2a; +CREATE TABLE t1 (f1 INTEGER NOT NULL PRIMARY KEY, f2 char) ENGINE=InnoDB; +INSERT INTO t1 VALUES (0,'a'); +INSERT INTO t1 VALUES (1,'a'); +connection node_2b; +SELECT * FROM t1; +f1 f2 +0 a +1 a +connection node_2c; +INSERT INTO t1 VALUES (2,'c'); +connection node_2d; +BEGIN; +SELECT * FROM t1; +f1 f2 +0 a +1 a +2 c +connection node_2e; +BEGIN; +UPDATE t1 SET f2='e' WHERE f1=0; +connection node_2; +connection node_1; +connection node_2; +connection node_1; +connection node_2; +DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/galera_threadpool.cnf b/mysql-test/suite/galera/t/galera_threadpool.cnf new file mode 100644 index 00000000000..c1a1e6a81aa --- /dev/null +++ b/mysql-test/suite/galera/t/galera_threadpool.cnf @@ -0,0 +1,17 @@ +!include ../galera_2nodes.cnf + +[mysqld.1] +wsrep-node-name="node1" +log_bin=binlog +log_slave_updates=ON +wsrep_sst_method=rsync +thread_handling = pool-of-threads + +[mysqld.2] +wsrep-node-name="node2" +log_bin=binlog +log_slave_updates=ON +wsrep_sst_method=rsync +thread_handling = pool-of-threads + + diff --git a/mysql-test/suite/galera/t/galera_threadpool.test b/mysql-test/suite/galera/t/galera_threadpool.test new file mode 100644 index 00000000000..78b26e6e89f --- /dev/null +++ b/mysql-test/suite/galera/t/galera_threadpool.test @@ -0,0 +1,67 @@ +# +# Tests for threadpool support +# +--source include/galera_cluster.inc + +--let $node_1 = node_1 +--let $node_2 = node_2 + +--source ../galera/include/auto_increment_offset_save.inc + +# +# start connections in node 2, and execute some SQL statements +# leave also open transactions in the node +# +--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2 +--connect node_2b, 127.0.0.1, root, , test, $NODE_MYPORT_2 +--connect node_2c, 127.0.0.1, root, , test, $NODE_MYPORT_2 +--connect node_2d, 127.0.0.1, root, , test, $NODE_MYPORT_2 +--connect node_2e, 127.0.0.1, root, , test, $NODE_MYPORT_2 + +--connection node_2a +CREATE TABLE t1 (f1 INTEGER NOT NULL PRIMARY KEY, f2 char) ENGINE=InnoDB; +INSERT INTO t1 VALUES (0,'a'); +INSERT INTO t1 VALUES (1,'a'); + +--connection node_2b +SELECT * FROM t1; + +--connection node_2c +INSERT INTO t1 VALUES (2,'c'); + +--connection node_2d +BEGIN; +SELECT * FROM t1; + +--connection node_2e +BEGIN; +UPDATE t1 SET f2='e' WHERE f1=0; + +# +# Shut down node 2, all open connections should be closed +# +--connection node_2 +--source include/shutdown_mysqld.inc + +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +# And restart the node +--connection node_2 +let $restart_noprint=2; +--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +--source include/start_mysqld.inc + +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +--connection node_2 + +DROP TABLE t1; + +# +# Restore auto increment variables. +# +--source ../galera/include/auto_increment_offset_restore.inc diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 5792158a5fc..eea5ade5e3d 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -2925,8 +2925,6 @@ static inline bool is_committing_connection(THD *thd) static my_bool have_client_connections(THD *thd, void*) { - DBUG_PRINT("quit",("Informing thread %lld that it's time to die", - (longlong) thd->thread_id)); if (is_client_connection(thd)) { if (thd->killed == KILL_CONNECTION || @@ -2980,13 +2978,18 @@ static my_bool kill_all_threads(THD *thd, THD *caller_thd) /* We skip slave threads & scheduler on this first loop through. */ if (is_client_connection(thd) && thd != caller_thd) { - if (thd->get_stmt_da()->is_eof()) + /* the connection executing SHUTDOWN, should do clean exit, + not aborting here */ + if (thd->get_command() == COM_SHUTDOWN) { + WSREP_DEBUG("leaving SHUTDOWN executing connection alive, thread: %lld", + (longlong) thd->thread_id); return 0; } - + /* replaying connection is killed by signal */ if (is_replaying_connection(thd)) { + WSREP_DEBUG("closing connection is replaying %lld", (longlong) thd->thread_id); thd->set_killed(KILL_CONNECTION_HARD); return 0; } @@ -2995,7 +2998,7 @@ static my_bool kill_all_threads(THD *thd, THD *caller_thd) { /* replicated transactions must be skipped */ WSREP_DEBUG("closing connection %lld", (longlong) thd->thread_id); - /* instead of wsrep_close_thread() we do now soft kill by THD::awake */ + /* instead of wsrep_close_thread() we do now hard kill by THD::awake */ thd->awake(KILL_CONNECTION_HARD); return 0; } @@ -3036,8 +3039,10 @@ void wsrep_close_client_connections(my_bool wait_to_end, THD* except_caller_thd) */ server_threads.iterate(kill_remaining_threads, except_caller_thd); - DBUG_PRINT("quit", ("Waiting for threads to die (count=%u)", THD_count::value())); - WSREP_DEBUG("waiting for client connections to close: %u", THD_count::value()); + DBUG_PRINT("quit", ("Waiting for threads to die (count=%u)", + THD_count::value())); + WSREP_DEBUG("waiting for client connections to close: %u", + THD_count::value()); while (wait_to_end && server_threads.iterate(have_client_connections)) { From d598ee3cf952e528a8b42261959360de637add2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Thu, 26 Sep 2024 08:43:45 +0300 Subject: [PATCH 140/213] MDEV-32780 : galera_as_slave_replay: assertion in the wsrep::transaction::before_rollback() Test changes only because assertion reported is not reproducable anymore. Signed-off-by: Julius Goryavsky --- mysql-test/suite/galera/disabled.def | 3 --- mysql-test/suite/galera/t/galera_as_slave_replay.test | 3 ++- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 5b92b282ece..fcaf38a3d7b 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -9,6 +9,3 @@ # Do not use any TAB characters for whitespace. # ############################################################################## - -galera_as_slave_replay : MDEV-32780 galera_as_slave_replay: assertion in the wsrep::transaction::before_rollback() -galera_slave_replay : MDEV-32780 galera_as_slave_replay: assertion in the wsrep::transaction::before_rollback() diff --git a/mysql-test/suite/galera/t/galera_as_slave_replay.test b/mysql-test/suite/galera/t/galera_as_slave_replay.test index 73fd7b3ff29..f6dd3f89f3e 100644 --- a/mysql-test/suite/galera/t/galera_as_slave_replay.test +++ b/mysql-test/suite/galera/t/galera_as_slave_replay.test @@ -10,6 +10,7 @@ --source include/have_debug.inc --source include/have_debug_sync.inc --source include/galera_have_debug_sync.inc +--source include/log_bin.inc --connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2 @@ -87,7 +88,7 @@ SET GLOBAL debug_dbug = "d,sync.wsrep_apply_cb"; INSERT INTO test.t1 VALUES (2, 'b'); # -# send the update from master, this will succeed here, beceuase of async replication. +# send the update from master, this will succeed here, because of async replication. # async replication will apply this in node 2 and pause before commit phase, --connection node_3 --error 0 From d77b9a4925c971364707d435028add41e8015173 Mon Sep 17 00:00:00 2001 From: Brandon Nesterenko Date: Sat, 25 Jan 2025 11:05:29 -0700 Subject: [PATCH 141/213] =?UTF-8?q?MDEV-34355:=20rpl.rpl=5Fsemi=5Fsync=5Fn?= =?UTF-8?q?o=5Fmissed=5Fack=5Fafter=5Fadd=5Fslave=20=E2=80=98server=5F3=20?= =?UTF-8?q?should=20have=20sent=E2=80=A6=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MDEV-35477 incorrectly reverted the original test fix of MDEV-34355, thinking it superseded that fix. It is still needed though. Pasting the content of the original patch’s commit message, as it is still relevant (and the method to reproduce the test failure still works). “”” The problem is that the test could query the status variable Rpl_semi_sync_slave_send_ack before the slave actually updated it. This would result in an immediate --die assertion killing the rest of the test. The bottom of this commit message has a small patch that can be applied to reproduce the test failure. This patch fixes the test failure by waiting for the variable to be updated before querying its value. diff --git a/sql/semisync_slave.cc b/sql/semisync_slave.cc index 9ddd4c5c8d7..60538079fce 100644 --- a/sql/semisync_slave.cc +++ b/sql/semisync_slave.cc @@ -303,7 +303,10 @@ int Repl_semi_sync_slave::slave_reply(Master_info *mi) reply_res= DBUG_EVALUATE_IF("semislave_failed_net_flush", 1, net_flush(net)); if (!reply_res) + { + sleep(1); rpl_semi_sync_slave_send_ack++; + } } DBUG_RETURN(reply_res); } “”” --- .../rpl/t/rpl_semi_sync_no_missed_ack_after_add_slave.test | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_no_missed_ack_after_add_slave.test b/mysql-test/suite/rpl/t/rpl_semi_sync_no_missed_ack_after_add_slave.test index 9d8f87b4345..1a7b3abfde0 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync_no_missed_ack_after_add_slave.test +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_no_missed_ack_after_add_slave.test @@ -86,6 +86,10 @@ if (`SELECT $slave1_sent_ack`) --connection server_3 --echo # Verifying server_3 did send ACK +--let $status_var= Rpl_semi_sync_slave_send_ack +--let $status_var_comparsion= > +--let $status_var_value= 0 +--source include/wait_for_status_var.inc --let $slave2_sent_ack= query_get_value(SHOW STATUS LIKE 'rpl_semi_sync_slave_send_ack', Value, 1) if (`SELECT NOT $slave2_sent_ack`) { From 47f87c5f88beccd1a450f96108a93462b35d7c73 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Fri, 24 Jan 2025 17:08:04 +0100 Subject: [PATCH 142/213] MDEV-20281 "[ERROR] Failed to write to mysql.slow_log:" without error reason Add "backup" (in case of absence issued by error) reasons for failed logging. --- mysql-test/main/slowlog_integrity.result | 108 ++++++++++++++++++++++ mysql-test/main/slowlog_integrity.test | 113 +++++++++++++++++++++++ sql/log.cc | 65 +++++++++++-- 3 files changed, 280 insertions(+), 6 deletions(-) create mode 100644 mysql-test/main/slowlog_integrity.result create mode 100644 mysql-test/main/slowlog_integrity.test diff --git a/mysql-test/main/slowlog_integrity.result b/mysql-test/main/slowlog_integrity.result new file mode 100644 index 00000000000..f65fbf49c03 --- /dev/null +++ b/mysql-test/main/slowlog_integrity.result @@ -0,0 +1,108 @@ +# +# MDEV-20281 "[ERROR] Failed to write to mysql.slow_log:" without +# error reason +# +call mtr.add_suppression("Failed to write to mysql.slow_log:"); +SET @old_slow_query_log= @@global.slow_query_log; +SET @old_log_output= @@global.log_output; +SET @old_long_query_time= @@long_query_time; +SET GLOBAL log_output= "TABLE"; +SET GLOBAL slow_query_log= ON; +SET SESSION long_query_time= 0; +select 1 from dual; +1 +1 +show create table mysql.slow_log; +Table Create Table +slow_log CREATE TABLE `slow_log` ( + `start_time` timestamp(6) NOT NULL DEFAULT current_timestamp(6) ON UPDATE current_timestamp(6), + `user_host` mediumtext NOT NULL, + `query_time` time(6) NOT NULL, + `lock_time` time(6) NOT NULL, + `rows_sent` bigint(20) unsigned NOT NULL, + `rows_examined` bigint(20) unsigned NOT NULL, + `db` varchar(512) NOT NULL, + `last_insert_id` int(11) NOT NULL, + `insert_id` int(11) NOT NULL, + `server_id` int(10) unsigned NOT NULL, + `sql_text` mediumtext NOT NULL, + `thread_id` bigint(21) unsigned NOT NULL, + `rows_affected` bigint(20) unsigned NOT NULL +) ENGINE=CSV DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='Slow log' +SET @@long_query_time= @old_long_query_time; +SET @@global.log_output= "FILE"; +SET GLOBAL slow_query_log= OFF; +drop table mysql.slow_log; +# one field missing +CREATE TABLE mysql.slow_log ( +`start_time` timestamp(6) NOT NULL DEFAULT current_timestamp(6) ON UPDATE current_timestamp(6), +`user_host` mediumtext NOT NULL, +`query_time` time(6) NOT NULL, +`lock_time` time(6) NOT NULL, +`rows_sent` bigint(20) unsigned NOT NULL, +`rows_examined` bigint(20) unsigned NOT NULL, +`db` varchar(512) NOT NULL, +`last_insert_id` int(11) NOT NULL, +`insert_id` int(11) NOT NULL, +`server_id` int(10) unsigned NOT NULL, +`sql_text` mediumtext NOT NULL, +`thread_id` bigint(21) unsigned NOT NULL +) ENGINE=CSV DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='Slow log'; +SET GLOBAL log_output= "TABLE"; +SET GLOBAL slow_query_log= ON; +SET SESSION long_query_time= 0; +select 1 from dual; +1 +1 +SET @@long_query_time= @old_long_query_time; +SET @@global.log_output= "FILE"; +SET GLOBAL slow_query_log= OFF; +drop table mysql.slow_log; +# crazy types +CREATE TABLE mysql.slow_log ( +`start_time` timestamp(6) NOT NULL DEFAULT current_timestamp(6) ON UPDATE current_timestamp(6), +`user_host` ENUM('apple','orange','pear') NOT NULL, +`query_time` ENUM('apple','orange','pear') NOT NULL, +`lock_time` ENUM('apple','orange','pear') NOT NULL, +`rows_sent` ENUM('apple','orange','pear') NOT NULL, +`rows_examined` ENUM('apple','orange','pear') NOT NULL, +`db` ENUM('apple','orange','pear') NOT NULL, +`last_insert_id` ENUM('apple','orange','pear') NOT NULL, +`insert_id` ENUM('apple','orange','pear') NOT NULL, +`server_id` ENUM('apple','orange','pear') NOT NULL, +`sql_text` ENUM('apple','orange','pear') NOT NULL, +`thread_id` ENUM('apple','orange','pear') NOT NULL, +`rows_affected` ENUM('apple','orange','pear') NOT NULL +) ENGINE=CSV DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='Slow log'; +SET GLOBAL log_output= "TABLE"; +SET GLOBAL slow_query_log= ON; +SET SESSION long_query_time= 0; +select 1 from dual; +1 +1 +SET @@long_query_time= @old_long_query_time; +SET @@global.log_output= "FILE"; +SET GLOBAL slow_query_log= OFF; +drop table mysql.slow_log; +# restore normal slow log table +CREATE TABLE mysql.slow_log ( +`start_time` timestamp(6) NOT NULL DEFAULT current_timestamp(6) ON UPDATE current_timestamp(6), +`user_host` mediumtext NOT NULL, +`query_time` time(6) NOT NULL, +`lock_time` time(6) NOT NULL, +`rows_sent` bigint(20) unsigned NOT NULL, +`rows_examined` bigint(20) unsigned NOT NULL, +`db` varchar(512) NOT NULL, +`last_insert_id` int(11) NOT NULL, +`insert_id` int(11) NOT NULL, +`server_id` int(10) unsigned NOT NULL, +`sql_text` mediumtext NOT NULL, +`thread_id` bigint(21) unsigned NOT NULL, +`rows_affected` bigint(20) unsigned NOT NULL +) ENGINE=CSV DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='Slow log'; +SET @@long_query_time= @old_long_query_time; +SET @@global.log_output= @old_log_output; +SET @@global.slow_query_log= @old_slow_query_log; +FOUND 2 /incorrect number of fields in the log table/ in mysqld.1.err +FOUND 2 /Can't write data \(possible incorrect log table structure\)/ in mysqld.1.err +# End of 10.5 tests diff --git a/mysql-test/main/slowlog_integrity.test b/mysql-test/main/slowlog_integrity.test new file mode 100644 index 00000000000..8db3a5ee881 --- /dev/null +++ b/mysql-test/main/slowlog_integrity.test @@ -0,0 +1,113 @@ +source include/not_embedded.inc; + +--echo # +--echo # MDEV-20281 "[ERROR] Failed to write to mysql.slow_log:" without +--echo # error reason +--echo # + + +call mtr.add_suppression("Failed to write to mysql.slow_log:"); + +--disable_ps_protocol +SET @old_slow_query_log= @@global.slow_query_log; +SET @old_log_output= @@global.log_output; +SET @old_long_query_time= @@long_query_time; +SET GLOBAL log_output= "TABLE"; +SET GLOBAL slow_query_log= ON; +SET SESSION long_query_time= 0; + +select 1 from dual; + +show create table mysql.slow_log; + +SET @@long_query_time= @old_long_query_time; +SET @@global.log_output= "FILE"; +SET GLOBAL slow_query_log= OFF; + +drop table mysql.slow_log; + +--echo # one field missing +CREATE TABLE mysql.slow_log ( + `start_time` timestamp(6) NOT NULL DEFAULT current_timestamp(6) ON UPDATE current_timestamp(6), + `user_host` mediumtext NOT NULL, + `query_time` time(6) NOT NULL, + `lock_time` time(6) NOT NULL, + `rows_sent` bigint(20) unsigned NOT NULL, + `rows_examined` bigint(20) unsigned NOT NULL, + `db` varchar(512) NOT NULL, + `last_insert_id` int(11) NOT NULL, + `insert_id` int(11) NOT NULL, + `server_id` int(10) unsigned NOT NULL, + `sql_text` mediumtext NOT NULL, + `thread_id` bigint(21) unsigned NOT NULL +) ENGINE=CSV DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='Slow log'; + +SET GLOBAL log_output= "TABLE"; +SET GLOBAL slow_query_log= ON; +SET SESSION long_query_time= 0; + +select 1 from dual; + +SET @@long_query_time= @old_long_query_time; +SET @@global.log_output= "FILE"; +SET GLOBAL slow_query_log= OFF; + +drop table mysql.slow_log; + +--echo # crazy types +CREATE TABLE mysql.slow_log ( + `start_time` timestamp(6) NOT NULL DEFAULT current_timestamp(6) ON UPDATE current_timestamp(6), + `user_host` ENUM('apple','orange','pear') NOT NULL, + `query_time` ENUM('apple','orange','pear') NOT NULL, + `lock_time` ENUM('apple','orange','pear') NOT NULL, + `rows_sent` ENUM('apple','orange','pear') NOT NULL, + `rows_examined` ENUM('apple','orange','pear') NOT NULL, + `db` ENUM('apple','orange','pear') NOT NULL, + `last_insert_id` ENUM('apple','orange','pear') NOT NULL, + `insert_id` ENUM('apple','orange','pear') NOT NULL, + `server_id` ENUM('apple','orange','pear') NOT NULL, + `sql_text` ENUM('apple','orange','pear') NOT NULL, + `thread_id` ENUM('apple','orange','pear') NOT NULL, + `rows_affected` ENUM('apple','orange','pear') NOT NULL +) ENGINE=CSV DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='Slow log'; + +SET GLOBAL log_output= "TABLE"; +SET GLOBAL slow_query_log= ON; +SET SESSION long_query_time= 0; + +select 1 from dual; + +SET @@long_query_time= @old_long_query_time; +SET @@global.log_output= "FILE"; +SET GLOBAL slow_query_log= OFF; + +drop table mysql.slow_log; + +--echo # restore normal slow log table +CREATE TABLE mysql.slow_log ( + `start_time` timestamp(6) NOT NULL DEFAULT current_timestamp(6) ON UPDATE current_timestamp(6), + `user_host` mediumtext NOT NULL, + `query_time` time(6) NOT NULL, + `lock_time` time(6) NOT NULL, + `rows_sent` bigint(20) unsigned NOT NULL, + `rows_examined` bigint(20) unsigned NOT NULL, + `db` varchar(512) NOT NULL, + `last_insert_id` int(11) NOT NULL, + `insert_id` int(11) NOT NULL, + `server_id` int(10) unsigned NOT NULL, + `sql_text` mediumtext NOT NULL, + `thread_id` bigint(21) unsigned NOT NULL, + `rows_affected` bigint(20) unsigned NOT NULL +) ENGINE=CSV DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='Slow log'; +SET @@long_query_time= @old_long_query_time; +SET @@global.log_output= @old_log_output; +SET @@global.slow_query_log= @old_slow_query_log; +--enable_ps_protocol + +--let SEARCH_FILE=$MYSQLTEST_VARDIR/log/mysqld.1.err +--let SEARCH_PATTERN=incorrect number of fields in the log table +--source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=Can't write data \(possible incorrect log table structure\) +--source include/search_pattern_in_file.inc + +--echo # End of 10.5 tests diff --git a/sql/log.cc b/sql/log.cc index 32a1436f9a6..e459e3a5b52 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -694,6 +694,7 @@ bool Log_to_csv_event_handler:: { TABLE_LIST table_list; TABLE *table; + const char *cause= 0; bool result= TRUE; bool need_close= FALSE; bool need_pop= FALSE; @@ -728,13 +729,19 @@ bool Log_to_csv_event_handler:: need_pop= TRUE; if (!(table= open_log_table(thd, &table_list, &open_tables_backup))) + { + cause= "can't open file"; goto err; + } need_close= TRUE; if (table->file->extra(HA_EXTRA_MARK_AS_LOG_TABLE) || table->file->ha_rnd_init_with_error(0)) + { + cause= "can't initialize table handler"; goto err; + } need_rnd_end= TRUE; @@ -753,12 +760,20 @@ bool Log_to_csv_event_handler:: /* check that all columns exist */ if (table->s->fields < 6) + { + cause= "incorrect number of fields in the log table"; goto err; + } DBUG_ASSERT(table->field[0]->type() == MYSQL_TYPE_TIMESTAMP); - table->field[0]->store_timestamp( - hrtime_to_my_time(event_time), hrtime_sec_part(event_time)); + if (table->field[0]->store_timestamp(hrtime_to_my_time(event_time), + hrtime_sec_part(event_time))) + { + cause= "Can't write data (possible incorrect log table structure)"; + goto err; + } + /* do a write */ if (table->field[1]->store(user_host, user_host_len, client_cs) || @@ -766,7 +781,10 @@ bool Log_to_csv_event_handler:: table->field[3]->store((longlong) global_system_variables.server_id, TRUE) || table->field[4]->store(command_type, command_type_len, client_cs)) + { + cause= "Can't write data (possible incorrect log table structure)"; goto err; + } /* A positive return value in store() means truncation. @@ -774,7 +792,10 @@ bool Log_to_csv_event_handler:: */ table->field[5]->flags|= FIELDFLAG_HEX_ESCAPE; if (table->field[5]->store(sql_text, sql_text_len, client_cs) < 0) + { + cause= "Can't write data (possible incorrect log table structure)"; goto err; + } /* mark all fields as not null */ table->field[1]->set_notnull(); @@ -790,14 +811,22 @@ bool Log_to_csv_event_handler:: } if (table->file->ha_write_row(table->record[0])) + { + cause= "Can't write record"; goto err; + } result= FALSE; err: if (result && !thd->killed) + { + const char *msg= error_handler.message(); + if (!msg || !msg[0]) + msg= cause; sql_print_error("Failed to write to mysql.general_log: %s", - error_handler.message()); + msg); + } if (need_rnd_end) { @@ -850,6 +879,8 @@ bool Log_to_csv_event_handler:: { TABLE_LIST table_list; TABLE *table; + const char *cause= 0; + const char *msg; bool result= TRUE; bool need_close= FALSE; bool need_rnd_end= FALSE; @@ -874,13 +905,19 @@ bool Log_to_csv_event_handler:: TL_WRITE_CONCURRENT_INSERT); if (!(table= open_log_table(thd, &table_list, &open_tables_backup))) + { + cause= "can't open file"; goto err; + } need_close= TRUE; if (table->file->extra(HA_EXTRA_MARK_AS_LOG_TABLE) || table->file->ha_rnd_init_with_error(0)) + { + cause= "can't initialize table handler"; goto err; + } need_rnd_end= TRUE; @@ -891,12 +928,19 @@ bool Log_to_csv_event_handler:: /* check that all columns exist */ if (table->s->fields < 13) + { + cause= "incorrect number of fields in the log table"; goto err; + } + + // It can be used in 13 places below so assign it here + cause= "Can't write data (possible incorrect log table structure)"; /* store the time and user values */ DBUG_ASSERT(table->field[0]->type() == MYSQL_TYPE_TIMESTAMP); - table->field[0]->store_timestamp( - hrtime_to_my_time(current_time), hrtime_sec_part(current_time)); + if(table->field[0]->store_timestamp(hrtime_to_my_time(current_time), + hrtime_sec_part(current_time))) + goto err; if (table->field[1]->store(user_host, user_host_len, client_cs)) goto err; @@ -976,9 +1020,13 @@ bool Log_to_csv_event_handler:: (longlong) thd->get_stmt_da()->affected_rows() : 0, TRUE)) goto err; + cause= 0; // just for safety if (table->file->ha_write_row(table->record[0])) + { + cause= "Can't write record"; goto err; + } result= FALSE; @@ -986,8 +1034,13 @@ err: thd->pop_internal_handler(); if (result && !thd->killed) + { + msg= error_handler.message(); + if (!msg || !msg[0]) + msg= cause; sql_print_error("Failed to write to mysql.slow_log: %s", - error_handler.message()); + msg); + } if (need_rnd_end) { From cb5dd76959859e465828672dedff6c7ee0811a06 Mon Sep 17 00:00:00 2001 From: Brandon Nesterenko Date: Sat, 25 Jan 2025 09:58:56 -0700 Subject: [PATCH 143/213] MDEV-35938: rpl.rpl_parallel_gco_wait_kill fails - "Can't initialize replace ..." Test rpl.rpl_parallel_gco_wait_kill has a race condition where it identifies that SQL using its state as "Slave has read all relay log", and immediately tries to save the thread id of the SQL thread by querying for threads with that same state. However, the state of the SQL thread may change in-between this time, leading to the query that saves the SQL thread finding no thread id that matches that state. Commit 3ee6f69d49a58422f994f51a0bd7a0cb1242a3dd aimed to fix this in 10.11+ by simplifying the query string to "%relay log%"; however, it could still fail (though less often). This commit instead changes the query to find the SQL thread from using some state, to using the command "Slave_SQL", which will not change --- mysql-test/suite/rpl/t/rpl_parallel_gco_wait_kill.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/rpl/t/rpl_parallel_gco_wait_kill.test b/mysql-test/suite/rpl/t/rpl_parallel_gco_wait_kill.test index d918b2ea692..f4d9777f75e 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel_gco_wait_kill.test +++ b/mysql-test/suite/rpl/t/rpl_parallel_gco_wait_kill.test @@ -297,7 +297,7 @@ SET GLOBAL slave_parallel_threads=10; # Find the thread id of the driver SQL thread that we want to kill. --let $wait_condition= SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE '%Slave has read all relay log%' --source include/wait_condition.inc ---let $thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE '%Slave has read all relay log%'` +--let $thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND LIKE 'Slave_SQL'` SET @old_max_queued= @@GLOBAL.slave_parallel_max_queued; SET GLOBAL slave_parallel_max_queued=9000; From e33064e0fcf991ec2d0535396a6061dad90c2a3e Mon Sep 17 00:00:00 2001 From: Nikita Malyavin Date: Thu, 16 Jan 2025 01:44:06 +0100 Subject: [PATCH 144/213] MDEV-27769 Assertion failed in Field::ptr_in_record upon UPDATE in ORACLE mode table->move_fields has some limitations: 1. It cannot be used in cascade 2. It should always have a restoring pair In this case, an error has occurred before the field ptr was restored, returning from the function in that state. Even in case of an error, the table can be reused afterwards and table->field[i]->ptr is not reset in between. The solution is to restore the field pointers immanently whenever they've been deviated. Also add an assertion that ensures that table fields are restored after the use in close_thread_tables. --- .../main/simultaneous_assignment.result | 12 ++++ mysql-test/main/simultaneous_assignment.test | 16 +++++ .../suite/compat/oracle/r/update.result | 16 +++++ mysql-test/suite/compat/oracle/t/update.test | 19 ++++++ sql/sql_base.cc | 58 ++++++++++++++----- 5 files changed, 105 insertions(+), 16 deletions(-) create mode 100644 mysql-test/suite/compat/oracle/r/update.result create mode 100644 mysql-test/suite/compat/oracle/t/update.test diff --git a/mysql-test/main/simultaneous_assignment.result b/mysql-test/main/simultaneous_assignment.result index 67cb58ba6af..2c01eb1c6c2 100644 --- a/mysql-test/main/simultaneous_assignment.result +++ b/mysql-test/main/simultaneous_assignment.result @@ -220,3 +220,15 @@ INDEXES Indexes TRANSACTIONS Transactions TRIGGERS Triggers DROP TABLE ft2; +# +# MDEV-27769 Assertion failed in Field::ptr_in_record upon UPDATE +# (duplicate) MDEV-35404 Assertion failed in Field::ptr_in_record +# +CREATE TABLE t (s geometry, t text); +INSERT INTO t () VALUES (); +UPDATE t SET t = '', s = 0; +ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field +UPDATE t SET t = '', s = 0; +ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field +ALTER TABLE t force; +DROP TABLE t; diff --git a/mysql-test/main/simultaneous_assignment.test b/mysql-test/main/simultaneous_assignment.test index aea454855f5..5b1badcaad1 100644 --- a/mysql-test/main/simultaneous_assignment.test +++ b/mysql-test/main/simultaneous_assignment.test @@ -205,3 +205,19 @@ UPDATE ft2 SET copy = UPPER(copy), copy2= copy; SELECT * FROM ft2; DROP TABLE ft2; + +--echo # +--echo # MDEV-27769 Assertion failed in Field::ptr_in_record upon UPDATE +--echo # (duplicate) MDEV-35404 Assertion failed in Field::ptr_in_record +--echo # +CREATE TABLE t (s geometry, t text); + +INSERT INTO t () VALUES (); +--error ER_CANT_CREATE_GEOMETRY_OBJECT +UPDATE t SET t = '', s = 0; +--error ER_CANT_CREATE_GEOMETRY_OBJECT +UPDATE t SET t = '', s = 0; + +ALTER TABLE t force; + +DROP TABLE t; diff --git a/mysql-test/suite/compat/oracle/r/update.result b/mysql-test/suite/compat/oracle/r/update.result new file mode 100644 index 00000000000..d7585e8e61d --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/update.result @@ -0,0 +1,16 @@ +SET @save_sql_mode=@@global.sql_mode; +SET sql_mode=ORACLE; +SET GLOBAL sql_mode='ORACLE'; +# MDEV-27769 Assertion failed in Field::ptr_in_record upon UPDATE +CREATE TABLE t (s geometry, t text) engine innodb; +Warnings: +Warning 1286 Unknown storage engine 'innodb' +Warning 1266 Using storage engine MyISAM for table 't' +INSERT IGNORE INTO t () VALUES (); +UPDATE IGNORE t SET t= '', s = 0; +ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field +UPDATE IGNORE t SET t= '', s = 0; +ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field +ALTER TABLE t force; +DROP TABLE t; +SET GLOBAL sql_mode=@save_sql_mode; diff --git a/mysql-test/suite/compat/oracle/t/update.test b/mysql-test/suite/compat/oracle/t/update.test new file mode 100644 index 00000000000..389a27f3dbd --- /dev/null +++ b/mysql-test/suite/compat/oracle/t/update.test @@ -0,0 +1,19 @@ +SET @save_sql_mode=@@global.sql_mode; +SET sql_mode=ORACLE; +SET GLOBAL sql_mode='ORACLE'; + + +--echo # MDEV-27769 Assertion failed in Field::ptr_in_record upon UPDATE +CREATE TABLE t (s geometry, t text) engine innodb; +INSERT IGNORE INTO t () VALUES (); +--error ER_CANT_CREATE_GEOMETRY_OBJECT +UPDATE IGNORE t SET t= '', s = 0; +--error ER_CANT_CREATE_GEOMETRY_OBJECT +UPDATE IGNORE t SET t= '', s = 0; + +ALTER TABLE t force; + +DROP TABLE t; + +# Test cleanup +SET GLOBAL sql_mode=@save_sql_mode; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index bb73dcef975..149cd541341 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -760,6 +760,22 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share, } } +static inline bool check_field_pointers(const TABLE *table) +{ + for (Field **pf= table->field; *pf; pf++) + { + Field *f= *pf; + if (f->ptr < table->record[0] || f->ptr > table->record[0] + + table->s->reclength) + return false; + if (f->null_ptr && + (f->null_ptr < table->record[0] || f->null_ptr > table->record[0] + + table->s->reclength)) + return false; + } + return true; +} + /* Close all tables used by the current substatement, or all tables @@ -809,6 +825,8 @@ int close_thread_tables(THD *thd) DBUG_PRINT("tcache", ("table: '%s' query_id: %lu", table->s->table_name.str, (ulong) table->query_id)); + DBUG_SLOW_ASSERT(check_field_pointers(table)); + if (thd->locked_tables_mode) { #ifdef WITH_PARTITION_STORAGE_ENGINE @@ -8465,6 +8483,24 @@ err_no_arena: } +static void unwind_stored_field_offsets(const List &fields, Field *end) +{ + for (Item &item_field: fields) + { + Field *f= item_field.field_for_view_update()->field; + if (f == end) + break; + + if (f->stored_in_db()) + { + TABLE *table= f->table; + f->move_field_offset((my_ptrdiff_t) (table->record[0] - + table->record[1])); + } + } +} + + /****************************************************************************** ** Fill a record with data (for INSERT or UPDATE) ** Returns : 1 if some field has wrong type @@ -8520,7 +8556,7 @@ fill_record(THD *thd, TABLE *table_arg, List &fields, List &values, if (!(field= fld->field_for_view_update())) { my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), fld->name.str); - goto err; + goto err_unwind_fields; } value=v++; DBUG_ASSERT(value); @@ -8548,7 +8584,7 @@ fill_record(THD *thd, TABLE *table_arg, List &fields, List &values, unlikely(value->save_in_field(rfield, 0) < 0) && !ignore_errors) { my_message(ER_UNKNOWN_ERROR, ER_THD(thd, ER_UNKNOWN_ERROR), MYF(0)); - goto err; + goto err_unwind_fields; } /* In sql MODE_SIMULTANEOUS_ASSIGNMENT, @@ -8563,20 +8599,7 @@ fill_record(THD *thd, TABLE *table_arg, List &fields, List &values, } if (update && thd->variables.sql_mode & MODE_SIMULTANEOUS_ASSIGNMENT) - { - // restore fields pointers on record[0] - f.rewind(); - while ((fld= f++)) - { - rfield= fld->field_for_view_update()->field; - if (rfield->stored_in_db()) - { - table= rfield->table; - rfield->move_field_offset((my_ptrdiff_t) (table->record[0] - - table->record[1])); - } - } - } + unwind_stored_field_offsets(fields, NULL); if (update) table_arg->evaluate_update_default_function(); @@ -8594,6 +8617,9 @@ fill_record(THD *thd, TABLE *table_arg, List &fields, List &values, thd->abort_on_warning= save_abort_on_warning; thd->no_errors= save_no_errors; DBUG_RETURN(thd->is_error()); +err_unwind_fields: + if (update && thd->variables.sql_mode & MODE_SIMULTANEOUS_ASSIGNMENT) + unwind_stored_field_offsets(fields, rfield); err: DBUG_PRINT("error",("got error")); thd->abort_on_warning= save_abort_on_warning; From ecaedbe299fe11372c36319f9b732b81e9f54883 Mon Sep 17 00:00:00 2001 From: Nikita Malyavin Date: Sat, 12 Oct 2024 21:32:18 +0200 Subject: [PATCH 145/213] MDEV-33658 1/2 Refactoring: extract Key length initialization mysql_prepare_create_table: Extract a Key initialization part that relates to length calculation and long unique index designation. append_system_key_parts call also moves there. Move this initialization before the duplicate elimination. Extract WITHOUT OVERPLAPS check into a separate function. It had to be moved earlier in the code to preserve the order of the error checks, as in the tests. --- .../r/binlog_spurious_ddl_errors.result | 2 +- .../binlog/t/binlog_spurious_ddl_errors.test | 2 +- .../suite/innodb/r/innodb-wl5522-1.result | 2 + mysql-test/suite/innodb_gis/r/1.result | 2 + .../suite/innodb_gis/r/point_basic.result | 4 +- mysql-test/suite/innodb_gis/t/1.test | 4 +- .../innodb_zip/r/index_large_prefix_8k.result | 3 + sql/sql_class.cc | 3 +- sql/sql_class.h | 5 +- sql/sql_table.cc | 586 ++++++++++-------- 10 files changed, 362 insertions(+), 251 deletions(-) diff --git a/mysql-test/suite/binlog/r/binlog_spurious_ddl_errors.result b/mysql-test/suite/binlog/r/binlog_spurious_ddl_errors.result index 798bd8ab853..39c0bd52fac 100644 --- a/mysql-test/suite/binlog/r/binlog_spurious_ddl_errors.result +++ b/mysql-test/suite/binlog/r/binlog_spurious_ddl_errors.result @@ -38,7 +38,7 @@ CREATE TABLE t_stmt (a VARCHAR(100)) ENGINE = EXAMPLE; ALTER TABLE t_stmt ADD COLUMN b INT; CREATE TRIGGER trig_stmt BEFORE INSERT ON t_stmt FOR EACH ROW INSERT INTO t_stmt VALUES (1); CREATE INDEX i ON t_stmt(a); -ERROR 42000: Too many key parts specified; max 0 parts allowed +ERROR 42000: Specified key was too long; max key length is 0 bytes CREATE TABLE t_stmt_new ENGINE = EXAMPLE SELECT * FROM t_stmt; ERROR HY000: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = ROW and at least one table uses a storage engine limited to statement-based logging DROP TABLE t_stmt; diff --git a/mysql-test/suite/binlog/t/binlog_spurious_ddl_errors.test b/mysql-test/suite/binlog/t/binlog_spurious_ddl_errors.test index 29a860764a9..5a015c2b8eb 100644 --- a/mysql-test/suite/binlog/t/binlog_spurious_ddl_errors.test +++ b/mysql-test/suite/binlog/t/binlog_spurious_ddl_errors.test @@ -75,7 +75,7 @@ ALTER TABLE t_stmt ADD COLUMN b INT; CREATE TRIGGER trig_stmt BEFORE INSERT ON t_stmt FOR EACH ROW INSERT INTO t_stmt VALUES (1); ---error ER_TOO_MANY_KEY_PARTS +--error ER_TOO_LONG_KEY CREATE INDEX i ON t_stmt(a); --error ER_BINLOG_ROW_MODE_AND_STMT_ENGINE diff --git a/mysql-test/suite/innodb/r/innodb-wl5522-1.result b/mysql-test/suite/innodb/r/innodb-wl5522-1.result index 42c0631dd29..72d7268244f 100644 --- a/mysql-test/suite/innodb/r/innodb-wl5522-1.result +++ b/mysql-test/suite/innodb/r/innodb-wl5522-1.result @@ -659,6 +659,8 @@ NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 15000 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 16000 ALTER TABLE testdb_wl5522.t1 ADD INDEX idx1 (col_1); ALTER TABLE testdb_wl5522.t1 ADD INDEX idx6 (col_1(255)); +Warnings: +Note 1831 Duplicate index `idx6`. This is deprecated and will be disallowed in a future release ALTER TABLE testdb_wl5522.t1 ADD INDEX idx10 (col_10(255)); SELECT col_1 = REPEAT("col1_00001",10), diff --git a/mysql-test/suite/innodb_gis/r/1.result b/mysql-test/suite/innodb_gis/r/1.result index 909051cc54e..9522ab1d41f 100644 --- a/mysql-test/suite/innodb_gis/r/1.result +++ b/mysql-test/suite/innodb_gis/r/1.result @@ -1075,6 +1075,8 @@ col1 POINT, col2 POINT ); CREATE SPATIAL INDEX idx0 ON t2 (col1, col2); +ERROR 42000: Key column 'col1' doesn't exist in table +CREATE SPATIAL INDEX idx0 ON t2 (col0, col2); ERROR HY000: Incorrect arguments to SPATIAL INDEX CREATE TABLE t4 ( col0 INTEGER NOT NULL, diff --git a/mysql-test/suite/innodb_gis/r/point_basic.result b/mysql-test/suite/innodb_gis/r/point_basic.result index bda5ae59238..fd7c8ac180e 100644 --- a/mysql-test/suite/innodb_gis/r/point_basic.result +++ b/mysql-test/suite/innodb_gis/r/point_basic.result @@ -1562,7 +1562,7 @@ ALTER TABLE child ADD FOREIGN KEY(p) REFERENCES parent(p); ERROR HY000: Can't create table `test`.`child` (errno: 150 "Foreign key constraint is incorrectly formed") show warnings; Level Code Message -Warning 150 Alter table `test`.`child` with foreign key (p) constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns. +Warning 150 Alter table `test`.`child` with foreign key (p) constraint failed. There is only prefix index in the referenced table where the referenced columns appear as the first columns. Error 1005 Can't create table `test`.`child` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint for `child` ALTER TABLE parent DROP INDEX idx1; @@ -1570,7 +1570,7 @@ ALTER TABLE child ADD FOREIGN KEY(p) REFERENCES parent(p); Got one of the listed errors show warnings; Level Code Message -Warning 150 Alter table `test`.`child` with foreign key (p) constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns. +Warning 150 Alter table `test`.`child` with foreign key (p) constraint failed. There is only prefix index in the referenced table where the referenced columns appear as the first columns. Error 1005 Can't create table `test`.`child` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint for `child` ALTER TABLE child DROP INDEX idx2; diff --git a/mysql-test/suite/innodb_gis/t/1.test b/mysql-test/suite/innodb_gis/t/1.test index 411cb10602b..711bc971945 100644 --- a/mysql-test/suite/innodb_gis/t/1.test +++ b/mysql-test/suite/innodb_gis/t/1.test @@ -839,8 +839,10 @@ CREATE TABLE t3 ( ); # --error ER_TOO_MANY_KEY_PARTS ---error ER_WRONG_ARGUMENTS +--error ER_KEY_COLUMN_DOES_NOT_EXITS CREATE SPATIAL INDEX idx0 ON t2 (col1, col2); +--error ER_WRONG_ARGUMENTS +CREATE SPATIAL INDEX idx0 ON t2 (col0, col2); CREATE TABLE t4 ( diff --git a/mysql-test/suite/innodb_zip/r/index_large_prefix_8k.result b/mysql-test/suite/innodb_zip/r/index_large_prefix_8k.result index 925bd3f8f9c..4451b149406 100644 --- a/mysql-test/suite/innodb_zip/r/index_large_prefix_8k.result +++ b/mysql-test/suite/innodb_zip/r/index_large_prefix_8k.result @@ -171,9 +171,11 @@ Note 1071 Specified key was too long; max key length is 1536 bytes create index idx3 on worklog5743_8(a2(3072)); Warnings: Note 1071 Specified key was too long; max key length is 1536 bytes +Note 1831 Duplicate index `idx3`. This is deprecated and will be disallowed in a future release show warnings; Level Code Message Note 1071 Specified key was too long; max key length is 1536 bytes +Note 1831 Duplicate index `idx3`. This is deprecated and will be disallowed in a future release create index idx4 on worklog5743_8(a1, a2(1533)); ERROR 42000: Specified key was too long; max key length is 1536 bytes show warnings; @@ -355,6 +357,7 @@ Note 1071 Specified key was too long; max key length is 1536 bytes create index idx2 on worklog5743(a(3072)); Warnings: Note 1071 Specified key was too long; max key length is 1536 bytes +Note 1831 Duplicate index `idx2`. This is deprecated and will be disallowed in a future release SET sql_mode= default; show create table worklog5743; Table Create Table diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 66f689c5312..e6ff4d87690 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -176,7 +176,8 @@ Key::Key(const Key &rhs, MEM_ROOT *mem_root) name(rhs.name), option_list(rhs.option_list), generated(rhs.generated), invisible(false), - without_overlaps(rhs.without_overlaps), old(rhs.old), period(rhs.period) + without_overlaps(rhs.without_overlaps), old(rhs.old), length(rhs.length), + period(rhs.period) { list_copy_and_replace_each_value(columns, mem_root); } diff --git a/sql/sql_class.h b/sql/sql_class.h index 03860e5ff4e..6dcc406e294 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -424,6 +424,7 @@ public: bool invisible; bool without_overlaps; bool old; + uint length; Lex_ident period; Key(enum Keytype type_par, const LEX_CSTRING *name_arg, @@ -431,7 +432,7 @@ public: :DDL_options(ddl_options), type(type_par), key_create_info(default_key_create_info), name(*name_arg), option_list(NULL), generated(generated_arg), - invisible(false), without_overlaps(false), old(false) + invisible(false), without_overlaps(false), old(false), length(0) { key_create_info.algorithm= algorithm_arg; } @@ -442,7 +443,7 @@ public: :DDL_options(ddl_options), type(type_par), key_create_info(*key_info_arg), columns(*cols), name(*name_arg), option_list(create_opt), generated(generated_arg), - invisible(false), without_overlaps(false), old(false) + invisible(false), without_overlaps(false), old(false), length(0) {} Key(const Key &rhs, MEM_ROOT *mem_root); virtual ~Key() = default; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 2162850172b..c7ee3f83647 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3558,6 +3558,303 @@ key_add_part_check_null(const handler *file, KEY *key_info, } +static +my_bool key_check_without_overlaps(THD *thd, HA_CREATE_INFO *create_info, + Alter_info *alter_info, + Key &key) +{ + DBUG_ENTER("key_check_without_overlaps"); + if (!key.without_overlaps) + DBUG_RETURN(FALSE); + // append_system_key_parts is already called, so we should check all the + // columns except the last two. + const auto &period_start= create_info->period_info.period.start; + const auto &period_end= create_info->period_info.period.end; + List_iterator part_it_forwarded(key.columns); + List_iterator part_it(key.columns); + part_it_forwarded++; + part_it_forwarded++; + while (part_it_forwarded++) + { + Key_part_spec *key_part= part_it++; + + if (period_start.streq(key_part->field_name) + || period_end.streq(key_part->field_name)) + { + my_error(ER_KEY_CONTAINS_PERIOD_FIELDS, MYF(0), key.name.str, + key_part->field_name.str); + DBUG_RETURN(TRUE); + } + } + + if (key.key_create_info.algorithm == HA_KEY_ALG_HASH || + key.key_create_info.algorithm == HA_KEY_ALG_LONG_HASH) + + { + my_error(ER_KEY_CANT_HAVE_WITHOUT_OVERLAPS, MYF(0), key.name.str); + DBUG_RETURN(TRUE); + } + for (Key &key2: alter_info->key_list) + { + if (key2.type != Key::FOREIGN_KEY) + continue; + DBUG_ASSERT(&key != &key2); + const Foreign_key &fk= (Foreign_key&)key2; + if (fk.update_opt != FK_OPTION_CASCADE) + continue; + for (Key_part_spec& kp: key.columns) + { + for (Key_part_spec& kp2: fk.columns) + { + if (kp.field_name.streq(kp2.field_name)) + { + my_error(ER_KEY_CANT_HAVE_WITHOUT_OVERLAPS, MYF(0), key.name.str); + DBUG_RETURN(TRUE); + } + } + } + } + create_info->period_info.unique_keys++; + + DBUG_RETURN(FALSE); +} + +static +my_bool init_key_part_spec(THD *thd, Alter_info *alter_info, + const handler *file, + const Key &key, Key_part_spec &kp, + uint max_key_length, uint max_key_part_length, + bool *is_hash_field_needed) +{ + DBUG_ENTER("init_key_part_spec"); + + const Lex_ident &field_name= kp.field_name; + Create_field *column= NULL; + + for (Create_field &c: alter_info->create_list) + if (c.field_name.streq(field_name)) + column= &c; + + /* + Either field is not present or field visibility is > INVISIBLE_USER + */ + if (!column || (column->invisible > INVISIBLE_USER && !kp.generated)) + { + my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), field_name.str); + DBUG_RETURN(TRUE); + } + + if (DBUG_EVALUATE_IF("test_invisible_index", 0, 1) + && column->invisible > INVISIBLE_USER + && !(column->flags & VERS_SYSTEM_FIELD) && !key.invisible) + { + my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str); + DBUG_RETURN(TRUE); + } + + const Type_handler *type_handler= column->type_handler(); + switch(key.type) + { + case Key::FULLTEXT: + if (type_handler->Key_part_spec_init_ft(&kp, *column)) + { + my_error(ER_BAD_FT_COLUMN, MYF(0), field_name.str); + DBUG_RETURN(-1); + } + break; + + case Key::SPATIAL: + if (type_handler->Key_part_spec_init_spatial(&kp, *column)) + DBUG_RETURN(TRUE); + break; + + case Key::PRIMARY: + if (column->vcol_info) + { + my_error(ER_PRIMARY_KEY_BASED_ON_GENERATED_COLUMN, MYF(0)); + DBUG_RETURN(TRUE); + } + if (type_handler->Key_part_spec_init_primary(&kp, *column, file)) + DBUG_RETURN(TRUE); + break; + + case Key::MULTIPLE: + if (type_handler->Key_part_spec_init_multiple(&kp, *column, file)) + DBUG_RETURN(TRUE); + break; + + case Key::FOREIGN_KEY: + if (type_handler->Key_part_spec_init_foreign(&kp, *column, file)) + DBUG_RETURN(TRUE); + break; + + case Key::UNIQUE: + if (type_handler->Key_part_spec_init_unique(&kp, *column, file, + is_hash_field_needed)) + DBUG_RETURN(TRUE); + break; + } + + uint key_part_length= type_handler->calc_key_length(*column); + + if (kp.length) + { + if (f_is_blob(column->pack_flag)) + { + key_part_length= MY_MIN(kp.length, + blob_length_by_type(column->real_field_type()) + * column->charset->mbmaxlen); + if (key_part_length > max_key_length || + key_part_length > max_key_part_length) + { + if (key.type == Key::MULTIPLE) + { + key_part_length= MY_MIN(max_key_length, max_key_part_length); + /* not a critical problem */ + push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, + ER_TOO_LONG_KEY, ER_THD(thd, ER_TOO_LONG_KEY), + key_part_length); + /* Align key length to multibyte char boundary */ + key_part_length-= key_part_length % column->charset->mbmaxlen; + } + } + } + // Catch invalid use of partial keys + else if (!f_is_geom(column->pack_flag) && + // is the key partial? + kp.length != key_part_length && + // is prefix length bigger than field length? + (kp.length > key_part_length || + // can the field have a partial key? + !type_handler->type_can_have_key_part() || + // a packed field can't be used in a partial key + f_is_packed(column->pack_flag) || + // does the storage engine allow prefixed search? + ((file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS) && + // and is this a 'unique' key? + (key.type == Key::PRIMARY || key.type == Key::UNIQUE)))) + { + my_message(ER_WRONG_SUB_KEY, ER_THD(thd, ER_WRONG_SUB_KEY), MYF(0)); + DBUG_RETURN(TRUE); + } + else if (!(file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS)) + key_part_length= kp.length; + } + else if (key_part_length == 0 && (column->flags & NOT_NULL_FLAG) && + !*is_hash_field_needed) + { + my_error(ER_WRONG_KEY_COLUMN, MYF(0), file->table_type(), field_name.str); + DBUG_RETURN(TRUE); + } + if (key_part_length > max_key_part_length && key.type != Key::FULLTEXT) + { + if (key.type == Key::MULTIPLE) + { + key_part_length= max_key_part_length; + /* not a critical problem */ + push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, + ER_TOO_LONG_KEY, ER_THD(thd, ER_TOO_LONG_KEY), + key_part_length); + /* Align key length to multibyte char boundary */ + key_part_length-= key_part_length % column->charset->mbmaxlen; + } + else if (key.type != Key::UNIQUE) + { + key_part_length= MY_MIN(max_key_length, max_key_part_length); + my_error(ER_TOO_LONG_KEY, MYF(0), key_part_length); + DBUG_RETURN(TRUE); + } + } + + if (key.type == Key::UNIQUE && key_part_length > MY_MIN(max_key_length, + max_key_part_length)) + *is_hash_field_needed= true; + + /* We can not store key_part_length more than 2^16 - 1 in frm. */ + if (*is_hash_field_needed && kp.length > UINT_MAX16) + { + my_error(ER_TOO_LONG_KEYPART, MYF(0), UINT_MAX16); + DBUG_RETURN(TRUE); + } + + kp.length= key_part_length; + + DBUG_RETURN(FALSE); +} + + +/** + @brief Initialize the key length and algorithm (if long hash). + + This function does: + 1. Append system key parts (versioning, periods) + 2. Call Type_handler key_part initialization function. + 3. Determine the length of each key_part. + 4. Calculate the total Key length. + 5. Determine if the key is long unique based on its length + smd result from type handler. It'll be saved in + key_create_info.algorithm as HA_KEY_ALG_LONG_HASH. + + @return FALSE OK + @return TRUE error + */ +static +my_bool init_key_info(THD *thd, Alter_info *alter_info, + HA_CREATE_INFO *create_info, + const handler *file) +{ + DBUG_ENTER("init_key_info"); + uint max_key_length= file->max_key_length(); + uint max_key_part_length= file->max_key_part_length(); + + for (Key &key: alter_info->key_list) + { + if (key.type == Key::FOREIGN_KEY) + continue; + + int parts_added= append_system_key_parts(thd, create_info, &key); + if (parts_added < 0) + DBUG_RETURN(true); + + bool is_hash_field_needed= false; + for (Key_part_spec &kp: key.columns) + { + if (init_key_part_spec(thd, alter_info, file, key, kp, + max_key_length, max_key_part_length, + &is_hash_field_needed)) + DBUG_RETURN(TRUE); + + key.length+= kp.length; + if (key.length > max_key_length && key.type == Key::UNIQUE) + is_hash_field_needed= true; // for case "a BLOB UNIQUE" + + if (key.length > max_key_length && key.type != Key::FULLTEXT && + !is_hash_field_needed) + { + my_error(ER_TOO_LONG_KEY, MYF(0), max_key_length); + DBUG_RETURN(TRUE); + } + + KEY_CREATE_INFO *key_cinfo= &key.key_create_info; + + if (is_hash_field_needed) + { + if (key_cinfo->algorithm == HA_KEY_ALG_UNDEF) + key_cinfo->algorithm= HA_KEY_ALG_LONG_HASH; + + if (key_cinfo->algorithm != HA_KEY_ALG_HASH && + key_cinfo->algorithm != HA_KEY_ALG_LONG_HASH) + { + my_error(ER_TOO_LONG_KEY, MYF(0), max_key_length); + DBUG_RETURN(TRUE); + } + } + } + } + DBUG_RETURN(FALSE); +} + + /* Preparation for table creation @@ -3592,7 +3889,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, { const char *key_name; Create_field *sql_field,*dup_field; - uint field,null_fields,max_key_length; + uint field,null_fields; ulong record_offset= 0; KEY_PART_INFO *key_part_info; int field_no,dup_no; @@ -3603,7 +3900,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, int select_field_count= C_CREATE_SELECT(create_table_mode); bool tmp_table= create_table_mode == C_ALTER_TABLE; const bool create_simple= thd->lex->create_simple(); - bool is_hash_field_needed= false; const Column_derived_attributes dattr(create_info->default_table_charset); const Column_bulk_alter_attributes battr(create_info->alter_table_convert_to_charset); @@ -3639,7 +3935,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, create_info->versioned()); null_fields= 0; create_info->varchar= 0; - max_key_length= file->max_key_length(); /* Handle creation of sequences */ if (create_info->sequence) @@ -3838,6 +4133,9 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, /* special marker for keys to be ignored */ static char ignore_key[1]; + if (init_key_info(thd, alter_info, create_info, file)) + DBUG_RETURN(TRUE); + /* Calculate number of key segements */ *key_count= 0; @@ -3967,10 +4265,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, key_info->name.length= strlen(key_name); key->name= key_info->name; - int parts_added= append_system_key_parts(thd, create_info, key); - if (parts_added < 0) - DBUG_RETURN(true); - key_parts += parts_added; key_info++; } tmp=file->max_keys(); @@ -3989,11 +4283,11 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, key_number=0; for (; (key=key_iterator++) ; key_number++) { - uint key_length=0; Create_field *auto_increment_key= 0; Key_part_spec *column; - is_hash_field_needed= false; + bool is_hash_field_needed= key->key_create_info.algorithm + == HA_KEY_ALG_LONG_HASH; if (key->name.str == ignore_key) { /* ignore redundant keys */ @@ -4004,6 +4298,9 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, break; } + if (key_check_without_overlaps(thd, create_info, alter_info, *key)) + DBUG_RETURN(true); + switch (key->type) { case Key::MULTIPLE: key_info->flags= 0; @@ -4034,10 +4331,12 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, if (key->generated) key_info->flags|= HA_GENERATED_KEY; + key_info->key_length= key->length; key_info->user_defined_key_parts=(uint8) key->columns.elements; key_info->key_part=key_part_info; key_info->usable_key_parts= key_number; key_info->algorithm= key->key_create_info.algorithm; + key_info->without_overlaps= key->without_overlaps; key_info->option_list= key->option_list; extend_option_list(thd, create_info->db_type, !key->old, &key_info->option_list, create_info->db_type->index_options); @@ -4121,37 +4420,11 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, CHARSET_INFO *ft_key_charset=0; // for FULLTEXT for (uint column_nr=0 ; (column=cols++) ; column_nr++) { - Key_part_spec *dup_column; - it.rewind(); field=0; while ((sql_field=it++) && lex_string_cmp(scs, &column->field_name, &sql_field->field_name)) field++; - /* - Either field is not present or field visibility is > INVISIBLE_USER - */ - if (!sql_field || (sql_field->invisible > INVISIBLE_USER && - !column->generated)) - { - my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str); - DBUG_RETURN(TRUE); - } - if (sql_field->invisible > INVISIBLE_USER && - !(sql_field->flags & VERS_SYSTEM_FIELD) && - !key->invisible && DBUG_EVALUATE_IF("test_invisible_index", 0, 1)) - { - my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str); - DBUG_RETURN(TRUE); - } - while ((dup_column= cols2++) != column) - { - if (!lex_string_cmp(scs, &column->field_name, &dup_column->field_name)) - { - my_error(ER_DUP_FIELDNAME, MYF(0), column->field_name.str); - DBUG_RETURN(TRUE); - } - } if (sql_field->compression_method()) { @@ -4161,12 +4434,10 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, } cols2.rewind(); - switch(key->type) { - + switch(key->type) + { case Key::FULLTEXT: - if (sql_field->type_handler()->Key_part_spec_init_ft(column, - *sql_field) || - (ft_key_charset && sql_field->charset != ft_key_charset)) + if (ft_key_charset && sql_field->charset != ft_key_charset) { my_error(ER_BAD_FT_COLUMN, MYF(0), column->field_name.str); DBUG_RETURN(-1); @@ -4174,64 +4445,46 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, ft_key_charset= sql_field->charset; break; - case Key::SPATIAL: - if (sql_field->type_handler()->Key_part_spec_init_spatial(column, - *sql_field) || - sql_field->check_vcol_for_key(thd)) - DBUG_RETURN(TRUE); - if (!(sql_field->flags & NOT_NULL_FLAG)) - { - my_message(ER_SPATIAL_CANT_HAVE_NULL, - ER_THD(thd, ER_SPATIAL_CANT_HAVE_NULL), MYF(0)); - DBUG_RETURN(TRUE); - } - break; - case Key::PRIMARY: - if (sql_field->vcol_info) - { - my_error(ER_PRIMARY_KEY_BASED_ON_GENERATED_COLUMN, MYF(0)); - DBUG_RETURN(TRUE); - } - if (sql_field->type_handler()->Key_part_spec_init_primary(column, - *sql_field, - file)) - DBUG_RETURN(TRUE); if (!(sql_field->flags & NOT_NULL_FLAG)) { - /* Implicitly set primary key fields to NOT NULL for ISO conf. */ + /* Implicitly set primary key fields to NOT NULL for ISO conformance. */ sql_field->flags|= NOT_NULL_FLAG; sql_field->pack_flag&= ~FIELDFLAG_MAYBE_NULL; null_fields--; } break; - case Key::MULTIPLE: - if (sql_field->type_handler()->Key_part_spec_init_multiple(column, - *sql_field, - file) || - sql_field->check_vcol_for_key(thd) || - key_add_part_check_null(file, key_info, sql_field, column)) - DBUG_RETURN(TRUE); - break; - - case Key::FOREIGN_KEY: - if (sql_field->type_handler()->Key_part_spec_init_foreign(column, - *sql_field, - file) || - sql_field->check_vcol_for_key(thd) || - key_add_part_check_null(file, key_info, sql_field, column)) - DBUG_RETURN(TRUE); - break; - case Key::UNIQUE: - if (sql_field->type_handler()->Key_part_spec_init_unique(column, - *sql_field, file, - &is_hash_field_needed) || - sql_field->check_vcol_for_key(thd) || - key_add_part_check_null(file, key_info, sql_field, column)) + case Key::MULTIPLE: + case Key::FOREIGN_KEY: + if (key_add_part_check_null(file, key_info, sql_field, column)) + DBUG_RETURN(TRUE); + if (sql_field->check_vcol_for_key(thd)) DBUG_RETURN(TRUE); break; + + case Key::SPATIAL: + if (!(sql_field->flags & NOT_NULL_FLAG)) + { + my_message(ER_SPATIAL_CANT_HAVE_NULL, + ER_THD(thd, ER_SPATIAL_CANT_HAVE_NULL), MYF(0)); + DBUG_RETURN(TRUE); + } + if (sql_field->check_vcol_for_key(thd)) + DBUG_RETURN(TRUE); + break; + } + + for (const Key_part_spec &kp2: key->columns) + { + if (column == &kp2) + break; + if (kp2.field_name.streq(column->field_name)) + { + my_error(ER_DUP_FIELDNAME, MYF(0), column->field_name.str); + DBUG_RETURN(TRUE); + } } if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER) @@ -4246,111 +4499,21 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, key_part_info->fieldnr= field; key_part_info->offset= (uint16) sql_field->offset; key_part_info->key_type=sql_field->pack_flag; - uint key_part_length= sql_field->type_handler()-> - calc_key_length(*sql_field); - - if (column->length) - { - if (f_is_blob(sql_field->pack_flag)) - { - key_part_length= MY_MIN(column->length, - blob_length_by_type(sql_field->real_field_type()) - * sql_field->charset->mbmaxlen); - if (key_part_length > max_key_length || - key_part_length > file->max_key_part_length()) - { - if (key->type == Key::MULTIPLE) - { - key_part_length= MY_MIN(max_key_length, file->max_key_part_length()); - /* not a critical problem */ - push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, - ER_TOO_LONG_KEY, ER_THD(thd, ER_TOO_LONG_KEY), - key_part_length); - /* Align key length to multibyte char boundary */ - key_part_length-= key_part_length % sql_field->charset->mbmaxlen; - } - } - } - // Catch invalid use of partial keys - else if (!f_is_geom(sql_field->pack_flag) && - // is the key partial? - column->length != key_part_length && - // is prefix length bigger than field length? - (column->length > key_part_length || - // can the field have a partial key? - !sql_field->type_handler()->type_can_have_key_part() || - // a packed field can't be used in a partial key - f_is_packed(sql_field->pack_flag) || - // does the storage engine allow prefixed search? - ((file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS) && - // and is this a 'unique' key? - (key_info->flags & HA_NOSAME)))) - { - my_message(ER_WRONG_SUB_KEY, ER_THD(thd, ER_WRONG_SUB_KEY), MYF(0)); - DBUG_RETURN(TRUE); - } - else if (!(file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS)) - key_part_length= column->length; - } - else if (key_part_length == 0 && (sql_field->flags & NOT_NULL_FLAG) && - !is_hash_field_needed) - { - my_error(ER_WRONG_KEY_COLUMN, MYF(0), file->table_type(), - column->field_name.str); - DBUG_RETURN(TRUE); - } - if (key_part_length > file->max_key_part_length() && - key->type != Key::FULLTEXT) - { - if (key->type == Key::MULTIPLE) - { - key_part_length= file->max_key_part_length(); - /* not a critical problem */ - push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, - ER_TOO_LONG_KEY, ER_THD(thd, ER_TOO_LONG_KEY), - key_part_length); - /* Align key length to multibyte char boundary */ - key_part_length-= key_part_length % sql_field->charset->mbmaxlen; - } - else - { - if (key->type != Key::UNIQUE) - { - key_part_length= MY_MIN(max_key_length, file->max_key_part_length()); - my_error(ER_TOO_LONG_KEY, MYF(0), key_part_length); - DBUG_RETURN(TRUE); - } - } - } - - if (key->type == Key::UNIQUE - && key_part_length > MY_MIN(max_key_length, - file->max_key_part_length())) - is_hash_field_needed= true; - - /* We can not store key_part_length more then 2^16 - 1 in frm */ - if (is_hash_field_needed && column->length > UINT_MAX16) - { - my_error(ER_TOO_LONG_KEYPART, MYF(0), UINT_MAX16); - DBUG_RETURN(TRUE); - } - else - key_part_info->length= (uint16) key_part_length; + key_part_info->length= column->length; /* Use packed keys for long strings on the first column */ if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) && !((create_info->table_options & HA_OPTION_NO_PACK_KEYS)) && - (key_part_length >= KEY_DEFAULT_PACK_LENGTH) && + (column->length >= KEY_DEFAULT_PACK_LENGTH) && !is_hash_field_needed) { key_info->flags|= sql_field->type_handler()->KEY_pack_flags(column_nr); } /* Check if the key segment is partial, set the key flag accordingly */ - if (key_part_length != sql_field->type_handler()-> + if (column->length != sql_field->type_handler()-> calc_key_length(*sql_field) && - key_part_length != sql_field->type_handler()->max_octet_length()) + column->length != sql_field->type_handler()->max_octet_length()) key_info->flags|= HA_KEY_HAS_PART_KEY_SEG; - key_length+= key_part_length; key_part_info++; } if (!key_info->name.str || check_column_name(key_info->name.str)) @@ -4360,15 +4523,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, } if (key->type == Key::UNIQUE && !(key_info->flags & HA_NULL_PART_KEY)) unique_key=1; - key_info->key_length=(uint16) key_length; - if (key_info->key_length > max_key_length && key->type == Key::UNIQUE) - is_hash_field_needed= true; // for case "a BLOB UNIQUE" - if (key_length > max_key_length && key->type != Key::FULLTEXT && - !is_hash_field_needed) - { - my_error(ER_TOO_LONG_KEY, MYF(0), max_key_length); - DBUG_RETURN(TRUE); - } /* Check long unique keys */ if (is_hash_field_needed) @@ -4380,12 +4534,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, key_info->name.str); DBUG_RETURN(TRUE); } - if (key_info->algorithm != HA_KEY_ALG_UNDEF && - key_info->algorithm != HA_KEY_ALG_HASH ) - { - my_error(ER_TOO_LONG_KEY, MYF(0), max_key_length); - DBUG_RETURN(TRUE); - } } if (is_hash_field_needed || (key_info->algorithm == HA_KEY_ALG_HASH && @@ -4425,40 +4573,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, // Check if a duplicate index is defined. check_duplicate_key(thd, key, key_info, &alter_info->key_list); - key_info->without_overlaps= key->without_overlaps; - if (key_info->without_overlaps) - { - if (key_info->algorithm == HA_KEY_ALG_HASH || - key_info->algorithm == HA_KEY_ALG_LONG_HASH) - - { -without_overlaps_err: - my_error(ER_KEY_CANT_HAVE_WITHOUT_OVERLAPS, MYF(0), key_info->name.str); - DBUG_RETURN(true); - } - key_iterator2.rewind(); - while ((key2 = key_iterator2++)) - { - if (key2->type != Key::FOREIGN_KEY) - continue; - DBUG_ASSERT(key != key2); - Foreign_key *fk= (Foreign_key*) key2; - if (fk->update_opt != FK_OPTION_CASCADE) - continue; - for (Key_part_spec& kp: key->columns) - { - for (Key_part_spec& kp2: fk->columns) - { - if (!lex_string_cmp(scs, &kp.field_name, &kp2.field_name)) - { - goto without_overlaps_err; - } - } - } - } - create_info->period_info.unique_keys++; - } - key_info++; } @@ -4886,20 +5000,6 @@ static int append_system_key_parts(THD *thd, HA_CREATE_INFO *create_info, my_error(ER_PERIOD_NOT_FOUND, MYF(0), key->period.str); return -1; } - - const auto &period_start= create_info->period_info.period.start; - const auto &period_end= create_info->period_info.period.end; - List_iterator part_it(key->columns); - while (Key_part_spec *key_part= part_it++) - { - if (period_start.streq(key_part->field_name) - || period_end.streq(key_part->field_name)) - { - my_error(ER_KEY_CONTAINS_PERIOD_FIELDS, MYF(0), key->name.str, - key_part->field_name.str); - return -1; - } - } const auto &period= create_info->period_info.period; key->columns.push_back(new (thd->mem_root) Key_part_spec(&period.end, 0, true)); From e7cc1a30470f650481d7ba069e122e95548c7a47 Mon Sep 17 00:00:00 2001 From: Nikita Malyavin Date: Sun, 13 Oct 2024 19:28:51 +0200 Subject: [PATCH 146/213] MDEV-33658 2/2 Cannot add a foreign key on a table with a matching long UNIQUE Cannot add a foreign key on a table with a long UNIQUE multi-column index, that contains a foreign key as a prefix. Check that index algorithms match during the "generated" keys duplicate removal. --- mysql-test/main/long_unique_bugs.result | 21 +++++++++++++++++++++ mysql-test/main/long_unique_bugs.test | 15 +++++++++++++++ sql/sql_class.cc | 12 +++++++++++- 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/long_unique_bugs.result b/mysql-test/main/long_unique_bugs.result index 5ee8b65fbf6..6da1a1978e8 100644 --- a/mysql-test/main/long_unique_bugs.result +++ b/mysql-test/main/long_unique_bugs.result @@ -741,6 +741,27 @@ insert into t1 select seq from seq_1_to_100; alter table t1 add partition (partition p3 values less than (maxvalue)); alter table t1 force; drop table t1; +# +# MDEV-33658 cannot add a foreign key on a table with a long UNIQUE +# multi-column index, that contains a foreign key as a prefix. +# +create table a (id int primary key) engine = innodb; +create table b (id int, +long_text varchar(1000), +constraint unique_b unique key (id, long_text) +) engine=innodb default charset utf8mb4; +alter table b add constraint b_fk_id foreign key (id) references a (id); +show create table b; +Table Create Table +b CREATE TABLE `b` ( + `id` int(11) DEFAULT NULL, + `long_text` varchar(1000) DEFAULT NULL, + UNIQUE KEY `unique_b` (`id`,`long_text`) USING HASH, + KEY `b_fk_id` (`id`), + CONSTRAINT `b_fk_id` FOREIGN KEY (`id`) REFERENCES `a` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci +drop table b; +drop table a; # veirfy that duplicate has unique is detected create table t1 (a blob unique); alter table t1 add constraint constraint_1 unique (a); diff --git a/mysql-test/main/long_unique_bugs.test b/mysql-test/main/long_unique_bugs.test index 3fbe2a6b777..7f487d4947f 100644 --- a/mysql-test/main/long_unique_bugs.test +++ b/mysql-test/main/long_unique_bugs.test @@ -721,6 +721,21 @@ alter table t1 force; drop table t1; +--echo # +--echo # MDEV-33658 cannot add a foreign key on a table with a long UNIQUE +--echo # multi-column index, that contains a foreign key as a prefix. +--echo # +create table a (id int primary key) engine = innodb; +create table b (id int, + long_text varchar(1000), + constraint unique_b unique key (id, long_text) + ) engine=innodb default charset utf8mb4; + +alter table b add constraint b_fk_id foreign key (id) references a (id); +show create table b; +drop table b; +drop table a; + --echo # veirfy that duplicate has unique is detected create table t1 (a blob unique); alter table t1 add constraint constraint_1 unique (a); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index e6ff4d87690..e49c920abed 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -204,7 +204,7 @@ Foreign_key::Foreign_key(const Foreign_key &rhs, MEM_ROOT *mem_root) /* Test if a foreign key (= generated key) is a prefix of the given key - (ignoring key name, key type and order of columns) + (ignoring key name and type, but minding the algorithm) NOTES: This is only used to test if an index for a FOREIGN KEY exists @@ -219,6 +219,16 @@ Foreign_key::Foreign_key(const Foreign_key &rhs, MEM_ROOT *mem_root) bool is_foreign_key_prefix(Key *a, Key *b) { + ha_key_alg a_alg= a->key_create_info.algorithm; + ha_key_alg b_alg= b->key_create_info.algorithm; + + // The real algorithm in InnoDB will be BTREE if none was given by user. + a_alg= a_alg == HA_KEY_ALG_UNDEF ? HA_KEY_ALG_BTREE : a_alg; + b_alg= b_alg == HA_KEY_ALG_UNDEF ? HA_KEY_ALG_BTREE : b_alg; + + if (a_alg != b_alg) + return false; + /* Ensure that 'a' is the generated key */ if (a->generated) { From 765458c93cd52f83f5dbb725124bbee24c903041 Mon Sep 17 00:00:00 2001 From: Nikita Malyavin Date: Tue, 17 Nov 2020 04:59:41 +0100 Subject: [PATCH 147/213] fix my_error usage --- sql/item_strfunc.cc | 10 +++++----- sql/sql_acl.cc | 2 +- sql/wsrep_mysqld.cc | 7 +++++-- storage/innobase/handler/ha_innodb.cc | 5 ++--- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 0e9c01c7a7e..ae936d0703d 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -5327,7 +5327,7 @@ String *Item_func_wsrep_last_written_gtid::val_str_ascii(String *str) { if (gtid_str.alloc(WSREP_MAX_WSREP_SERVER_GTID_STR_LEN+1)) { - my_error(ER_OUTOFMEMORY, WSREP_MAX_WSREP_SERVER_GTID_STR_LEN); + my_error(ER_OUTOFMEMORY, MYF(0), WSREP_MAX_WSREP_SERVER_GTID_STR_LEN); null_value= TRUE; return 0; } @@ -5352,7 +5352,7 @@ String *Item_func_wsrep_last_seen_gtid::val_str_ascii(String *str) { if (gtid_str.alloc(WSREP_MAX_WSREP_SERVER_GTID_STR_LEN+1)) { - my_error(ER_OUTOFMEMORY, WSREP_MAX_WSREP_SERVER_GTID_STR_LEN); + my_error(ER_OUTOFMEMORY, MYF(0), WSREP_MAX_WSREP_SERVER_GTID_STR_LEN); null_value= TRUE; return 0; } @@ -5397,7 +5397,7 @@ longlong Item_func_wsrep_sync_wait_upto::val_int() if (!(gtid_list= gtid_parse_string_to_list(gtid_str->ptr(), gtid_str->length(), &count))) { - my_error(ER_INCORRECT_GTID_STATE, MYF(0), func_name()); + my_error(ER_INCORRECT_GTID_STATE, MYF(0)); null_value= TRUE; return 0; } @@ -5409,12 +5409,12 @@ longlong Item_func_wsrep_sync_wait_upto::val_int() wait_gtid_ret= wsrep_gtid_server.wait_gtid_upto(gtid_list[0].seq_no, timeout); if ((wait_gtid_ret == ETIMEDOUT) || (wait_gtid_ret == ETIME)) { - my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0), func_name()); + my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0)); ret= 0; } else if (wait_gtid_ret == ENOMEM) { - my_error(ER_OUTOFMEMORY, MYF(0), func_name()); + my_error(ER_OUTOFMEMORY, MYF(0), sizeof(std::pair)); ret= 0; } } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index c7f2a8d3d46..a7e9ea7d6f7 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3345,7 +3345,7 @@ end: switch (result) { case ER_INVALID_CURRENT_USER: - my_error(ER_INVALID_CURRENT_USER, MYF(0), rolename); + my_error(ER_INVALID_CURRENT_USER, MYF(0)); break; case ER_INVALID_ROLE: /* Role doesn't exist at all */ diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index eea5ade5e3d..8c2a2bda31b 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -2468,8 +2468,11 @@ static int wsrep_TOI_begin(THD *thd, const char *db, const char *table, if (!thd->is_error()) { - my_error(ER_LOCK_DEADLOCK, MYF(0), "WSREP replication failed. Check " - "your wsrep connection state and retry the query."); + push_warning_printf(thd, Sql_state_errno_level::WARN_LEVEL_ERROR, + ER_LOCK_DEADLOCK, + "WSREP replication failed. Check " + "your wsrep connection state and retry the query."); + my_error(ER_LOCK_DEADLOCK, MYF(0)); } } rc= -1; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 68e3f6c7b56..890cdbaf429 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -9530,8 +9530,7 @@ ha_innobase::ft_init_ext( /* If tablespace is discarded, we should return here */ if (!ft_table->space) { - my_error(ER_TABLESPACE_MISSING, MYF(0), table->s->db.str, - table->s->table_name.str); + my_error(ER_TABLESPACE_MISSING, MYF(0), ft_table->name.m_name); return(NULL); } @@ -13892,7 +13891,7 @@ ha_innobase::rename_table( error = DB_ERROR; } else if (error == DB_LOCK_WAIT_TIMEOUT) { - my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0), to); + my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0)); error = DB_LOCK_WAIT; } From 01fafd45eba396cb051641134ec07b9e43e71483 Mon Sep 17 00:00:00 2001 From: Brandon Nesterenko Date: Sun, 26 Jan 2025 09:17:20 -0700 Subject: [PATCH 148/213] MDEV-35939: rpl.rpl_parallel_sbm: "Slave_last_event_time is not equal to Master_last_event_time" The test rpl.rpl_parallel_sbm would fail because Slave_last_event_time would not match Master_last_event_time after syncing with the master (i.e. via sync_with_master_gtid.inc). This happens because the timing statistics are updated after updating gtid_slave_pos. That is, gtid_slave_pos is updated with the transaction commit, whereas the timing statistics are updated when the relay log position is updated (i.e. after the commit). This is by design. For the test, this means there is a small amount of time after sync_with_master_gtid.inc where the SHOW SLAVE STATUS output lags behind the data state of the slave. This would cause the test to fail if comparing Slave_last_event_time to Master_last_event_time during this period, because Slave_last_event_time would not yet reflect the latest committed transaction. The fix is to add a wait_condition before the comparison to wait for the SHOW SLAVE STATUS statistics to be updated. The actual check is to wait for Seconds_Behind_Master == 0, because the slave should be idle at this point, which forces the value to be 0. The test failure can be reproduced with the following patch: diff --git a/sql/rpl_gtid.cc b/sql/rpl_gtid.cc index db5c26b6237..b346a32b573 100644 --- a/sql/rpl_gtid.cc +++ b/sql/rpl_gtid.cc @@ -300,6 +300,7 @@ rpl_slave_state::update(uint32 domain_id, uint32 server_id, uint64 sub_id, mysql_mutex_lock(&LOCK_slave_state); res= update_nolock(domain_id, server_id, sub_id, seq_no, hton, rgi); mysql_mutex_unlock(&LOCK_slave_state); + sleep(1); return res; } --- mysql-test/suite/rpl/r/rpl_parallel_sbm.result | 1 + mysql-test/suite/rpl/t/rpl_parallel_sbm.test | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/mysql-test/suite/rpl/r/rpl_parallel_sbm.result b/mysql-test/suite/rpl/r/rpl_parallel_sbm.result index 1c00180b3cc..43ae0b663fa 100644 --- a/mysql-test/suite/rpl/r/rpl_parallel_sbm.result +++ b/mysql-test/suite/rpl/r/rpl_parallel_sbm.result @@ -68,6 +68,7 @@ connection server_2; UNLOCK TABLES; include/sync_with_master_gtid.inc # MDEV-33856: New definition for Seconds_Behind_Master +# Waiting for slave timing statistics to update .. # Ensuring Slave_last_event_time is now up-to-date once event is executed # ..done # diff --git a/mysql-test/suite/rpl/t/rpl_parallel_sbm.test b/mysql-test/suite/rpl/t/rpl_parallel_sbm.test index 91c566a1234..c269c4d96cd 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel_sbm.test +++ b/mysql-test/suite/rpl/t/rpl_parallel_sbm.test @@ -154,6 +154,15 @@ UNLOCK TABLES; --source include/sync_with_master_gtid.inc --echo # MDEV-33856: New definition for Seconds_Behind_Master + +# The update of slave timing statistics (Seconds_Behind_Master, +# Slave_last_event_time, etc) lags slightly behind the update of +# gtid_slave_pos (we just called sync_with_master_gtid), so wait for SBM==0 to +# indicate the statistics have been updated +--echo # Waiting for slave timing statistics to update .. +--let $wait_condition= SELECT count(*) FROM information_schema.slave_status WHERE Seconds_Behind_Master=0 +--source include/wait_condition.inc + --echo # Ensuring Slave_last_event_time is now up-to-date once event is executed --let $slave_time_trx1_commit= query_get_value(SHOW ALL SLAVES STATUS, Slave_last_event_time, 1) --let $slave_time_trx1_commit_unix= `SELECT truncate(unix_timestamp("$slave_time_trx1_commit"),0)` From dffe3d1fb24f33047c53feae4ff2f4cb429ee31c Mon Sep 17 00:00:00 2001 From: Galina Shalygina Date: Sun, 26 Jan 2025 20:39:38 -0800 Subject: [PATCH 149/213] MDEV-35910 Conditions with SP local variables are not pushed into derived table This bug prevented building conditions that could be pushed into a derived table if the derived table was used in a query of a stored procedure and the conditions contained local variables of the procedure. This could lead to a slow execution of the procedure. Also in some cases the bug prevented building conditions that could be pushed from the HAVING condition into the WHERE condition of a query if the conditions to be built used local variables of a stored procedure. To failure to build such pushable conditions was due to lack of a proper implementation of the virtual method to copy items for the objects of the class Item_splocal. Approved by Igor Babaev who had to change the original fix that just added the regular copying of the nodes of the Item_splocal class to take into account the wrappers do_get_copy() and do_build_clone() introduced after the fix had been prepared. He also changed the test case to demonstrate that the fix was really needed for pushdown from HAVING into WHERE. --- mysql-test/main/sp.result | 176 ++++++++++++++++++++++++++++++++++++++ mysql-test/main/sp.test | 88 +++++++++++++++++++ sql/item.h | 5 +- 3 files changed, 267 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/sp.result b/mysql-test/main/sp.result index 1b3405e47b1..204af23f09f 100644 --- a/mysql-test/main/sp.result +++ b/mysql-test/main/sp.result @@ -8974,3 +8974,179 @@ DROP PROCEDURE p1; DROP PROCEDURE p2; # End of 10.4 tests # +# +# MDEV-35910: Pushdown of conditions with local SP variables +# into materialized derived table +# Pushdown of conditions with local variables from HAVING +# into WHERE +# +CREATE TABLE t1( +pk INT PRIMARY KEY AUTO_INCREMENT, +a INT, +b INT +); +INSERT INTO t1(a,b) VALUES (1, 2), (3, 2), (4, 5); +INSERT INTO t1(a,b) VALUES (3, 7), (4, 1), (3, 4); +CREATE PROCEDURE pushdownDerivedSp() +BEGIN +DECLARE localA INT DEFAULT 1; +DECLARE localB INT DEFAULT 2; +SELECT dt.a +FROM ( +SELECT t1.a, MIN(t1.b) as minB +FROM t1 +GROUP BY t1.a +) AS dt +WHERE dt.minB = localB AND dt.a = localA + localB; +END$$ +CREATE PROCEDURE explainPushdownDerivedSp() +BEGIN +DECLARE localA INT DEFAULT 1; +DECLARE localB INT DEFAULT 2; +EXPLAIN format=json SELECT dt.a +FROM ( +SELECT t1.a, MIN(t1.b) as minB +FROM t1 +GROUP BY t1.a +) AS dt +WHERE dt.minB = localB AND dt.a = localA + localB; +END$$ +CREATE PROCEDURE pushdownFromHavingSp() +BEGIN +DECLARE localA INT DEFAULT 1; +DECLARE localB INT DEFAULT 2; +SELECT t1.a, SUM(b) +FROM t1 +GROUP BY t1.a +HAVING t1.a > localA AND SUM(b) > 10 OR t1.a <= localB AND SUM(b) <= 2; +END$$ +CREATE PROCEDURE explainPushdownFromHavingSp() +BEGIN +DECLARE localA INT DEFAULT 1; +DECLARE localB INT DEFAULT 2; +EXPLAIN format=json +SELECT t1.a, SUM(b) +FROM t1 +GROUP BY t1.a +HAVING t1.a > localA AND SUM(b) > 10 OR t1.a <= localB AND SUM(b) <= 2; +END$$ +CALL pushdownDerivedSp(); +a +3 +set statement optimizer_switch='condition_pushdown_for_derived=off' +for CALL pushdownDerivedSp(); +a +3 +CALL explainPushdownDerivedSp(); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "", + "access_type": "ALL", + "rows": 6, + "filtered": 100, + "attached_condition": "dt.minB = (localB@1) and dt.a = (localA@0 + localB@1)", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "minB = (localB@1)", + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 6, + "filtered": 100, + "attached_condition": "t1.a = (localA@0 + localB@1)" + } + } + } + } + } +} +set statement optimizer_switch='condition_pushdown_for_derived=off' for +CALL explainPushdownDerivedSp(); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "", + "access_type": "ALL", + "rows": 6, + "filtered": 100, + "attached_condition": "dt.minB = (localB@1) and dt.a = (localA@0 + localB@1)", + "materialized": { + "query_block": { + "select_id": 2, + "filesort": { + "sort_key": "t1.a", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 6, + "filtered": 100 + } + } + } + } + } + } + } +} +CALL pushdownFromHavingSp(); +a SUM(b) +1 2 +3 13 +set statement optimizer_switch='condition_pushdown_from_having=off' for +CALL pushdownFromHavingSp(); +a SUM(b) +1 2 +3 13 +CALL explainPushdownFromHavingSp(); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "having_condition": "t1.a > (localA@0) and sum(t1.b) > 10 or t1.a <= (localB@1) and sum(t1.b) <= 2", + "filesort": { + "sort_key": "t1.a", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 6, + "filtered": 100, + "attached_condition": "t1.a > (localA@0) or t1.a <= (localB@1)" + } + } + } + } +} +set statement optimizer_switch='condition_pushdown_from_having=off' for +CALL explainPushdownFromHavingSp(); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "having_condition": "t1.a > (localA@0) and sum(t1.b) > 10 or t1.a <= (localB@1) and sum(t1.b) <= 2", + "filesort": { + "sort_key": "t1.a", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 6, + "filtered": 100 + } + } + } + } +} +DROP PROCEDURE pushdownDerivedSp; +DROP PROCEDURE explainPushdownDerivedSp; +DROP PROCEDURE pushdownFromHavingSp; +DROP PROCEDURE explainPushdownFromHavingSp; +DROP TABLE t1; +# End of 10.5 tests diff --git a/mysql-test/main/sp.test b/mysql-test/main/sp.test index c1e107b69e1..7799e34210a 100644 --- a/mysql-test/main/sp.test +++ b/mysql-test/main/sp.test @@ -10593,3 +10593,91 @@ DROP PROCEDURE p2; --echo # End of 10.4 tests --echo # +--echo # +--echo # MDEV-35910: Pushdown of conditions with local SP variables +--echo # into materialized derived table +--echo # Pushdown of conditions with local variables from HAVING +--echo # into WHERE +--echo # + +CREATE TABLE t1( + pk INT PRIMARY KEY AUTO_INCREMENT, + a INT, + b INT +); +INSERT INTO t1(a,b) VALUES (1, 2), (3, 2), (4, 5); +INSERT INTO t1(a,b) VALUES (3, 7), (4, 1), (3, 4); + +DELIMITER $$; +CREATE PROCEDURE pushdownDerivedSp() +BEGIN + DECLARE localA INT DEFAULT 1; + DECLARE localB INT DEFAULT 2; + SELECT dt.a + FROM ( + SELECT t1.a, MIN(t1.b) as minB + FROM t1 + GROUP BY t1.a + ) AS dt + WHERE dt.minB = localB AND dt.a = localA + localB; +END$$ + +CREATE PROCEDURE explainPushdownDerivedSp() +BEGIN + DECLARE localA INT DEFAULT 1; + DECLARE localB INT DEFAULT 2; + EXPLAIN format=json SELECT dt.a + FROM ( + SELECT t1.a, MIN(t1.b) as minB + FROM t1 + GROUP BY t1.a + ) AS dt + WHERE dt.minB = localB AND dt.a = localA + localB; +END$$ + +CREATE PROCEDURE pushdownFromHavingSp() +BEGIN + DECLARE localA INT DEFAULT 1; + DECLARE localB INT DEFAULT 2; + SELECT t1.a, SUM(b) + FROM t1 + GROUP BY t1.a + HAVING t1.a > localA AND SUM(b) > 10 OR t1.a <= localB AND SUM(b) <= 2; +END$$ + +CREATE PROCEDURE explainPushdownFromHavingSp() +BEGIN + DECLARE localA INT DEFAULT 1; + DECLARE localB INT DEFAULT 2; + EXPLAIN format=json + SELECT t1.a, SUM(b) + FROM t1 + GROUP BY t1.a + HAVING t1.a > localA AND SUM(b) > 10 OR t1.a <= localB AND SUM(b) <= 2; +END$$ + +DELIMITER ;$$ + +CALL pushdownDerivedSp(); +set statement optimizer_switch='condition_pushdown_for_derived=off' +for CALL pushdownDerivedSp(); + +CALL explainPushdownDerivedSp(); +set statement optimizer_switch='condition_pushdown_for_derived=off' for +CALL explainPushdownDerivedSp(); + +CALL pushdownFromHavingSp(); +set statement optimizer_switch='condition_pushdown_from_having=off' for +CALL pushdownFromHavingSp(); + +CALL explainPushdownFromHavingSp(); +set statement optimizer_switch='condition_pushdown_from_having=off' for +CALL explainPushdownFromHavingSp(); + +DROP PROCEDURE pushdownDerivedSp; +DROP PROCEDURE explainPushdownDerivedSp; +DROP PROCEDURE pushdownFromHavingSp; +DROP PROCEDURE explainPushdownFromHavingSp; +DROP TABLE t1; + +--echo # End of 10.5 tests diff --git a/sql/item.h b/sql/item.h index a146107508f..ce02b0edda1 100644 --- a/sql/item.h +++ b/sql/item.h @@ -3099,8 +3099,9 @@ public: bool append_for_log(THD *thd, String *str) override; - Item *do_get_copy(THD *) const override { return nullptr; } - Item *do_build_clone(THD *thd) const override { return nullptr; } + Item *do_get_copy(THD *thd) const override + { return get_item_copy(thd, this); } + Item *do_build_clone(THD *thd) const override { return get_copy(thd); } /* Override the inherited create_field_for_create_select(), From 95a0325b58d9992f02f47c865c5265456f679809 Mon Sep 17 00:00:00 2001 From: Oleg Smirnov Date: Mon, 13 Jan 2025 17:27:03 +0700 Subject: [PATCH 150/213] MDEV-32575 MSAN / Valgrind errors in test_if_cheaper_ordering upon reaching in_predicate_conversion_threshold When converting an IN-list to a subquery, a temporary table stores the IN-list values and participates in join optimization. The problem is the bitmap of usable keys for the temporary table is initialized after the optimization phase, during execution. It happens when the table is opened via `ha_heap::open()`, after the subroutine `set_keys_for_scanning()` is called. Trying to access the bitmap earlier, during optimization, leads to MSAN/Valgrind errors. This fix removes the dependency on `set_keys_for_scanning()`. The key bitmap is now dynamically composed on demand in `keys_to_use_for_scanning()`, ensuring correctness without imposing strict call-order constraints. Reviewer: Oleksandr Byelkin --- mysql-test/main/opt_tvc.result | 12 ++++++++++++ mysql-test/main/opt_tvc.test | 15 +++++++++++++++ storage/heap/ha_heap.cc | 31 ++++++++++++++----------------- storage/heap/ha_heap.h | 3 +-- 4 files changed, 42 insertions(+), 19 deletions(-) diff --git a/mysql-test/main/opt_tvc.result b/mysql-test/main/opt_tvc.result index c08c68eb7ee..15b6d9b4218 100644 --- a/mysql-test/main/opt_tvc.result +++ b/mysql-test/main/opt_tvc.result @@ -780,3 +780,15 @@ deallocate prepare stmt; drop table t1; set in_predicate_conversion_threshold=default; # End of 10.3 tests +# +# MDEV-32575 MSAN / Valgrind errors in test_if_cheaper_ordering +# upon reaching in_predicate_conversion_threshold +# +create table t1 (a int, b int, c int, primary key (a, b)); +insert into t1 (a, b) values (1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8); +set in_predicate_conversion_threshold = 2; +select * from t1 where a in (1, 2) and b = 2 order by a, b; +a b c +1 2 NULL +drop table t1; +# End of 11.4 tests diff --git a/mysql-test/main/opt_tvc.test b/mysql-test/main/opt_tvc.test index d676188401a..7d39c6a8979 100644 --- a/mysql-test/main/opt_tvc.test +++ b/mysql-test/main/opt_tvc.test @@ -474,3 +474,18 @@ drop table t1; set in_predicate_conversion_threshold=default; --echo # End of 10.3 tests + +--echo # +--echo # MDEV-32575 MSAN / Valgrind errors in test_if_cheaper_ordering +--echo # upon reaching in_predicate_conversion_threshold +--echo # + +create table t1 (a int, b int, c int, primary key (a, b)); +insert into t1 (a, b) values (1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8); + +set in_predicate_conversion_threshold = 2; +select * from t1 where a in (1, 2) and b = 2 order by a, b; + +drop table t1; + +--echo # End of 11.4 tests diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc index 08f235c843a..1f37ad8b991 100644 --- a/storage/heap/ha_heap.cc +++ b/storage/heap/ha_heap.cc @@ -144,8 +144,6 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked) } ref_length= sizeof(HEAP_PTR); - /* Initialize variables for the opened table */ - set_keys_for_scanning(); /* We cannot run update_key_stats() here because we do not have a lock on the table. The 'records' count might just be changed @@ -186,22 +184,24 @@ handler *ha_heap::clone(const char *name, MEM_ROOT *mem_root) /* - Compute which keys to use for scanning + Return set of keys usable for scanning SYNOPSIS - set_keys_for_scanning() - no parameter + keys_to_use_for_scanning() + (no parameters) DESCRIPTION - Set the bitmap btree_keys, which is used when the upper layers ask - which keys to use for scanning. For each btree index the - corresponding bit is set. + This function populates the bitmap `btree_keys`, where each bit represents + a key that can be used for scanning the table. The bitmap is dynamically + updated on every call, ensuring it reflects the current state of the + table's keys. Caching is avoided because the set of usable keys for + MEMORY tables may change during optimization or execution. RETURN - void + Pointer to the updated bitmap of keys (`btree_keys`) */ -void ha_heap::set_keys_for_scanning(void) +const key_map *ha_heap::keys_to_use_for_scanning() { btree_keys.clear_all(); for (uint i= 0 ; i < table->s->keys ; i++) @@ -209,9 +209,9 @@ void ha_heap::set_keys_for_scanning(void) if (table->key_info[i].algorithm == HA_KEY_ALG_BTREE) btree_keys.set_bit(i); } + return &btree_keys; } - int ha_heap::can_continue_handler_scan() { int error= 0; @@ -515,8 +515,7 @@ int ha_heap::disable_indexes(key_map map, bool persist) if (!persist) { DBUG_ASSERT(map.is_clear_all()); - if (!(error= heap_disable_indexes(file))) - set_keys_for_scanning(); + error= heap_disable_indexes(file); } else { @@ -534,8 +533,7 @@ int ha_heap::disable_indexes(key_map map, bool persist) enable_indexes() DESCRIPTION - Enable indexes and set keys to use for scanning. - The indexes might have been disabled by disable_index() before. + Enable indexes taht might have been disabled by disable_index() before. The function works only if both data and indexes are empty, since the heap storage engine cannot repair the indexes. To be sure, call handler::delete_all_rows() before. @@ -555,8 +553,7 @@ int ha_heap::enable_indexes(key_map map, bool persist) if (!persist) { DBUG_ASSERT(map.is_prefix(table->s->keys)); - if (!(error= heap_enable_indexes(file))) - set_keys_for_scanning(); + error= heap_enable_indexes(file); } else { diff --git a/storage/heap/ha_heap.h b/storage/heap/ha_heap.h index 837eae15fee..693ae2ad38b 100644 --- a/storage/heap/ha_heap.h +++ b/storage/heap/ha_heap.h @@ -59,7 +59,7 @@ public: HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_READ_RANGE : HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR); } - const key_map *keys_to_use_for_scanning() override { return &btree_keys; } + const key_map *keys_to_use_for_scanning() override; uint max_supported_keys() const override { return MAX_KEY; } uint max_supported_key_part_length() const override { return MAX_KEY_LENGTH; } IO_AND_CPU_COST scan_time() override; @@ -121,5 +121,4 @@ public: int find_unique_row(uchar *record, uint unique_idx) override; private: void update_key_stats(); - void set_keys_for_scanning(void); }; From 831f5bc66f8d2147edd7991caf69e34058566b67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 27 Jan 2025 12:08:30 +0200 Subject: [PATCH 151/213] MDEV-33978 P_S.THREADS is not showing all server threads page_encrypt_thread_key: The key for fil_crypt_thread(). All other InnoDB threads should already have been registered for performance_schema ever since commit a2f510fccff23e5011486c240587b8f1a98ecacc --- mysql-test/suite/perfschema/r/threads_innodb.result | 1 + mysql-test/suite/perfschema/t/threads_innodb.opt | 1 + storage/innobase/fil/fil0crypt.cc | 9 +++++++++ storage/innobase/handler/ha_innodb.cc | 1 + storage/innobase/include/srv0srv.h | 1 + 5 files changed, 13 insertions(+) create mode 100644 mysql-test/suite/perfschema/t/threads_innodb.opt diff --git a/mysql-test/suite/perfschema/r/threads_innodb.result b/mysql-test/suite/perfschema/r/threads_innodb.result index d79420f6fb5..abfedb57644 100644 --- a/mysql-test/suite/perfschema/r/threads_innodb.result +++ b/mysql-test/suite/perfschema/r/threads_innodb.result @@ -6,4 +6,5 @@ WHERE name LIKE 'thread/innodb/%' GROUP BY name; name type processlist_user processlist_host processlist_db processlist_command processlist_time processlist_state processlist_info parent_thread_id role instrumented thread/innodb/page_cleaner_thread BACKGROUND NULL NULL NULL NULL NULL NULL NULL NULL NULL YES +thread/innodb/page_encrypt_thread BACKGROUND NULL NULL NULL NULL NULL NULL NULL NULL NULL YES thread/innodb/thread_pool_thread BACKGROUND NULL NULL NULL NULL NULL NULL NULL NULL NULL YES diff --git a/mysql-test/suite/perfschema/t/threads_innodb.opt b/mysql-test/suite/perfschema/t/threads_innodb.opt new file mode 100644 index 00000000000..bd33f76701e --- /dev/null +++ b/mysql-test/suite/perfschema/t/threads_innodb.opt @@ -0,0 +1 @@ +--innodb-encryption-threads=2 diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index bfaaaafc359..28078747318 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -2007,10 +2007,18 @@ static void fil_crypt_complete_rotate_space(rotate_thread_t* state) mysql_mutex_unlock(&crypt_data->mutex); } +#ifdef UNIV_PFS_THREAD +mysql_pfs_key_t page_encrypt_thread_key; +#endif /* UNIV_PFS_THREAD */ + /** A thread which monitors global key state and rotates tablespaces accordingly */ static void fil_crypt_thread() { + my_thread_init(); +#ifdef UNIV_PFS_THREAD + pfs_register_thread(page_encrypt_thread_key); +#endif /* UNIV_PFS_THREAD */ mysql_mutex_lock(&fil_crypt_threads_mutex); rotate_thread_t thr(srv_n_fil_crypt_threads_started++); pthread_cond_signal(&fil_crypt_cond); /* signal that we started */ @@ -2088,6 +2096,7 @@ wait_for_work: pthread_cond_signal(&fil_crypt_cond); /* signal that we stopped */ mysql_mutex_unlock(&fil_crypt_threads_mutex); + my_thread_end(); #ifdef UNIV_PFS_THREAD pfs_delete_thread(); #endif diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 4dd7a9405dd..bb7594cf1a0 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -624,6 +624,7 @@ performance schema instrumented if "UNIV_PFS_THREAD" is defined */ static PSI_thread_info all_innodb_threads[] = { PSI_KEY(page_cleaner_thread), + PSI_KEY(page_encrypt_thread), PSI_KEY(trx_rollback_clean_thread), PSI_KEY(thread_pool_thread) }; diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 5fbf2a3d4f2..7195b062e70 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -462,6 +462,7 @@ extern ulong srv_buf_dump_status_frequency; # ifdef UNIV_PFS_THREAD extern mysql_pfs_key_t page_cleaner_thread_key; +extern mysql_pfs_key_t page_encrypt_thread_key; extern mysql_pfs_key_t trx_rollback_clean_thread_key; extern mysql_pfs_key_t thread_pool_thread_key; From 746471b8d86de9c53ec87b576f8fbef0768e6c22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 27 Jan 2025 12:11:47 +0200 Subject: [PATCH 152/213] MDEV-33978 P_S.THREADS is not showing all server threads page_encrypt_thread_key: The key for fil_crypt_thread(). All other InnoDB threads should already have been registered for performance_schema ever since commit a2f510fccff23e5011486c240587b8f1a98ecacc --- mysql-test/suite/perfschema/r/threads_innodb.result | 1 + mysql-test/suite/perfschema/t/threads_innodb.opt | 1 + storage/innobase/fil/fil0crypt.cc | 9 +++++++++ storage/innobase/handler/ha_innodb.cc | 1 + storage/innobase/include/srv0srv.h | 1 + 5 files changed, 13 insertions(+) create mode 100644 mysql-test/suite/perfschema/t/threads_innodb.opt diff --git a/mysql-test/suite/perfschema/r/threads_innodb.result b/mysql-test/suite/perfschema/r/threads_innodb.result index d79420f6fb5..abfedb57644 100644 --- a/mysql-test/suite/perfschema/r/threads_innodb.result +++ b/mysql-test/suite/perfschema/r/threads_innodb.result @@ -6,4 +6,5 @@ WHERE name LIKE 'thread/innodb/%' GROUP BY name; name type processlist_user processlist_host processlist_db processlist_command processlist_time processlist_state processlist_info parent_thread_id role instrumented thread/innodb/page_cleaner_thread BACKGROUND NULL NULL NULL NULL NULL NULL NULL NULL NULL YES +thread/innodb/page_encrypt_thread BACKGROUND NULL NULL NULL NULL NULL NULL NULL NULL NULL YES thread/innodb/thread_pool_thread BACKGROUND NULL NULL NULL NULL NULL NULL NULL NULL NULL YES diff --git a/mysql-test/suite/perfschema/t/threads_innodb.opt b/mysql-test/suite/perfschema/t/threads_innodb.opt new file mode 100644 index 00000000000..bd33f76701e --- /dev/null +++ b/mysql-test/suite/perfschema/t/threads_innodb.opt @@ -0,0 +1 @@ +--innodb-encryption-threads=2 diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index fce308bcc81..7433e957d0a 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -80,6 +80,10 @@ static uint n_fil_crypt_iops_allocated = 0; #define DEBUG_KEYROTATION_THROTTLING 0 +#ifdef UNIV_PFS_THREAD +mysql_pfs_key_t page_encrypt_thread_key; +#endif /* UNIV_PFS_THREAD */ + /** Statistics variables */ static fil_crypt_stat_t crypt_stat; static ib_mutex_t crypt_stat_mutex; @@ -2145,6 +2149,10 @@ extern "C" UNIV_INTERN os_thread_ret_t DECLARE_THREAD(fil_crypt_thread)(void*) { + my_thread_init(); +#ifdef UNIV_PFS_THREAD + pfs_register_thread(page_encrypt_thread_key); +#endif /* UNIV_PFS_THREAD */ mutex_enter(&fil_crypt_threads_mutex); uint thread_no = srv_n_fil_crypt_threads_started; srv_n_fil_crypt_threads_started++; @@ -2242,6 +2250,7 @@ DECLARE_THREAD(fil_crypt_thread)(void*) /* We count the number of threads in os_thread_exit(). A created thread should always use that to exit and not use return() to exit. */ + my_thread_end(); return os_thread_exit(); } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 890cdbaf429..e0d7e91c10b 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -579,6 +579,7 @@ performance schema instrumented if "UNIV_PFS_THREAD" is defined */ static PSI_thread_info all_innodb_threads[] = { PSI_KEY(page_cleaner_thread), + PSI_KEY(page_encrypt_thread), PSI_KEY(trx_rollback_clean_thread), PSI_KEY(thread_pool_thread) }; diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 75718a92a10..fd615742ba3 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -469,6 +469,7 @@ extern ulong srv_buf_dump_status_frequency; # ifdef UNIV_PFS_THREAD extern mysql_pfs_key_t page_cleaner_thread_key; +extern mysql_pfs_key_t page_encrypt_thread_key; extern mysql_pfs_key_t trx_rollback_clean_thread_key; extern mysql_pfs_key_t thread_pool_thread_key; From 25b1c3505fd4e1d2f39627fdd77f2920ace6323d Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 27 Jan 2025 16:17:48 +0400 Subject: [PATCH 153/213] MDEV-35677 Assertion `thd->is_error()' failed in virtual bool Field::sp_prepare_and_store_item(THD*, Item**) The Count_handler (derived from Internal_error_handler) used in Type_handler_datetime_common::convert_item_for_comparison() suppressed all error codes. This caused a DBUG_ASSERT(thd->is_error()) in Field::sp_prepare_and_store_item() when the error happened while evaluating a subselect in a scenario like this: CREATE FUNCTION f() RETURNS INT DETERMINISTIC RETURN (SELECT a FROM t); CREATE TABLE t (c TIMESTAMP); SELECT * FROM t WHERE c=f(); Notice there is no such column 'a' in in the table 't'. Fix: Handle only DATETIME->TIMESTAMP conversion related errors in Count_handler: - ER_TRUNCATED_WRONG_VALUE - ER_DATETIME_FUNCTION_OVERFLOW thus let other error kinds be processed in their usual way. The reported scenario now returns this (expected) error: ERROR 1054 (42S22): Unknown column 'a' in 'SELECT' --- mysql-test/main/type_timestamp.result | 11 +++++++++++ mysql-test/main/type_timestamp.test | 18 ++++++++++++++++++ sql/sql_type.cc | 9 +++++++-- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/type_timestamp.result b/mysql-test/main/type_timestamp.result index 1950410c7c4..e00e6d8bacd 100644 --- a/mysql-test/main/type_timestamp.result +++ b/mysql-test/main/type_timestamp.result @@ -2335,3 +2335,14 @@ DROP TABLE t1; # # End of 11.3 tests # +# Start of 11.4 tests +# +# MDEV-35677 Assertion `thd->is_error()' failed in virtual bool Field::sp_prepare_and_store_item(THD*, Item**) +# +CREATE FUNCTION f() RETURNS INT DETERMINISTIC RETURN (SELECT a FROM t); +CREATE TABLE t (c TIMESTAMP); +SELECT * FROM t WHERE c=f(); +ERROR 42S22: Unknown column 'a' in 'SELECT' +DROP TABLE t; +DROP FUNCTION f; +# End of 11.4 tests diff --git a/mysql-test/main/type_timestamp.test b/mysql-test/main/type_timestamp.test index 8b45bd1590c..2b0e772d54b 100644 --- a/mysql-test/main/type_timestamp.test +++ b/mysql-test/main/type_timestamp.test @@ -1370,3 +1370,21 @@ DROP TABLE t1; --echo # --echo # End of 11.3 tests --echo # + +--echo # Start of 11.4 tests + +--echo # +--echo # MDEV-35677 Assertion `thd->is_error()' failed in virtual bool Field::sp_prepare_and_store_item(THD*, Item**) +--echo # + +CREATE FUNCTION f() RETURNS INT DETERMINISTIC RETURN (SELECT a FROM t); +CREATE TABLE t (c TIMESTAMP); +# with view protocol it raises ER_VIEW_INVALID +--disable_view_protocol +--error ER_BAD_FIELD_ERROR +SELECT * FROM t WHERE c=f(); +--enable_view_protocol +DROP TABLE t; +DROP FUNCTION f; + +--echo # End of 11.4 tests diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 12c971b3bd7..2c74c42b1be 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -7959,8 +7959,13 @@ Type_handler_datetime_common::convert_item_for_comparison( const char *msg, Sql_condition **cond_hdl) override { - hit++; - return *level >= Sql_condition::WARN_LEVEL_WARN; + if (sql_errno == ER_TRUNCATED_WRONG_VALUE || + sql_errno == ER_DATETIME_FUNCTION_OVERFLOW) + { + hit++; + return *level >= Sql_condition::WARN_LEVEL_WARN; + } + return false; } } cnt_handler; From c0b11e75fff9ea513cd6cccfe47837678cedb473 Mon Sep 17 00:00:00 2001 From: Hemant Dangi Date: Wed, 8 Jan 2025 13:22:46 +0530 Subject: [PATCH 154/213] MDEV-34218: Mariadb Galera cluster fails when replicating from Mysql 5.7 on use of DDL Issue: Mariadb Galera cluster fails to replicate from Mysql 5.7 when configured with MASTER_USE_GTID=no option for CHANGE MASTER. HOST: mysql, mysql 5.7.44 binlog_format=ROW HOST: m1, mariadb 10.6 GALERA NODE replicating from HOST mysql, Using_Gtid: No (log file and position) HOST: m2 mariadb 10.6 GALERA NODE HOST: m3 mariadb 10.6 GALERA NODE Error on m1: 2024-05-22 16:11:07 1 [ERROR] WSREP: Vote 0 (success) on 78cebda7-1876-11ef-896b-8a58fca50d36:2565 is inconsistent with group. Leaving cluster. Error on m2 and m3: 2024-05-22 16:11:06 2 [ERROR] Error in Log_event::read_log_event(): 'Found invalid event in binary log', data_len: 42, event_type: -94 2024-05-22 16:11:06 2 [ERROR] WSREP: applier could not read binlog event, seqno: 2565, len: 482 It fails in Gtid_log_event::is_valid() check on secondary node when sequence number sent from primary is 0. On primary for applier or slave thread sequence number is set to 0, when both thd->variables.gtid_seq_no and thd->variables.wsrep_gtid_seq_no have value 0. Solution: Skip adding Gtid Event on primary for applier or slave thread when both thd->variables.gtid_seq_no and thd->variables.wsrep_gtid_seq_no have value 0. Signed-off-by: Julius Goryavsky --- sql/wsrep_mysqld.cc | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 8c2a2bda31b..ae52e319e3f 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -1863,11 +1863,18 @@ int wsrep_to_buf_helper( domain_id= wsrep_gtid_server.domain_id; server_id= wsrep_gtid_server.server_id; } - Gtid_log_event gtid_event(thd, seqno, domain_id, true, - LOG_EVENT_SUPPRESS_USE_F, true, 0); - gtid_event.server_id= server_id; - if (!gtid_event.is_valid()) ret= 0; - ret= writer.write(>id_event); + /* + * Ignore if both thd->variables.gtid_seq_no and + * thd->variables.wsrep_gtid_seq_no are not set. + */ + if (seqno) + { + Gtid_log_event gtid_event(thd, seqno, domain_id, true, + LOG_EVENT_SUPPRESS_USE_F, true, 0); + gtid_event.server_id= server_id; + if (!gtid_event.is_valid()) ret= 0; + ret= writer.write(>id_event); + } } /* It's local DDL so in case of possible gtid seqno (SET gtid_seq_no=X) From 6e3274e814d743d6337e1836101568be561e8b43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Tue, 19 Nov 2024 14:16:48 +0200 Subject: [PATCH 155/213] MENT-31857 post-fix: fix for timeouts in the galera_as_slave_ctas test Caused by MDEV-31857 enable --ssl-verify-server-cert by default in the internal client. Fixed by disabling master_ssl_verify_server_cert because account is passwordless. Signed-off-by: Julius Goryavsky --- mysql-test/suite/galera/t/galera_as_slave_ctas.test | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/galera/t/galera_as_slave_ctas.test b/mysql-test/suite/galera/t/galera_as_slave_ctas.test index eced636c600..0ef4c3f5986 100644 --- a/mysql-test/suite/galera/t/galera_as_slave_ctas.test +++ b/mysql-test/suite/galera/t/galera_as_slave_ctas.test @@ -34,11 +34,13 @@ CREATE TABLE target AS SELECT * FROM source; --connection node_1 --let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'target'; ---source include/wait_condition.inc +--let $wait_condition_on_error_output = SELECT * FROM INFORMATION_SCHEMA.TABLES +--source include/wait_condition_with_debug.inc --connection node_2 --let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'target'; ---source include/wait_condition.inc +--let $wait_condition_on_error_output = SELECT * FROM INFORMATION_SCHEMA.TABLES +--source include/wait_condition_with_debug.inc # # test phase two, issue CTAS with populated source table From 0ddaefcc76844e94867bcbfa4dc9613e95ec3ec3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 20 Nov 2024 16:17:50 +0200 Subject: [PATCH 156/213] galera fix : MW-402 galera test fails sporadically Test was using after certification sync point when it was intended to use before certification sync point. This caused sporadic failures. Signed-off-by: Julius Goryavsky --- mysql-test/suite/galera/r/MW-369.result | 56 +++++++++---------- mysql-test/suite/galera/r/MW-402.result | 54 ++++++++++-------- mysql-test/suite/galera/t/MW-369.inc | 12 ++-- mysql-test/suite/galera/t/MW-402.combinations | 5 ++ mysql-test/suite/galera/t/MW-402.test | 8 ++- 5 files changed, 76 insertions(+), 59 deletions(-) create mode 100644 mysql-test/suite/galera/t/MW-402.combinations diff --git a/mysql-test/suite/galera/r/MW-369.result b/mysql-test/suite/galera/r/MW-369.result index b4fb8668e74..4c487c57030 100644 --- a/mysql-test/suite/galera/r/MW-369.result +++ b/mysql-test/suite/galera/r/MW-369.result @@ -18,12 +18,12 @@ INSERT INTO c VALUES (1, 1); connection node_1a; SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; -SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; +SET SESSION DEBUG_SYNC = "wsrep_before_certification SIGNAL before_certification_reached WAIT_FOR continue_before_certification"; COMMIT; connection node_1a; -SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; -SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; -SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR before_certification_reached"; +SET SESSION DEBUG_SYNC = 'now SIGNAL continue_before_certification'; +SET SESSION DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; SET GLOBAL DEBUG_DBUG = ""; SET DEBUG_SYNC = 'RESET'; connection node_1; @@ -58,12 +58,12 @@ UPDATE c SET f2 = 1 WHERE f1 = 1; connection node_1a; SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; -SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; +SET SESSION DEBUG_SYNC = "wsrep_before_certification SIGNAL before_certification_reached WAIT_FOR continue_before_certification"; COMMIT; connection node_1a; -SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; -SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; -SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR before_certification_reached"; +SET SESSION DEBUG_SYNC = 'now SIGNAL continue_before_certification'; +SET SESSION DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; SET GLOBAL DEBUG_DBUG = ""; SET DEBUG_SYNC = 'RESET'; connection node_1; @@ -96,12 +96,12 @@ DELETE FROM c WHERE f1 = 1; connection node_1a; SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; -SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; +SET SESSION DEBUG_SYNC = "wsrep_before_certification SIGNAL before_certification_reached WAIT_FOR continue_before_certification"; COMMIT; connection node_1a; -SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; -SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; -SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR before_certification_reached"; +SET SESSION DEBUG_SYNC = 'now SIGNAL continue_before_certification'; +SET SESSION DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; SET GLOBAL DEBUG_DBUG = ""; SET DEBUG_SYNC = 'RESET'; connection node_1; @@ -130,12 +130,12 @@ INSERT INTO c VALUES (1, 0);; connection node_1a; SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; -SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; +SET SESSION DEBUG_SYNC = "wsrep_before_certification SIGNAL before_certification_reached WAIT_FOR continue_before_certification"; COMMIT; connection node_1a; -SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; -SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; -SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR before_certification_reached"; +SET SESSION DEBUG_SYNC = 'now SIGNAL continue_before_certification'; +SET SESSION DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; SET GLOBAL DEBUG_DBUG = ""; SET DEBUG_SYNC = 'RESET'; connection node_1; @@ -168,12 +168,12 @@ UPDATE c SET f2 = 1 WHERE f1 = 1; connection node_1a; SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; -SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; +SET SESSION DEBUG_SYNC = "wsrep_before_certification SIGNAL before_certification_reached WAIT_FOR continue_before_certification"; COMMIT; connection node_1a; -SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; -SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; -SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR before_certification_reached"; +SET SESSION DEBUG_SYNC = 'now SIGNAL continue_before_certification'; +SET SESSION DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; SET GLOBAL DEBUG_DBUG = ""; SET DEBUG_SYNC = 'RESET'; connection node_1; @@ -211,12 +211,12 @@ INSERT INTO cf (f1, p_id) VALUES (20, 1); connection node_1a; SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; -SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; +SET SESSION DEBUG_SYNC = "wsrep_before_certification SIGNAL before_certification_reached WAIT_FOR continue_before_certification"; COMMIT; connection node_1a; -SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; -SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; -SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR before_certification_reached"; +SET SESSION DEBUG_SYNC = 'now SIGNAL continue_before_certification'; +SET SESSION DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; SET GLOBAL DEBUG_DBUG = ""; SET DEBUG_SYNC = 'RESET'; connection node_1; @@ -249,12 +249,12 @@ INSERT INTO cg VALUES (1, 1, 0); connection node_1a; SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; -SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; +SET SESSION DEBUG_SYNC = "wsrep_before_certification SIGNAL before_certification_reached WAIT_FOR continue_before_certification"; COMMIT; connection node_1a; -SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; -SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; -SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR before_certification_reached"; +SET SESSION DEBUG_SYNC = 'now SIGNAL continue_before_certification'; +SET SESSION DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; SET GLOBAL DEBUG_DBUG = ""; SET DEBUG_SYNC = 'RESET'; connection node_1; diff --git a/mysql-test/suite/galera/r/MW-402.result b/mysql-test/suite/galera/r/MW-402.result index e936b83553d..925d208f5c6 100644 --- a/mysql-test/suite/galera/r/MW-402.result +++ b/mysql-test/suite/galera/r/MW-402.result @@ -21,16 +21,17 @@ DELETE FROM p WHERE f1 = 1; connection node_1a; SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; -SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; +SET SESSION DEBUG_SYNC = "wsrep_before_certification SIGNAL before_certification_reached WAIT_FOR continue_before_certification"; COMMIT; connection node_1a; -SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; -SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; -SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR before_certification_reached"; +SET SESSION DEBUG_SYNC = 'now SIGNAL continue_before_certification'; +SET SESSION DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; SET GLOBAL DEBUG_DBUG = ""; SET DEBUG_SYNC = 'RESET'; connection node_1; ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SET DEBUG_SYNC = 'RESET'; connection node_2; SELECT * FROM p; f1 f2 @@ -59,16 +60,17 @@ UPDATE p set f1=11 WHERE f1 = 1; connection node_1a; SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; -SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; +SET SESSION DEBUG_SYNC = "wsrep_before_certification SIGNAL before_certification_reached WAIT_FOR continue_before_certification"; COMMIT; connection node_1a; -SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; -SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; -SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR before_certification_reached"; +SET SESSION DEBUG_SYNC = 'now SIGNAL continue_before_certification'; +SET SESSION DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; SET GLOBAL DEBUG_DBUG = ""; SET DEBUG_SYNC = 'RESET'; connection node_1; ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SET DEBUG_SYNC = 'RESET'; connection node_2; SELECT * FROM p; f1 f2 @@ -99,16 +101,17 @@ UPDATE p set f1=11 WHERE f1 = 1; connection node_1a; SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; -SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; +SET SESSION DEBUG_SYNC = "wsrep_before_certification SIGNAL before_certification_reached WAIT_FOR continue_before_certification"; COMMIT; connection node_1a; -SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; -SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; -SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR before_certification_reached"; +SET SESSION DEBUG_SYNC = 'now SIGNAL continue_before_certification'; +SET SESSION DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; SET GLOBAL DEBUG_DBUG = ""; SET DEBUG_SYNC = 'RESET'; connection node_1; ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SET DEBUG_SYNC = 'RESET'; connection node_2; SELECT * FROM p; f1 f2 @@ -130,16 +133,17 @@ UPDATE c SET p_id=2 where f1=1; connection node_1a; SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; -SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; +SET SESSION DEBUG_SYNC = "wsrep_before_certification SIGNAL before_certification_reached WAIT_FOR continue_before_certification"; COMMIT; connection node_1a; -SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; -SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; -SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR before_certification_reached"; +SET SESSION DEBUG_SYNC = 'now SIGNAL continue_before_certification'; +SET SESSION DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; SET GLOBAL DEBUG_DBUG = ""; SET DEBUG_SYNC = 'RESET'; connection node_1; ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SET DEBUG_SYNC = 'RESET'; connection node_2; SELECT * FROM p; f1 f2 @@ -174,15 +178,16 @@ DELETE FROM p1 WHERE f1 = 1; connection node_1a; SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; -SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; +SET SESSION DEBUG_SYNC = "wsrep_before_certification SIGNAL before_certification_reached WAIT_FOR continue_before_certification"; COMMIT; connection node_1a; -SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; -SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; -SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR before_certification_reached"; +SET SESSION DEBUG_SYNC = 'now SIGNAL continue_before_certification'; +SET SESSION DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; SET GLOBAL DEBUG_DBUG = ""; SET DEBUG_SYNC = 'RESET'; connection node_1; +SET DEBUG_SYNC = 'RESET'; connection node_2; SELECT * FROM p1; f1 f2 @@ -219,16 +224,17 @@ DELETE FROM p1 WHERE f1=1; connection node_1a; SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; -SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; +SET SESSION DEBUG_SYNC = "wsrep_before_certification SIGNAL before_certification_reached WAIT_FOR continue_before_certification"; COMMIT; connection node_1a; -SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; -SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; -SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR before_certification_reached"; +SET SESSION DEBUG_SYNC = 'now SIGNAL continue_before_certification'; +SET SESSION DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; SET GLOBAL DEBUG_DBUG = ""; SET DEBUG_SYNC = 'RESET'; connection node_1; ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SET DEBUG_SYNC = 'RESET'; connection node_2; SELECT * FROM p1; f1 f2 diff --git a/mysql-test/suite/galera/t/MW-369.inc b/mysql-test/suite/galera/t/MW-369.inc index f080d99fe7e..3b0a32bdd9d 100644 --- a/mysql-test/suite/galera/t/MW-369.inc +++ b/mysql-test/suite/galera/t/MW-369.inc @@ -14,7 +14,7 @@ # node_2 # $mw_369_child_query - will be blocked on node_1 in wsrep_apply_cb # node_1: -# COMMIT; - will be blocked on node_1 in wsrep_after_certification +# COMMIT; - will be blocked on node_1 in after_wsrep_before_prepare # # The $mw_369_child_query is always expected to succeed. The caller is # responsible for checking if the final COMMIT on connection node_1 @@ -49,14 +49,14 @@ SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_cb"; SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; --connection node_1 -SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; +SET SESSION DEBUG_SYNC = "wsrep_before_certification SIGNAL before_certification_reached WAIT_FOR continue_before_certification"; --send COMMIT # # Wait until both sync points have been reached # --connection node_1a -SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; +SET SESSION DEBUG_SYNC = "now WAIT_FOR before_certification_reached"; # # both threads are now parked in sync points, signal them to continue @@ -66,13 +66,13 @@ SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; --let $wait_condition_on_error_output = SELECT STATE FROM INFORMATION_SCHEMA.PROCESSLIST --source include/wait_condition_with_debug.inc -SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; +SET SESSION DEBUG_SYNC = 'now SIGNAL continue_before_certification'; --let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE 'debug sync point:%' --let $wait_condition_on_error_output = SELECT STATE FROM INFORMATION_SCHEMA.PROCESSLIST --source include/wait_condition_with_debug.inc -SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET SESSION DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; --let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE 'debug sync point:%' --let $wait_condition_on_error_output = SELECT STATE FROM INFORMATION_SCHEMA.PROCESSLIST @@ -80,3 +80,5 @@ SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; SET GLOBAL DEBUG_DBUG = ""; SET DEBUG_SYNC = 'RESET'; + + diff --git a/mysql-test/suite/galera/t/MW-402.combinations b/mysql-test/suite/galera/t/MW-402.combinations new file mode 100644 index 00000000000..def4dda7def --- /dev/null +++ b/mysql-test/suite/galera/t/MW-402.combinations @@ -0,0 +1,5 @@ +[binlogon] +log-bin +log-slave-updates=ON + +[binlogoff] diff --git a/mysql-test/suite/galera/t/MW-402.test b/mysql-test/suite/galera/t/MW-402.test index f84752e1b25..8b954a19405 100644 --- a/mysql-test/suite/galera/t/MW-402.test +++ b/mysql-test/suite/galera/t/MW-402.test @@ -2,7 +2,6 @@ --source include/have_innodb.inc --source include/have_debug.inc --source include/have_debug_sync.inc ---source include/galera_have_debug_sync.inc # # we must open connection node_1a here, MW-369.inc will use it later @@ -36,6 +35,7 @@ INSERT INTO c VALUES (1, 1, 0); --connection node_1 --error ER_LOCK_DEADLOCK --reap +SET DEBUG_SYNC = 'RESET'; --connection node_2 SELECT * FROM p; @@ -72,6 +72,7 @@ INSERT INTO c VALUES (1, 1, 0); --connection node_1 --error ER_LOCK_DEADLOCK --reap +SET DEBUG_SYNC = 'RESET'; --connection node_2 SELECT * FROM p; @@ -112,6 +113,7 @@ INSERT INTO c VALUES (1, 1, 0); --connection node_1 --error ER_LOCK_DEADLOCK --reap +SET DEBUG_SYNC = 'RESET'; # same as previous, but statements in different order --connection node_2 @@ -128,7 +130,7 @@ SELECT * FROM c; --connection node_1 --error ER_LOCK_DEADLOCK --reap - +SET DEBUG_SYNC = 'RESET'; --connection node_2 SELECT * FROM p; @@ -172,6 +174,7 @@ INSERT INTO c VALUES (1, 1, 1, 0); # Commit succeeds --connection node_1 --reap +SET DEBUG_SYNC = 'RESET'; --connection node_2 SELECT * FROM p1; @@ -217,6 +220,7 @@ INSERT INTO c VALUES (1, 1, 1, 0); --connection node_1 --error ER_LOCK_DEADLOCK --reap +SET DEBUG_SYNC = 'RESET'; --connection node_2 SELECT * FROM p1; From 2cfad396ee1a7ab270f91b5986beba7e323be6ba Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Fri, 24 Jan 2025 02:22:01 +0100 Subject: [PATCH 157/213] galera tests: more informative messages about the number of variables --- mysql-test/include/galera_variables_ok.inc | 13 ++++++++++--- mysql-test/include/galera_variables_ok_debug.inc | 12 ++++-------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/mysql-test/include/galera_variables_ok.inc b/mysql-test/include/galera_variables_ok.inc index c9a54724c17..d10bf1fd36e 100644 --- a/mysql-test/include/galera_variables_ok.inc +++ b/mysql-test/include/galera_variables_ok.inc @@ -1,9 +1,16 @@ --disable_query_log ---let $galera_variables_ok = `SELECT COUNT(*) = 50 FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIKE 'wsrep%'` +let $_galera_variables_delta=$galera_variables_delta; +if (!$_galera_variables_delta) { +--let $galera_variables_delta=0 +} ---if (!$galera_variables_ok) { - --skip Galera number of variables has changed! +--let $galera_variables_expected=`SELECT 50 + $galera_variables_delta` + +--let $galera_variables_count=`SELECT COUNT(*) FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIKE 'wsrep%'` + +--if ($galera_variables_count != $galera_variables_expected) { + --skip Galera number of variables has changed! ($galera_variables_count instead of $galera_variables_expected) } --enable_query_log diff --git a/mysql-test/include/galera_variables_ok_debug.inc b/mysql-test/include/galera_variables_ok_debug.inc index e420b3af6c3..495b850c871 100644 --- a/mysql-test/include/galera_variables_ok_debug.inc +++ b/mysql-test/include/galera_variables_ok_debug.inc @@ -1,9 +1,5 @@ ---disable_query_log +# Now the number of variables for the release and debug versions +# of the library is equal to each other... +--let $galera_variables_delta=0 ---let $galera_variables_ok = `SELECT COUNT(*) = 51 FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIKE 'wsrep%'` - ---if (!$galera_variables_ok) { - --skip Galera number of variables has changed! -} - ---enable_query_log +--source include/galera_variables_ok.inc From e53ffdee965b8d056faa15fd4e6513577b830438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Thu, 19 Dec 2024 15:03:10 +0200 Subject: [PATCH 158/213] MDEV-35804 : galera_ddl_fk_conflict test failed due to timeout Test case changes only. Use better wait_conditions. Signed-off-by: Julius Goryavsky --- .../suite/galera/r/galera_ddl_fk_conflict.result | 3 +++ mysql-test/suite/galera/t/galera_ddl_fk_conflict.cnf | 11 +++++++++++ mysql-test/suite/galera/t/galera_ddl_fk_conflict.inc | 10 ++++++++-- mysql-test/suite/galera/t/galera_ddl_fk_conflict.test | 2 ++ 4 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 mysql-test/suite/galera/t/galera_ddl_fk_conflict.cnf diff --git a/mysql-test/suite/galera/r/galera_ddl_fk_conflict.result b/mysql-test/suite/galera/r/galera_ddl_fk_conflict.result index 904c5eb1a82..226aebde69e 100644 --- a/mysql-test/suite/galera/r/galera_ddl_fk_conflict.result +++ b/mysql-test/suite/galera/r/galera_ddl_fk_conflict.result @@ -3,6 +3,7 @@ connection node_1; connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1; connection node_1a; SET SESSION wsrep_sync_wait=0; +FLUSH STATUS; connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1; connection node_1b; SET SESSION wsrep_sync_wait=0; @@ -17,6 +18,7 @@ SET SESSION wsrep_sync_wait=0; ###################################################################### connection node_1; SET SESSION wsrep_sync_wait=0; +FLUSH STATUS; CREATE TABLE p1 (pk INTEGER PRIMARY KEY, f2 CHAR(30)); INSERT INTO p1 VALUES (1, 'INITIAL VALUE'); CREATE TABLE p2 (pk INTEGER PRIMARY KEY, f2 CHAR(30)); @@ -156,6 +158,7 @@ DROP TABLE p1, p2; ###################################################################### connection node_1; SET SESSION wsrep_sync_wait=0; +FLUSH STATUS; CREATE TABLE p1 (pk INTEGER PRIMARY KEY, f2 CHAR(30)); INSERT INTO p1 VALUES (1, 'INITIAL VALUE'); CREATE TABLE p2 (pk INTEGER PRIMARY KEY, f2 CHAR(30)); diff --git a/mysql-test/suite/galera/t/galera_ddl_fk_conflict.cnf b/mysql-test/suite/galera/t/galera_ddl_fk_conflict.cnf new file mode 100644 index 00000000000..2975070498e --- /dev/null +++ b/mysql-test/suite/galera/t/galera_ddl_fk_conflict.cnf @@ -0,0 +1,11 @@ +!include ../galera_2nodes.cnf + +[mysqld.1] +wsrep-debug=1 +loose-galera-ddl-fk-conflict=1 + +[mysqld.2] +wsrep-debug=1 +loose-galera-ddl-fk-conflict=1 + + diff --git a/mysql-test/suite/galera/t/galera_ddl_fk_conflict.inc b/mysql-test/suite/galera/t/galera_ddl_fk_conflict.inc index 6964446a363..f9fad92ac62 100644 --- a/mysql-test/suite/galera/t/galera_ddl_fk_conflict.inc +++ b/mysql-test/suite/galera/t/galera_ddl_fk_conflict.inc @@ -39,6 +39,7 @@ --connection node_1 SET SESSION wsrep_sync_wait=0; +FLUSH STATUS; CREATE TABLE p1 (pk INTEGER PRIMARY KEY, f2 CHAR(30)); INSERT INTO p1 VALUES (1, 'INITIAL VALUE'); @@ -108,6 +109,7 @@ BEGIN; --connection node_1a --source include/galera_wait_sync_point.inc --source include/galera_clear_sync_point.inc + --let $expected_cert_failures = `SELECT VARIABLE_VALUE+1 FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_cert_failures'` --connection node_1 @@ -116,7 +118,8 @@ UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1; --connection node_1a --let $wait_condition = SELECT VARIABLE_VALUE = $expected_cert_failures FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_cert_failures' ---source include/wait_condition.inc +--let $wait_condition_on_error_output = SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_cert_failures' +--source include/wait_condition_with_debug.inc --let $galera_sync_point = apply_monitor_slave_enter_sync --source include/galera_signal_sync_point.inc @@ -166,6 +169,8 @@ BEGIN; --source include/galera_wait_sync_point.inc --source include/galera_clear_sync_point.inc --let $expected_cert_failures = `SELECT VARIABLE_VALUE+2 FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_cert_failures'` +--let $wait_condition_on_error_output = SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_cert_failures' +--source include/wait_condition_with_debug.inc --connection node_1 UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1; @@ -177,7 +182,8 @@ UPDATE p2 SET f2 = 'TO DEADLOCK' WHERE pk = 2; --connection node_1a --let $wait_condition = SELECT VARIABLE_VALUE = $expected_cert_failures FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_cert_failures' ---source include/wait_condition.inc +--let $wait_condition_on_error_output = SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_cert_failures' +--source include/wait_condition_with_debug.inc --let $galera_sync_point = apply_monitor_slave_enter_sync --source include/galera_signal_sync_point.inc diff --git a/mysql-test/suite/galera/t/galera_ddl_fk_conflict.test b/mysql-test/suite/galera/t/galera_ddl_fk_conflict.test index b98c6daa73b..a8fb6614e41 100644 --- a/mysql-test/suite/galera/t/galera_ddl_fk_conflict.test +++ b/mysql-test/suite/galera/t/galera_ddl_fk_conflict.test @@ -6,11 +6,13 @@ --source include/have_innodb.inc --source include/have_debug_sync.inc --source include/galera_have_debug_sync.inc +--source include/force_restart.inc # sync point controlling session --connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 --connection node_1a SET SESSION wsrep_sync_wait=0; +FLUSH STATUS; # secondary conflicting DML victim session --connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1 From acf7b000ff3adbf87b1595f36d62e9b53ac0161d Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Fri, 24 Jan 2025 19:31:00 +0100 Subject: [PATCH 159/213] fixes for galera_as_slave replication tests --- mysql-test/suite/galera/r/galera_slave_replay.result | 3 +++ mysql-test/suite/galera/t/MDEV-28053.test | 2 +- mysql-test/suite/galera/t/MDEV-6860.test | 2 +- mysql-test/suite/galera/t/galera_as_master.test | 2 +- mysql-test/suite/galera/t/galera_as_slave.test | 2 +- mysql-test/suite/galera/t/galera_as_slave_autoinc.test | 2 +- mysql-test/suite/galera/t/galera_as_slave_ctas.test | 2 +- mysql-test/suite/galera/t/galera_as_slave_nonprim.test | 1 - .../suite/galera/t/galera_as_slave_parallel_retry.test | 1 - mysql-test/suite/galera/t/galera_as_slave_replay.cnf | 1 - mysql-test/suite/galera/t/galera_as_slave_replay.test | 8 +++----- .../suite/galera/t/galera_gtid_slave_sst_rsync.test | 2 +- .../suite/galera/t/galera_query_cache_invalidate.test | 2 +- mysql-test/suite/galera/t/galera_slave_replay.test | 7 +++++-- 14 files changed, 19 insertions(+), 18 deletions(-) diff --git a/mysql-test/suite/galera/r/galera_slave_replay.result b/mysql-test/suite/galera/r/galera_slave_replay.result index 8fb7e1ab099..263e1a675d5 100644 --- a/mysql-test/suite/galera/r/galera_slave_replay.result +++ b/mysql-test/suite/galera/r/galera_slave_replay.result @@ -94,3 +94,6 @@ DROP TABLE t1; connection node_3; DROP TABLE t1; RESET MASTER; +connection node_1; +disconnect node_2a; +disconnect node_3; diff --git a/mysql-test/suite/galera/t/MDEV-28053.test b/mysql-test/suite/galera/t/MDEV-28053.test index 85cb20c7e10..f3d7a775454 100644 --- a/mysql-test/suite/galera/t/MDEV-28053.test +++ b/mysql-test/suite/galera/t/MDEV-28053.test @@ -37,7 +37,7 @@ while ($counter) { --connection node_2 --disable_query_log --disable_result_log ---eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_3; +--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_3; START SLAVE; --eval SELECT MASTER_GTID_WAIT('$gtid', 600) --enable_result_log diff --git a/mysql-test/suite/galera/t/MDEV-6860.test b/mysql-test/suite/galera/t/MDEV-6860.test index 3a8c98f317f..e254dbceeeb 100644 --- a/mysql-test/suite/galera/t/MDEV-6860.test +++ b/mysql-test/suite/galera/t/MDEV-6860.test @@ -4,7 +4,7 @@ --connection node_2 --disable_query_log ---eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_3, MASTER_USE_GTID=slave_pos; +--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_3, MASTER_USE_GTID=slave_pos; --enable_query_log START SLAVE; diff --git a/mysql-test/suite/galera/t/galera_as_master.test b/mysql-test/suite/galera/t/galera_as_master.test index a5554a735fe..4bdbc24635a 100644 --- a/mysql-test/suite/galera/t/galera_as_master.test +++ b/mysql-test/suite/galera/t/galera_as_master.test @@ -9,7 +9,7 @@ --connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 --disable_query_log ---eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_1; +--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_1; --enable_query_log START SLAVE; diff --git a/mysql-test/suite/galera/t/galera_as_slave.test b/mysql-test/suite/galera/t/galera_as_slave.test index da92437b118..1e2e5b2ea7b 100644 --- a/mysql-test/suite/galera/t/galera_as_slave.test +++ b/mysql-test/suite/galera/t/galera_as_slave.test @@ -13,7 +13,7 @@ --connection node_2 --disable_query_log ---eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_3; +--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_3; --enable_query_log START SLAVE; diff --git a/mysql-test/suite/galera/t/galera_as_slave_autoinc.test b/mysql-test/suite/galera/t/galera_as_slave_autoinc.test index ce4c87e2bee..69c16baeb08 100644 --- a/mysql-test/suite/galera/t/galera_as_slave_autoinc.test +++ b/mysql-test/suite/galera/t/galera_as_slave_autoinc.test @@ -13,7 +13,7 @@ --connection node_2 --disable_query_log ---eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_3; +--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_3; --enable_query_log START SLAVE; diff --git a/mysql-test/suite/galera/t/galera_as_slave_ctas.test b/mysql-test/suite/galera/t/galera_as_slave_ctas.test index 0ef4c3f5986..32301a3d0d3 100644 --- a/mysql-test/suite/galera/t/galera_as_slave_ctas.test +++ b/mysql-test/suite/galera/t/galera_as_slave_ctas.test @@ -16,7 +16,7 @@ SELECT @@wsrep_on; --connection node_1 --disable_query_log ---eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_3; +--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_3; --enable_query_log START SLAVE; diff --git a/mysql-test/suite/galera/t/galera_as_slave_nonprim.test b/mysql-test/suite/galera/t/galera_as_slave_nonprim.test index e22f0240a59..600d64e5a81 100644 --- a/mysql-test/suite/galera/t/galera_as_slave_nonprim.test +++ b/mysql-test/suite/galera/t/galera_as_slave_nonprim.test @@ -15,7 +15,6 @@ # we open the node_4 connection here --connect node_4, 127.0.0.1, root, , test, $NODE_MYPORT_4 - --connection node_2 --disable_query_log --eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$NODE_MYPORT_4, MASTER_USER='root'; diff --git a/mysql-test/suite/galera/t/galera_as_slave_parallel_retry.test b/mysql-test/suite/galera/t/galera_as_slave_parallel_retry.test index 0d499f22fcd..e106c5f08c3 100644 --- a/mysql-test/suite/galera/t/galera_as_slave_parallel_retry.test +++ b/mysql-test/suite/galera/t/galera_as_slave_parallel_retry.test @@ -38,7 +38,6 @@ SET debug_sync = 'now SIGNAL signal.wsrep_retry_event_group'; --let $wait_condition = SELECT COUNT(*) = 1 FROM t1; --source include/wait_condition.inc - --connection node_1 SET debug_sync = 'RESET'; diff --git a/mysql-test/suite/galera/t/galera_as_slave_replay.cnf b/mysql-test/suite/galera/t/galera_as_slave_replay.cnf index c20c65f86d9..5ae8b0b1ba7 100644 --- a/mysql-test/suite/galera/t/galera_as_slave_replay.cnf +++ b/mysql-test/suite/galera/t/galera_as_slave_replay.cnf @@ -10,4 +10,3 @@ wsrep-debug=1 [mysqld.2] wsrep_restart_slave=1 wsrep-debug=1 - diff --git a/mysql-test/suite/galera/t/galera_as_slave_replay.test b/mysql-test/suite/galera/t/galera_as_slave_replay.test index f6dd3f89f3e..20455f2843c 100644 --- a/mysql-test/suite/galera/t/galera_as_slave_replay.test +++ b/mysql-test/suite/galera/t/galera_as_slave_replay.test @@ -16,7 +16,6 @@ --connection node_2a --source include/galera_cluster.inc -#--source suite/galera/include/galera_have_debug_sync.inc ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; @@ -33,12 +32,11 @@ RESET MASTER; # --let $wsrep_local_replays_old = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_replays'` - # -# nodes 1 and 2 form a galera cluster, node 2 operates as slave for native MariaDB naster in node 3 +# nodes 1 and 2 form a galera cluster, node 2 operates as slave for native MariaDB master in node 3 # --disable_query_log ---eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_3; +--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_3; --enable_query_log START SLAVE; @@ -81,7 +79,7 @@ SET SESSION wsrep_sync_wait = 0; SET GLOBAL debug_dbug = "d,sync.wsrep_apply_cb"; # -# now inject a conflicting insert from node 3, it will replicate with +# now inject a conflicting insert from node 1, it will replicate with # earlier seqno (than async transaction) and pause before applying in node 2 # --connection node_1 diff --git a/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.test b/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.test index 148bbc2b460..0f68a02426e 100644 --- a/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.test +++ b/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.test @@ -16,7 +16,7 @@ --echo #Connection 2 --connection node_2 --disable_query_log ---eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_3,master_use_gtid=slave_pos; +--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_3, master_use_gtid=slave_pos; --enable_query_log START SLAVE; --sleep 1 diff --git a/mysql-test/suite/galera/t/galera_query_cache_invalidate.test b/mysql-test/suite/galera/t/galera_query_cache_invalidate.test index c5c5f69dc27..67069577011 100644 --- a/mysql-test/suite/galera/t/galera_query_cache_invalidate.test +++ b/mysql-test/suite/galera/t/galera_query_cache_invalidate.test @@ -29,7 +29,7 @@ call mtr.add_suppression("WSREP: Ignoring server id .* for non bootstrap node"); --connection node_3 --replace_result $NODE_MYPORT_1 NODE_MYPORT_1 ---eval CHANGE MASTER TO master_host='127.0.0.1', master_user='root', master_port=$NODE_MYPORT_1, master_use_gtid=current_pos; +--eval CHANGE MASTER TO master_host='127.0.0.1', master_user='root', MASTER_PORT=$NODE_MYPORT_1, master_use_gtid=current_pos START SLAVE; --source include/wait_for_slave_to_start.inc diff --git a/mysql-test/suite/galera/t/galera_slave_replay.test b/mysql-test/suite/galera/t/galera_slave_replay.test index 6680e66ffa1..d289cfb3bd2 100644 --- a/mysql-test/suite/galera/t/galera_slave_replay.test +++ b/mysql-test/suite/galera/t/galera_slave_replay.test @@ -32,7 +32,6 @@ RESET MASTER; # --let $wsrep_local_replays_old = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_replays'` - # # nodes 1 and 2 form a galera cluster, node 2 operates as slave for native MariaDB master in node 3 # @@ -134,7 +133,7 @@ SELECT * FROM t1; SET DEBUG_SYNC = "RESET"; #******************************************************************************** -# test phase 2 +# test phase 2 #******************************************************************************** --echo # @@ -197,3 +196,7 @@ DROP TABLE t1; --connection node_3 DROP TABLE t1; RESET MASTER; + +--connection node_1 +--disconnect node_2a +--disconnect node_3 From 0a5d6cf4789a0dbbaa5e970201fb9773a9608a2d Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Sat, 25 Jan 2025 12:43:12 +0100 Subject: [PATCH 160/213] galera: disable problematic test (galera_sequences) --- mysql-test/suite/galera/disabled.def | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index fcaf38a3d7b..3d3ef86f04a 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -9,3 +9,5 @@ # Do not use any TAB characters for whitespace. # ############################################################################## + +galera_sequences : MDEV-35934/MDEV-33850 For Galera, create sequence with low cache got signal 6 error: [ERROR] WSREP: FSM: no such a transition REPLICATING -> COMMITTED From 5af1f69a849d16f07f01fe4b8cfa0b3d5b700571 Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Sat, 25 Jan 2025 16:53:47 +0100 Subject: [PATCH 161/213] MDEV-26266 addendum: more stable test This test must be performed on newly launched nodes and then a restart must be performed. --- mysql-test/suite/galera/t/MDEV-26266.cnf | 6 ++++++ mysql-test/suite/galera/t/MDEV-26266.test | 2 ++ 2 files changed, 8 insertions(+) create mode 100644 mysql-test/suite/galera/t/MDEV-26266.cnf diff --git a/mysql-test/suite/galera/t/MDEV-26266.cnf b/mysql-test/suite/galera/t/MDEV-26266.cnf new file mode 100644 index 00000000000..53eeb9c82bc --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-26266.cnf @@ -0,0 +1,6 @@ +!include ../galera_2nodes.cnf + +[mysqld] +# We want both nodes to restart before this test, +# so let's add a dummy parameter here: +loose-MDEV-26266 diff --git a/mysql-test/suite/galera/t/MDEV-26266.test b/mysql-test/suite/galera/t/MDEV-26266.test index 7167e029cb5..8560cb3c7b6 100644 --- a/mysql-test/suite/galera/t/MDEV-26266.test +++ b/mysql-test/suite/galera/t/MDEV-26266.test @@ -10,6 +10,8 @@ # --source include/galera_cluster.inc +--source include/have_innodb.inc +--source include/force_restart.inc SET SESSION query_prealloc_size=8192; SET max_session_mem_used=50000; From 331975c5c50102029caf58c4501e32227e403fb4 Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Sat, 25 Jan 2025 19:38:41 +0100 Subject: [PATCH 162/213] galera: disable problematic test (galera_nbo_master_non_prim_failure) --- mysql-test/suite/galera_3nodes/disabled.def | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mysql-test/suite/galera_3nodes/disabled.def b/mysql-test/suite/galera_3nodes/disabled.def index c52df019c65..bb9d7cbd7b8 100644 --- a/mysql-test/suite/galera_3nodes/disabled.def +++ b/mysql-test/suite/galera_3nodes/disabled.def @@ -11,6 +11,4 @@ ############################################################################## galera_2_cluster : MDEV-32631 galera_2_cluster: before_rollback(): Assertion `0' failed -galera_ipv6_rsync : MDEV-34842 Can't connect to server on '::1' (115) -galera_ipv6_rsync_section : MDEV-34842 Can't connect to server on '::1' (115) -galera_ipv6_mariabackup_section : MDEV-34842 Can't connect to server on '::1' (115) +galera_nbo_master_phase_two_crash : MENT-2215 Test failure on galera_3nodes.galera_nbo_master_non_prim_failure From 779ae4c511fcc9a5a4719841cd4f9c8acd4ff407 Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Sat, 25 Jan 2025 21:01:58 +0100 Subject: [PATCH 163/213] wsrep mtr tests: fix for MDEV-23081 failure Sometimes a database can be created with --log-bin but then the .combinations file causes a switch to start without --log-bin causing a failure on recovery. This commit fixes this issue. --- mysql-test/suite/wsrep/disabled.def | 2 -- mysql-test/suite/wsrep/t/MDEV-23081.test | 14 +++++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/wsrep/disabled.def b/mysql-test/suite/wsrep/disabled.def index f4145211680..fcaf38a3d7b 100644 --- a/mysql-test/suite/wsrep/disabled.def +++ b/mysql-test/suite/wsrep/disabled.def @@ -9,5 +9,3 @@ # Do not use any TAB characters for whitespace. # ############################################################################## - - diff --git a/mysql-test/suite/wsrep/t/MDEV-23081.test b/mysql-test/suite/wsrep/t/MDEV-23081.test index 04305b22b24..6cd7d6dd037 100644 --- a/mysql-test/suite/wsrep/t/MDEV-23081.test +++ b/mysql-test/suite/wsrep/t/MDEV-23081.test @@ -7,6 +7,11 @@ --source include/have_wsrep_provider.inc --source include/have_debug_sync.inc +--let $log_bin=1 +if (`select not @@log_bin`) { +--let $log_bin=0 +} + CREATE TABLE t1 (f1 INT PRIMARY KEY) ENGINE=InnoDB; # @@ -40,7 +45,14 @@ SET DEBUG_SYNC = "now WAIT_FOR before_commit_order_reached_1"; # and restart it with wsrep-on=OFF # let $restart_noprint=2; ---let $restart_parameters=--wsrep-on=OFF +if ($log_bin == 0) { +# The database could have been created with --log-bin +# and so let's add this parameter explicitly: +--let $restart_parameters=--wsrep-on=OFF --loose-innodb --loose-log-bin +} +if ($log_bin == 1) { +--let $restart_parameters=--wsrep-on=OFF --loose-innodb +} --source include/start_mysqld.inc # From 862d1be2e6b3dce7b8b7acebad1c4e86da594f4e Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Sun, 26 Jan 2025 05:26:26 +0100 Subject: [PATCH 164/213] MDEV-25718 addendum: stabilization of test success (especially for 11.4+) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added DEBUG_SYNC_С("ha_write_row_end") in the WSREP branch, and added a new status to the list of pending statuses in the mtr test. --- mysql-test/suite/galera_sr/t/MDEV-25718.test | 2 +- sql/handler.cc | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/galera_sr/t/MDEV-25718.test b/mysql-test/suite/galera_sr/t/MDEV-25718.test index 037cd300709..147b62fe145 100644 --- a/mysql-test/suite/galera_sr/t/MDEV-25718.test +++ b/mysql-test/suite/galera_sr/t/MDEV-25718.test @@ -43,7 +43,7 @@ SET SESSION wsrep_sync_wait = 0; SET debug_sync = "now SIGNAL write_row_continue"; # Let's give the INSERT some time, to make sure it does rollback ---let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO = "INSERT INTO t1 VALUES (1)" AND (STATE = "Freeing items" OR STATE = 'Rollback'); +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO = "INSERT INTO t1 VALUES (1)" AND (STATE = 'Freeing items' OR STATE = 'Rollback' OR STATE = 'Query end'); --let $wait_condition_on_error_output = SELECT INFO, STATE FROM INFORMATION_SCHEMA.PROCESSLIST --source include/wait_condition_with_debug.inc diff --git a/sql/handler.cc b/sql/handler.cc index c3aa1c64906..7e30968cb1d 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -7375,6 +7375,7 @@ int handler::ha_write_row(const uchar *buf) ht->flags & HTON_WSREP_REPLICATION && !error && (error= wsrep_after_row(ha_thd()))) { + DEBUG_SYNC_C("ha_write_row_end"); DBUG_RETURN(error); } #endif /* WITH_WSREP */ From 479a5832f0dc4a146702f3adbca34ee051c39080 Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Wed, 28 Aug 2024 04:12:10 +0200 Subject: [PATCH 165/213] galera fix: MSAN reports use-of-uninitialized-value on binlog_encryption This commit fixes a bug in MSAN verification in debug builds related to the member of a lex->definer structure field that may be uninitialized for some SET statements. The bug is caused by debug output in a wsrep-specific insert and does not affect server functionality. --- sql/log_event_server.cc | 7 +++++-- sql/service_wsrep.cc | 3 +-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc index 9f7fea18075..603bd2f6e78 100644 --- a/sql/log_event_server.cc +++ b/sql/log_event_server.cc @@ -1728,8 +1728,11 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, DBUG_PRINT("query",("%s", thd->query())); #ifdef WITH_WSREP - WSREP_DEBUG("Query_log_event thread=%llu for query=%s", - thd_get_thread_id(thd), wsrep_thd_query(thd)); + if (WSREP(thd)) + { + WSREP_DEBUG("Query_log_event thread=%llu for query=%s", + thd_get_thread_id(thd), wsrep_thd_query(thd)); + } #endif if (unlikely(!(expected_error= error_code)) || diff --git a/sql/service_wsrep.cc b/sql/service_wsrep.cc index d1e0260d53c..16bb2783cfb 100644 --- a/sql/service_wsrep.cc +++ b/sql/service_wsrep.cc @@ -82,8 +82,7 @@ extern "C" const char *wsrep_thd_query(const THD *thd) case SQLCOM_REVOKE: return "REVOKE"; case SQLCOM_SET_OPTION: - if (thd->lex->definer) - return "SET PASSWORD"; + return "SET OPTION"; /* fallthrough */ default: { From c43db43a7cea2dca028093e10012e5ab8293172f Mon Sep 17 00:00:00 2001 From: Daniele Sciascia Date: Thu, 22 Feb 2024 09:17:29 +0100 Subject: [PATCH 166/213] MENT-2038 Assert WSREP(thd) fails in wsrep_restore_kill_after_commit Fix wrong assertion: function wsrep_restore_kill_after_commit() asserts `WSREP(thd)`, however for the caller (wsrep_after_statement()) it is enough that the THD has an active transaction. Fixed the assertion accordingly. Signed-off-by: Julius Goryavsky --- mysql-test/suite/galera_sr/r/MENT-2038.result | 7 +++++++ mysql-test/suite/galera_sr/t/MENT-2038.test | 12 ++++++++++++ sql/wsrep_thd.cc | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/galera_sr/r/MENT-2038.result create mode 100644 mysql-test/suite/galera_sr/t/MENT-2038.test diff --git a/mysql-test/suite/galera_sr/r/MENT-2038.result b/mysql-test/suite/galera_sr/r/MENT-2038.result new file mode 100644 index 00000000000..bbd7c568925 --- /dev/null +++ b/mysql-test/suite/galera_sr/r/MENT-2038.result @@ -0,0 +1,7 @@ +connection node_2; +connection node_1; +SET SESSION wsrep_on=OFF; +BEGIN; +BEGIN; +COMMIT; +SET SESSION wsrep_on=ON; diff --git a/mysql-test/suite/galera_sr/t/MENT-2038.test b/mysql-test/suite/galera_sr/t/MENT-2038.test new file mode 100644 index 00000000000..311b0d3a36f --- /dev/null +++ b/mysql-test/suite/galera_sr/t/MENT-2038.test @@ -0,0 +1,12 @@ +# +# MENT-2038: Assertion `(thd && (WSREP_PROVIDER_EXISTS_ && thd->variables.wsrep_on))' +# failed in void wsrep_restore_kill_after_commit(THD*) +# + +--source include/galera_cluster.inc + +SET SESSION wsrep_on=OFF; +BEGIN; +BEGIN; # If bug is present, assertion triggers during implicit commit +COMMIT; +SET SESSION wsrep_on=ON; diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc index 1c51d05c56a..2c2e3a0e44d 100644 --- a/sql/wsrep_thd.cc +++ b/sql/wsrep_thd.cc @@ -496,7 +496,7 @@ void wsrep_backup_kill_for_commit(THD *thd) void wsrep_restore_kill_after_commit(THD *thd) { - DBUG_ASSERT(WSREP(thd)); + DBUG_ASSERT(wsrep_is_active(thd)); mysql_mutex_assert_owner(&thd->LOCK_thd_kill); thd->killed= thd->wsrep_abort_by_kill; my_free(thd->killed_err); From 50d49493db079609bdae00da040ebc47b3f276dc Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Wed, 6 Mar 2024 03:40:37 +0100 Subject: [PATCH 167/213] galera: fixes for mtr test for performance schema --- mysql-test/suite/galera/t/galera_performance_schema.test | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/galera/t/galera_performance_schema.test b/mysql-test/suite/galera/t/galera_performance_schema.test index d54555ea301..531c45ea3c5 100644 --- a/mysql-test/suite/galera/t/galera_performance_schema.test +++ b/mysql-test/suite/galera/t/galera_performance_schema.test @@ -5,6 +5,9 @@ --source include/galera_cluster.inc --source include/have_perfschema.inc +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + use performance_schema; --vertical_results @@ -22,6 +25,7 @@ insert into t1 values (1),(2); use performance_schema; select name from mutex_instances where name like 'wait/synch/mutex/sql/LOCK_wsrep%' order by name; select name from cond_instances where name like 'wait/synch/cond/sql/COND_wsrep%' order by name; + # Whenever a node fails to apply an event on a slave node, the database server creates a # special binary log file of the event in the data directory. The naming convention the # node uses for the filename is GRA_*.log. @@ -55,4 +59,3 @@ CALL mtr.add_suppression("Slave SQL: Error 'Table 't2' already exists' on query" use test; drop table t1; drop table t2; - From 0018df2b553e302a97a85e3f6120c2f5126fe758 Mon Sep 17 00:00:00 2001 From: Daniele Sciascia Date: Tue, 5 Dec 2023 01:40:57 +0100 Subject: [PATCH 168/213] galera fix: Assertion `WSREP(thd)` failed in wsrep_restore_kill_after_commit() Wsrep_commit_empty happens too early when wsrep is disabled. Let the cleanup happen at end of statement. Signed-off-by: Julius Goryavsky --- sql/handler.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/handler.cc b/sql/handler.cc index 7e30968cb1d..22bc363e88c 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1660,7 +1660,7 @@ int ha_commit_trans(THD *thd, bool all) thd->m_transaction_psi= NULL; } #ifdef WITH_WSREP - if (wsrep_is_active(thd) && is_real_trans && !error) + if (WSREP(thd) && wsrep_is_active(thd) && is_real_trans && !error) wsrep_commit_empty(thd, all); #endif /* WITH_WSREP */ From bcb87f5ccb554d755d1ff3e548d911bba893849b Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Mon, 27 Jan 2025 23:07:23 +0100 Subject: [PATCH 169/213] fix for galera_query_cache_invalidate test results --- mysql-test/suite/galera/r/galera_query_cache_invalidate.result | 1 - mysql-test/suite/galera/t/galera_query_cache_invalidate.test | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/galera/r/galera_query_cache_invalidate.result b/mysql-test/suite/galera/r/galera_query_cache_invalidate.result index 078920da3f2..b45f8ee01b7 100644 --- a/mysql-test/suite/galera/r/galera_query_cache_invalidate.result +++ b/mysql-test/suite/galera/r/galera_query_cache_invalidate.result @@ -7,7 +7,6 @@ call mtr.add_suppression("WSREP: Ignoring server id .* for non bootstrap node"); connection node_4; call mtr.add_suppression("WSREP: Ignoring server id .* for non bootstrap node"); connection node_3; -CHANGE MASTER TO master_host='127.0.0.1', master_user='root', master_port=NODE_MYPORT_1, master_use_gtid=current_pos;; START SLAVE; include/wait_for_slave_to_start.inc connection node_1; diff --git a/mysql-test/suite/galera/t/galera_query_cache_invalidate.test b/mysql-test/suite/galera/t/galera_query_cache_invalidate.test index 67069577011..b5560c54253 100644 --- a/mysql-test/suite/galera/t/galera_query_cache_invalidate.test +++ b/mysql-test/suite/galera/t/galera_query_cache_invalidate.test @@ -28,8 +28,9 @@ call mtr.add_suppression("WSREP: Ignoring server id .* for non bootstrap node"); --connection node_3 ---replace_result $NODE_MYPORT_1 NODE_MYPORT_1 +--disable_query_log --eval CHANGE MASTER TO master_host='127.0.0.1', master_user='root', MASTER_PORT=$NODE_MYPORT_1, master_use_gtid=current_pos +--enable_query_log START SLAVE; --source include/wait_for_slave_to_start.inc From b8b77177c27412777fe1763f28b344a3a260741a Mon Sep 17 00:00:00 2001 From: Dave Gosselin Date: Fri, 24 Jan 2025 08:21:48 -0500 Subject: [PATCH 170/213] MDEV-35964 fix cast warnings on mac in mysql_file.h Cast create_flags to mode_t when passing to my_create and my_create_with_symlink --- include/mysql/psi/mysql_file.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mysql/psi/mysql_file.h b/include/mysql/psi/mysql_file.h index fd3b29cc5c9..096815ed02d 100644 --- a/include/mysql/psi/mysql_file.h +++ b/include/mysql/psi/mysql_file.h @@ -1018,7 +1018,7 @@ inline_mysql_file_create( #ifdef HAVE_PSI_FILE_INTERFACE PSI_file_key key, const char *src_file, uint src_line, #endif - const char *filename, int create_flags, int access_flags, myf myFlags) + const char *filename, mode_t create_flags, int access_flags, myf myFlags) { File file; #ifdef HAVE_PSI_FILE_INTERFACE @@ -1344,7 +1344,7 @@ inline_mysql_file_create_with_symlink( #ifdef HAVE_PSI_FILE_INTERFACE PSI_file_key key, const char *src_file, uint src_line, #endif - const char *linkname, const char *filename, int create_flags, + const char *linkname, const char *filename, mode_t create_flags, int access_flags, myf flags) { File file; From f6e00abda0c786d1834eb1b5da81f05211ec3769 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Tue, 28 Jan 2025 11:56:35 +0530 Subject: [PATCH 171/213] MDEV-35169 ALTER TABLE...IMPORT TABLESPACE does not work with INDEX DESC Problem: ======= - Import tablespace fails to check the index fields descending property while matching the schema given in cfg file with the table schema. Fix: === row_quiesce_write_index_fields(): Write the descending property of the field into field fixed length field. Since the field fixed length uses only 10 bits, InnoDB can use 0th bit of the field fixed length to store the descending field property. row_import_cfg_read_index_fields(): Read the field descending information from field fixed length. --- mysql-test/suite/innodb/r/import_cfg.result | 67 +++++++++++++++ .../suite/innodb/r/innodb-wl5522-debug.result | 10 --- mysql-test/suite/innodb/t/import_cfg.test | 83 +++++++++++++++++++ .../suite/innodb/t/innodb-wl5522-debug.test | 16 ---- storage/innobase/row/row0import.cc | 16 +++- storage/innobase/row/row0quiesce.cc | 33 +++----- 6 files changed, 178 insertions(+), 47 deletions(-) create mode 100644 mysql-test/suite/innodb/r/import_cfg.result create mode 100644 mysql-test/suite/innodb/t/import_cfg.test diff --git a/mysql-test/suite/innodb/r/import_cfg.result b/mysql-test/suite/innodb/r/import_cfg.result new file mode 100644 index 00000000000..163252c4dac --- /dev/null +++ b/mysql-test/suite/innodb/r/import_cfg.result @@ -0,0 +1,67 @@ +# +# MDEV-35169 ALTER TABLE...IMPORT TABLESPACE does not +# work with INDEX DESC +# +# prepare cfg for primary key with desc column +create table t1 (pk int, a int, primary key(pk desc)) engine=InnoDB; +insert into t1 values (1,10),(2,20),(3,15); +flush table t1 for export; +unlock tables; +drop table t1; +# prepare cfg for secondary index with desc column +create table t1 (pk int primary key, a int,key(a desc)) engine=InnoDB; +insert into t1 values (1,10),(2,20),(3,15); +flush table t1 for export; +unlock tables; +drop table t1; +# prepare cfg for secondary index with ascending column +create table t1 (pk int primary key, a int, key(a)) engine=InnoDB; +insert into t1 values (1,10),(2,20),(3,15); +flush table t1 for export; +unlock tables; +drop table t1; +# Import desc tablespace into desc frm +# Import into table with desc primary key column +create table t1 (pk int, a int, primary key(pk desc)) engine=InnoDB; +alter table t1 discard tablespace; +alter table t1 import tablespace; +check table t1 extended; +Table Op Msg_type Msg_text +test.t1 check status OK +drop table t1; +# Import into table with desc secondary index +create table t1 (pk int primary key, a int, key(a desc))engine=InnoDB; +alter table t1 discard tablespace; +alter table t1 import tablespace; +check table t1 extended; +Table Op Msg_type Msg_text +test.t1 check status OK +drop table t1; +# Import asc tablespace into desc frm +create table t1 (pk int primary key, a int, key(a desc))engine=InnoDB; +alter table t1 discard tablespace; +alter table t1 import tablespace; +ERROR HY000: Schema mismatch (Index a field a is DESC which does not match with .cfg file) +check table t1 extended; +Table Op Msg_type Msg_text +test.t1 check Error Tablespace has been discarded for table `t1` +test.t1 check error Corrupt +drop table t1; +# Import desc tablespace into asc frm +create table t1 (pk int primary key, a int, key(a)) engine=InnoDB; +alter table t1 discard tablespace; +alter table t1 import tablespace; +ERROR HY000: Schema mismatch (Index a field a is ASC which does not match with .cfg file) +check table t1 extended; +Table Op Msg_type Msg_text +test.t1 check Error Tablespace has been discarded for table `t1` +test.t1 check error Corrupt +drop table t1; +# Import asc tablespace into asc frm +create table t1 (pk int primary key, a int, key(a)) engine=InnoDB; +alter table t1 discard tablespace; +alter table t1 import tablespace; +check table t1 extended; +Table Op Msg_type Msg_text +test.t1 check status OK +drop table t1; diff --git a/mysql-test/suite/innodb/r/innodb-wl5522-debug.result b/mysql-test/suite/innodb/r/innodb-wl5522-debug.result index 18819087e4a..ab62c03b110 100644 --- a/mysql-test/suite/innodb/r/innodb-wl5522-debug.result +++ b/mysql-test/suite/innodb/r/innodb-wl5522-debug.result @@ -158,16 +158,6 @@ SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE t1; CREATE TABLE t1 (c1 INT) ENGINE = Innodb; INSERT INTO t1 VALUES (1); -SET SESSION debug_dbug="+d,ib_export_io_write_failure_9"; -FLUSH TABLES t1 FOR EXPORT; -Warnings: -Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flush() failed -Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flose() failed -UNLOCK TABLES; -SET SESSION debug_dbug=@saved_debug_dbug; -DROP TABLE t1; -CREATE TABLE t1 (c1 INT) ENGINE = Innodb; -INSERT INTO t1 VALUES (1); SET SESSION debug_dbug="+d,ib_export_io_write_failure_10"; FLUSH TABLES t1 FOR EXPORT; Warnings: diff --git a/mysql-test/suite/innodb/t/import_cfg.test b/mysql-test/suite/innodb/t/import_cfg.test new file mode 100644 index 00000000000..297de767d5d --- /dev/null +++ b/mysql-test/suite/innodb/t/import_cfg.test @@ -0,0 +1,83 @@ +--source include/have_innodb.inc +--let $datadir= `select @@datadir` + +--echo # +--echo # MDEV-35169 ALTER TABLE...IMPORT TABLESPACE does not +--echo # work with INDEX DESC +--echo # + +--echo # prepare cfg for primary key with desc column +create table t1 (pk int, a int, primary key(pk desc)) engine=InnoDB; +insert into t1 values (1,10),(2,20),(3,15); +flush table t1 for export; +--copy_file $datadir/test/t1.ibd $datadir/test/t1_pk.ibd.desc +--copy_file $datadir/test/t1.cfg $datadir/test/t1_pk.cfg.desc +unlock tables; +drop table t1; + +--echo # prepare cfg for secondary index with desc column +create table t1 (pk int primary key, a int,key(a desc)) engine=InnoDB; +insert into t1 values (1,10),(2,20),(3,15); +flush table t1 for export; +--copy_file $datadir/test/t1.ibd $datadir/test/t1.ibd.desc +--copy_file $datadir/test/t1.cfg $datadir/test/t1.cfg.desc +unlock tables; +drop table t1; + +--echo # prepare cfg for secondary index with ascending column +create table t1 (pk int primary key, a int, key(a)) engine=InnoDB; +insert into t1 values (1,10),(2,20),(3,15); +flush table t1 for export; +--copy_file $datadir/test/t1.ibd $datadir/test/t1.ibd.asc +--copy_file $datadir/test/t1.cfg $datadir/test/t1.cfg.asc +unlock tables; +drop table t1; + +--echo # Import desc tablespace into desc frm + +--echo # Import into table with desc primary key column +create table t1 (pk int, a int, primary key(pk desc)) engine=InnoDB; +alter table t1 discard tablespace; +--copy_file $datadir/test/t1_pk.ibd.desc $datadir/test/t1.ibd +--copy_file $datadir/test/t1_pk.cfg.desc $datadir/test/t1.cfg +alter table t1 import tablespace; +check table t1 extended; +drop table t1; + +--echo # Import into table with desc secondary index +create table t1 (pk int primary key, a int, key(a desc))engine=InnoDB; +alter table t1 discard tablespace; +--copy_file $datadir/test/t1.ibd.desc $datadir/test/t1.ibd +--copy_file $datadir/test/t1.cfg.desc $datadir/test/t1.cfg +alter table t1 import tablespace; +check table t1 extended; +drop table t1; + +--echo # Import asc tablespace into desc frm +create table t1 (pk int primary key, a int, key(a desc))engine=InnoDB; +alter table t1 discard tablespace; +--copy_file $datadir/test/t1.ibd.asc $datadir/test/t1.ibd +--copy_file $datadir/test/t1.cfg.asc $datadir/test/t1.cfg +--error ER_TABLE_SCHEMA_MISMATCH +alter table t1 import tablespace; +check table t1 extended; +drop table t1; + +--echo # Import desc tablespace into asc frm +create table t1 (pk int primary key, a int, key(a)) engine=InnoDB; +alter table t1 discard tablespace; +--copy_file $datadir/test/t1.ibd.desc $datadir/test/t1.ibd +--copy_file $datadir/test/t1.cfg.desc $datadir/test/t1.cfg +--error ER_TABLE_SCHEMA_MISMATCH +alter table t1 import tablespace; +check table t1 extended; +drop table t1; + +--echo # Import asc tablespace into asc frm +create table t1 (pk int primary key, a int, key(a)) engine=InnoDB; +alter table t1 discard tablespace; +--copy_file $datadir/test/t1.ibd.asc $datadir/test/t1.ibd +--copy_file $datadir/test/t1.cfg.asc $datadir/test/t1.cfg +alter table t1 import tablespace; +check table t1 extended; +drop table t1; diff --git a/mysql-test/suite/innodb/t/innodb-wl5522-debug.test b/mysql-test/suite/innodb/t/innodb-wl5522-debug.test index 68330692390..44a7b4acf5f 100644 --- a/mysql-test/suite/innodb/t/innodb-wl5522-debug.test +++ b/mysql-test/suite/innodb/t/innodb-wl5522-debug.test @@ -280,22 +280,6 @@ SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE t1; -CREATE TABLE t1 (c1 INT) ENGINE = Innodb; -INSERT INTO t1 VALUES (1); - -SET SESSION debug_dbug="+d,ib_export_io_write_failure_9"; - ---replace_regex /, .*\).*t1.cfg/, Bad file descriptor) t1.cfg/ - -FLUSH TABLES t1 FOR EXPORT; - -UNLOCK TABLES; - -SET SESSION debug_dbug=@saved_debug_dbug; - -DROP TABLE t1; - - CREATE TABLE t1 (c1 INT) ENGINE = Innodb; INSERT INTO t1 VALUES (1); diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 7035c33ccf4..4338ad034b1 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -1213,6 +1213,16 @@ row_import::match_index_columns( err = DB_ERROR; } + + if (cfg_field->descending != field->descending) { + ib_errf(thd, IB_LOG_LEVEL_ERROR, + ER_TABLE_SCHEMA_MISMATCH, + "Index %s field %s is %s which does " + "not match with .cfg file", + index->name(), field->name(), + field->descending ? "DESC" : "ASC"); + err = DB_ERROR; + } } return(err); @@ -2557,7 +2567,11 @@ row_import_cfg_read_index_fields( field->prefix_len = mach_read_from_4(ptr) & ((1U << 12) - 1); ptr += sizeof(ib_uint32_t); - field->fixed_len = mach_read_from_4(ptr) & ((1U << 10) - 1); + uint32_t fixed_len = mach_read_from_4(ptr); + + field->descending = bool(fixed_len >> 31); + + field->fixed_len = fixed_len & ((1U << 10) - 1); ptr += sizeof(ib_uint32_t); /* Include the NUL byte in the length. */ diff --git a/storage/innobase/row/row0quiesce.cc b/storage/innobase/row/row0quiesce.cc index 057b20c77bd..9fe30709824 100644 --- a/storage/innobase/row/row0quiesce.cc +++ b/storage/innobase/row/row0quiesce.cc @@ -47,45 +47,38 @@ row_quiesce_write_index_fields( FILE* file, /*!< in: file to write to */ THD* thd) /*!< in/out: session */ { - byte row[sizeof(ib_uint32_t) * 2]; + byte row[sizeof(ib_uint32_t) * 3]; for (ulint i = 0; i < index->n_fields; ++i) { byte* ptr = row; const dict_field_t* field = &index->fields[i]; mach_write_to_4(ptr, field->prefix_len); - ptr += sizeof(ib_uint32_t); + ptr += 4; - mach_write_to_4(ptr, field->fixed_len); - - DBUG_EXECUTE_IF("ib_export_io_write_failure_9", - close(fileno(file));); - - if (fwrite(row, 1, sizeof(row), file) != sizeof(row)) { - - ib_senderrf( - thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR, - (ulong) errno, strerror(errno), - "while writing index fields."); - - return(DB_IO_ERROR); - } + /* Since maximum fixed length can be + DICT_ANTELOPE_MAX_INDEX_COL_LEN, InnoDB + can use the 0th bit to store the + field descending information */ + mach_write_to_4(ptr, field->fixed_len + | uint32_t(field->descending) << 31); + ptr += 4; const char* field_name = field->name ? field->name : ""; /* Include the NUL byte in the length. */ - ib_uint32_t len = static_cast(strlen(field_name) + 1); - mach_write_to_4(row, len); + uint32_t len = uint32_t(strlen(field_name) + 1); + mach_write_to_4(ptr, len); DBUG_EXECUTE_IF("ib_export_io_write_failure_10", close(fileno(file));); - if (fwrite(row, 1, sizeof(len), file) != sizeof(len) + if (fwrite(row, 1, sizeof(row), file) != sizeof(row) || fwrite(field_name, 1, len, file) != len) { ib_senderrf( thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR, (ulong) errno, strerror(errno), - "while writing index column."); + "while writing index fields."); return(DB_IO_ERROR); } From 9a0ac0cdf7814241dbc8f3d95fa045f9fa6358e6 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 24 Jan 2025 13:48:12 +0100 Subject: [PATCH 172/213] MDEV-35911 Assertion `marked_for_write_or_computed()' failed in bool Field_new_decimal::store_value(const my_decimal*, int*) disable the assert. also, use the same check for check_that_all_fields_are_given_values() as it's used in not_null_fields_have_null_values() - to avoid issuing the same warning twice. --- .../{trigger_null-8605.result => trigger_null.result} | 11 +++++++++++ .../{trigger_null-8605.test => trigger_null.test} | 10 ++++++++++ sql/field_conv.cc | 2 ++ sql/sql_insert.cc | 3 +-- 4 files changed, 24 insertions(+), 2 deletions(-) rename mysql-test/main/{trigger_null-8605.result => trigger_null.result} (96%) rename mysql-test/main/{trigger_null-8605.test => trigger_null.test} (97%) diff --git a/mysql-test/main/trigger_null-8605.result b/mysql-test/main/trigger_null.result similarity index 96% rename from mysql-test/main/trigger_null-8605.result rename to mysql-test/main/trigger_null.result index 6480fbf9a7e..91bae7e3b0e 100644 --- a/mysql-test/main/trigger_null-8605.result +++ b/mysql-test/main/trigger_null.result @@ -388,4 +388,15 @@ id rate 3 15 4 5 drop table t1; +# +# MDEV-35911 Assertion `marked_for_write_or_computed()' failed in bool Field_new_decimal::store_value(const my_decimal*, int*) +# +set sql_mode=''; +create table t1 (c fixed,c2 binary (1),c5 fixed not null); +create trigger tr1 before update on t1 for each row set @a=0; +insert into t1 (c) values (1); +Warnings: +Warning 1364 Field 'c5' doesn't have a default value +drop table t1; +set sql_mode=default; # End of 10.5 tests diff --git a/mysql-test/main/trigger_null-8605.test b/mysql-test/main/trigger_null.test similarity index 97% rename from mysql-test/main/trigger_null-8605.test rename to mysql-test/main/trigger_null.test index e33f17151bf..d3b74af49b3 100644 --- a/mysql-test/main/trigger_null-8605.test +++ b/mysql-test/main/trigger_null.test @@ -415,4 +415,14 @@ select * from t1; drop table t1; +--echo # +--echo # MDEV-35911 Assertion `marked_for_write_or_computed()' failed in bool Field_new_decimal::store_value(const my_decimal*, int*) +--echo # +set sql_mode=''; +create table t1 (c fixed,c2 binary (1),c5 fixed not null); +create trigger tr1 before update on t1 for each row set @a=0; +insert into t1 (c) values (1); +drop table t1; +set sql_mode=default; + --echo # End of 10.5 tests diff --git a/sql/field_conv.cc b/sql/field_conv.cc index dcbb6b39a31..a8c528d07fd 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -172,7 +172,9 @@ int convert_null_to_field_value_or_error(Field *field, uint err) return 0; } + MY_BITMAP *old_map= dbug_tmp_use_all_columns(field->table, &field->table->write_set); field->reset(); // Note: we ignore any potential failure of reset() here. + dbug_tmp_restore_column_map(&field->table->write_set, old_map); if (field == field->table->next_number_field) { diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 0182ca0ee1b..26adcf3d228 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -950,8 +950,7 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list, if (fields.elements || !value_count || table_list->view != 0) { - if (table->triggers && - table->triggers->has_triggers(TRG_EVENT_INSERT, TRG_ACTION_BEFORE)) + if (table->field != table->field_to_fill()) { /* BEFORE INSERT triggers exist, the check will be done later, per row */ } From caec03cb79ab5b39b9cf7bce784a4f8865234ebd Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 23 Jan 2025 23:32:02 +0100 Subject: [PATCH 173/213] MDEV-35907 debian-start script fails when using non-standard socket path consistently use --defaults-extra-file for all command-line tools --- debian/additions/debian-start | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/debian/additions/debian-start b/debian/additions/debian-start index 2a8b61ddaff..27483c3a87c 100755 --- a/debian/additions/debian-start +++ b/debian/additions/debian-start @@ -17,11 +17,11 @@ if [ -f /etc/default/mariadb ]; then . /etc/default/mariadb fi -MARIADB="/usr/bin/mariadb --defaults-file=/etc/mysql/debian.cnf" -MYADMIN="/usr/bin/mariadb-admin --defaults-file=/etc/mysql/debian.cnf" +MARIADB="/usr/bin/mariadb --defaults-extra-file=/etc/mysql/debian.cnf" +MYADMIN="/usr/bin/mariadb-admin --defaults-extra-file=/etc/mysql/debian.cnf" # Don't run full mariadb-upgrade on every server restart, use --version-check to do it only once MYUPGRADE="/usr/bin/mariadb-upgrade --defaults-extra-file=/etc/mysql/debian.cnf --version-check --silent" -MYCHECK="/usr/bin/mariadb-check --defaults-file=/etc/mysql/debian.cnf" +MYCHECK="/usr/bin/mariadb-check --defaults-extra-file=/etc/mysql/debian.cnf" MYCHECK_SUBJECT="WARNING: mariadb-check has found corrupt tables" MYCHECK_PARAMS="--all-databases --fast --silent" MYCHECK_RCPT="${MYCHECK_RCPT:-root}" From c1933b46e4ca2722951fa6772a6964582da14826 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 25 Jan 2025 09:51:20 +0100 Subject: [PATCH 174/213] MDEV-33285 make the test deterministic need to clear old signals before waiting for new signals with the same name --- mysql-test/main/kill_debug.result | 1 + mysql-test/main/kill_debug.test | 1 + 2 files changed, 2 insertions(+) diff --git a/mysql-test/main/kill_debug.result b/mysql-test/main/kill_debug.result index 40047ef7eb7..1b61b8ae885 100644 --- a/mysql-test/main/kill_debug.result +++ b/mysql-test/main/kill_debug.result @@ -252,6 +252,7 @@ KILL QUERY id; SET debug_sync='now SIGNAL go'; connection default; ERROR 70100: Query execution was interrupted +SET debug_sync='RESET'; SET debug_sync='mysql_checksum_table_before_calculate_checksum SIGNAL parked WAIT_FOR go'; CHECKSUM TABLE t1; connection con1; diff --git a/mysql-test/main/kill_debug.test b/mysql-test/main/kill_debug.test index 0285fb48bd2..0fb6672cd60 100644 --- a/mysql-test/main/kill_debug.test +++ b/mysql-test/main/kill_debug.test @@ -338,6 +338,7 @@ connection default; error ER_QUERY_INTERRUPTED; reap; +SET debug_sync='RESET'; SET debug_sync='mysql_checksum_table_before_calculate_checksum SIGNAL parked WAIT_FOR go'; send CHECKSUM TABLE t1; connection con1; From 66cf3c6974c4a295687a78dc7bf5050db8bdbf2f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 25 Jan 2025 14:57:16 +0100 Subject: [PATCH 175/213] MDEV-35612 fix for system-versioning only ignore fully invisible fields --- mysql-test/main/partition_exchange.result | 8 ++++++++ mysql-test/main/partition_exchange.test | 14 +++++++++++--- sql/sql_table.cc | 4 ++-- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/mysql-test/main/partition_exchange.result b/mysql-test/main/partition_exchange.result index c9169c5c818..b856843877b 100644 --- a/mysql-test/main/partition_exchange.result +++ b/mysql-test/main/partition_exchange.result @@ -1353,3 +1353,11 @@ ERROR HY000: Tables have different definitions create or replace table tp (a int, b text, unique (b), unique(a, b)); alter table t exchange partition p0 with table tp; drop table t, tp; +create table t (a int, b int) with system versioning partition by list (a) (partition p0 values in (1,2)); +create table tp (a int, b int); +alter table t exchange partition p0 with table tp; +ERROR HY000: Tables have different definitions +create or replace table tp (a int, b int) with system versioning; +alter table t exchange partition p0 with table tp; +drop table t, tp; +# End of 10.5 tests diff --git a/mysql-test/main/partition_exchange.test b/mysql-test/main/partition_exchange.test index 767f682ea0d..5439f6411ab 100644 --- a/mysql-test/main/partition_exchange.test +++ b/mysql-test/main/partition_exchange.test @@ -594,9 +594,17 @@ create table t (a int, b text, unique (b), unique(a, b)) partition by list (a) ( create table tp (a int, b text, c int invisible, unique (b), unique(a, b)); --error ER_TABLES_DIFFERENT_METADATA alter table t exchange partition p0 with table tp; - create or replace table tp (a int, b text, unique (b), unique(a, b)); alter table t exchange partition p0 with table tp; - -# cleanup drop table t, tp; + +# same for system versioning: +create table t (a int, b int) with system versioning partition by list (a) (partition p0 values in (1,2)); +create table tp (a int, b int); # without system versioning +--error ER_TABLES_DIFFERENT_METADATA +alter table t exchange partition p0 with table tp; +create or replace table tp (a int, b int) with system versioning; +alter table t exchange partition p0 with table tp; +drop table t, tp; + +--echo # End of 10.5 tests diff --git a/sql/sql_table.cc b/sql/sql_table.cc index c7ee3f83647..428b406c58c 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -7954,10 +7954,10 @@ bool mysql_compare_tables(TABLE *table, Alter_info *alter_info, /* Some very basic checks. */ uint fields= table->s->fields; - /* There is no field count on system-invisible fields, count them. */ + /* There is no field count on fully-invisible fields, count them. */ for (Field **f_ptr= table->field; *f_ptr; f_ptr++) { - if ((*f_ptr)->invisible >= INVISIBLE_SYSTEM) + if ((*f_ptr)->invisible >= INVISIBLE_FULL) fields--; } From fafa10dbc4f59b90f08fa67363e3c96aa2e34db3 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 23 Jan 2025 12:21:32 +0100 Subject: [PATCH 176/213] update HeidiSQL to 12.10 also, switch to https --- win/packaging/heidisql.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/win/packaging/heidisql.cmake b/win/packaging/heidisql.cmake index f745eeb060b..157e5517594 100644 --- a/win/packaging/heidisql.cmake +++ b/win/packaging/heidisql.cmake @@ -1,6 +1,6 @@ -SET(HEIDISQL_BASE_NAME "HeidiSQL_12.8_32_Portable") +SET(HEIDISQL_BASE_NAME "HeidiSQL_12.10_32_Portable") SET(HEIDISQL_ZIP "${HEIDISQL_BASE_NAME}.zip") -SET(HEIDISQL_URL "http://www.heidisql.com/downloads/releases/${HEIDISQL_ZIP}") +SET(HEIDISQL_URL "https://www.heidisql.com/downloads/releases/${HEIDISQL_ZIP}") SET(HEIDISQL_DOWNLOAD_DIR ${THIRD_PARTY_DOWNLOAD_LOCATION}/${HEIDISQL_BASE_NAME}) IF(NOT EXISTS ${HEIDISQL_DOWNLOAD_DIR}/${HEIDISQL_ZIP}) From ffff702623e5a9d298161f5ea2e72109e301c384 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 23 Jan 2025 12:14:31 +0100 Subject: [PATCH 177/213] C/C 3.1.27 --- libmariadb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmariadb b/libmariadb index 9a40079349c..7d930974c0c 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit 9a40079349c44399fb8b620084862abed9c34052 +Subproject commit 7d930974c0c5588a8872f30b83d6bc429106f825 From 1fec4fc4f81b2a16ec887855ef3a1d05387bb9ea Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 14 Nov 2022 20:46:42 +0100 Subject: [PATCH 178/213] more C API methods in the service_sql for columnstore --- include/mariadb_capi_rename.h | 3 +++ include/mysql/plugin_audit.h.pp | 7 ++++-- include/mysql/plugin_auth.h.pp | 7 ++++-- include/mysql/plugin_data_type.h.pp | 7 ++++-- include/mysql/plugin_encryption.h.pp | 7 ++++-- include/mysql/plugin_ftparser.h.pp | 7 ++++-- include/mysql/plugin_function.h.pp | 7 ++++-- include/mysql/plugin_password_validation.h.pp | 7 ++++-- include/mysql/service_sql.h | 14 +++++++----- include/service_versions.h | 2 +- libmysqld/libmysql.c | 19 ---------------- sql-common/client.c | 22 +++++++++++++++++++ sql/sql_plugin_services.inl | 3 +++ 13 files changed, 73 insertions(+), 39 deletions(-) diff --git a/include/mariadb_capi_rename.h b/include/mariadb_capi_rename.h index 58e16fdc0c0..4f6750d4664 100644 --- a/include/mariadb_capi_rename.h +++ b/include/mariadb_capi_rename.h @@ -37,16 +37,19 @@ #define mysql_free_result MARIADB_ADD_PREFIX(mysql_free_result) #define mysql_get_socket MARIADB_ADD_PREFIX(mysql_get_socket) #define mysql_set_character_set MARIADB_ADD_PREFIX(mysql_set_character_set) +#define mysql_real_escape_string MARIADB_ADD_PREFIX(mysql_real_escape_string) #define mysql_get_server_version MARIADB_ADD_PREFIX(mysql_get_server_version) #define mysql_error MARIADB_ADD_PREFIX(mysql_error) #define mysql_errno MARIADB_ADD_PREFIX(mysql_errno) #define mysql_num_fields MARIADB_ADD_PREFIX(mysql_num_fields) #define mysql_num_rows MARIADB_ADD_PREFIX(mysql_num_rows) #define mysql_options4 MARIADB_ADD_PREFIX(mysql_options4) +#define mysql_fetch_fields MARIADB_ADD_PREFIX(mysql_fetch_fields) #define mysql_fetch_lengths MARIADB_ADD_PREFIX(mysql_fetch_lengths) #define mysql_fetch_row MARIADB_ADD_PREFIX(mysql_fetch_row) #define mysql_affected_rows MARIADB_ADD_PREFIX(mysql_affected_rows) #define mysql_store_result MARIADB_ADD_PREFIX(mysql_store_result) +#define mysql_use_result MARIADB_ADD_PREFIX(mysql_use_result) #define mysql_select_db MARIADB_ADD_PREFIX(mysql_select_db) #define mysql_get_ssl_cipher MARIADB_ADD_PREFIX(mysql_get_ssl_cipher) #define mysql_ssl_set MARIADB_ADD_PREFIX(mysql_ssl_set) diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp index 6e3e003ad4d..07d3148ab8b 100644 --- a/include/mysql/plugin_audit.h.pp +++ b/include/mysql/plugin_audit.h.pp @@ -487,9 +487,12 @@ extern struct sql_service_st { int (STDCALL *mysql_set_character_set_func)(MYSQL *mysql, const char *cs_name); unsigned int (STDCALL *mysql_num_fields_func)(MYSQL_RES *res); int (STDCALL *mysql_select_db_func)(MYSQL *mysql, const char *db); + MYSQL_RES *(STDCALL *mysql_use_result_func)(MYSQL *mysql); + MYSQL_FIELD *(STDCALL *mysql_fetch_fields_func)(MYSQL_RES *res); + unsigned long (STDCALL *mysql_real_escape_string_func)(MYSQL *mysql, char *to, + const char *from, unsigned long length); my_bool (STDCALL *mysql_ssl_set_func)(MYSQL *mysql, const char *key, - const char *cert, const char *ca, - const char *capath, const char *cipher); + const char *cert, const char *ca, const char *capath, const char *cipher); } *sql_service; MYSQL *mysql_real_connect_local(MYSQL *mysql); } diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp index 7b5ce25a975..a291fcc7712 100644 --- a/include/mysql/plugin_auth.h.pp +++ b/include/mysql/plugin_auth.h.pp @@ -487,9 +487,12 @@ extern struct sql_service_st { int (STDCALL *mysql_set_character_set_func)(MYSQL *mysql, const char *cs_name); unsigned int (STDCALL *mysql_num_fields_func)(MYSQL_RES *res); int (STDCALL *mysql_select_db_func)(MYSQL *mysql, const char *db); + MYSQL_RES *(STDCALL *mysql_use_result_func)(MYSQL *mysql); + MYSQL_FIELD *(STDCALL *mysql_fetch_fields_func)(MYSQL_RES *res); + unsigned long (STDCALL *mysql_real_escape_string_func)(MYSQL *mysql, char *to, + const char *from, unsigned long length); my_bool (STDCALL *mysql_ssl_set_func)(MYSQL *mysql, const char *key, - const char *cert, const char *ca, - const char *capath, const char *cipher); + const char *cert, const char *ca, const char *capath, const char *cipher); } *sql_service; MYSQL *mysql_real_connect_local(MYSQL *mysql); } diff --git a/include/mysql/plugin_data_type.h.pp b/include/mysql/plugin_data_type.h.pp index 290dafcccdb..2065abdc714 100644 --- a/include/mysql/plugin_data_type.h.pp +++ b/include/mysql/plugin_data_type.h.pp @@ -487,9 +487,12 @@ extern struct sql_service_st { int (STDCALL *mysql_set_character_set_func)(MYSQL *mysql, const char *cs_name); unsigned int (STDCALL *mysql_num_fields_func)(MYSQL_RES *res); int (STDCALL *mysql_select_db_func)(MYSQL *mysql, const char *db); + MYSQL_RES *(STDCALL *mysql_use_result_func)(MYSQL *mysql); + MYSQL_FIELD *(STDCALL *mysql_fetch_fields_func)(MYSQL_RES *res); + unsigned long (STDCALL *mysql_real_escape_string_func)(MYSQL *mysql, char *to, + const char *from, unsigned long length); my_bool (STDCALL *mysql_ssl_set_func)(MYSQL *mysql, const char *key, - const char *cert, const char *ca, - const char *capath, const char *cipher); + const char *cert, const char *ca, const char *capath, const char *cipher); } *sql_service; MYSQL *mysql_real_connect_local(MYSQL *mysql); } diff --git a/include/mysql/plugin_encryption.h.pp b/include/mysql/plugin_encryption.h.pp index d43cc1ef0df..866dbe4ad35 100644 --- a/include/mysql/plugin_encryption.h.pp +++ b/include/mysql/plugin_encryption.h.pp @@ -487,9 +487,12 @@ extern struct sql_service_st { int (STDCALL *mysql_set_character_set_func)(MYSQL *mysql, const char *cs_name); unsigned int (STDCALL *mysql_num_fields_func)(MYSQL_RES *res); int (STDCALL *mysql_select_db_func)(MYSQL *mysql, const char *db); + MYSQL_RES *(STDCALL *mysql_use_result_func)(MYSQL *mysql); + MYSQL_FIELD *(STDCALL *mysql_fetch_fields_func)(MYSQL_RES *res); + unsigned long (STDCALL *mysql_real_escape_string_func)(MYSQL *mysql, char *to, + const char *from, unsigned long length); my_bool (STDCALL *mysql_ssl_set_func)(MYSQL *mysql, const char *key, - const char *cert, const char *ca, - const char *capath, const char *cipher); + const char *cert, const char *ca, const char *capath, const char *cipher); } *sql_service; MYSQL *mysql_real_connect_local(MYSQL *mysql); } diff --git a/include/mysql/plugin_ftparser.h.pp b/include/mysql/plugin_ftparser.h.pp index 0dea5f94a97..18f8f5829e0 100644 --- a/include/mysql/plugin_ftparser.h.pp +++ b/include/mysql/plugin_ftparser.h.pp @@ -487,9 +487,12 @@ extern struct sql_service_st { int (STDCALL *mysql_set_character_set_func)(MYSQL *mysql, const char *cs_name); unsigned int (STDCALL *mysql_num_fields_func)(MYSQL_RES *res); int (STDCALL *mysql_select_db_func)(MYSQL *mysql, const char *db); + MYSQL_RES *(STDCALL *mysql_use_result_func)(MYSQL *mysql); + MYSQL_FIELD *(STDCALL *mysql_fetch_fields_func)(MYSQL_RES *res); + unsigned long (STDCALL *mysql_real_escape_string_func)(MYSQL *mysql, char *to, + const char *from, unsigned long length); my_bool (STDCALL *mysql_ssl_set_func)(MYSQL *mysql, const char *key, - const char *cert, const char *ca, - const char *capath, const char *cipher); + const char *cert, const char *ca, const char *capath, const char *cipher); } *sql_service; MYSQL *mysql_real_connect_local(MYSQL *mysql); } diff --git a/include/mysql/plugin_function.h.pp b/include/mysql/plugin_function.h.pp index 2e05f2720d5..6200cccab3d 100644 --- a/include/mysql/plugin_function.h.pp +++ b/include/mysql/plugin_function.h.pp @@ -487,9 +487,12 @@ extern struct sql_service_st { int (STDCALL *mysql_set_character_set_func)(MYSQL *mysql, const char *cs_name); unsigned int (STDCALL *mysql_num_fields_func)(MYSQL_RES *res); int (STDCALL *mysql_select_db_func)(MYSQL *mysql, const char *db); + MYSQL_RES *(STDCALL *mysql_use_result_func)(MYSQL *mysql); + MYSQL_FIELD *(STDCALL *mysql_fetch_fields_func)(MYSQL_RES *res); + unsigned long (STDCALL *mysql_real_escape_string_func)(MYSQL *mysql, char *to, + const char *from, unsigned long length); my_bool (STDCALL *mysql_ssl_set_func)(MYSQL *mysql, const char *key, - const char *cert, const char *ca, - const char *capath, const char *cipher); + const char *cert, const char *ca, const char *capath, const char *cipher); } *sql_service; MYSQL *mysql_real_connect_local(MYSQL *mysql); } diff --git a/include/mysql/plugin_password_validation.h.pp b/include/mysql/plugin_password_validation.h.pp index 3f8f6210ecf..6f79f5a534c 100644 --- a/include/mysql/plugin_password_validation.h.pp +++ b/include/mysql/plugin_password_validation.h.pp @@ -487,9 +487,12 @@ extern struct sql_service_st { int (STDCALL *mysql_set_character_set_func)(MYSQL *mysql, const char *cs_name); unsigned int (STDCALL *mysql_num_fields_func)(MYSQL_RES *res); int (STDCALL *mysql_select_db_func)(MYSQL *mysql, const char *db); + MYSQL_RES *(STDCALL *mysql_use_result_func)(MYSQL *mysql); + MYSQL_FIELD *(STDCALL *mysql_fetch_fields_func)(MYSQL_RES *res); + unsigned long (STDCALL *mysql_real_escape_string_func)(MYSQL *mysql, char *to, + const char *from, unsigned long length); my_bool (STDCALL *mysql_ssl_set_func)(MYSQL *mysql, const char *key, - const char *cert, const char *ca, - const char *capath, const char *cipher); + const char *cert, const char *ca, const char *capath, const char *cipher); } *sql_service; MYSQL *mysql_real_connect_local(MYSQL *mysql); } diff --git a/include/mysql/service_sql.h b/include/mysql/service_sql.h index 0a3a2294fa1..a4a61cc0f47 100644 --- a/include/mysql/service_sql.h +++ b/include/mysql/service_sql.h @@ -68,9 +68,12 @@ extern struct sql_service_st { int (STDCALL *mysql_set_character_set_func)(MYSQL *mysql, const char *cs_name); unsigned int (STDCALL *mysql_num_fields_func)(MYSQL_RES *res); int (STDCALL *mysql_select_db_func)(MYSQL *mysql, const char *db); + MYSQL_RES *(STDCALL *mysql_use_result_func)(MYSQL *mysql); + MYSQL_FIELD *(STDCALL *mysql_fetch_fields_func)(MYSQL_RES *res); + unsigned long (STDCALL *mysql_real_escape_string_func)(MYSQL *mysql, char *to, + const char *from, unsigned long length); my_bool (STDCALL *mysql_ssl_set_func)(MYSQL *mysql, const char *key, - const char *cert, const char *ca, - const char *capath, const char *cipher); + const char *cert, const char *ca, const char *capath, const char *cipher); } *sql_service; #ifdef MYSQL_DYNAMIC_PLUGIN @@ -92,7 +95,10 @@ extern struct sql_service_st { #define mysql_set_character_set(M,C) sql_service->mysql_set_character_set_func(M,C) #define mysql_num_fields(R) sql_service->mysql_num_fields_func(R) #define mysql_select_db(M,D) sql_service->mysql_select_db_func(M,D) -#define mysql_ssl_set(M,K,C,A,P,H) sql_service->mysql_ssl_set_func(M,K,C,A,P,H) +#define mysql_use_result(M) sql_service->mysql_use_result_func(M) +#define mysql_fetch_fields(R) sql_service->mysql_fetch_fields_func(R) +#define mysql_real_escape_string(M,T,F,L) sql_service->mysql_real_escape_string_func(M,T,F,L) +#define mysql_ssl_set(M,K,C1,C2,C3,C4) sql_service->mysql_ssl_set_func(M,K,C1,C2,C3,C4) #else @@ -115,5 +121,3 @@ MYSQL *mysql_real_connect_local(MYSQL *mysql); #endif #endif /*MYSQL_SERVICE_SQL */ - - diff --git a/include/service_versions.h b/include/service_versions.h index cace4f37c69..af3e3d98785 100644 --- a/include/service_versions.h +++ b/include/service_versions.h @@ -43,6 +43,6 @@ #define VERSION_thd_wait 0x0100 #define VERSION_wsrep 0x0500 #define VERSION_json 0x0100 -#define VERSION_sql_service 0x0100 +#define VERSION_sql_service 0x0102 #define VERSION_thd_mdl 0x0100 #define VERSION_print_check_msg 0x0100 diff --git a/libmysqld/libmysql.c b/libmysqld/libmysql.c index 4fb5212d6e3..514a2c6e92d 100644 --- a/libmysqld/libmysql.c +++ b/libmysqld/libmysql.c @@ -1065,11 +1065,6 @@ MYSQL_FIELD * STDCALL mysql_fetch_field_direct(MYSQL_RES *res,uint fieldnr) return &(res)->fields[fieldnr]; } -MYSQL_FIELD * STDCALL mysql_fetch_fields(MYSQL_RES *res) -{ - return (res)->fields; -} - MYSQL_ROW_OFFSET STDCALL mysql_row_tell(MYSQL_RES *res) { return res->data_cursor; @@ -1213,15 +1208,6 @@ mysql_escape_string(char *to,const char *from,ulong length) return (uint) escape_string_for_mysql(default_charset_info, to, 0, from, length); } -ulong STDCALL -mysql_real_escape_string(MYSQL *mysql, char *to,const char *from, - ulong length) -{ - if (mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES) - return (uint) escape_quotes_for_mysql(mysql->charset, to, 0, from, length); - return (uint) escape_string_for_mysql(mysql->charset, to, 0, from, length); -} - void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name) { @@ -4936,11 +4922,6 @@ int STDCALL mysql_stmt_next_result(MYSQL_STMT *stmt) } -MYSQL_RES * STDCALL mysql_use_result(MYSQL *mysql) -{ - return (*mysql->methods->use_result)(mysql); -} - my_bool STDCALL mysql_read_query_result(MYSQL *mysql) { return (*mysql->methods->read_query_result)(mysql); diff --git a/sql-common/client.c b/sql-common/client.c index 476b655d6ef..b4120844920 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -4343,3 +4343,25 @@ int STDCALL mysql_cancel(MYSQL *mysql) return vio_shutdown(mysql->net.vio, SHUT_RDWR); return -1; } + + +MYSQL_RES *STDCALL mysql_use_result(MYSQL *mysql) +{ + return (*mysql->methods->use_result)(mysql); +} + + +MYSQL_FIELD *STDCALL mysql_fetch_fields(MYSQL_RES *res) +{ + return (res)->fields; +} + + +ulong STDCALL +mysql_real_escape_string(MYSQL *mysql, char *to,const char *from, + ulong length) +{ + if (mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES) + return (ulong) escape_quotes_for_mysql(mysql->charset, to, 0, from, length); + return (ulong) escape_string_for_mysql(mysql->charset, to, 0, from, length); +} diff --git a/sql/sql_plugin_services.inl b/sql/sql_plugin_services.inl index e560812260a..a0e9ecd8f4e 100644 --- a/sql/sql_plugin_services.inl +++ b/sql/sql_plugin_services.inl @@ -252,6 +252,9 @@ struct sql_service_st sql_service_handler= mysql_set_character_set, mysql_num_fields, mysql_select_db, + mysql_use_result, + mysql_fetch_fields, + mysql_real_escape_string, mysql_ssl_set }; From 7eded23be6597b4c485e8cad1538f2ae14541f91 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 23 Jan 2025 13:22:12 +0100 Subject: [PATCH 179/213] ColumnStore 5.6.9-1 --- storage/columnstore/columnstore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/columnstore/columnstore b/storage/columnstore/columnstore index f91c12c9df0..305fe27fa08 160000 --- a/storage/columnstore/columnstore +++ b/storage/columnstore/columnstore @@ -1 +1 @@ -Subproject commit f91c12c9df0597561b0d7f5cc6876e246d24763b +Subproject commit 305fe27fa085627000728bbaac750112365e3d55 From 3cfffb4de661fb70f27e514d9c0e4851813010f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 29 Jan 2025 09:04:50 +0200 Subject: [PATCH 180/213] MDEV-35962 CREATE INDEX fails to heal a FOREIGN KEY constraint commit_cache_norebuild(): Replace any newly added indexes in the attached foreign key constraints. --- mysql-test/suite/innodb/r/foreign_key.result | 29 ++++++++++++++++-- mysql-test/suite/innodb/t/foreign_key.test | 31 ++++++++++++++++++-- storage/innobase/handler/handler0alter.cc | 31 ++++++++++++++++++++ 3 files changed, 85 insertions(+), 6 deletions(-) diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result index 0404ab81c61..6c17504b5e0 100644 --- a/mysql-test/suite/innodb/r/foreign_key.result +++ b/mysql-test/suite/innodb/r/foreign_key.result @@ -164,9 +164,6 @@ DELETE FROM parent; ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`a`) REFERENCES `parent` (`a`) ON DELETE CASCADE) ALTER TABLE child ADD INDEX(a); DELETE FROM parent; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`a`) REFERENCES `parent` (`a`) ON DELETE CASCADE) -ALTER TABLE child FORCE; -DELETE FROM parent; DROP TABLE child,parent; SELECT unique_constraint_name FROM information_schema.referential_constraints WHERE table_name = 't2'; @@ -1142,5 +1139,31 @@ DELETE FROM t2; DELETE FROM t1; DROP DATABASE `#mysql50##mysql50#d-b`; USE test; +# +# MDEV-35962 CREATE INDEX fails to heal a FOREIGN KEY constraint +# +CREATE TABLE t2 (b INT, FOREIGN KEY (b) REFERENCES t1(a)) ENGINE=InnoDB; +ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") +SET STATEMENT foreign_key_checks=0 FOR +CREATE TABLE t2 (b INT, FOREIGN KEY (b) REFERENCES t1(a)) ENGINE=InnoDB; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") +SET STATEMENT foreign_key_checks=0 FOR +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t1` (`a`)) +ALTER TABLE t1 ADD KEY(a), ALGORITHM=NOCOPY; +INSERT INTO t2 VALUES (1); +DROP INDEX b ON t2; +ERROR HY000: Cannot drop index 'b': needed in a foreign key constraint +SET STATEMENT foreign_key_checks=0 FOR +DROP INDEX b ON t2; +DELETE FROM t2; +DELETE FROM t1; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t1` (`a`)) +ALTER TABLE t2 ADD KEY(b), ALGORITHM=NOCOPY; +DELETE FROM t1; +DROP TABLE t2, t1; # End of 10.6 tests SET GLOBAL innodb_stats_persistent = @save_stats_persistent; diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test index e31320ee810..23e9bf8fc82 100644 --- a/mysql-test/suite/innodb/t/foreign_key.test +++ b/mysql-test/suite/innodb/t/foreign_key.test @@ -142,9 +142,6 @@ INSERT INTO child SET a=1; --error ER_ROW_IS_REFERENCED_2 DELETE FROM parent; ALTER TABLE child ADD INDEX(a); ---error ER_ROW_IS_REFERENCED_2 -DELETE FROM parent; -ALTER TABLE child FORCE; DELETE FROM parent; DROP TABLE child,parent; @@ -1205,6 +1202,34 @@ DELETE FROM t1; DROP DATABASE `#mysql50##mysql50#d-b`; USE test; +--echo # +--echo # MDEV-35962 CREATE INDEX fails to heal a FOREIGN KEY constraint +--echo # + +--error ER_CANT_CREATE_TABLE +CREATE TABLE t2 (b INT, FOREIGN KEY (b) REFERENCES t1(a)) ENGINE=InnoDB; +SET STATEMENT foreign_key_checks=0 FOR +CREATE TABLE t2 (b INT, FOREIGN KEY (b) REFERENCES t1(a)) ENGINE=InnoDB; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +SET STATEMENT foreign_key_checks=0 FOR +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +--error ER_NO_REFERENCED_ROW_2 +INSERT INTO t2 VALUES (1); +ALTER TABLE t1 ADD KEY(a), ALGORITHM=NOCOPY; +INSERT INTO t2 VALUES (1); +--error ER_DROP_INDEX_FK +DROP INDEX b ON t2; +SET STATEMENT foreign_key_checks=0 FOR +DROP INDEX b ON t2; +DELETE FROM t2; +--error ER_ROW_IS_REFERENCED_2 +DELETE FROM t1; +ALTER TABLE t2 ADD KEY(b), ALGORITHM=NOCOPY; +DELETE FROM t1; +DROP TABLE t2, t1; + --echo # End of 10.6 tests SET GLOBAL innodb_stats_persistent = @save_stats_persistent; diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index a967259a2ab..04e57c83f10 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -11036,6 +11036,37 @@ commit_cache_norebuild( dict_index_remove_from_cache(index->table, index); } + if (ctx->num_to_add_index) { + for (dict_foreign_t* foreign: ctx->new_table->foreign_set) { + if (foreign->foreign_table == ctx->new_table + && !foreign->foreign_index) { + foreign->foreign_index = + dict_foreign_find_index( + foreign->foreign_table, + nullptr, + foreign->foreign_col_names, + foreign->n_fields, nullptr, + /*check_charsets=*/TRUE, + /*check_null=*/FALSE, + nullptr, nullptr, nullptr); + } + } + for (dict_foreign_t* foreign: ctx->new_table->referenced_set) { + if (foreign->referenced_table == ctx->new_table + && !foreign->referenced_index) { + foreign->referenced_index = + dict_foreign_find_index( + foreign->referenced_table, + nullptr, + foreign->referenced_col_names, + foreign->n_fields, nullptr, + /*check_charsets=*/TRUE, + /*check_null=*/FALSE, + nullptr, nullptr, nullptr); + } + } + } + fts_clear_all(ctx->old_table); if (!ctx->is_instant()) { From d5e7bce14be521e59224d200434655d5edf34292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 29 Jan 2025 10:42:01 +0200 Subject: [PATCH 181/213] MDEV-35966 galera.galera_as_master crashes in debug builds innobase_commit(): When Galera is used with SET SQL_LOG_BIN=OFF, some debug assertions that had been added in commit ddd7d5d8e34c3edd7ebf4790eec2c4e4d9141e94 (MDEV-24035) would fail. Let us relax those assertions for Galera transactions, to allow an implicit commit after an internally executed XA PREPARE. Note that trx_undo_report_row_operation() only allows undo log records to be added to ACTIVE transactions (not after XA PREPARE). Hence, this relaxation should be safe with respect to writes. --- storage/innobase/handler/ha_innodb.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index bb7594cf1a0..612a4f640b4 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -4677,9 +4677,10 @@ innobase_commit( ut_ad("invalid state" == 0); /* fall through */ case TRX_STATE_PREPARED: - ut_ad(commit_trx); + ut_ad(commit_trx || trx->is_wsrep()); ut_ad(thd_test_options(thd, OPTION_NOT_AUTOCOMMIT - | OPTION_BEGIN)); + | OPTION_BEGIN) + || trx->is_wsrep()); /* fall through */ case TRX_STATE_ACTIVE: /* Transaction is deregistered only in a commit or a From 03d2328785db2ec1467a9c465712b2c559bcd6e6 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 27 Jan 2025 19:22:20 +0100 Subject: [PATCH 182/213] MDEV-35944 DELETE fails to notice transaction abort, violating ACID Process errors of read_record(). Also, add an assert that Marko requested --- mysql-test/main/delete_innodb.result | 27 +++++++++++++++++++ mysql-test/main/delete_innodb.test | 39 +++++++++++++++++++++++++++ sql/sql_delete.cc | 18 +++++-------- storage/innobase/handler/ha_innodb.cc | 1 + 4 files changed, 73 insertions(+), 12 deletions(-) diff --git a/mysql-test/main/delete_innodb.result b/mysql-test/main/delete_innodb.result index b9f4c8bdaf5..ebee36d6ce7 100644 --- a/mysql-test/main/delete_innodb.result +++ b/mysql-test/main/delete_innodb.result @@ -24,3 +24,30 @@ SELECT * FROM t1; c1 SET sort_buffer_size=@save_sort_buffer_size; DROP TABLE t1; +# +# MDEV-35944 DELETE fails to notice transaction abort, violating ACID +# +CREATE TABLE t1 (id INT PRIMARY KEY, col_varchar VARCHAR(8)) ENGINE=InnoDB; +INSERT INTO t1 (id) VALUES (1),(2); +CREATE TABLE t2 (id INT, f INT, s DATE, e DATE, PERIOD FOR p(s,e), PRIMARY KEY(id, p WITHOUT OVERLAPS)) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,0,'2000-01-01','2000-01-02'); +CREATE TABLE t3 (id INT, f BLOB, UNIQUE(f)) ENGINE=InnoDB; +connection default; +SET innodb_lock_wait_timeout=1; +START TRANSACTION; +DELETE FROM t1; +connect con1,localhost,root,,; +START TRANSACTION; +UPDATE t2 SET f = 20; +connection default; +DELETE FROM t2 FOR PORTION OF p FROM '2000-01-01' TO '2000-01-02'; +connection con1; +INSERT INTO t3 (id) VALUES (1), (2); +UPDATE t1 SET col_varchar = 'bar'; +COMMIT; +connection default; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +COMMIT; +UPDATE t3 SET f = 'foo' ORDER BY f LIMIT 1; +DROP TABLE t1, t2, t3; +# End of 10.5 tests diff --git a/mysql-test/main/delete_innodb.test b/mysql-test/main/delete_innodb.test index c5c5c5d0172..e654b8fe691 100644 --- a/mysql-test/main/delete_innodb.test +++ b/mysql-test/main/delete_innodb.test @@ -20,3 +20,42 @@ SELECT * FROM t1; SET sort_buffer_size=@save_sort_buffer_size; DROP TABLE t1; + +--echo # +--echo # MDEV-35944 DELETE fails to notice transaction abort, violating ACID +--echo # + +CREATE TABLE t1 (id INT PRIMARY KEY, col_varchar VARCHAR(8)) ENGINE=InnoDB; +INSERT INTO t1 (id) VALUES (1),(2); +CREATE TABLE t2 (id INT, f INT, s DATE, e DATE, PERIOD FOR p(s,e), PRIMARY KEY(id, p WITHOUT OVERLAPS)) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,0,'2000-01-01','2000-01-02'); +CREATE TABLE t3 (id INT, f BLOB, UNIQUE(f)) ENGINE=InnoDB; + +--connection default +SET innodb_lock_wait_timeout=1; +START TRANSACTION; +DELETE FROM t1; + +--connect (con1,localhost,root,,) +START TRANSACTION; +UPDATE t2 SET f = 20; + +--connection default +--send + DELETE FROM t2 FOR PORTION OF p FROM '2000-01-01' TO '2000-01-02'; + +--connection con1 +INSERT INTO t3 (id) VALUES (1), (2); +UPDATE t1 SET col_varchar = 'bar'; +COMMIT; + +--connection default +--error ER_LOCK_DEADLOCK +--reap +COMMIT; +UPDATE t3 SET f = 'foo' ORDER BY f LIMIT 1; + +# Cleanup +DROP TABLE t1, t2, t3; + +--echo # End of 10.5 tests diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 2e77e32aed9..dc7b3fc00c4 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -773,27 +773,21 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, MEM_STRIP_BUF_SIZE); THD_STAGE_INFO(thd, stage_searching_rows_for_update); - while (!(error=info.read_record()) && !thd->killed && - ! thd->is_error()) + while (!(error=info.read_record()) && !thd->killed && !thd->is_error()) { if (record_should_be_deleted(thd, table, select, explain, delete_history)) { table->file->position(table->record[0]); - if (unlikely((error= - deltempfile->unique_add((char*) table->file->ref)))) - { - error= 1; - goto terminate_delete; - } + if ((error= deltempfile->unique_add((char*) table->file->ref))) + break; if (!--tmplimit && using_limit) break; } } end_read_record(&info); - if (unlikely(deltempfile->get(table)) || - unlikely(table->file->ha_index_or_rnd_end()) || - unlikely(init_read_record(&info, thd, table, 0, &deltempfile->sort, 0, - 1, false))) + if (table->file->ha_index_or_rnd_end() || error > 0 || + deltempfile->get(table) || + init_read_record(&info, thd, table, 0, &deltempfile->sort, 0, 1, 0)) { error= 1; goto terminate_delete; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 612a4f640b4..33ebb9f1291 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -16313,6 +16313,7 @@ ha_innobase::external_lock( case F_UNLCK: DEBUG_SYNC_C("ha_innobase_end_statement"); m_mysql_has_locked = false; + ut_a(trx->n_mysql_tables_in_use); if (--trx->n_mysql_tables_in_use) { break; From 38d3b6027b6637d7be0da2060a6aa4c314d2337d Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 26 Jan 2025 21:24:53 +0100 Subject: [PATCH 183/213] MDEV-35943 ASAN errors in Query_arena::free_items / fill_schema_table_from_frm shouldn't try to close the table if open failed. followup for deb20fb751f6 --- sql/sql_show.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 97db86644f0..6ba6f8088fa 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -5093,9 +5093,11 @@ static int fill_schema_table_from_frm(THD *thd, MEM_ROOT *mem_root, tbl.s= share; table_list.table= &tbl; table_list.view= (LEX*) share->is_view; - res= schema_table->process_table(thd, &table_list, table, - res, db_name, table_name); - closefrm(&tbl); + bool res2= schema_table->process_table(thd, &table_list, table, res, + db_name, table_name); + if (res == 0) + closefrm(&tbl); + res= res2; } From 17e31abd8b6a045d6f5240a0d3387dbad942683a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 24 Jan 2025 18:05:31 +0100 Subject: [PATCH 184/213] compilation failure on CentOS 7 --- storage/innobase/handler/ha_innodb.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 33ebb9f1291..5188f5b511b 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -12447,9 +12447,9 @@ create_table_info_t::create_foreign_keys() if (sqlcom == SQLCOM_ALTER_TABLE) { mem_heap_t* heap = mem_heap_create(10000); - LEX_CSTRING t{innodb_convert_name(cs, m_form->s->table_name, - t_name)}; - LEX_CSTRING d{innodb_convert_name(cs, m_form->s->db, db_name)}; + LEX_CSTRING t = innodb_convert_name(cs, m_form->s->table_name, + t_name); + LEX_CSTRING d = innodb_convert_name(cs, m_form->s->db, db_name); dict_table_t* alter_table; char* n = dict_table_lookup(d, t, &alter_table, heap); @@ -12638,7 +12638,7 @@ create_table_info_t::create_foreign_keys() memcpy(foreign->foreign_col_names, column_names, i * sizeof(void*)); - LEX_CSTRING t{innodb_convert_name(cs, fk->ref_table, t_name)}; + LEX_CSTRING t = innodb_convert_name(cs, fk->ref_table, t_name); LEX_CSTRING d = fk->ref_db.str ? innodb_convert_name(cs, fk->ref_db, db_name) : LEX_CSTRING{table->name.m_name, table->name.dblen()}; From d0c2a007ee99d299042e3729bbb08b49d9eb6ba0 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 24 Jan 2025 14:26:20 +0100 Subject: [PATCH 185/213] C/C 3.3.14 --- libmariadb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmariadb b/libmariadb index 3f2196d84e2..2d56f340c4a 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit 3f2196d84e20dd89c682fde6154849ec5bb36c85 +Subproject commit 2d56f340c4a0f2c636e317a3efd41b8c5f554088 From a89e734fcb43bf04bf82c36f49eff490c110d209 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 24 Jan 2025 14:17:15 +0100 Subject: [PATCH 186/213] ColumnStore 6.4.10-1 --- storage/columnstore/columnstore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/columnstore/columnstore b/storage/columnstore/columnstore index 9f905c07b9c..ef0647b74ac 160000 --- a/storage/columnstore/columnstore +++ b/storage/columnstore/columnstore @@ -1 +1 @@ -Subproject commit 9f905c07b9c5ba68590a7cec24e71859d4082d56 +Subproject commit ef0647b74ac41263cfdc25d3d4b5169c9e8df7ec From 04bd6ed44c6cb4d97e627691d88b77dcffc02993 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 17 Jan 2025 17:54:59 +0100 Subject: [PATCH 187/213] MDEV-35368 Validation of SSL certificate fails for mariadb-backup Just like in CONC-712, disable hostname checks for connections over unix socket. Even for not self-signed certificates. --- .../mariabackup/backup_ssl_system_ca.opt | 2 ++ .../mariabackup/backup_ssl_system_ca.result | 8 +++++ .../mariabackup/backup_ssl_system_ca.test | 30 +++++++++++++++++++ sql-common/client.c | 7 +++-- 4 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 mysql-test/suite/mariabackup/backup_ssl_system_ca.opt create mode 100644 mysql-test/suite/mariabackup/backup_ssl_system_ca.result create mode 100644 mysql-test/suite/mariabackup/backup_ssl_system_ca.test diff --git a/mysql-test/suite/mariabackup/backup_ssl_system_ca.opt b/mysql-test/suite/mariabackup/backup_ssl_system_ca.opt new file mode 100644 index 00000000000..9fd05d254fb --- /dev/null +++ b/mysql-test/suite/mariabackup/backup_ssl_system_ca.opt @@ -0,0 +1,2 @@ +--ssl-key=$MYSQL_TEST_DIR/std_data/server8k-key.pem +--ssl-cert=$MYSQL_TEST_DIR/std_data/server8k-cert.pem diff --git a/mysql-test/suite/mariabackup/backup_ssl_system_ca.result b/mysql-test/suite/mariabackup/backup_ssl_system_ca.result new file mode 100644 index 00000000000..e3f3f4750c2 --- /dev/null +++ b/mysql-test/suite/mariabackup/backup_ssl_system_ca.result @@ -0,0 +1,8 @@ +# +# MDEV-35368 Validation of SSL certificate fails for mariadb-backup +# +GRANT ALL PRIVILEGES on *.* TO backup_user IDENTIFIED by 'x' REQUIRE SSL; +# localhost, not self-signed cert with a wrong hostname: ok +# tcp, not self-signed cert with a wrong hostname: fails +# tcp, not self-signed cert with a wrong hostname: fails even with a password (no auto-verification) +DROP USER backup_user; diff --git a/mysql-test/suite/mariabackup/backup_ssl_system_ca.test b/mysql-test/suite/mariabackup/backup_ssl_system_ca.test new file mode 100644 index 00000000000..18db74fe431 --- /dev/null +++ b/mysql-test/suite/mariabackup/backup_ssl_system_ca.test @@ -0,0 +1,30 @@ +source include/not_embedded.inc; +source include/not_windows.inc; +if (`select @@version_ssl_library not like 'OpenSSL%'`) { + skip Needs OpenSSL; +} + + +--echo # +--echo # MDEV-35368 Validation of SSL certificate fails for mariadb-backup +--echo # +GRANT ALL PRIVILEGES on *.* TO backup_user IDENTIFIED by 'x' REQUIRE SSL; +let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; + +let SSL_CERT_DIR=$MYSQL_TMP_DIR; +copy_file $MYSQL_TEST_DIR/std_data/cacert.pem $MYSQL_TMP_DIR/ed1f42db.0; + +echo # localhost, not self-signed cert with a wrong hostname: ok; +exec $XTRABACKUP --user=root --socket=$MASTER_MYSOCK --backup --target-dir=$targetdir; +rmdir $targetdir; + +echo # tcp, not self-signed cert with a wrong hostname: fails; +error 1; +exec $XTRABACKUP --protocol=tcp --user=root --port=$MASTER_MYPORT --backup --target-dir=$targetdir; + +echo # tcp, not self-signed cert with a wrong hostname: fails even with a password (no auto-verification); +error 1; +exec $XTRABACKUP --protocol=tcp --user=backup_user --password=x --port=$MASTER_MYPORT --backup --target-dir=$targetdir; + +remove_file $MYSQL_TMP_DIR/ed1f42db.0; +DROP USER backup_user; diff --git a/sql-common/client.c b/sql-common/client.c index c5656be6a1e..c468f3fd3d9 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1587,7 +1587,7 @@ mysql_get_ssl_cipher(MYSQL *mysql __attribute__((unused))) #include -static int ssl_verify_server_cert(MYSQL *mysql, const char **errptr) +static int ssl_verify_server_cert(MYSQL *mysql, const char **errptr, int is_local) { SSL *ssl; X509 *server_cert= NULL; @@ -1628,7 +1628,8 @@ static int ssl_verify_server_cert(MYSQL *mysql, const char **errptr) mysql->tls_self_signed_error= *errptr= "SSL certificate is self-signed"; break; case X509_V_OK: - ret_validation= X509_check_host(server_cert, mysql->host, + ret_validation= !is_local && + X509_check_host(server_cert, mysql->host, strlen(mysql->host), 0, 0) != 1 && X509_check_ip_asc(server_cert, mysql->host, 0) != 1; *errptr= "SSL certificate validation failure"; @@ -2171,7 +2172,7 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio, /* Verify server cert */ if ((!mysql->options.extension || !mysql->options.extension->tls_allow_invalid_server_cert) && - ssl_verify_server_cert(mysql, &cert_error)) + ssl_verify_server_cert(mysql, &cert_error, vio_type == VIO_TYPE_SOCKET)) { set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate, ER(CR_SSL_CONNECTION_ERROR), cert_error); From 92a6789638d27f10044be9fb2d57b63f8bbf5e6e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 25 Jan 2025 18:09:41 +0100 Subject: [PATCH 188/213] C/C 3.4.4 --- client/mysqlbinlog.cc | 5 ----- libmariadb | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index d34fdb85beb..22946132913 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -43,11 +43,6 @@ #include "sql_priv.h" #include "sql_basic_types.h" #include -#if 0 /* FIXME: the following is broken for now */ -# include "mariadb_rpl.h" -#else -enum Item_result {STRING_RESULT,REAL_RESULT,INT_RESULT,ROW_RESULT,DECIMAL_RESULT}; -#endif #include "log_event.h" #include "compat56.h" #include "sql_common.h" diff --git a/libmariadb b/libmariadb index 52d0a38ed15..93e420621a9 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit 52d0a38ed15f62906206d77b675079fc159cec7e +Subproject commit 93e420621a9b367081dcfab17fd1a8340c411cf2 From 5be38d14fce4cc6ed2ea02633ba1bb9b1b53ed3b Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 25 Jan 2025 20:07:02 +0100 Subject: [PATCH 189/213] ColumnStore 23.10.3-1 --- storage/columnstore/columnstore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/columnstore/columnstore b/storage/columnstore/columnstore index 9040430422b..9763b126517 160000 --- a/storage/columnstore/columnstore +++ b/storage/columnstore/columnstore @@ -1 +1 @@ -Subproject commit 9040430422b58d131ad5c50c6e6f980ab674bee2 +Subproject commit 9763b126517c8efb716e767fd5ba4eb2b5b405fc From 04595175621446d685fbb7b664977178cb8cb473 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 30 Jan 2025 11:42:21 +0100 Subject: [PATCH 190/213] MDEV-35169 cleanup after the test followup for f6e00abda0c7 --- mysql-test/suite/innodb/t/import_cfg.test | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/suite/innodb/t/import_cfg.test b/mysql-test/suite/innodb/t/import_cfg.test index 297de767d5d..1f518c65886 100644 --- a/mysql-test/suite/innodb/t/import_cfg.test +++ b/mysql-test/suite/innodb/t/import_cfg.test @@ -81,3 +81,5 @@ alter table t1 discard tablespace; alter table t1 import tablespace; check table t1 extended; drop table t1; + +--remove_files_wildcard $datadir/test t1*sc From 0771110266ff5c04216af4bf1243c65f8c67ccf4 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 30 Jan 2025 10:25:18 +0100 Subject: [PATCH 191/213] MDEV-33658 1/2 FULLTEXT and SPATIAL keys are not "too long" max_key_length applies only to PRIMARY/UNIQUE/MULTIPLE keys, but not to FULLTEXT/SPATIAL/VECTOR keys. this fixes main.partition_geometries test followup for ecaedbe299fe --- sql/sql_table.cc | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index b119ba0dfd9..81438d4583a 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2944,7 +2944,7 @@ my_bool init_key_part_spec(THD *thd, Alter_info *alter_info, my_error(ER_WRONG_KEY_COLUMN, MYF(0), file->table_type(), field_name.str); DBUG_RETURN(TRUE); } - if (key_part_length > max_key_part_length && key.type != Key::FULLTEXT) + if (key_part_length > max_key_part_length) { if (key.type == Key::MULTIPLE) { @@ -2956,7 +2956,7 @@ my_bool init_key_part_spec(THD *thd, Alter_info *alter_info, /* Align key length to multibyte char boundary */ key_part_length-= key_part_length % column->charset->mbmaxlen; } - else if (key.type != Key::UNIQUE) + else if (key.type == Key::PRIMARY) { key_part_length= MY_MIN(max_key_length, max_key_part_length); my_error(ER_TOO_LONG_KEY, MYF(0), key_part_length); @@ -3023,14 +3023,15 @@ my_bool init_key_info(THD *thd, Alter_info *alter_info, DBUG_RETURN(TRUE); key.length+= kp.length; - if (key.length > max_key_length && key.type == Key::UNIQUE) - is_hash_field_needed= true; // for case "a BLOB UNIQUE" - - if (key.length > max_key_length && key.type != Key::FULLTEXT && - !is_hash_field_needed) + if (key.length > max_key_length) { - my_error(ER_TOO_LONG_KEY, MYF(0), max_key_length); - DBUG_RETURN(TRUE); + if (key.type == Key::UNIQUE) + is_hash_field_needed= true; // for case "a BLOB UNIQUE" + else if (key.type <= Key::MULTIPLE) + { + my_error(ER_TOO_LONG_KEY, MYF(0), max_key_length); + DBUG_RETURN(TRUE); + } } KEY_CREATE_INFO *key_cinfo= &key.key_create_info; From aaa02f6aa3169b61f6c49a530a25932310ae3c33 Mon Sep 17 00:00:00 2001 From: ParadoxV5 Date: Fri, 31 Jan 2025 14:02:44 -0700 Subject: [PATCH 192/213] MDEV-35693: Improve SHOW REPLICA STATUS column sizes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resize the types and widths of SHOW REPLICA STATUS (technically `INFORMATION_SCHEMA.SLAVE_STATUS`) columns to better match their possible values In case of intentionally but absurdly long lists, text columns that list an uncapped number of elements have expanded to accept as many bytes as we could support. Particularly, the first-gen `Replicate_` filters were incorrectly typed as singlular `Name()`s during MDEV-33526. Under `Name`s’ 64-char limit, they could overflow (read: truncate) even before their lengths got absurd. In response to `‘MAX_SLAVE_ERRMSG’ was not declared in this scope` in Embedded builds, a new `#ifdef HAVE_REPLICATION` guard wraps `slave_status_info` to skip this unused data in Replication-less builds. For testing, this commit forward-ports a modified cherry-pick of #3795 (the latter targets our oldest maintained LTS as part of MDEV-35948). > Assert that 1st-gen `replicate_*` filter variables display > their input – including long but reasonable lists – > correctly (without truncation) in > * direct SELECT > * [semi-new] INFORMATION_SCHEMA.GLOBAL_VARIABLES.VARIABLE_VALUE > * [new] SHOW REPLICA STATUS Reviewed-by: Brandon Nesterenko --- mysql-test/main/information_schema.result | 2 +- .../suite/funcs_1/r/is_columns_is.result | 120 +++++++++--------- .../sys_vars/r/replicate_do_db_basic.result | 16 +++ .../r/replicate_do_table_basic.result | 16 +++ .../r/replicate_ignore_db_basic.result | 16 +++ .../r/replicate_ignore_table_basic.result | 16 +++ .../r/replicate_wild_do_table_basic.result | 16 +++ .../replicate_wild_ignore_table_basic.result | 16 +++ .../sys_vars/t/replicate_do_db_basic.test | 16 +++ .../sys_vars/t/replicate_do_table_basic.test | 16 +++ .../sys_vars/t/replicate_ignore_db_basic.test | 16 +++ .../t/replicate_ignore_table_basic.test | 16 +++ .../t/replicate_wild_do_table_basic.test | 16 +++ .../t/replicate_wild_ignore_table_basic.test | 16 +++ sql/sql_i_s.h | 9 ++ sql/sql_show.cc | 65 +++++----- 16 files changed, 294 insertions(+), 94 deletions(-) diff --git a/mysql-test/main/information_schema.result b/mysql-test/main/information_schema.result index 5f720a2aa66..820c6c488ef 100644 --- a/mysql-test/main/information_schema.result +++ b/mysql-test/main/information_schema.result @@ -1341,7 +1341,7 @@ table_schema='information_schema' and group by column_type order by num; column_type group_concat(table_schema, '.', table_name) num varchar(7) information_schema.ROUTINES,information_schema.VIEWS,information_schema.SLAVE_STATUS 3 -varchar(20) information_schema.ALL_PLUGINS,information_schema.ALL_PLUGINS,information_schema.ALL_PLUGINS,information_schema.FILES,information_schema.FILES,information_schema.PLUGINS,information_schema.PLUGINS,information_schema.PLUGINS,information_schema.PROFILING,information_schema.SLAVE_STATUS 10 +varchar(20) information_schema.ALL_PLUGINS,information_schema.ALL_PLUGINS,information_schema.ALL_PLUGINS,information_schema.FILES,information_schema.FILES,information_schema.PLUGINS,information_schema.PLUGINS,information_schema.PLUGINS,information_schema.PROFILING 9 create table t1(f1 char(1) not null, f2 char(9) not null) default character set utf8; select CHARACTER_MAXIMUM_LENGTH, CHARACTER_OCTET_LENGTH from diff --git a/mysql-test/suite/funcs_1/r/is_columns_is.result b/mysql-test/suite/funcs_1/r/is_columns_is.result index e5c938c1e48..48635a34e91 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is.result @@ -392,21 +392,21 @@ def information_schema SESSION_VARIABLES VARIABLE_VALUE 2 NULL NO varchar 4096 1 def information_schema SLAVE_STATUS Connection_name 1 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL NO NO def information_schema SLAVE_STATUS Connect_Retry 7 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) select NEVER NULL NO NO def information_schema SLAVE_STATUS Executed_log_entries 59 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select NEVER NULL NO NO -def information_schema SLAVE_STATUS Exec_Master_Log_Pos 24 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(10) unsigned select NEVER NULL NO NO -def information_schema SLAVE_STATUS Gtid_IO_Pos 46 NULL NO varchar 1024 3072 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(1024) select NEVER NULL NO NO -def information_schema SLAVE_STATUS Gtid_Slave_Pos 62 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO -def information_schema SLAVE_STATUS Last_Errno 21 NULL NO int NULL NULL 10 0 NULL NULL NULL int(4) select NEVER NULL NO NO -def information_schema SLAVE_STATUS Last_Error 22 NULL YES varchar 20 60 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(20) select NEVER NULL NO NO -def information_schema SLAVE_STATUS Last_IO_Errno 37 NULL NO int NULL NULL 10 0 NULL NULL NULL int(4) select NEVER NULL NO NO -def information_schema SLAVE_STATUS Last_IO_Error 38 NULL YES varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO -def information_schema SLAVE_STATUS Last_SQL_Errno 39 NULL NO int NULL NULL 10 0 NULL NULL NULL int(4) select NEVER NULL NO NO -def information_schema SLAVE_STATUS Last_SQL_Error 40 NULL YES varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Exec_Master_Log_Pos 24 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Gtid_IO_Pos 46 NULL NO varchar 21844 65532 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(21844) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Gtid_Slave_Pos 62 NULL NO varchar 21844 65532 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(21844) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Last_Errno 21 NULL NO smallint NULL NULL 5 0 NULL NULL NULL smallint(4) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Last_Error 22 NULL YES varchar 1024 3072 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(1024) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Last_IO_Errno 37 NULL NO smallint NULL NULL 5 0 NULL NULL NULL smallint(4) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Last_IO_Error 38 NULL YES varchar 1024 3072 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(1024) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Last_SQL_Errno 39 NULL NO smallint NULL NULL 5 0 NULL NULL NULL smallint(4) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Last_SQL_Error 40 NULL YES varchar 1024 3072 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(1024) select NEVER NULL NO NO def information_schema SLAVE_STATUS Master_Host 4 NULL YES varchar 255 765 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(255) select NEVER NULL NO NO def information_schema SLAVE_STATUS Master_last_event_time 63 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select NEVER NULL NO NO def information_schema SLAVE_STATUS Master_Log_File 8 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO -def information_schema SLAVE_STATUS Master_Port 6 NULL NO int NULL NULL 10 0 NULL NULL NULL int(7) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Master_Port 6 NULL NO smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned select NEVER NULL NO NO def information_schema SLAVE_STATUS Master_Server_Id 42 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select NEVER NULL NO NO -def information_schema SLAVE_STATUS Master_Slave_time_diff 65 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(10) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Master_Slave_time_diff 65 NULL YES int NULL NULL 10 0 NULL NULL NULL int(10) select NEVER NULL NO NO def information_schema SLAVE_STATUS Master_SSL_Allowed 29 NULL YES varchar 7 21 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(7) select NEVER NULL NO NO def information_schema SLAVE_STATUS Master_SSL_CA_File 30 NULL YES varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO def information_schema SLAVE_STATUS Master_SSL_CA_Path 31 NULL YES varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO @@ -417,25 +417,25 @@ def information_schema SLAVE_STATUS Master_SSL_Crlpath 44 NULL YES varchar 512 1 def information_schema SLAVE_STATUS Master_SSL_Key 34 NULL YES varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO def information_schema SLAVE_STATUS Master_SSL_Verify_Server_Cert 36 NULL NO varchar 3 9 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(3) select NEVER NULL NO NO def information_schema SLAVE_STATUS Master_User 5 NULL YES varchar 384 1152 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(384) select NEVER NULL NO NO -def information_schema SLAVE_STATUS Max_relay_log_size 58 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(10) unsigned select NEVER NULL NO NO -def information_schema SLAVE_STATUS Parallel_Mode 49 NULL NO varchar 15 45 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(15) select NEVER NULL NO NO -def information_schema SLAVE_STATUS Read_Master_Log_Pos 9 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(10) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Max_relay_log_size 58 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Parallel_Mode 49 NULL NO varchar 12 36 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(12) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Read_Master_Log_Pos 9 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select NEVER NULL NO NO def information_schema SLAVE_STATUS Relay_Log_File 10 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO -def information_schema SLAVE_STATUS Relay_Log_Pos 11 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(10) unsigned select NEVER NULL NO NO -def information_schema SLAVE_STATUS Relay_Log_Space 25 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(10) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Relay_Log_Pos 11 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Relay_Log_Space 25 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select NEVER NULL NO NO def information_schema SLAVE_STATUS Relay_Master_Log_File 12 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO -def information_schema SLAVE_STATUS Replicate_Do_DB 15 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL NO NO -def information_schema SLAVE_STATUS Replicate_Do_Domain_Ids 47 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO -def information_schema SLAVE_STATUS Replicate_Do_Table 17 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL NO NO -def information_schema SLAVE_STATUS Replicate_Ignore_DB 16 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL NO NO -def information_schema SLAVE_STATUS Replicate_Ignore_Domain_Ids 48 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO -def information_schema SLAVE_STATUS Replicate_Ignore_Server_Ids 41 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO -def information_schema SLAVE_STATUS Replicate_Ignore_Table 18 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL NO NO -def information_schema SLAVE_STATUS Replicate_Rewrite_DB 56 NULL NO varchar 1024 3072 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(1024) select NEVER NULL NO NO -def information_schema SLAVE_STATUS Replicate_Wild_Do_Table 19 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL NO NO -def information_schema SLAVE_STATUS Replicate_Wild_Ignore_Table 20 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Replicate_Do_DB 15 NULL NO varchar 21844 65532 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(21844) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Replicate_Do_Domain_Ids 47 NULL NO varchar 21844 65532 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(21844) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Replicate_Do_Table 17 NULL NO varchar 21844 65532 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(21844) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Replicate_Ignore_DB 16 NULL NO varchar 21844 65532 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(21844) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Replicate_Ignore_Domain_Ids 48 NULL NO varchar 21844 65532 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(21844) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Replicate_Ignore_Server_Ids 41 NULL NO varchar 21844 65532 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(21844) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Replicate_Ignore_Table 18 NULL NO varchar 21844 65532 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(21844) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Replicate_Rewrite_DB 56 NULL NO varchar 21844 65532 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(21844) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Replicate_Wild_Do_Table 19 NULL NO varchar 21844 65532 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(21844) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Replicate_Wild_Ignore_Table 20 NULL NO varchar 21844 65532 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(21844) select NEVER NULL NO NO def information_schema SLAVE_STATUS Retried_transactions 57 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select NEVER NULL NO NO -def information_schema SLAVE_STATUS Seconds_Behind_Master 35 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(10) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Seconds_Behind_Master 35 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select NEVER NULL NO NO def information_schema SLAVE_STATUS Skip_Counter 23 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select NEVER NULL NO NO def information_schema SLAVE_STATUS Slave_DDL_Groups 53 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select NEVER NULL NO NO def information_schema SLAVE_STATUS Slave_heartbeat_period 61 NULL NO float NULL NULL 9 3 NULL NULL NULL float(9,3) select NEVER NULL NO NO @@ -445,15 +445,15 @@ def information_schema SLAVE_STATUS Slave_last_event_time 64 NULL YES datetime N def information_schema SLAVE_STATUS Slave_Non_Transactional_Groups 54 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select NEVER NULL NO NO def information_schema SLAVE_STATUS Slave_received_heartbeats 60 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select NEVER NULL NO NO def information_schema SLAVE_STATUS Slave_SQL_Running 14 NULL NO varchar 3 9 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(3) select NEVER NULL NO NO -def information_schema SLAVE_STATUS Slave_SQL_Running_State 52 NULL YES varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Slave_SQL_Running_State 52 NULL YES varchar 21844 65532 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(21844) select NEVER NULL NO NO def information_schema SLAVE_STATUS Slave_SQL_State 2 NULL YES varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL NO NO def information_schema SLAVE_STATUS Slave_Transactional_Groups 55 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select NEVER NULL NO NO def information_schema SLAVE_STATUS SQL_Delay 50 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select NEVER NULL NO NO def information_schema SLAVE_STATUS SQL_Remaining_Delay 51 NULL YES int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select NEVER NULL NO NO def information_schema SLAVE_STATUS Until_Condition 26 NULL NO varchar 6 18 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(6) select NEVER NULL NO NO def information_schema SLAVE_STATUS Until_Log_File 27 NULL YES varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO -def information_schema SLAVE_STATUS Until_Log_Pos 28 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(10) unsigned select NEVER NULL NO NO -def information_schema SLAVE_STATUS Using_Gtid 45 NULL YES varchar 15 45 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(15) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Until_Log_Pos 28 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Using_Gtid 45 NULL YES varchar 11 33 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(11) select NEVER NULL NO NO def information_schema SPATIAL_REF_SYS AUTH_NAME 2 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO def information_schema SPATIAL_REF_SYS AUTH_SRID 3 NULL NO int NULL NULL 10 0 NULL NULL NULL int(5) select NEVER NULL NO NO def information_schema SPATIAL_REF_SYS SRID 1 NULL NO smallint NULL NULL 5 0 NULL NULL NULL smallint(5) select NEVER NULL NO NO @@ -1069,66 +1069,66 @@ NULL information_schema SEQUENCES INCREMENT bigint NULL NULL NULL NULL bigint(21 3.0000 information_schema SLAVE_STATUS Slave_IO_State varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) 3.0000 information_schema SLAVE_STATUS Master_Host varchar 255 765 utf8mb3 utf8mb3_general_ci varchar(255) 3.0000 information_schema SLAVE_STATUS Master_User varchar 384 1152 utf8mb3 utf8mb3_general_ci varchar(384) -NULL information_schema SLAVE_STATUS Master_Port int NULL NULL NULL NULL int(7) unsigned +NULL information_schema SLAVE_STATUS Master_Port smallint NULL NULL NULL NULL smallint(5) unsigned NULL information_schema SLAVE_STATUS Connect_Retry int NULL NULL NULL NULL int(10) 3.0000 information_schema SLAVE_STATUS Master_Log_File varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) -NULL information_schema SLAVE_STATUS Read_Master_Log_Pos bigint NULL NULL NULL NULL bigint(10) unsigned +NULL information_schema SLAVE_STATUS Read_Master_Log_Pos bigint NULL NULL NULL NULL bigint(20) unsigned 3.0000 information_schema SLAVE_STATUS Relay_Log_File varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) -NULL information_schema SLAVE_STATUS Relay_Log_Pos bigint NULL NULL NULL NULL bigint(10) unsigned +NULL information_schema SLAVE_STATUS Relay_Log_Pos bigint NULL NULL NULL NULL bigint(20) unsigned 3.0000 information_schema SLAVE_STATUS Relay_Master_Log_File varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) 3.0000 information_schema SLAVE_STATUS Slave_IO_Running varchar 10 30 utf8mb3 utf8mb3_general_ci varchar(10) 3.0000 information_schema SLAVE_STATUS Slave_SQL_Running varchar 3 9 utf8mb3 utf8mb3_general_ci varchar(3) -3.0000 information_schema SLAVE_STATUS Replicate_Do_DB varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) -3.0000 information_schema SLAVE_STATUS Replicate_Ignore_DB varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) -3.0000 information_schema SLAVE_STATUS Replicate_Do_Table varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) -3.0000 information_schema SLAVE_STATUS Replicate_Ignore_Table varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) -3.0000 information_schema SLAVE_STATUS Replicate_Wild_Do_Table varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) -3.0000 information_schema SLAVE_STATUS Replicate_Wild_Ignore_Table varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) -NULL information_schema SLAVE_STATUS Last_Errno int NULL NULL NULL NULL int(4) -3.0000 information_schema SLAVE_STATUS Last_Error varchar 20 60 utf8mb3 utf8mb3_general_ci varchar(20) +3.0000 information_schema SLAVE_STATUS Replicate_Do_DB varchar 21844 65532 utf8mb3 utf8mb3_general_ci varchar(21844) +3.0000 information_schema SLAVE_STATUS Replicate_Ignore_DB varchar 21844 65532 utf8mb3 utf8mb3_general_ci varchar(21844) +3.0000 information_schema SLAVE_STATUS Replicate_Do_Table varchar 21844 65532 utf8mb3 utf8mb3_general_ci varchar(21844) +3.0000 information_schema SLAVE_STATUS Replicate_Ignore_Table varchar 21844 65532 utf8mb3 utf8mb3_general_ci varchar(21844) +3.0000 information_schema SLAVE_STATUS Replicate_Wild_Do_Table varchar 21844 65532 utf8mb3 utf8mb3_general_ci varchar(21844) +3.0000 information_schema SLAVE_STATUS Replicate_Wild_Ignore_Table varchar 21844 65532 utf8mb3 utf8mb3_general_ci varchar(21844) +NULL information_schema SLAVE_STATUS Last_Errno smallint NULL NULL NULL NULL smallint(4) unsigned +3.0000 information_schema SLAVE_STATUS Last_Error varchar 1024 3072 utf8mb3 utf8mb3_general_ci varchar(1024) NULL information_schema SLAVE_STATUS Skip_Counter int NULL NULL NULL NULL int(10) unsigned -NULL information_schema SLAVE_STATUS Exec_Master_Log_Pos bigint NULL NULL NULL NULL bigint(10) unsigned -NULL information_schema SLAVE_STATUS Relay_Log_Space bigint NULL NULL NULL NULL bigint(10) unsigned +NULL information_schema SLAVE_STATUS Exec_Master_Log_Pos bigint NULL NULL NULL NULL bigint(20) unsigned +NULL information_schema SLAVE_STATUS Relay_Log_Space bigint NULL NULL NULL NULL bigint(20) unsigned 3.0000 information_schema SLAVE_STATUS Until_Condition varchar 6 18 utf8mb3 utf8mb3_general_ci varchar(6) 3.0000 information_schema SLAVE_STATUS Until_Log_File varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) -NULL information_schema SLAVE_STATUS Until_Log_Pos bigint NULL NULL NULL NULL bigint(10) unsigned +NULL information_schema SLAVE_STATUS Until_Log_Pos bigint NULL NULL NULL NULL bigint(20) unsigned 3.0000 information_schema SLAVE_STATUS Master_SSL_Allowed varchar 7 21 utf8mb3 utf8mb3_general_ci varchar(7) 3.0000 information_schema SLAVE_STATUS Master_SSL_CA_File varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) 3.0000 information_schema SLAVE_STATUS Master_SSL_CA_Path varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) 3.0000 information_schema SLAVE_STATUS Master_SSL_Cert varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) 3.0000 information_schema SLAVE_STATUS Master_SSL_Cipher varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) 3.0000 information_schema SLAVE_STATUS Master_SSL_Key varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) -NULL information_schema SLAVE_STATUS Seconds_Behind_Master bigint NULL NULL NULL NULL bigint(10) +NULL information_schema SLAVE_STATUS Seconds_Behind_Master bigint NULL NULL NULL NULL bigint(20) unsigned 3.0000 information_schema SLAVE_STATUS Master_SSL_Verify_Server_Cert varchar 3 9 utf8mb3 utf8mb3_general_ci varchar(3) -NULL information_schema SLAVE_STATUS Last_IO_Errno int NULL NULL NULL NULL int(4) -3.0000 information_schema SLAVE_STATUS Last_IO_Error varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) -NULL information_schema SLAVE_STATUS Last_SQL_Errno int NULL NULL NULL NULL int(4) -3.0000 information_schema SLAVE_STATUS Last_SQL_Error varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) -3.0000 information_schema SLAVE_STATUS Replicate_Ignore_Server_Ids varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) +NULL information_schema SLAVE_STATUS Last_IO_Errno smallint NULL NULL NULL NULL smallint(4) unsigned +3.0000 information_schema SLAVE_STATUS Last_IO_Error varchar 1024 3072 utf8mb3 utf8mb3_general_ci varchar(1024) +NULL information_schema SLAVE_STATUS Last_SQL_Errno smallint NULL NULL NULL NULL smallint(4) unsigned +3.0000 information_schema SLAVE_STATUS Last_SQL_Error varchar 1024 3072 utf8mb3 utf8mb3_general_ci varchar(1024) +3.0000 information_schema SLAVE_STATUS Replicate_Ignore_Server_Ids varchar 21844 65532 utf8mb3 utf8mb3_general_ci varchar(21844) NULL information_schema SLAVE_STATUS Master_Server_Id int NULL NULL NULL NULL int(10) unsigned 3.0000 information_schema SLAVE_STATUS Master_SSL_Crl varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) 3.0000 information_schema SLAVE_STATUS Master_SSL_Crlpath varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) -3.0000 information_schema SLAVE_STATUS Using_Gtid varchar 15 45 utf8mb3 utf8mb3_general_ci varchar(15) -3.0000 information_schema SLAVE_STATUS Gtid_IO_Pos varchar 1024 3072 utf8mb3 utf8mb3_general_ci varchar(1024) -3.0000 information_schema SLAVE_STATUS Replicate_Do_Domain_Ids varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) -3.0000 information_schema SLAVE_STATUS Replicate_Ignore_Domain_Ids varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) -3.0000 information_schema SLAVE_STATUS Parallel_Mode varchar 15 45 utf8mb3 utf8mb3_general_ci varchar(15) +3.0000 information_schema SLAVE_STATUS Using_Gtid varchar 11 33 utf8mb3 utf8mb3_general_ci varchar(11) +3.0000 information_schema SLAVE_STATUS Gtid_IO_Pos varchar 21844 65532 utf8mb3 utf8mb3_general_ci varchar(21844) +3.0000 information_schema SLAVE_STATUS Replicate_Do_Domain_Ids varchar 21844 65532 utf8mb3 utf8mb3_general_ci varchar(21844) +3.0000 information_schema SLAVE_STATUS Replicate_Ignore_Domain_Ids varchar 21844 65532 utf8mb3 utf8mb3_general_ci varchar(21844) +3.0000 information_schema SLAVE_STATUS Parallel_Mode varchar 12 36 utf8mb3 utf8mb3_general_ci varchar(12) NULL information_schema SLAVE_STATUS SQL_Delay int NULL NULL NULL NULL int(10) unsigned NULL information_schema SLAVE_STATUS SQL_Remaining_Delay int NULL NULL NULL NULL int(10) unsigned -3.0000 information_schema SLAVE_STATUS Slave_SQL_Running_State varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) +3.0000 information_schema SLAVE_STATUS Slave_SQL_Running_State varchar 21844 65532 utf8mb3 utf8mb3_general_ci varchar(21844) NULL information_schema SLAVE_STATUS Slave_DDL_Groups bigint NULL NULL NULL NULL bigint(20) unsigned NULL information_schema SLAVE_STATUS Slave_Non_Transactional_Groups bigint NULL NULL NULL NULL bigint(20) unsigned NULL information_schema SLAVE_STATUS Slave_Transactional_Groups bigint NULL NULL NULL NULL bigint(20) unsigned -3.0000 information_schema SLAVE_STATUS Replicate_Rewrite_DB varchar 1024 3072 utf8mb3 utf8mb3_general_ci varchar(1024) +3.0000 information_schema SLAVE_STATUS Replicate_Rewrite_DB varchar 21844 65532 utf8mb3 utf8mb3_general_ci varchar(21844) NULL information_schema SLAVE_STATUS Retried_transactions int NULL NULL NULL NULL int(10) unsigned -NULL information_schema SLAVE_STATUS Max_relay_log_size bigint NULL NULL NULL NULL bigint(10) unsigned +NULL information_schema SLAVE_STATUS Max_relay_log_size int NULL NULL NULL NULL int(10) unsigned NULL information_schema SLAVE_STATUS Executed_log_entries int NULL NULL NULL NULL int(10) unsigned NULL information_schema SLAVE_STATUS Slave_received_heartbeats int NULL NULL NULL NULL int(10) unsigned NULL information_schema SLAVE_STATUS Slave_heartbeat_period float NULL NULL NULL NULL float(9,3) -3.0000 information_schema SLAVE_STATUS Gtid_Slave_Pos varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) +3.0000 information_schema SLAVE_STATUS Gtid_Slave_Pos varchar 21844 65532 utf8mb3 utf8mb3_general_ci varchar(21844) NULL information_schema SLAVE_STATUS Master_last_event_time datetime NULL NULL NULL NULL datetime NULL information_schema SLAVE_STATUS Slave_last_event_time datetime NULL NULL NULL NULL datetime -NULL information_schema SLAVE_STATUS Master_Slave_time_diff bigint NULL NULL NULL NULL bigint(10) +NULL information_schema SLAVE_STATUS Master_Slave_time_diff int NULL NULL NULL NULL int(10) NULL information_schema SPATIAL_REF_SYS SRID smallint NULL NULL NULL NULL smallint(5) 3.0000 information_schema SPATIAL_REF_SYS AUTH_NAME varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) NULL information_schema SPATIAL_REF_SYS AUTH_SRID int NULL NULL NULL NULL int(5) diff --git a/mysql-test/suite/sys_vars/r/replicate_do_db_basic.result b/mysql-test/suite/sys_vars/r/replicate_do_db_basic.result index 54adf835962..26489a83344 100644 --- a/mysql-test/suite/sys_vars/r/replicate_do_db_basic.result +++ b/mysql-test/suite/sys_vars/r/replicate_do_db_basic.result @@ -1,3 +1,4 @@ +CHANGE MASTER TO master_host='127.0.0.1', master_user='root', master_ssl_verify_server_cert=0; # # Basic testing of replicate_do_db. # @@ -17,6 +18,20 @@ SET @@GLOBAL.replicate_do_db=1.1; ERROR 42000: Incorrect argument type to variable 'replicate_do_db' SET @@GLOBAL.replicate_do_db=1e1; ERROR 42000: Incorrect argument type to variable 'replicate_do_db' +# Argument size acceptance. +SELECT GROUP_CONCAT(CONCAT("database_name_", seq) SEPARATOR ",") +INTO @name FROM seq_1_to_8; +SELECT LENGTH(@name); +LENGTH(@name) +127 +SET @@GLOBAL.replicate_do_db= @name; +SELECT @@GLOBAL.replicate_do_db; +@@GLOBAL.replicate_do_db +database_name_1,database_name_2,database_name_3,database_name_4,database_name_5,database_name_6,database_name_7,database_name_8 +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_do_db'; +VARIABLE_VALUE +database_name_1,database_name_2,database_name_3,database_name_4,database_name_5,database_name_6,database_name_7,database_name_8 +Replicate_Do_DB = 'database_name_1,database_name_2,database_name_3,database_name_4,database_name_5,database_name_6,database_name_7,database_name_8' # Argument syntax. SET @@GLOBAL.replicate_do_db="db1,,,,,db3"; SELECT @@GLOBAL.replicate_do_db; @@ -25,6 +40,7 @@ db1,db3 SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_do_db'; VARIABLE_NAME VARIABLE_VALUE REPLICATE_DO_DB db1,db3 +Replicate_Do_DB = 'db1,db3' SET @@GLOBAL.replicate_do_db="db1,,,db2,,,db3"; SELECT @@GLOBAL.replicate_do_db; @@GLOBAL.replicate_do_db diff --git a/mysql-test/suite/sys_vars/r/replicate_do_table_basic.result b/mysql-test/suite/sys_vars/r/replicate_do_table_basic.result index e67b1eeca01..85aff814e3a 100644 --- a/mysql-test/suite/sys_vars/r/replicate_do_table_basic.result +++ b/mysql-test/suite/sys_vars/r/replicate_do_table_basic.result @@ -1,3 +1,4 @@ +CHANGE MASTER TO master_host='127.0.0.1', master_user='root', master_ssl_verify_server_cert=0; # # Basic testing of replicate_do_table. # @@ -24,6 +25,20 @@ SET @@GLOBAL.replicate_do_table="test.t1, t2"; ERROR HY000: Incorrect arguments to SET SET @@GLOBAL.replicate_do_table="test.,t1"; ERROR HY000: Incorrect arguments to SET +# Argument size acceptance. +SELECT GROUP_CONCAT(CONCAT("database_name.long_table_name_", seq) SEPARATOR ",") +INTO @name FROM seq_1_to_8; +SELECT LENGTH(@name); +LENGTH(@name) +255 +SET @@GLOBAL.replicate_do_table= @name; +SELECT @@GLOBAL.replicate_do_table; +@@GLOBAL.replicate_do_table +database_name.long_table_name_5,database_name.long_table_name_1,database_name.long_table_name_6,database_name.long_table_name_2,database_name.long_table_name_7,database_name.long_table_name_3,database_name.long_table_name_8,database_name.long_table_name_4 +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_do_table'; +VARIABLE_VALUE +database_name.long_table_name_5,database_name.long_table_name_1,database_name.long_table_name_6,database_name.long_table_name_2,database_name.long_table_name_7,database_name.long_table_name_3,database_name.long_table_name_8,database_name.long_table_name_4 +Replicate_Do_Table = 'database_name.long_table_name_5,database_name.long_table_name_1,database_name.long_table_name_6,database_name.long_table_name_2,database_name.long_table_name_7,database_name.long_table_name_3,database_name.long_table_name_8,database_name.long_table_name_4' # Argument syntax. SET @@GLOBAL.replicate_do_table="test.t1,,,,,test.t3"; SELECT @@GLOBAL.replicate_do_table; @@ -32,6 +47,7 @@ test.t3,test.t1 SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_do_table'; VARIABLE_NAME VARIABLE_VALUE REPLICATE_DO_TABLE test.t3,test.t1 +Replicate_Do_Table = 'test.t3,test.t1' SET @@GLOBAL.replicate_do_table="test.t1,,,test2.t2,,,test.t3"; SELECT @@GLOBAL.replicate_do_table; @@GLOBAL.replicate_do_table diff --git a/mysql-test/suite/sys_vars/r/replicate_ignore_db_basic.result b/mysql-test/suite/sys_vars/r/replicate_ignore_db_basic.result index c7ff697b34f..219bee0649d 100644 --- a/mysql-test/suite/sys_vars/r/replicate_ignore_db_basic.result +++ b/mysql-test/suite/sys_vars/r/replicate_ignore_db_basic.result @@ -1,3 +1,4 @@ +CHANGE MASTER TO master_host='127.0.0.1', master_user='root', master_ssl_verify_server_cert=0; # # Basic testing of replicate_ignore_db. # @@ -17,6 +18,20 @@ SET @@GLOBAL.replicate_ignore_db=1.1; ERROR 42000: Incorrect argument type to variable 'replicate_ignore_db' SET @@GLOBAL.replicate_ignore_db=1e1; ERROR 42000: Incorrect argument type to variable 'replicate_ignore_db' +# Argument size acceptance. +SELECT GROUP_CONCAT(CONCAT("database_name_", seq) SEPARATOR ",") +INTO @name FROM seq_1_to_8; +SELECT LENGTH(@name); +LENGTH(@name) +127 +SET @@GLOBAL.replicate_ignore_db= @name; +SELECT @@GLOBAL.replicate_ignore_db; +@@GLOBAL.replicate_ignore_db +database_name_1,database_name_2,database_name_3,database_name_4,database_name_5,database_name_6,database_name_7,database_name_8 +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_ignore_db'; +VARIABLE_VALUE +database_name_1,database_name_2,database_name_3,database_name_4,database_name_5,database_name_6,database_name_7,database_name_8 +Replicate_Ignore_DB = 'database_name_1,database_name_2,database_name_3,database_name_4,database_name_5,database_name_6,database_name_7,database_name_8' # Argument syntax. SET @@GLOBAL.replicate_ignore_db="db1,,,,,db3"; SELECT @@GLOBAL.replicate_ignore_db; @@ -25,6 +40,7 @@ db1,db3 SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_ignore_db'; VARIABLE_NAME VARIABLE_VALUE REPLICATE_IGNORE_DB db1,db3 +Replicate_Ignore_DB = 'db1,db3' SET @@GLOBAL.replicate_ignore_db="db1,,,db2,,,db3"; SELECT @@GLOBAL.replicate_ignore_db; @@GLOBAL.replicate_ignore_db diff --git a/mysql-test/suite/sys_vars/r/replicate_ignore_table_basic.result b/mysql-test/suite/sys_vars/r/replicate_ignore_table_basic.result index a1701635f0e..44743223e8f 100644 --- a/mysql-test/suite/sys_vars/r/replicate_ignore_table_basic.result +++ b/mysql-test/suite/sys_vars/r/replicate_ignore_table_basic.result @@ -1,3 +1,4 @@ +CHANGE MASTER TO master_host='127.0.0.1', master_user='root', master_ssl_verify_server_cert=0; # # Basic testing of replicate_ignore_table. # @@ -24,6 +25,20 @@ SET @@GLOBAL.replicate_ignore_table="test.t1, t2"; ERROR HY000: Incorrect arguments to SET SET @@GLOBAL.replicate_ignore_table="test.,t1"; ERROR HY000: Incorrect arguments to SET +# Argument size acceptance. +SELECT GROUP_CONCAT(CONCAT("database_name.long_table_name_", seq) SEPARATOR ",") +INTO @name FROM seq_1_to_8; +SELECT LENGTH(@name); +LENGTH(@name) +255 +SET @@GLOBAL.replicate_ignore_table= @name; +SELECT @@GLOBAL.replicate_ignore_table; +@@GLOBAL.replicate_ignore_table +database_name.long_table_name_5,database_name.long_table_name_1,database_name.long_table_name_6,database_name.long_table_name_2,database_name.long_table_name_7,database_name.long_table_name_3,database_name.long_table_name_8,database_name.long_table_name_4 +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_ignore_table'; +VARIABLE_VALUE +database_name.long_table_name_5,database_name.long_table_name_1,database_name.long_table_name_6,database_name.long_table_name_2,database_name.long_table_name_7,database_name.long_table_name_3,database_name.long_table_name_8,database_name.long_table_name_4 +Replicate_Ignore_Table = 'database_name.long_table_name_5,database_name.long_table_name_1,database_name.long_table_name_6,database_name.long_table_name_2,database_name.long_table_name_7,database_name.long_table_name_3,database_name.long_table_name_8,database_name.long_table_name_4' # Argument syntax. SET @@GLOBAL.replicate_ignore_table="test.t1,,,,,test.t3"; SELECT @@GLOBAL.replicate_ignore_table; @@ -32,6 +47,7 @@ test.t3,test.t1 SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_ignore_table'; VARIABLE_NAME VARIABLE_VALUE REPLICATE_IGNORE_TABLE test.t3,test.t1 +Replicate_Ignore_Table = 'test.t3,test.t1' SET @@GLOBAL.replicate_ignore_table="test.t1,,,test2.t2,,,test.t3"; SELECT @@GLOBAL.replicate_ignore_table; @@GLOBAL.replicate_ignore_table diff --git a/mysql-test/suite/sys_vars/r/replicate_wild_do_table_basic.result b/mysql-test/suite/sys_vars/r/replicate_wild_do_table_basic.result index 8c55103080f..ecec3cc03a3 100644 --- a/mysql-test/suite/sys_vars/r/replicate_wild_do_table_basic.result +++ b/mysql-test/suite/sys_vars/r/replicate_wild_do_table_basic.result @@ -1,3 +1,4 @@ +CHANGE MASTER TO master_host='127.0.0.1', master_user='root', master_ssl_verify_server_cert=0; # # Basic testing of replicate_wild_do_table. # @@ -24,6 +25,20 @@ SET @@GLOBAL.replicate_wild_do_table="test.t, t2"; ERROR HY000: Incorrect arguments to SET SET @@GLOBAL.replicate_wild_do_table="test.,t1"; ERROR HY000: Incorrect arguments to SET +# Argument size acceptance. +SELECT GROUP_CONCAT(CONCAT("database_name.long_table_name_", seq) SEPARATOR ",") +INTO @name FROM seq_1_to_8; +SELECT LENGTH(@name); +LENGTH(@name) +255 +SET @@GLOBAL.replicate_wild_do_table= @name; +SELECT @@GLOBAL.replicate_wild_do_table; +@@GLOBAL.replicate_wild_do_table +database_name.long_table_name_1,database_name.long_table_name_2,database_name.long_table_name_3,database_name.long_table_name_4,database_name.long_table_name_5,database_name.long_table_name_6,database_name.long_table_name_7,database_name.long_table_name_8 +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_wild_do_table'; +VARIABLE_VALUE +database_name.long_table_name_1,database_name.long_table_name_2,database_name.long_table_name_3,database_name.long_table_name_4,database_name.long_table_name_5,database_name.long_table_name_6,database_name.long_table_name_7,database_name.long_table_name_8 +Replicate_Wild_Do_Table = 'database_name.long_table_name_1,database_name.long_table_name_2,database_name.long_table_name_3,database_name.long_table_name_4,database_name.long_table_name_5,database_name.long_table_name_6,database_name.long_table_name_7,database_name.long_table_name_8' # Argument syntax. SET @@GLOBAL.replicate_wild_do_table="test.%,,,,,test.t3"; SELECT @@GLOBAL.replicate_wild_do_table; @@ -32,6 +47,7 @@ test.%,test.t3 SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_wild_do_table'; VARIABLE_NAME VARIABLE_VALUE REPLICATE_WILD_DO_TABLE test.%,test.t3 +Replicate_Wild_Do_Table = 'test.%,test.t3' SET @@GLOBAL.replicate_wild_do_table="test.t1,,,test2.%,,,test.t3"; SELECT @@GLOBAL.replicate_wild_do_table; @@GLOBAL.replicate_wild_do_table diff --git a/mysql-test/suite/sys_vars/r/replicate_wild_ignore_table_basic.result b/mysql-test/suite/sys_vars/r/replicate_wild_ignore_table_basic.result index 0f46ce38805..693aa257e4d 100644 --- a/mysql-test/suite/sys_vars/r/replicate_wild_ignore_table_basic.result +++ b/mysql-test/suite/sys_vars/r/replicate_wild_ignore_table_basic.result @@ -1,3 +1,4 @@ +CHANGE MASTER TO master_host='127.0.0.1', master_user='root', master_ssl_verify_server_cert=0; # # Basic testing of replicate_wild_ignore_table. # @@ -24,6 +25,20 @@ SET @@GLOBAL.replicate_wild_ignore_table="test.t, t2"; ERROR HY000: Incorrect arguments to SET SET @@GLOBAL.replicate_wild_ignore_table="test.,t1"; ERROR HY000: Incorrect arguments to SET +# Argument size acceptance. +SELECT GROUP_CONCAT(CONCAT("database_name.long_table_name_", seq) SEPARATOR ",") +INTO @name FROM seq_1_to_8; +SELECT LENGTH(@name); +LENGTH(@name) +255 +SET @@GLOBAL.replicate_wild_ignore_table= @name; +SELECT @@GLOBAL.replicate_wild_ignore_table; +@@GLOBAL.replicate_wild_ignore_table +database_name.long_table_name_1,database_name.long_table_name_2,database_name.long_table_name_3,database_name.long_table_name_4,database_name.long_table_name_5,database_name.long_table_name_6,database_name.long_table_name_7,database_name.long_table_name_8 +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_wild_ignore_table'; +VARIABLE_VALUE +database_name.long_table_name_1,database_name.long_table_name_2,database_name.long_table_name_3,database_name.long_table_name_4,database_name.long_table_name_5,database_name.long_table_name_6,database_name.long_table_name_7,database_name.long_table_name_8 +Replicate_Wild_Ignore_Table = 'database_name.long_table_name_1,database_name.long_table_name_2,database_name.long_table_name_3,database_name.long_table_name_4,database_name.long_table_name_5,database_name.long_table_name_6,database_name.long_table_name_7,database_name.long_table_name_8' # Argument syntax. SET @@GLOBAL.replicate_wild_ignore_table="test.%,,,,,test.t3"; SELECT @@GLOBAL.replicate_wild_ignore_table; @@ -32,6 +47,7 @@ test.%,test.t3 SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_wild_ignore_table'; VARIABLE_NAME VARIABLE_VALUE REPLICATE_WILD_IGNORE_TABLE test.%,test.t3 +Replicate_Wild_Ignore_Table = 'test.%,test.t3' SET @@GLOBAL.replicate_wild_ignore_table="test.t1,,,test2.%,,,test.t3"; SELECT @@GLOBAL.replicate_wild_ignore_table; @@GLOBAL.replicate_wild_ignore_table diff --git a/mysql-test/suite/sys_vars/t/replicate_do_db_basic.test b/mysql-test/suite/sys_vars/t/replicate_do_db_basic.test index b7004d1938b..2ff32df8e15 100644 --- a/mysql-test/suite/sys_vars/t/replicate_do_db_basic.test +++ b/mysql-test/suite/sys_vars/t/replicate_do_db_basic.test @@ -1,4 +1,8 @@ +--source include/have_sequence.inc +# have show_slave_status --source include/not_embedded.inc +CHANGE MASTER TO master_host='127.0.0.1', master_user='root', master_ssl_verify_server_cert=0; +--let $status_items= Replicate_Do_DB --echo # --echo # Basic testing of replicate_do_db. @@ -23,11 +27,23 @@ SET @@GLOBAL.replicate_do_db=1.1; --error ER_WRONG_TYPE_FOR_VAR SET @@GLOBAL.replicate_do_db=1e1; +# MDEV-35693 Replicate_* fields of Show-Slave-Status display truncated +--echo # Argument size acceptance. + +SELECT GROUP_CONCAT(CONCAT("database_name_", seq) SEPARATOR ",") + INTO @name FROM seq_1_to_8; +SELECT LENGTH(@name); +SET @@GLOBAL.replicate_do_db= @name; +SELECT @@GLOBAL.replicate_do_db; +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_do_db'; +--source include/show_slave_status.inc + --echo # Argument syntax. SET @@GLOBAL.replicate_do_db="db1,,,,,db3"; SELECT @@GLOBAL.replicate_do_db; SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_do_db'; +--source include/show_slave_status.inc SET @@GLOBAL.replicate_do_db="db1,,,db2,,,db3"; SELECT @@GLOBAL.replicate_do_db; diff --git a/mysql-test/suite/sys_vars/t/replicate_do_table_basic.test b/mysql-test/suite/sys_vars/t/replicate_do_table_basic.test index 346bdf3b038..7715df6c528 100644 --- a/mysql-test/suite/sys_vars/t/replicate_do_table_basic.test +++ b/mysql-test/suite/sys_vars/t/replicate_do_table_basic.test @@ -1,4 +1,8 @@ +--source include/have_sequence.inc +# have show_slave_status --source include/not_embedded.inc +CHANGE MASTER TO master_host='127.0.0.1', master_user='root', master_ssl_verify_server_cert=0; +--let $status_items= Replicate_Do_Table --echo # --echo # Basic testing of replicate_do_table. @@ -32,11 +36,23 @@ SET @@GLOBAL.replicate_do_table="test.t1, t2"; --error ER_WRONG_ARGUMENTS SET @@GLOBAL.replicate_do_table="test.,t1"; +# MDEV-35693 Replicate_* fields of Show-Slave-Status display truncated +--echo # Argument size acceptance. + +SELECT GROUP_CONCAT(CONCAT("database_name.long_table_name_", seq) SEPARATOR ",") + INTO @name FROM seq_1_to_8; +SELECT LENGTH(@name); +SET @@GLOBAL.replicate_do_table= @name; +SELECT @@GLOBAL.replicate_do_table; +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_do_table'; +--source include/show_slave_status.inc + --echo # Argument syntax. SET @@GLOBAL.replicate_do_table="test.t1,,,,,test.t3"; SELECT @@GLOBAL.replicate_do_table; SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_do_table'; +--source include/show_slave_status.inc SET @@GLOBAL.replicate_do_table="test.t1,,,test2.t2,,,test.t3"; SELECT @@GLOBAL.replicate_do_table; diff --git a/mysql-test/suite/sys_vars/t/replicate_ignore_db_basic.test b/mysql-test/suite/sys_vars/t/replicate_ignore_db_basic.test index 376397d1635..3dbd9f64ef9 100644 --- a/mysql-test/suite/sys_vars/t/replicate_ignore_db_basic.test +++ b/mysql-test/suite/sys_vars/t/replicate_ignore_db_basic.test @@ -1,4 +1,8 @@ +--source include/have_sequence.inc +# have show_slave_status --source include/not_embedded.inc +CHANGE MASTER TO master_host='127.0.0.1', master_user='root', master_ssl_verify_server_cert=0; +--let $status_items= Replicate_Ignore_DB --echo # --echo # Basic testing of replicate_ignore_db. @@ -23,11 +27,23 @@ SET @@GLOBAL.replicate_ignore_db=1.1; --error ER_WRONG_TYPE_FOR_VAR SET @@GLOBAL.replicate_ignore_db=1e1; +# MDEV-35693 Replicate_* fields of Show-Slave-Status display truncated +--echo # Argument size acceptance. + +SELECT GROUP_CONCAT(CONCAT("database_name_", seq) SEPARATOR ",") + INTO @name FROM seq_1_to_8; +SELECT LENGTH(@name); +SET @@GLOBAL.replicate_ignore_db= @name; +SELECT @@GLOBAL.replicate_ignore_db; +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_ignore_db'; +--source include/show_slave_status.inc + --echo # Argument syntax. SET @@GLOBAL.replicate_ignore_db="db1,,,,,db3"; SELECT @@GLOBAL.replicate_ignore_db; SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_ignore_db'; +--source include/show_slave_status.inc SET @@GLOBAL.replicate_ignore_db="db1,,,db2,,,db3"; SELECT @@GLOBAL.replicate_ignore_db; diff --git a/mysql-test/suite/sys_vars/t/replicate_ignore_table_basic.test b/mysql-test/suite/sys_vars/t/replicate_ignore_table_basic.test index 1cf6f010eca..fdce4094c31 100644 --- a/mysql-test/suite/sys_vars/t/replicate_ignore_table_basic.test +++ b/mysql-test/suite/sys_vars/t/replicate_ignore_table_basic.test @@ -1,4 +1,8 @@ +--source include/have_sequence.inc +# have show_slave_status --source include/not_embedded.inc +CHANGE MASTER TO master_host='127.0.0.1', master_user='root', master_ssl_verify_server_cert=0; +--let $status_items= Replicate_Ignore_Table --echo # --echo # Basic testing of replicate_ignore_table. @@ -32,11 +36,23 @@ SET @@GLOBAL.replicate_ignore_table="test.t1, t2"; --error ER_WRONG_ARGUMENTS SET @@GLOBAL.replicate_ignore_table="test.,t1"; +# MDEV-35693 Replicate_* fields of Show-Slave-Status display truncated +--echo # Argument size acceptance. + +SELECT GROUP_CONCAT(CONCAT("database_name.long_table_name_", seq) SEPARATOR ",") + INTO @name FROM seq_1_to_8; +SELECT LENGTH(@name); +SET @@GLOBAL.replicate_ignore_table= @name; +SELECT @@GLOBAL.replicate_ignore_table; +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_ignore_table'; +--source include/show_slave_status.inc + --echo # Argument syntax. SET @@GLOBAL.replicate_ignore_table="test.t1,,,,,test.t3"; SELECT @@GLOBAL.replicate_ignore_table; SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_ignore_table'; +--source include/show_slave_status.inc SET @@GLOBAL.replicate_ignore_table="test.t1,,,test2.t2,,,test.t3"; SELECT @@GLOBAL.replicate_ignore_table; diff --git a/mysql-test/suite/sys_vars/t/replicate_wild_do_table_basic.test b/mysql-test/suite/sys_vars/t/replicate_wild_do_table_basic.test index 832d3397f89..e4b5cb90a8f 100644 --- a/mysql-test/suite/sys_vars/t/replicate_wild_do_table_basic.test +++ b/mysql-test/suite/sys_vars/t/replicate_wild_do_table_basic.test @@ -1,4 +1,8 @@ +--source include/have_sequence.inc +# have show_slave_status --source include/not_embedded.inc +CHANGE MASTER TO master_host='127.0.0.1', master_user='root', master_ssl_verify_server_cert=0; +--let $status_items= Replicate_Wild_Do_Table --echo # --echo # Basic testing of replicate_wild_do_table. @@ -32,11 +36,23 @@ SET @@GLOBAL.replicate_wild_do_table="test.t, t2"; --error ER_WRONG_ARGUMENTS SET @@GLOBAL.replicate_wild_do_table="test.,t1"; +# MDEV-35693 Replicate_* fields of Show-Slave-Status display truncated +--echo # Argument size acceptance. + +SELECT GROUP_CONCAT(CONCAT("database_name.long_table_name_", seq) SEPARATOR ",") + INTO @name FROM seq_1_to_8; +SELECT LENGTH(@name); +SET @@GLOBAL.replicate_wild_do_table= @name; +SELECT @@GLOBAL.replicate_wild_do_table; +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_wild_do_table'; +--source include/show_slave_status.inc + --echo # Argument syntax. SET @@GLOBAL.replicate_wild_do_table="test.%,,,,,test.t3"; SELECT @@GLOBAL.replicate_wild_do_table; SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_wild_do_table'; +--source include/show_slave_status.inc SET @@GLOBAL.replicate_wild_do_table="test.t1,,,test2.%,,,test.t3"; SELECT @@GLOBAL.replicate_wild_do_table; diff --git a/mysql-test/suite/sys_vars/t/replicate_wild_ignore_table_basic.test b/mysql-test/suite/sys_vars/t/replicate_wild_ignore_table_basic.test index 5cb1ff6c820..004c08065bf 100644 --- a/mysql-test/suite/sys_vars/t/replicate_wild_ignore_table_basic.test +++ b/mysql-test/suite/sys_vars/t/replicate_wild_ignore_table_basic.test @@ -1,4 +1,8 @@ +--source include/have_sequence.inc +# have show_slave_status --source include/not_embedded.inc +CHANGE MASTER TO master_host='127.0.0.1', master_user='root', master_ssl_verify_server_cert=0; +--let $status_items= Replicate_Wild_Ignore_Table --echo # --echo # Basic testing of replicate_wild_ignore_table. @@ -32,11 +36,23 @@ SET @@GLOBAL.replicate_wild_ignore_table="test.t, t2"; --error ER_WRONG_ARGUMENTS SET @@GLOBAL.replicate_wild_ignore_table="test.,t1"; +# MDEV-35693 Replicate_* fields of Show-Slave-Status display truncated +--echo # Argument size acceptance. + +SELECT GROUP_CONCAT(CONCAT("database_name.long_table_name_", seq) SEPARATOR ",") + INTO @name FROM seq_1_to_8; +SELECT LENGTH(@name); +SET @@GLOBAL.replicate_wild_ignore_table= @name; +SELECT @@GLOBAL.replicate_wild_ignore_table; +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_wild_ignore_table'; +--source include/show_slave_status.inc + --echo # Argument syntax. SET @@GLOBAL.replicate_wild_ignore_table="test.%,,,,,test.t3"; SELECT @@GLOBAL.replicate_wild_ignore_table; SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_wild_ignore_table'; +--source include/show_slave_status.inc SET @@GLOBAL.replicate_wild_ignore_table="test.t1,,,test2.%,,,test.t3"; SELECT @@GLOBAL.replicate_wild_ignore_table; diff --git a/sql/sql_i_s.h b/sql/sql_i_s.h index 12cec39ad71..6782d62bd1f 100644 --- a/sql/sql_i_s.h +++ b/sql/sql_i_s.h @@ -142,8 +142,10 @@ class Varchar: public Type public: Varchar(uint length) :Type(&type_handler_varchar, length, false) { + // utf8mb3 Varchars longer than MAX_FIELD_VARCHARLENGTH/3 become Longtexts DBUG_ASSERT(length * 3 <= MAX_FIELD_VARCHARLENGTH); } + Varchar(): Type(&type_handler_varchar, MAX_FIELD_VARCHARLENGTH/3, false) {} }; @@ -245,6 +247,13 @@ public: }; +class UShort: public Type +{ +public: + UShort(uint length): Type(&type_handler_ushort, length, true) {} +}; + + class SLonglong: public Type { public: diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 254d9a6b9d4..acb57793e56 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -10619,6 +10619,7 @@ ST_FIELD_INFO check_constraints_fields_info[]= }; +#ifdef HAVE_REPLICATION ST_FIELD_INFO slave_status_info[]= { Column("Connection_name", Name(), NOT_NULL), @@ -10626,72 +10627,70 @@ ST_FIELD_INFO slave_status_info[]= Column("Slave_IO_State", Varchar(64), NULLABLE), Column("Master_Host", Varchar(HOSTNAME_LENGTH), NULLABLE), Column("Master_User", Varchar(USERNAME_LENGTH), NULLABLE), - Column("Master_Port", ULong(7), NOT_NULL), + Column("Master_Port", UShort(5), NOT_NULL), Column("Connect_Retry", SLong(10), NOT_NULL), Column("Master_Log_File", Varchar(FN_REFLEN), NOT_NULL), - Column("Read_Master_Log_Pos", ULonglong(10), NOT_NULL), + Column("Read_Master_Log_Pos", ULonglong(20), NOT_NULL), Column("Relay_Log_File", Varchar(FN_REFLEN), NOT_NULL), - Column("Relay_Log_Pos", ULonglong(10), NOT_NULL), + Column("Relay_Log_Pos", ULonglong(20), NOT_NULL), Column("Relay_Master_Log_File", Varchar(FN_REFLEN), NOT_NULL), Column("Slave_IO_Running", Varchar(10), NOT_NULL), Column("Slave_SQL_Running", Varchar(3), NOT_NULL), - Column("Replicate_Do_DB", Name(), NOT_NULL), - Column("Replicate_Ignore_DB", Name(), NOT_NULL), - Column("Replicate_Do_Table", Name(), NOT_NULL), - Column("Replicate_Ignore_Table", Name(), NOT_NULL), - Column("Replicate_Wild_Do_Table", Name(), NOT_NULL), - Column("Replicate_Wild_Ignore_Table", Name(), NOT_NULL), - Column("Last_Errno", SLong(4), NOT_NULL), - Column("Last_Error", Varchar(20), NULLABLE), + Column("Replicate_Do_DB", Varchar(), NOT_NULL), + Column("Replicate_Ignore_DB", Varchar(), NOT_NULL), + Column("Replicate_Do_Table", Varchar(), NOT_NULL), + Column("Replicate_Ignore_Table", Varchar(), NOT_NULL), + Column("Replicate_Wild_Do_Table", Varchar(), NOT_NULL), + Column("Replicate_Wild_Ignore_Table", Varchar(), NOT_NULL), + Column("Last_Errno", UShort(4), NOT_NULL), + Column("Last_Error", Varchar(MAX_SLAVE_ERRMSG), NULLABLE), Column("Skip_Counter", ULong(10), NOT_NULL), - Column("Exec_Master_Log_Pos", ULonglong(10), NOT_NULL), - Column("Relay_Log_Space", ULonglong(10), NOT_NULL), + Column("Exec_Master_Log_Pos", ULonglong(20), NOT_NULL), + Column("Relay_Log_Space", ULonglong(20), NOT_NULL), Column("Until_Condition", Varchar(6), NOT_NULL), Column("Until_Log_File", Varchar(FN_REFLEN), NULLABLE), - Column("Until_Log_Pos", ULonglong(10), NOT_NULL), + Column("Until_Log_Pos", ULonglong(20), NOT_NULL), Column("Master_SSL_Allowed", Varchar(7), NULLABLE), Column("Master_SSL_CA_File", Varchar(FN_REFLEN), NULLABLE), Column("Master_SSL_CA_Path", Varchar(FN_REFLEN), NULLABLE), Column("Master_SSL_Cert", Varchar(FN_REFLEN), NULLABLE), Column("Master_SSL_Cipher", Varchar(FN_REFLEN), NULLABLE), Column("Master_SSL_Key", Varchar(FN_REFLEN), NULLABLE), - Column("Seconds_Behind_Master", SLonglong(10), NULLABLE), + Column("Seconds_Behind_Master", ULonglong(20), NULLABLE), Column("Master_SSL_Verify_Server_Cert", Varchar(3), NOT_NULL), - Column("Last_IO_Errno", SLong(4), NOT_NULL), - Column("Last_IO_Error", Varchar(MYSQL_ERRMSG_SIZE), NULLABLE), - Column("Last_SQL_Errno", SLong(4), NOT_NULL), - Column("Last_SQL_Error", Varchar(MYSQL_ERRMSG_SIZE), NULLABLE), - Column("Replicate_Ignore_Server_Ids", Varchar(FN_REFLEN), NOT_NULL), + Column("Last_IO_Errno", UShort(4), NOT_NULL), + Column("Last_IO_Error", Varchar(MAX_SLAVE_ERRMSG), NULLABLE), + Column("Last_SQL_Errno", UShort(4), NOT_NULL), + Column("Last_SQL_Error", Varchar(MAX_SLAVE_ERRMSG), NULLABLE), + Column("Replicate_Ignore_Server_Ids", Varchar(), NOT_NULL), Column("Master_Server_Id", ULong(10), NOT_NULL), Column("Master_SSL_Crl", Varchar(FN_REFLEN), NULLABLE), Column("Master_SSL_Crlpath", Varchar(FN_REFLEN), NULLABLE), - Column("Using_Gtid", Varchar(15), NULLABLE), - Column("Gtid_IO_Pos", Varchar(1024), NOT_NULL), - Column("Replicate_Do_Domain_Ids", Varchar(FN_REFLEN), NOT_NULL), - Column("Replicate_Ignore_Domain_Ids", Varchar(FN_REFLEN), NOT_NULL), - Column("Parallel_Mode", Varchar(15), NOT_NULL), + Column("Using_Gtid", Varchar(11), NULLABLE), + Column("Gtid_IO_Pos", Varchar(), NOT_NULL), + Column("Replicate_Do_Domain_Ids", Varchar(), NOT_NULL), + Column("Replicate_Ignore_Domain_Ids", Varchar(), NOT_NULL), + Column("Parallel_Mode", Varchar(12), NOT_NULL), Column("SQL_Delay", ULong(10), NOT_NULL), Column("SQL_Remaining_Delay", ULong(10), NULLABLE), - Column("Slave_SQL_Running_State", Varchar(64), NULLABLE), + Column("Slave_SQL_Running_State", Varchar(), NULLABLE), Column("Slave_DDL_Groups", ULonglong(20), NOT_NULL), Column("Slave_Non_Transactional_Groups", ULonglong(20), NOT_NULL), Column("Slave_Transactional_Groups", ULonglong(20), NOT_NULL), - Column("Replicate_Rewrite_DB",Varchar(1024), NOT_NULL), + Column("Replicate_Rewrite_DB", Varchar(), NOT_NULL), Column("Retried_transactions", ULong(10), NOT_NULL), - Column("Max_relay_log_size", ULonglong(10), NOT_NULL), + Column("Max_relay_log_size", ULong(10), NOT_NULL), Column("Executed_log_entries", ULong(10), NOT_NULL), Column("Slave_received_heartbeats", ULong(10), NOT_NULL), Column("Slave_heartbeat_period", Float(703), NOT_NULL), // 3 decimals - Column("Gtid_Slave_Pos", Varchar(FN_REFLEN), NOT_NULL), + Column("Gtid_Slave_Pos", Varchar(), NOT_NULL), Column("Master_last_event_time", Datetime(0), NULLABLE), Column("Slave_last_event_time", Datetime(0), NULLABLE), - Column("Master_Slave_time_diff", SLonglong(10), NULLABLE), + Column("Master_Slave_time_diff", SLong(10), NULLABLE), CEnd() }; +#endif -}; // namespace Show - -namespace Show { /** For creating fields of information_schema.OPTIMIZER_TRACE */ extern ST_FIELD_INFO optimizer_trace_info[]; From 697b88bf75d89b79a18c6dd0bfb9c5c9d6f25503 Mon Sep 17 00:00:00 2001 From: ParadoxV5 Date: Wed, 22 Jan 2025 17:31:30 -0700 Subject: [PATCH 193/213] SHOW REPLICA STATUS: mark columns as unsigned MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update all integer columns of SHOW REPLICA STATUS (technically INFORMATION_SCHEMA.SLAVE_STATUS) to unsigned because, well, they are (:. Some `uint32` ones were accidentally using the `Field::store(double nr)` overload because they forgot the `, true` for `Field::store(longlong nr, bool unsigned_val)`. The mistake’s harmless, fortunately, as `double` supports over 15 significant decimal digits, well over `uint32`’s 9-and-a-half. --- .../suite/funcs_1/r/is_columns_is.result | 8 ++++---- sql/slave.cc | 19 ++++++++++--------- sql/sql_show.cc | 4 ++-- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/mysql-test/suite/funcs_1/r/is_columns_is.result b/mysql-test/suite/funcs_1/r/is_columns_is.result index 48635a34e91..59f266f45dc 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is.result @@ -390,7 +390,7 @@ def information_schema SESSION_STATUS VARIABLE_VALUE 2 NULL NO varchar 4096 1228 def information_schema SESSION_VARIABLES VARIABLE_NAME 1 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL NO NO def information_schema SESSION_VARIABLES VARIABLE_VALUE 2 NULL NO varchar 4096 12288 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(4096) select NEVER NULL NO NO def information_schema SLAVE_STATUS Connection_name 1 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL NO NO -def information_schema SLAVE_STATUS Connect_Retry 7 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Connect_Retry 7 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select NEVER NULL NO NO def information_schema SLAVE_STATUS Executed_log_entries 59 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select NEVER NULL NO NO def information_schema SLAVE_STATUS Exec_Master_Log_Pos 24 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select NEVER NULL NO NO def information_schema SLAVE_STATUS Gtid_IO_Pos 46 NULL NO varchar 21844 65532 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(21844) select NEVER NULL NO NO @@ -406,7 +406,7 @@ def information_schema SLAVE_STATUS Master_last_event_time 63 NULL YES datetime def information_schema SLAVE_STATUS Master_Log_File 8 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO def information_schema SLAVE_STATUS Master_Port 6 NULL NO smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned select NEVER NULL NO NO def information_schema SLAVE_STATUS Master_Server_Id 42 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select NEVER NULL NO NO -def information_schema SLAVE_STATUS Master_Slave_time_diff 65 NULL YES int NULL NULL 10 0 NULL NULL NULL int(10) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Master_Slave_time_diff 65 NULL YES int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select NEVER NULL NO NO def information_schema SLAVE_STATUS Master_SSL_Allowed 29 NULL YES varchar 7 21 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(7) select NEVER NULL NO NO def information_schema SLAVE_STATUS Master_SSL_CA_File 30 NULL YES varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO def information_schema SLAVE_STATUS Master_SSL_CA_Path 31 NULL YES varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO @@ -1070,7 +1070,7 @@ NULL information_schema SEQUENCES INCREMENT bigint NULL NULL NULL NULL bigint(21 3.0000 information_schema SLAVE_STATUS Master_Host varchar 255 765 utf8mb3 utf8mb3_general_ci varchar(255) 3.0000 information_schema SLAVE_STATUS Master_User varchar 384 1152 utf8mb3 utf8mb3_general_ci varchar(384) NULL information_schema SLAVE_STATUS Master_Port smallint NULL NULL NULL NULL smallint(5) unsigned -NULL information_schema SLAVE_STATUS Connect_Retry int NULL NULL NULL NULL int(10) +NULL information_schema SLAVE_STATUS Connect_Retry int NULL NULL NULL NULL int(10) unsigned 3.0000 information_schema SLAVE_STATUS Master_Log_File varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) NULL information_schema SLAVE_STATUS Read_Master_Log_Pos bigint NULL NULL NULL NULL bigint(20) unsigned 3.0000 information_schema SLAVE_STATUS Relay_Log_File varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) @@ -1128,7 +1128,7 @@ NULL information_schema SLAVE_STATUS Slave_heartbeat_period float NULL NULL NULL 3.0000 information_schema SLAVE_STATUS Gtid_Slave_Pos varchar 21844 65532 utf8mb3 utf8mb3_general_ci varchar(21844) NULL information_schema SLAVE_STATUS Master_last_event_time datetime NULL NULL NULL NULL datetime NULL information_schema SLAVE_STATUS Slave_last_event_time datetime NULL NULL NULL NULL datetime -NULL information_schema SLAVE_STATUS Master_Slave_time_diff int NULL NULL NULL NULL int(10) +NULL information_schema SLAVE_STATUS Master_Slave_time_diff int NULL NULL NULL NULL int(10) unsigned NULL information_schema SPATIAL_REF_SYS SRID smallint NULL NULL NULL NULL smallint(5) 3.0000 information_schema SPATIAL_REF_SYS AUTH_NAME varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) NULL information_schema SPATIAL_REF_SYS AUTH_SRID int NULL NULL NULL NULL int(5) diff --git a/sql/slave.cc b/sql/slave.cc index e16834a387d..25e948c6413 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2955,8 +2955,8 @@ void store_master_info(THD *thd, Master_info *mi, TABLE *table, store_string_or_null(field++, mi->host); store_string_or_null(field++, mi->user); - (*field++)->store((uint32) mi->port); - (*field++)->store((uint32) mi->connect_retry); + (*field++)->store((uint32) mi->port, true); + (*field++)->store((uint32) mi->connect_retry, true); (*field++)->store(mi->master_log_name, strlen(mi->master_log_name), &my_charset_bin); (*field++)->store((ulonglong) mi->master_log_pos, true); @@ -2979,9 +2979,9 @@ void store_master_info(THD *thd, Master_info *mi, TABLE *table, rpl_filter->get_wild_ignore_table(&tmp); (*field++)->store(tmp.ptr(), tmp.length(), &my_charset_bin); - (*field++)->store(mi->rli.last_error().number); + (*field++)->store(mi->rli.last_error().number, true); store_string_or_null(field++, mi->rli.last_error().message); - (*field++)->store((uint32) mi->rli.slave_skip_counter); + (*field++)->store((uint32) mi->rli.slave_skip_counter, true); (*field++)->store((ulonglong) mi->rli.group_master_log_pos, true); (*field++)->store((ulonglong) mi->rli.log_space_total, true); @@ -3069,17 +3069,17 @@ void store_master_info(THD *thd, Master_info *mi, TABLE *table, &my_charset_bin); // Last_IO_Errno - (*field++)->store(mi->last_error().number); + (*field++)->store(mi->last_error().number, true); // Last_IO_Error store_string_or_null(field++, mi->last_error().message); // Last_SQL_Errno - (*field++)->store(mi->rli.last_error().number); + (*field++)->store(mi->rli.last_error().number, true); // Last_SQL_Error store_string_or_null(field++, mi->rli.last_error().message); // Replicate_Ignore_Server_Ids field_store_ids((*field++), &mi->ignore_server_ids); // Master_Server_id - (*field++)->store((uint32) mi->master_id); + (*field++)->store((uint32) mi->master_id, true); // SQL_Delay // Master_Ssl_Crl store_string_or_null(field++, mi->ssl_crl); @@ -3103,7 +3103,8 @@ void store_master_info(THD *thd, Master_info *mi, TABLE *table, (*field++)->store(mode_name, strlen(mode_name), &my_charset_bin); } - (*field++)->store((uint32) mi->rli.get_sql_delay()); + // int32 on paper, unsigned in practice + (*field++)->store((uint32) mi->rli.get_sql_delay(), true); // SQL_Remaining_Delay // THD::proc_info is not protected by any lock, so we read it once // to ensure that we use the same value throughout this function. @@ -3112,7 +3113,7 @@ void store_master_info(THD *thd, Master_info *mi, TABLE *table, if (slave_sql_running_state == stage_sql_thd_waiting_until_delay.m_name) { time_t t= my_time(0), sql_delay_end= mi->rli.get_sql_delay_end(); - (*field++)->store((uint32)(t < sql_delay_end ? sql_delay_end - t : 0)); + (*field++)->store((uint32)(t < sql_delay_end ? sql_delay_end - t : 0), true); } else (*field++)->set_null(); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index acb57793e56..bf2833f2ce3 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -10628,7 +10628,7 @@ ST_FIELD_INFO slave_status_info[]= Column("Master_Host", Varchar(HOSTNAME_LENGTH), NULLABLE), Column("Master_User", Varchar(USERNAME_LENGTH), NULLABLE), Column("Master_Port", UShort(5), NOT_NULL), - Column("Connect_Retry", SLong(10), NOT_NULL), + Column("Connect_Retry", ULong(10), NOT_NULL), Column("Master_Log_File", Varchar(FN_REFLEN), NOT_NULL), Column("Read_Master_Log_Pos", ULonglong(20), NOT_NULL), Column("Relay_Log_File", Varchar(FN_REFLEN), NOT_NULL), @@ -10686,7 +10686,7 @@ ST_FIELD_INFO slave_status_info[]= Column("Gtid_Slave_Pos", Varchar(), NOT_NULL), Column("Master_last_event_time", Datetime(0), NULLABLE), Column("Slave_last_event_time", Datetime(0), NULLABLE), - Column("Master_Slave_time_diff", SLong(10), NULLABLE), + Column("Master_Slave_time_diff", ULong(10), NULLABLE), CEnd() }; #endif From 491e2b17a946016652797bcbdb0a46698061f2a4 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 29 Jan 2025 00:25:12 +0400 Subject: [PATCH 194/213] MDEV-35081 - Assertion `!n_mysql_tables_in_use' failed after error upon binary logging of DML involving vector table InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED. This limitation is enforced by a check within ha_innobase::external_lock(). InnoDB also expects number of "successful external locks" to match number of "external unlocks", which is controlled by the assertion in subject. However "unlock" was called even after failing "lock" for high-level indexes. Fixed by calling "unlock" only after "successful lock". --- mysql-test/suite/binlog/r/binlog_innodb_stm.result | 9 +++++++++ mysql-test/suite/binlog/t/binlog_innodb_stm.test | 14 ++++++++++++++ sql/sql_base.cc | 3 ++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/binlog/r/binlog_innodb_stm.result b/mysql-test/suite/binlog/r/binlog_innodb_stm.result index 829ed7d3c61..4a7702a1685 100644 --- a/mysql-test/suite/binlog/r/binlog_innodb_stm.result +++ b/mysql-test/suite/binlog/r/binlog_innodb_stm.result @@ -15,3 +15,12 @@ on update cascade insert into categories values (1, 'drinks', 'drinks'); update categories set cat_description=2 where cat_id=1; drop table products, categories; +# +# MDEV-35081 - Assertion `!n_mysql_tables_in_use' failed after error +# upon binary logging of DML involving vector table +# +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +CREATE TABLE t (pk INT PRIMARY KEY, v VECTOR(1) NOT NULL, VECTOR(v)) ENGINE=InnoDB; +UPDATE t SET pk = 2 WHERE pk = 1; +ERROR HY000: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging. InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED. +DROP TABLE t; diff --git a/mysql-test/suite/binlog/t/binlog_innodb_stm.test b/mysql-test/suite/binlog/t/binlog_innodb_stm.test index 4dfa7a76584..b1218a76452 100644 --- a/mysql-test/suite/binlog/t/binlog_innodb_stm.test +++ b/mysql-test/suite/binlog/t/binlog_innodb_stm.test @@ -24,3 +24,17 @@ create table products( insert into categories values (1, 'drinks', 'drinks'); update categories set cat_description=2 where cat_id=1; drop table products, categories; + + +--echo # +--echo # MDEV-35081 - Assertion `!n_mysql_tables_in_use' failed after error +--echo # upon binary logging of DML involving vector table +--echo # +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +CREATE TABLE t (pk INT PRIMARY KEY, v VECTOR(1) NOT NULL, VECTOR(v)) ENGINE=InnoDB; + +--error ER_BINLOG_STMT_MODE_AND_ROW_ENGINE +UPDATE t SET pk = 2 WHERE pk = 1; + +# Cleanup +DROP TABLE t; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index eb5f2af8be7..4e9261a453b 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -9830,7 +9830,6 @@ int TABLE::hlindex_lock(uint nr) DBUG_ASSERT(hlindex); if (hlindex->in_use == in_use) return 0; - hlindex->in_use= in_use; // mark in use for this query hlindex->use_all_columns(); THR_LOCK_DATA *lock_data; @@ -9839,6 +9838,8 @@ int TABLE::hlindex_lock(uint nr) int res= hlindex->file->ha_external_lock(in_use, reginfo.lock_type < TL_FIRST_WRITE ? F_RDLCK : F_WRLCK); + if (res == 0) + hlindex->in_use= in_use; // mark in use for this query if (hlindex->file->lock_count() > 0) { /* From 0e21ff8ca47ab637564b4c120322215caa70835d Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Mon, 20 Jan 2025 17:44:51 +0200 Subject: [PATCH 195/213] MDEV-35318 Assertion `tl->jtbm_subselect' failed in JOIN::calc_allowed_top_level_tables Alternative, more general fix, Variant 2. The problem was as follows: Suppose we are running a PS/SP statement and we get an error while doing optimization that is done once per statement life. This may leave the statement data structures in an undefined state, where it is not safe to execute it again. The fix: introduce LEX::needs_reprepare and set it in such cases. Make PS and SP runtime check it and re-prepare the statement before executing it again. We do not use Reprepare_observer, because it turns out it is tightly tied to watching versions of statement's objects. For example, it must not be used when running the statement for the first time, exactly when the once-per-statement-lifetime optimizations are done. --- mysql-test/main/create.result | 47 +++++++++++++++++++++++++++++++++++ mysql-test/main/create.test | 43 ++++++++++++++++++++++++++++++++ sql/sp_instr.cc | 2 +- sql/sql_lex.cc | 1 + sql/sql_lex.h | 7 ++++++ sql/sql_prepare.cc | 11 ++++++++ sql/sql_select.cc | 6 +++++ 7 files changed, 116 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/create.result b/mysql-test/main/create.result index a07695d5ba7..55521c18b76 100644 --- a/mysql-test/main/create.result +++ b/mysql-test/main/create.result @@ -2070,3 +2070,50 @@ SHOW CREATE DATABASE `#testone#■■■■■■■■■■■■■■■■ ERROR 42000: Incorrect database name '#testone#■■■■■■■■■■■■■■■■■■■■■■■■■■■■■...' SET NAMES DEFAULT; # End of 10.5 Test +# +# MDEV-35318 Assertion `tl->jtbm_subselect' failed in JOIN::calc_allowed_top_level_tables on 2nd execution of PS +# +CREATE TABLE t (a INT); +INSERT INTO t VALUES (1),(2); +PREPARE stmt FROM 'CREATE TABLE tmp AS SELECT * FROM (select t1.* from t t1 join t t2 on(t1.a = t2.a)) sq WHERE "x"=0'; +EXECUTE stmt; +ERROR 22007: Truncated incorrect DECIMAL value: 'x' +EXECUTE stmt; +ERROR 22007: Truncated incorrect DECIMAL value: 'x' +DEALLOCATE PREPARE stmt; +# Now, run the same in SP: +create procedure sp1() +begin +declare i int unsigned default 1; +declare continue handler for SQLEXCEPTION +begin +select 'In Continue handler' as printf; +end; +while i <= 3 do +begin +select concat('Iteration ', i) as printf; +CREATE temporary TABLE tmp AS +SELECT * FROM (select t1.* from t t1 join t t2 on(t1.a = t2.a)) sq WHERE "x"=0 ; +drop temporary table if exists tmp; +set i=i+1; +end; +end while; +end| +call sp1(); +printf +Iteration 1 +printf +In Continue handler +printf +Iteration 2 +printf +In Continue handler +printf +Iteration 3 +printf +In Continue handler +Warnings: +Note 1051 Unknown table 'test.tmp' +DROP PROCEDURE sp1; +DROP TABLE t; +# End of 11.7 Test diff --git a/mysql-test/main/create.test b/mysql-test/main/create.test index dada6963fdb..1213c8be6e0 100644 --- a/mysql-test/main/create.test +++ b/mysql-test/main/create.test @@ -1945,3 +1945,46 @@ SHOW CREATE DATABASE `#testone#■■■■■■■■■■■■■■■■ SET NAMES DEFAULT; --echo # End of 10.5 Test + +--echo # +--echo # MDEV-35318 Assertion `tl->jtbm_subselect' failed in JOIN::calc_allowed_top_level_tables on 2nd execution of PS +--echo # + +CREATE TABLE t (a INT); +INSERT INTO t VALUES (1),(2); # Optional, fails either way + +PREPARE stmt FROM 'CREATE TABLE tmp AS SELECT * FROM (select t1.* from t t1 join t t2 on(t1.a = t2.a)) sq WHERE "x"=0'; +--error ER_TRUNCATED_WRONG_VALUE +EXECUTE stmt; +--error ER_TRUNCATED_WRONG_VALUE +EXECUTE stmt; +DEALLOCATE PREPARE stmt; + +--echo # Now, run the same in SP: +delimiter |; + +create procedure sp1() +begin + declare i int unsigned default 1; + declare continue handler for SQLEXCEPTION + begin + select 'In Continue handler' as printf; + end; + while i <= 3 do + begin + select concat('Iteration ', i) as printf; + CREATE temporary TABLE tmp AS + SELECT * FROM (select t1.* from t t1 join t t2 on(t1.a = t2.a)) sq WHERE "x"=0 ; + drop temporary table if exists tmp; + set i=i+1; + end; + end while; +end| + +delimiter ;| +call sp1(); + +DROP PROCEDURE sp1; +DROP TABLE t; + +--echo # End of 11.7 Test diff --git a/sql/sp_instr.cc b/sql/sp_instr.cc index 20022741075..599301e7df2 100644 --- a/sql/sp_instr.cc +++ b/sql/sp_instr.cc @@ -459,7 +459,7 @@ int sp_lex_keeper::validate_lex_and_exec_core(THD *thd, uint *nextp, while (true) { - if (instr->is_invalid()) + if (instr->is_invalid() || m_lex->needs_reprepare) { thd->clear_error(); free_lex(thd); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 015b1a59a0f..098dcca8e09 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1336,6 +1336,7 @@ void LEX::start(THD *thd_arg) exchange= 0; table_count_update= 0; + needs_reprepare= false; memset(&trg_chistics, 0, sizeof(trg_chistics)); DBUG_VOID_RETURN; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 55fd7dc652a..07b50743b31 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -3136,6 +3136,13 @@ public: /* Query Plan Footprint of a currently running select */ Explain_query *explain; + /* + If true, query optimizer has encountered an unrecoverable error when doing + once-per-statement optimization and it is not safe to re-execute this + statement. + */ + bool needs_reprepare{false}; + /* LEX which represents current statement (conventional, SP or PS) diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 5c7a225da86..df485288243 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -4401,6 +4401,16 @@ Prepared_statement::execute_loop(String *expanded_query, */ DBUG_ASSERT(thd->free_list == NULL); + if (lex->needs_reprepare) + { + /* + Something has happened on previous execution that requires us to + re-prepare before we try to execute. + */ + lex->needs_reprepare= false; + goto start_with_reprepare; + } + /* Check if we got an error when sending long data */ if (unlikely(state == Query_arena::STMT_ERROR)) { @@ -4448,6 +4458,7 @@ reexecute: DBUG_ASSERT(thd->get_stmt_da()->sql_errno() == ER_NEED_REPREPARE); thd->clear_error(); +start_with_reprepare: error= reprepare(); if (likely(!error)) /* Success */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 62350b3754f..fbfd8446dfc 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2316,6 +2316,12 @@ JOIN::optimize_inner() if (thd->is_error() || (!select_lex->leaf_tables_saved && select_lex->save_leaf_tables(thd))) { + /* + If there was an error above, the data structures may have been left in + some undefined state. If this is a PS/SP statement, it might not be + safe to run it again. Note that it needs to be re-prepared. + */ + thd->lex->needs_reprepare= true; if (arena) thd->restore_active_arena(arena, &backup); DBUG_RETURN(1); From 14a80f092914c966e552128f1f5ae744dad86220 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Mon, 3 Feb 2025 14:58:58 +0200 Subject: [PATCH 196/213] MDEV-35318 Assertion `tl->jtbm_subselect' failed... - PART 2 After the fix in the previous commit, we should never end up in a situation where select_lex->first_cond_optimization=false (i.e, "it's done") but select_lex->leaf_tables_saved==false ("not done"). So, in setup_tables(), revert the the condition added in the fix for MDEV-25008. Add an assert instead. --- sql/sql_base.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 4e9261a453b..6165575b300 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -8241,7 +8241,7 @@ bool setup_tables(THD *thd, Name_resolution_context *context, 0); SELECT_LEX *select_lex= select_insert ? thd->lex->first_select_lex() : thd->lex->current_select; - if (select_lex->first_cond_optimization || !select_lex->leaf_tables_saved) + if (select_lex->first_cond_optimization) { leaves.empty(); if (select_lex->prep_leaf_list_state != SELECT_LEX::SAVED) @@ -8305,6 +8305,7 @@ bool setup_tables(THD *thd, Name_resolution_context *context, } else { + DBUG_ASSERT(select_lex->leaf_tables_saved); List_iterator_fast ti(select_lex->leaf_tables_exec); select_lex->leaf_tables.empty(); while ((table_list= ti++)) From fe31424e00083403bf746a0b6e4aa9a822f08b97 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 6 Feb 2025 16:47:52 +0100 Subject: [PATCH 197/213] fix sporadic test failures caused by InnoDB #record estimation --- mysql-test/main/desc_index_min_max.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/desc_index_min_max.test b/mysql-test/main/desc_index_min_max.test index 7df261cd749..fc786fc45d5 100644 --- a/mysql-test/main/desc_index_min_max.test +++ b/mysql-test/main/desc_index_min_max.test @@ -102,13 +102,13 @@ eval $query; # double reversion let $query= select max(200 - a) from t1; -replace_result 101 100; +replace_column 9 100; eval explain $query; eval $query; let $query= select min(200 - a) from t1; -replace_result 101 100; +replace_column 9 100; eval explain $query; eval $query; From adc1beb8680fc54a4c975a35880b5923d449eb20 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 5 Feb 2025 22:19:42 +0100 Subject: [PATCH 198/213] relax the assert it is possible (rocksdb_rpl.mdev12179) to have innobase_xa_prepare called and then innobase_commit, not innobase_commit_ordered, in autocommit mode. for example, with two XA-capable engines and no binlog. Or (galera.galera_as_master), WSREP_EMULATE_BINLOG() enables binlogging but SQL_BIN_LOG=0 disables write_transaction_to_binlog(). --- storage/innobase/handler/ha_innodb.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index cab9142d350..c5d3918e7ad 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -4637,10 +4637,9 @@ innobase_commit( ut_ad("invalid state" == 0); /* fall through */ case TRX_STATE_PREPARED: - ut_ad(commit_trx || trx->is_wsrep()); - ut_ad(thd_test_options(thd, OPTION_NOT_AUTOCOMMIT - | OPTION_BEGIN) - || trx->is_wsrep()); + ut_ad(commit_trx || + !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT + | OPTION_BEGIN)); /* fall through */ case TRX_STATE_ACTIVE: /* Transaction is deregistered only in a commit or a From 44d0f5864e8dc04464524c42dd916be20e9f152e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 5 Feb 2025 22:21:37 +0100 Subject: [PATCH 199/213] fix the test case --- mysql-test/main/vector_innodb.result | 4 ++-- mysql-test/main/vector_innodb.test | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/vector_innodb.result b/mysql-test/main/vector_innodb.result index 424873d0efe..ba84415b333 100644 --- a/mysql-test/main/vector_innodb.result +++ b/mysql-test/main/vector_innodb.result @@ -249,7 +249,7 @@ create table t (pk int primary key, v vector(1) not null, vector(v)) engine=inno insert into t values (1,0x31313131),(2,0x32323232); select distinct vec_distance_euclidean(v, 0x30303030) as d from t order by pk; d -0.0000000019375161827791346 -0.000000009731407668281116 +0.00000 +0.00000 drop table t; # End of 11.7 tests diff --git a/mysql-test/main/vector_innodb.test b/mysql-test/main/vector_innodb.test index 03a91bae33c..7d07650e79f 100644 --- a/mysql-test/main/vector_innodb.test +++ b/mysql-test/main/vector_innodb.test @@ -250,6 +250,7 @@ drop table t; create table t (pk int primary key, v vector(1) not null, vector(v)) engine=innodb; insert into t values (1,0x31313131),(2,0x32323232); # optional, fails either way +--replace_regex /(\.\d{5})\d+/\1/ select distinct vec_distance_euclidean(v, 0x30303030) as d from t order by pk; drop table t; From c45339118778b1d49db478f197c5c9110b2a3e97 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 15 Jan 2025 09:57:49 +0100 Subject: [PATCH 200/213] MDEV-35834 Server crash in FVector::distance_to upon concurrent SELECT a start node in the shared context must be atomically assigned to a valid and fully initialized node otherwise a concurrent thread might use it before it's safe --- sql/vector_mhnsw.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sql/vector_mhnsw.cc b/sql/vector_mhnsw.cc index 9777ce19ccd..4ef5f64296b 100644 --- a/sql/vector_mhnsw.cc +++ b/sql/vector_mhnsw.cc @@ -686,8 +686,13 @@ int MHNSW_Share::acquire(MHNSW_Share **ctx, TABLE *table, bool for_update) graph->file->position(graph->record[0]); (*ctx)->set_lengths(FVector::data_to_value_size(graph->field[FIELD_VEC]->value_length())); - (*ctx)->start= (*ctx)->get_node(graph->file->ref); - return (*ctx)->start->load_from_record(graph); + + auto node= (*ctx)->get_node(graph->file->ref); + if ((err= node->load_from_record(graph))) + return err; + + (*ctx)->start= node; // set the shared start only when node is fully loaded + return 0; } /* copy the vector, preprocessed as needed */ From e928bf1c0e4c3724b8837bf5e266086ba315ee5b Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Fri, 1 Nov 2024 12:04:49 +0400 Subject: [PATCH 201/213] MDEV-35292 - ALTER TABLE re-creating vector key is no-op with non-copying alter algorithms (default) ALTER TABLE didn't recognize VECTOR index options change and kept table intact. VECTOR indexes have their own options_struct, let ALTER TABLE use it. --- mysql-test/main/vector,aria.rdiff | 7 +++++++ mysql-test/main/vector,myisam.rdiff | 7 +++++++ mysql-test/main/vector.result | 14 ++++++++++++++ mysql-test/main/vector.test | 10 ++++++++++ mysql-test/main/vector2.result | 2 +- sql/sql_table.cc | 2 ++ 6 files changed, 41 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/vector,aria.rdiff b/mysql-test/main/vector,aria.rdiff index e7ab52f05da..71e16bea8ed 100644 --- a/mysql-test/main/vector,aria.rdiff +++ b/mysql-test/main/vector,aria.rdiff @@ -572,3 +572,10 @@ drop table t1; create table t1(v vector(5) not null, vector index(v)); alter table t1 add column a int; +@@ -889,5 +879,5 @@ Table Create Table + t CREATE TABLE `t` ( + `v` vector(1) NOT NULL, + VECTOR KEY `v` (`v`) `distance`=cosine +-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci ++) ENGINE=Aria DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci PAGE_CHECKSUM=1 + drop table t; diff --git a/mysql-test/main/vector,myisam.rdiff b/mysql-test/main/vector,myisam.rdiff index b33fa194569..e96a39a67c7 100644 --- a/mysql-test/main/vector,myisam.rdiff +++ b/mysql-test/main/vector,myisam.rdiff @@ -509,3 +509,10 @@ -) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci drop table t1; +@@ -877,5 +877,5 @@ + t CREATE TABLE `t` ( + `v` vector(1) NOT NULL, + VECTOR KEY `v` (`v`) `distance`=cosine +-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci ++) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + drop table t; diff --git a/mysql-test/main/vector.result b/mysql-test/main/vector.result index 86a4b56008f..8da9d1ac070 100644 --- a/mysql-test/main/vector.result +++ b/mysql-test/main/vector.result @@ -877,3 +877,17 @@ drop table t1; create table t1(v vector(5) not null, vector index(v)); alter table t1 add column a int; drop table t1; +# +# MDEV-35292 - ALTER TABLE re-creating vector key is no-op with +# non-copying alter algorithms (default) +# +create table t (v vector(1) not null, vector(v) distance=euclidean); +insert into t values (0x31313131); +alter table t drop index v, add vector(v) distance=cosine; +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `v` vector(1) NOT NULL, + VECTOR KEY `v` (`v`) `distance`=cosine +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +drop table t; diff --git a/mysql-test/main/vector.test b/mysql-test/main/vector.test index b89db83a750..969686dd59a 100644 --- a/mysql-test/main/vector.test +++ b/mysql-test/main/vector.test @@ -430,3 +430,13 @@ drop table t1; create table t1(v vector(5) not null, vector index(v)); alter table t1 add column a int; drop table t1; + +--echo # +--echo # MDEV-35292 - ALTER TABLE re-creating vector key is no-op with +--echo # non-copying alter algorithms (default) +--echo # +create table t (v vector(1) not null, vector(v) distance=euclidean); +insert into t values (0x31313131); # Optional, fails either way +alter table t drop index v, add vector(v) distance=cosine; +show create table t; +drop table t; diff --git a/mysql-test/main/vector2.result b/mysql-test/main/vector2.result index 92678db9c14..b30babb1c6d 100644 --- a/mysql-test/main/vector2.result +++ b/mysql-test/main/vector2.result @@ -143,7 +143,7 @@ Table Create Table t CREATE TABLE `t` ( `a` int(11) DEFAULT NULL, `v` vector(10) NOT NULL, - VECTOR KEY `v` (`v`) `m`=10 `distance`='cosine' + VECTOR KEY `v` (`v`) `distance`='cosine' ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci drop table t; set mhnsw_default_distance= default; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index bf321d1efa9..6f9a7c2019f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6794,6 +6794,8 @@ Compare_keys compare_keys_but_name(const KEY *table_key, const KEY *new_key, return Compare_keys::NotEqual; if (engine_options_differ(table_key->option_struct, new_key->option_struct, + table_key->algorithm == HA_KEY_ALG_VECTOR ? + mhnsw_index_options : table->file->ht->index_options)) return Compare_keys::NotEqual; From 5b8c087e84d094ea08e3c162919794a5a9ccb07f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 2 Feb 2025 20:13:57 +0100 Subject: [PATCH 202/213] MDEV-36005 Server crashes when checking/updating a table having vector key after enabling innodb_force_primary_key if creating a hlindex table failed, it should not unlock main table's plugin --- mysql-test/main/vector_innodb.result | 25 +++++++++++++++++++++++++ mysql-test/main/vector_innodb.test | 18 ++++++++++++++++++ sql/sql_base.cc | 2 ++ 3 files changed, 45 insertions(+) diff --git a/mysql-test/main/vector_innodb.result b/mysql-test/main/vector_innodb.result index ba84415b333..a78454ac723 100644 --- a/mysql-test/main/vector_innodb.result +++ b/mysql-test/main/vector_innodb.result @@ -252,4 +252,29 @@ d 0.00000 0.00000 drop table t; +# +# MDEV-36005 Server crashes when checking/updating a table having vector key after enabling innodb_force_primary_key +# +create table t (v vector (3) not null,vector index (v)) engine=innodb; +set global innodb_force_primary_key=1; +check table t extended; +Table Op Msg_type Msg_text +test.t check Error This table type requires a primary key +test.t check Error Engine InnoDB failed to discover table `test`.`t` with 'CREATE TABLE i ( layer tinyint not null, tref varbinary(6), vec blob not null, neighbors blob not null, unique (tref), key (layer)) ' +test.t check status Operation failed +check table t extended; +Table Op Msg_type Msg_text +test.t check Error This table type requires a primary key +test.t check Error Engine InnoDB failed to discover table `test`.`t` with 'CREATE TABLE i ( layer tinyint not null, tref varbinary(6), vec blob not null, neighbors blob not null, unique (tref), key (layer)) ' +test.t check status Operation failed +set global innodb_force_primary_key=0; +drop table t; +create table t (v vector (1) not null,vector index (v)) engine=innodb; +set global innodb_force_primary_key=1; +insert into t values (0x31313131); +ERROR HY000: Engine InnoDB failed to discover table `test`.`t` with 'CREATE TABLE i ( layer tinyint not null, tref varbinary(6), vec blob not null, neighbors blob not null, unique (tref), key (layer)) ' +insert into t values (0x32323232); +ERROR HY000: Engine InnoDB failed to discover table `test`.`t` with 'CREATE TABLE i ( layer tinyint not null, tref varbinary(6), vec blob not null, neighbors blob not null, unique (tref), key (layer)) ' +set global innodb_force_primary_key=0; +drop table t; # End of 11.7 tests diff --git a/mysql-test/main/vector_innodb.test b/mysql-test/main/vector_innodb.test index 7d07650e79f..70be0a5d97d 100644 --- a/mysql-test/main/vector_innodb.test +++ b/mysql-test/main/vector_innodb.test @@ -254,4 +254,22 @@ insert into t values (1,0x31313131),(2,0x32323232); # optional, fails either way select distinct vec_distance_euclidean(v, 0x30303030) as d from t order by pk; drop table t; +--echo # +--echo # MDEV-36005 Server crashes when checking/updating a table having vector key after enabling innodb_force_primary_key +--echo # +create table t (v vector (3) not null,vector index (v)) engine=innodb; +set global innodb_force_primary_key=1; +check table t extended; +check table t extended; +set global innodb_force_primary_key=0; +drop table t; + +create table t (v vector (1) not null,vector index (v)) engine=innodb; +set global innodb_force_primary_key=1; +--error ER_SQL_DISCOVER_ERROR +insert into t values (0x31313131); +--error ER_SQL_DISCOVER_ERROR +insert into t values (0x32323232); +set global innodb_force_primary_key=0; +drop table t; --echo # End of 11.7 tests diff --git a/sql/sql_base.cc b/sql/sql_base.cc index c2ec97b7221..8da9d2cfb92 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -9827,6 +9827,8 @@ int TABLE::hlindex_open(uint nr) if (share->init_from_sql_statement_string(in_use, false, sql.str, sql.length)) { + if (share->db_plugin == s->db_plugin) + share->db_plugin= NULL; free_table_share(share); return 1; } From 69041af67d3d89fcad0eda4771c02afd530ff3e9 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 2 Feb 2025 22:51:12 +0100 Subject: [PATCH 203/213] only enforce innodb_force_primary_key when a table is created not when a hlindex table is auto-discovered internally --- mysql-test/main/vector_innodb.result | 14 +++++--------- mysql-test/main/vector_innodb.test | 8 +++++--- sql/table.cc | 1 + storage/innobase/handler/ha_innodb.cc | 8 +++++++- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/mysql-test/main/vector_innodb.result b/mysql-test/main/vector_innodb.result index a78454ac723..673c047eed1 100644 --- a/mysql-test/main/vector_innodb.result +++ b/mysql-test/main/vector_innodb.result @@ -259,22 +259,18 @@ create table t (v vector (3) not null,vector index (v)) engine=innodb; set global innodb_force_primary_key=1; check table t extended; Table Op Msg_type Msg_text -test.t check Error This table type requires a primary key -test.t check Error Engine InnoDB failed to discover table `test`.`t` with 'CREATE TABLE i ( layer tinyint not null, tref varbinary(6), vec blob not null, neighbors blob not null, unique (tref), key (layer)) ' -test.t check status Operation failed +test.t check status OK check table t extended; Table Op Msg_type Msg_text -test.t check Error This table type requires a primary key -test.t check Error Engine InnoDB failed to discover table `test`.`t` with 'CREATE TABLE i ( layer tinyint not null, tref varbinary(6), vec blob not null, neighbors blob not null, unique (tref), key (layer)) ' -test.t check status Operation failed +test.t check status OK set global innodb_force_primary_key=0; drop table t; create table t (v vector (1) not null,vector index (v)) engine=innodb; set global innodb_force_primary_key=1; insert into t values (0x31313131); -ERROR HY000: Engine InnoDB failed to discover table `test`.`t` with 'CREATE TABLE i ( layer tinyint not null, tref varbinary(6), vec blob not null, neighbors blob not null, unique (tref), key (layer)) ' insert into t values (0x32323232); -ERROR HY000: Engine InnoDB failed to discover table `test`.`t` with 'CREATE TABLE i ( layer tinyint not null, tref varbinary(6), vec blob not null, neighbors blob not null, unique (tref), key (layer)) ' -set global innodb_force_primary_key=0; drop table t; +create table t (v vector (1) not null,vector index (v)) engine=innodb; +ERROR 42000: This table type requires a primary key +set global innodb_force_primary_key=0; # End of 11.7 tests diff --git a/mysql-test/main/vector_innodb.test b/mysql-test/main/vector_innodb.test index 70be0a5d97d..90ae83f2cf5 100644 --- a/mysql-test/main/vector_innodb.test +++ b/mysql-test/main/vector_innodb.test @@ -266,10 +266,12 @@ drop table t; create table t (v vector (1) not null,vector index (v)) engine=innodb; set global innodb_force_primary_key=1; ---error ER_SQL_DISCOVER_ERROR insert into t values (0x31313131); ---error ER_SQL_DISCOVER_ERROR insert into t values (0x32323232); -set global innodb_force_primary_key=0; drop table t; + +# vector index table has no PK, so cannot be created: +--error ER_REQUIRES_PRIMARY_KEY +create table t (v vector (1) not null,vector index (v)) engine=innodb; +set global innodb_force_primary_key=0; --echo # End of 11.7 tests diff --git a/sql/table.cc b/sql/table.cc index 3361b017632..9fadee37cb6 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -3699,6 +3699,7 @@ int TABLE_SHARE::init_from_sql_statement_string(THD *thd, bool write, if (tabledef_version.str) tmp_lex.create_info.tabledef_version= tabledef_version; + tmp_lex.sql_command= old_lex->sql_command; tmp_lex.alter_info.db= db; tmp_lex.alter_info.table_name= table_name; promote_first_timestamp_column(&tmp_lex.alter_info.create_list); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index c5d3918e7ad..806afb0f0a4 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -3097,7 +3097,6 @@ ha_innobase::ha_innobase( | HA_CAN_ONLINE_BACKUPS | HA_CONCURRENT_OPTIMIZE | HA_CAN_SKIP_LOCKED - | (srv_force_primary_key ? HA_REQUIRE_PRIMARY_KEY : 0) ), m_start_of_scan(), m_mysql_has_locked() @@ -5062,6 +5061,13 @@ ha_innobase::table_flags() const THD* thd = ha_thd(); handler::Table_flags flags = m_int_table_flags; + /* enforce primary key when a table is created, but not when + an existing (hlindex?) table is auto-discovered */ + if (srv_force_primary_key && + thd_sql_command(thd) == SQLCOM_CREATE_TABLE) { + flags|= HA_REQUIRE_PRIMARY_KEY; + } + /* Need to use tx_isolation here since table flags is (also) called before prebuilt is inited. */ From 6fc75e086874b97e23a0c631d5b272cf94e1258f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 3 Feb 2025 12:08:10 +0100 Subject: [PATCH 204/213] MDEV-35922 Server crashes in mhnsw_read_first upon using vector key with views --- mysql-test/main/vector_innodb.result | 12 ++++++++++++ mysql-test/main/vector_innodb.test | 11 +++++++++++ sql/item_vectorfunc.h | 4 ++-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/vector_innodb.result b/mysql-test/main/vector_innodb.result index 673c047eed1..f308b8a93dd 100644 --- a/mysql-test/main/vector_innodb.result +++ b/mysql-test/main/vector_innodb.result @@ -273,4 +273,16 @@ drop table t; create table t (v vector (1) not null,vector index (v)) engine=innodb; ERROR 42000: This table type requires a primary key set global innodb_force_primary_key=0; +# +# MDEV-35922 Server crashes in mhnsw_read_first upon using vector key with views +# +create table t (pk int primary key, v vector(1) not null, vector(v)) engine=innodb; +insert into t values (1,0x31313131),(2,0x32323232); +create view v as select * from t; +select pk from v order by vec_distance_euclidean(v, 0x30303030) limit 2; +pk +1 +2 +drop view v; +drop table t; # End of 11.7 tests diff --git a/mysql-test/main/vector_innodb.test b/mysql-test/main/vector_innodb.test index 90ae83f2cf5..60e1f8ac7d6 100644 --- a/mysql-test/main/vector_innodb.test +++ b/mysql-test/main/vector_innodb.test @@ -274,4 +274,15 @@ drop table t; --error ER_REQUIRES_PRIMARY_KEY create table t (v vector (1) not null,vector index (v)) engine=innodb; set global innodb_force_primary_key=0; + +--echo # +--echo # MDEV-35922 Server crashes in mhnsw_read_first upon using vector key with views +--echo # +create table t (pk int primary key, v vector(1) not null, vector(v)) engine=innodb; +insert into t values (1,0x31313131),(2,0x32323232); +create view v as select * from t; +select pk from v order by vec_distance_euclidean(v, 0x30303030) limit 2; +drop view v; +drop table t; + --echo # End of 11.7 tests diff --git a/sql/item_vectorfunc.h b/sql/item_vectorfunc.h index e6da1b77441..d2094e28e4b 100644 --- a/sql/item_vectorfunc.h +++ b/sql/item_vectorfunc.h @@ -49,9 +49,9 @@ public: double val_real() override; Item *get_const_arg() const { - if (args[0]->type() == Item::FIELD_ITEM && args[1]->const_item()) + if (args[0]->real_item()->type() == Item::FIELD_ITEM && args[1]->const_item()) return args[1]; - if (args[1]->type() == Item::FIELD_ITEM && args[0]->const_item()) + if (args[1]->real_item()->type() == Item::FIELD_ITEM && args[0]->const_item()) return args[0]; return NULL; } From a2f0234c82a67d6af13ace3bda0e6735a5c9f9f7 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 3 Feb 2025 12:27:03 +0100 Subject: [PATCH 205/213] MDEV-36011 Server crashes in Charset::mbminlen / Item_func_vec_fromtext::val_str upon mixing vector type with string --- mysql-test/main/vector_funcs.result | Bin 6364 -> 6604 bytes mysql-test/main/vector_funcs.test | 7 +++++++ sql/item_vectorfunc.cc | 1 + 3 files changed, 8 insertions(+) diff --git a/mysql-test/main/vector_funcs.result b/mysql-test/main/vector_funcs.result index ab29a760c7b24e21fcc302abff54a22518b67acc..ec3a5830138f8165f32c97631c503ca30aa35d9f 100644 GIT binary patch delta 216 zcmca(c*c0c9SIX1IoLxtefqO#N?h2)~d;*8W{h0Ht!=ZwUn;?xo= ztK6jA%)Fe`JO%y9`66odxtSH2dFcvesmUezMG7UA1*r<null_value' failed upon VEC_TOTEXT call --echo # select vec_totext(`null`) from (values (null),(0x00000000)) x; + +--echo # +--echo # MDEV-36011 Server crashes in Charset::mbminlen / Item_func_vec_fromtext::val_str upon mixing vector type with string +--echo # +select 0x31313131 in ('1111', vec_fromtext('[1]')); + +--echo # End of 11. tests diff --git a/sql/item_vectorfunc.cc b/sql/item_vectorfunc.cc index e7686657728..1179855ce80 100644 --- a/sql/item_vectorfunc.cc +++ b/sql/item_vectorfunc.cc @@ -142,6 +142,7 @@ String *Item_func_vec_fromtext::val_str(String *buf) return nullptr; buf->length(0); + buf->set_charset(&my_charset_bin); CHARSET_INFO *cs= value->charset(); const uchar *start= reinterpret_cast(value->ptr()); const uchar *end= start + value->length(); From 40d39b1176444fe297d593415d5c1089c4614905 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 3 Feb 2025 15:19:30 +0100 Subject: [PATCH 206/213] MDEV-35221 Vector values do not survive mariadb-dump / restore force --hex-dump for fields of GEOMETRY, BIT, and VECTOR types. Until MDEV-35831 is fixed, vector type is detected by name. --- client/mysqldump.cc | 47 +++++++++---- mysql-test/main/vector2_notembedded.result | 78 +++++++++++----------- mysql-test/main/vector2_notembedded.test | 16 ++--- 3 files changed, 78 insertions(+), 63 deletions(-) diff --git a/client/mysqldump.cc b/client/mysqldump.cc index bc895a3f4f0..460738edcb9 100644 --- a/client/mysqldump.cc +++ b/client/mysqldump.cc @@ -103,6 +103,9 @@ #define DUMP_TABLE_TABLE 0 #define DUMP_TABLE_SEQUENCE 1 +/* until MDEV-35831 is implemented, we'll have to detect VECTOR by name */ +#define MYSQL_TYPE_VECTOR "V" + static my_bool ignore_table_data(const uchar *hash_key, size_t len); static void add_load_option(DYNAMIC_STRING *str, const char *option, const char *option_value); @@ -147,7 +150,7 @@ static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0, static ulong opt_max_allowed_packet, opt_net_buffer_length; static double opt_max_statement_time= 0.0; static MYSQL *mysql=0; -static DYNAMIC_STRING insert_pat, select_field_names, +static DYNAMIC_STRING insert_pat, select_field_names, field_flags, select_field_names_for_header, insert_field_names; static char *opt_password=0,*current_user=0, *current_host=0,*path=0,*fields_terminated=0, @@ -2009,6 +2012,7 @@ static void free_resources() dynstr_free(&dynamic_where); dynstr_free(&insert_pat); dynstr_free(&select_field_names); + dynstr_free(&field_flags); dynstr_free(&select_field_names_for_header); dynstr_free(&insert_field_names); if (defaults_argv) @@ -3181,6 +3185,7 @@ static uint get_table_structure(const char *table, const char *db, char *table_t { select_field_names_inited= 1; init_dynamic_string_checked(&select_field_names, "", 1024, 1024); + init_dynamic_string_checked(&field_flags, "", 1024, 1024); init_dynamic_string_checked(&insert_field_names, "", 1024, 1024); if (opt_header) init_dynamic_string_checked(&select_field_names_for_header, "", 1024, 1024); @@ -3188,6 +3193,7 @@ static uint get_table_structure(const char *table, const char *db, char *table_t else { dynstr_set_checked(&select_field_names, ""); + dynstr_set_checked(&field_flags, ""); dynstr_set_checked(&insert_field_names, ""); if (opt_header) dynstr_set_checked(&select_field_names_for_header, ""); @@ -3489,6 +3495,11 @@ static uint get_table_structure(const char *table, const char *db, char *table_t if (opt_header) dynstr_append_checked(&select_field_names_for_header, quote_for_equal(row[0], name_buff)); + /* VECTOR doesn't have a type code yet, must be detected by name */ + if (row[3] && strcmp(row[3], "vector") == 0) + dynstr_append_checked(&field_flags, MYSQL_TYPE_VECTOR); + else + dynstr_append_checked(&field_flags, " "); } if (vers_hidden) @@ -3502,6 +3513,7 @@ static uint get_table_structure(const char *table, const char *db, char *table_t "row_end" : "row_end"); dynstr_append_checked(&insert_field_names, ", row_start, row_end"); + dynstr_append_checked(&field_flags, " "); } /* @@ -3608,6 +3620,11 @@ static uint get_table_structure(const char *table, const char *db, char *table_t while ((row= mysql_fetch_row(result))) { ulong *lengths= mysql_fetch_lengths(result); + /* VECTOR doesn't have a type code yet, must be detected by name */ + if (strncmp(row[SHOW_TYPE], STRING_WITH_LEN("vector(")) == 0) + dynstr_append_checked(&field_flags, MYSQL_TYPE_VECTOR); + else + dynstr_append_checked(&field_flags, " "); if (init) { if (!opt_xml && !opt_no_create_info) @@ -4491,21 +4508,23 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key, "Not enough fields from table %s! Aborting.\n", result_table); + DBUG_ASSERT(field_flags.length > i); /* 63 is my_charset_bin. If charsetnr is not 63, we have not a BLOB but a TEXT column. we'll dump in hex only BLOB columns. */ - is_blob= (opt_hex_blob && field->charsetnr == 63 && - (field->type == MYSQL_TYPE_BIT || - field->type == MYSQL_TYPE_STRING || - field->type == MYSQL_TYPE_VAR_STRING || - field->type == MYSQL_TYPE_VARCHAR || - field->type == MYSQL_TYPE_BLOB || - field->type == MYSQL_TYPE_LONG_BLOB || - field->type == MYSQL_TYPE_MEDIUM_BLOB || - field->type == MYSQL_TYPE_TINY_BLOB || - field->type == MYSQL_TYPE_GEOMETRY)) ? 1 : 0; + is_blob= field->type == MYSQL_TYPE_GEOMETRY || + field->type == MYSQL_TYPE_BIT || + field_flags.str[i] == MYSQL_TYPE_VECTOR[0] || + (opt_hex_blob && field->charsetnr == 63 && + (field->type == MYSQL_TYPE_STRING || + field->type == MYSQL_TYPE_VAR_STRING || + field->type == MYSQL_TYPE_VARCHAR || + field->type == MYSQL_TYPE_BLOB || + field->type == MYSQL_TYPE_LONG_BLOB || + field->type == MYSQL_TYPE_MEDIUM_BLOB || + field->type == MYSQL_TYPE_TINY_BLOB)); if (extended_insert && !opt_xml) { if (i == 0) @@ -4528,7 +4547,7 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key, Also we need to reserve 1 byte for terminating '\0'. */ dynstr_realloc_checked(&extended_row,length * 2 + 2 + 1); - if (opt_hex_blob && is_blob) + if (is_blob) { dynstr_append_checked(&extended_row, "0x"); extended_row.length+= mysql_hex_string(extended_row.str + @@ -4589,7 +4608,7 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key, { if (opt_xml) { - if (opt_hex_blob && is_blob && length) + if (is_blob && length) { /* Define xsi:type="xs:hexBinary" for hex encoded data */ print_xml_tag(md_result_file, "\t\t", "", "field", "name=", @@ -4604,7 +4623,7 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key, } fputs("\n", md_result_file); } - else if (opt_hex_blob && is_blob && length) + else if (is_blob && length) { fputs("0x", md_result_file); print_blob_as_hex(md_result_file, row[i], length); diff --git a/mysql-test/main/vector2_notembedded.result b/mysql-test/main/vector2_notembedded.result index 22c7483e597..b84e6cdee95 100644 --- a/mysql-test/main/vector2_notembedded.result +++ b/mysql-test/main/vector2_notembedded.result @@ -1,68 +1,70 @@ # # mysqldump # -create table t1 (id int auto_increment primary key, v vector(5) not null, vector index (v)); +create table t1 (id int auto_increment primary key, v vector(5) not null); insert t1 (v) values (Vec_Fromtext('[0.418,0.809,0.823,0.598,0.033]')), -(Vec_Fromtext('[0.687,0.789,0.496,0.574,0.917]')), -(Vec_Fromtext('[0.333,0.962,0.467,0.448,0.475]')), -(Vec_Fromtext('[0.822,0.185,0.683,0.211,0.554]')), -(Vec_Fromtext('[0.437,0.167,0.077,0.428,0.241]')), -(Vec_Fromtext('[0.769,0.926,0.803,0.015,0.589]')), -(Vec_Fromtext('[0.493,0.641,0.761,0.942,0.425]')), -(Vec_Fromtext('[0.924,0.275,0.054,0.073,0.136]')), (Vec_Fromtext('[0.186,0.696,0.035,0.668,0.847]')), (Vec_Fromtext('[0.415,0.609,0.426,0.988,0.475]')); select id from t1 order by vec_distance_euclidean(v, Vec_FromText('[1,0,0,0,0]')) limit 3; id -8 -5 -4 +1 +3 +2 /*M!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `v` vector(5) NOT NULL, - PRIMARY KEY (`id`), - VECTOR KEY `v` (`v`) -) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; + PRIMARY KEY (`id`) +) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; INSERT INTO `t1` VALUES (1,0x1904D63EA01A4F3F21B0523F8716193F022B073D), -(2,0x3BDF2F3FE7FB493FB6F3FD3EAAF1123F83C06A3F), -(3,0xFA7EAA3EA245763FA01AEF3E4260E53E3333F33E), -(4,0x986E523FA4703D3E17D92E3F6210583EF2D20D3F), -(5,0x77BEDF3E0C022B3E2DB29D3DD122DB3EB4C8763E), -(6,0x2FDD443F560E6D3F68914D3F8FC2753CB4C8163F), -(7,0x7F6AFC3E9318243FE5D0423FE926713F9A99D93E), -(8,0x448B6C3FCDCC8C3E1B2F5D3D0681953D96430B3E), -(9,0xC9763E3E0E2D323F295C0F3D0C022B3FFED4583F), -(10,0xE17AD43E6DE71B3FAC1CDA3E91ED7C3F3333F33E); +(2,0xC9763E3E0E2D323F295C0F3D0C022B3FFED4583F), +(3,0xE17AD43E6DE71B3FAC1CDA3E91ED7C3F3333F33E); + + + + + + + + + + + + 1 + 1904D63EA01A4F3F21B0523F8716193F022B073D + + + 2 + C9763E3E0E2D323F295C0F3D0C022B3FFED4583F + + + 3 + E17AD43E6DE71B3FAC1CDA3E91ED7C3F3333F33E + + + + show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `v` vector(5) NOT NULL, - PRIMARY KEY (`id`), - VECTOR KEY `v` (`v`) -) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PRIMARY KEY (`id`) +) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci select id, Vec_ToText(v) from t1; id Vec_ToText(v) 1 [0.418,0.809,0.823,0.598,0.033] -2 [0.687,0.789,0.496,0.574,0.917] -3 [0.333,0.962,0.467,0.448,0.475] -4 [0.822,0.185,0.683,0.211,0.554] -5 [0.437,0.167,0.077,0.428,0.241] -6 [0.769,0.926,0.803,0.015,0.589] -7 [0.493,0.641,0.761,0.942,0.425] -8 [0.924,0.275,0.054,0.073,0.136] -9 [0.186,0.696,0.035,0.668,0.847] -10 [0.415,0.609,0.426,0.988,0.475] +2 [0.186,0.696,0.035,0.668,0.847] +3 [0.415,0.609,0.426,0.988,0.475] select id from t1 order by vec_distance_euclidean(v, Vec_FromText('[1,0,0,0,0]')) limit 3; id -8 -5 -4 +1 +3 +2 drop table t1; # # MDEV-35044 ALTER on a table with vector index attempts to bypass unsupported locking limitation, server crashes in THD::free_tmp_table_share diff --git a/mysql-test/main/vector2_notembedded.test b/mysql-test/main/vector2_notembedded.test index 63f827ce864..b7cd82b1a9d 100644 --- a/mysql-test/main/vector2_notembedded.test +++ b/mysql-test/main/vector2_notembedded.test @@ -5,21 +5,15 @@ --echo # --echo # mysqldump --echo # -create table t1 (id int auto_increment primary key, v vector(5) not null, vector index (v)); +create table t1 (id int auto_increment primary key, v vector(5) not null); insert t1 (v) values (Vec_Fromtext('[0.418,0.809,0.823,0.598,0.033]')), - (Vec_Fromtext('[0.687,0.789,0.496,0.574,0.917]')), - (Vec_Fromtext('[0.333,0.962,0.467,0.448,0.475]')), - (Vec_Fromtext('[0.822,0.185,0.683,0.211,0.554]')), - (Vec_Fromtext('[0.437,0.167,0.077,0.428,0.241]')), - (Vec_Fromtext('[0.769,0.926,0.803,0.015,0.589]')), - (Vec_Fromtext('[0.493,0.641,0.761,0.942,0.425]')), - (Vec_Fromtext('[0.924,0.275,0.054,0.073,0.136]')), (Vec_Fromtext('[0.186,0.696,0.035,0.668,0.847]')), (Vec_Fromtext('[0.415,0.609,0.426,0.988,0.475]')); select id from t1 order by vec_distance_euclidean(v, Vec_FromText('[1,0,0,0,0]')) limit 3; -replace_result InnoDB MyISAM; -exec $MYSQL_DUMP --compact --hex-blob test t1; -exec $MYSQL_DUMP --hex-blob test t1 > $MYSQL_TMP_DIR/vector.sql; +exec $MYSQL_DUMP --compact test t1; +replace_regex /\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d/YYYY-MM-DD hh:mm:ss/; +exec $MYSQL_DUMP --compact --xml test t1; +exec $MYSQL_DUMP test t1 > $MYSQL_TMP_DIR/vector.sql; exec $MYSQL test < $MYSQL_TMP_DIR/vector.sql; remove_file $MYSQL_TMP_DIR/vector.sql; show create table t1; From 1ea79d17748d5c63409e91fd42e7029b4104fa06 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 3 Feb 2025 18:27:13 +0100 Subject: [PATCH 207/213] MDEV-35317 Server crashes in mhnsw_insert upon using vector key on a Spider table don't allow VECTOR indexes in SPIDER tables --- storage/spider/ha_spider.cc | 6 +++++ .../spider/mysql-test/spider/r/vector.result | 27 +++++++++++++++++++ .../spider/mysql-test/spider/t/vector.test | 21 +++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 storage/spider/mysql-test/spider/r/vector.result create mode 100644 storage/spider/mysql-test/spider/t/vector.test diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc index d97e114990c..038609ce6c6 100644 --- a/storage/spider/ha_spider.cc +++ b/storage/spider/ha_spider.cc @@ -65,6 +65,7 @@ void ha_spider::init_fields() append_tblnm_alias = NULL; use_index_merge = FALSE; is_clone = FALSE; + pushed_pos = NULL; pt_clone_source_handler = NULL; pt_clone_last_searcher = NULL; ft_handler = NULL; @@ -6783,6 +6784,11 @@ int ha_spider::create( sql_command == SQLCOM_DROP_INDEX ) DBUG_RETURN(0); + if (form->s->hlindexes() > 0) + { + my_error(ER_ILLEGAL_HA_CREATE_OPTION, MYF(0), "SPIDER", "VECTOR"); + DBUG_RETURN(HA_ERR_UNSUPPORTED); + } if (!is_supported_parser_charset(info->default_table_charset)) { String charset_option; diff --git a/storage/spider/mysql-test/spider/r/vector.result b/storage/spider/mysql-test/spider/r/vector.result new file mode 100644 index 00000000000..7541bacfc24 --- /dev/null +++ b/storage/spider/mysql-test/spider/r/vector.result @@ -0,0 +1,27 @@ +INSTALL SONAME 'ha_spider'; +SET spider_same_server_link= ON; +create server s foreign data wrapper mysql options (host "127.0.0.1", database "test", user "root", port $MASTER_1_MYPORT); +# +# MDEV-35317 Server crashes in mhnsw_insert upon using vector key on a Spider table +# +CREATE TABLE t (v VECTOR(1) NOT NULL, VECTOR(v)); +CREATE TABLE t_spider (v VECTOR(1) NOT NULL, VECTOR(v)) ENGINE=Spider WRAPPER=mysql REMOTE_TABLE=t REMOTE_SERVER=s; +ERROR HY000: Table storage engine 'SPIDER' does not support the create option 'VECTOR' +INSERT INTO t_spider (v) VALUES (0x30303030); +ERROR 42S02: Table 'test.t_spider' doesn't exist +DROP TABLE t; +DROP FUNCTION IF EXISTS spider_flush_table_mon_cache; +DROP FUNCTION IF EXISTS spider_copy_tables; +DROP FUNCTION IF EXISTS spider_ping_table; +DROP FUNCTION IF EXISTS spider_bg_direct_sql; +DROP FUNCTION IF EXISTS spider_direct_sql; +UNINSTALL SONAME IF EXISTS 'ha_spider'; +DROP TABLE IF EXISTS mysql.spider_xa; +DROP TABLE IF EXISTS mysql.spider_xa_member; +DROP TABLE IF EXISTS mysql.spider_xa_failed_log; +DROP TABLE IF EXISTS mysql.spider_tables; +DROP TABLE IF EXISTS mysql.spider_link_mon_servers; +DROP TABLE IF EXISTS mysql.spider_link_failed_log; +DROP TABLE IF EXISTS mysql.spider_table_position_for_recovery; +DROP TABLE IF EXISTS mysql.spider_table_sts; +DROP TABLE IF EXISTS mysql.spider_table_crd; diff --git a/storage/spider/mysql-test/spider/t/vector.test b/storage/spider/mysql-test/spider/t/vector.test new file mode 100644 index 00000000000..f27e40edc95 --- /dev/null +++ b/storage/spider/mysql-test/spider/t/vector.test @@ -0,0 +1,21 @@ +INSTALL SONAME 'ha_spider'; +SET spider_same_server_link= ON; + +--evalp create server s foreign data wrapper mysql options (host "127.0.0.1", database "test", user "root", port $MASTER_1_MYPORT) + +--echo # +--echo # MDEV-35317 Server crashes in mhnsw_insert upon using vector key on a Spider table +--echo # +CREATE TABLE t (v VECTOR(1) NOT NULL, VECTOR(v)); + +# +# For now, SPIDER doesn't support VECTOR indexes. +# When it's fixed, two --error below should be removed +# +--error ER_ILLEGAL_HA_CREATE_OPTION +CREATE TABLE t_spider (v VECTOR(1) NOT NULL, VECTOR(v)) ENGINE=Spider WRAPPER=mysql REMOTE_TABLE=t REMOTE_SERVER=s; +--error ER_NO_SUCH_TABLE +INSERT INTO t_spider (v) VALUES (0x30303030); + +DROP TABLE t; +--source include/clean_up_spider.inc From a37eb6d01312b850459a744162d1fe9e91ba218a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 3 Feb 2025 19:33:59 +0100 Subject: [PATCH 208/213] MDEV-35792 Adding a regular index on a vector column leads to invalid table structure don't create a prefix key for types that don't support prefix keys --- mysql-test/main/vector2.result | 13 +++++++++++++ mysql-test/main/vector2.test | 9 +++++++++ sql/sql_table.cc | 2 +- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/vector2.result b/mysql-test/main/vector2.result index b30babb1c6d..e1ed40d0774 100644 --- a/mysql-test/main/vector2.result +++ b/mysql-test/main/vector2.result @@ -395,4 +395,17 @@ flush tables; update t set v = 1; ERROR HY000: Cannot cast 'int' as 'vector' in assignment of `test`.`t`.`v` drop table t; +# +# MDEV-35792 Adding a regular index on a vector column leads to invalid table structure +# +create table t (v vector(800), key(v)); +ERROR 42000: Specified key was too long; max key length is 1000 bytes +create table t (v vector(8), key(v)); +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `v` vector(8) DEFAULT NULL, + KEY `v` (`v`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +drop table t; # End of 11.7 tests diff --git a/mysql-test/main/vector2.test b/mysql-test/main/vector2.test index 916792277b1..d63583f9c07 100644 --- a/mysql-test/main/vector2.test +++ b/mysql-test/main/vector2.test @@ -289,4 +289,13 @@ flush tables; update t set v = 1; drop table t; +--echo # +--echo # MDEV-35792 Adding a regular index on a vector column leads to invalid table structure +--echo # +--error ER_TOO_LONG_KEY +create table t (v vector(800), key(v)); +create table t (v vector(8), key(v)); +show create table t; +drop table t; + --echo # End of 11.7 tests diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 6f9a7c2019f..3d29d1115b3 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3012,7 +3012,7 @@ my_bool init_key_part_spec(THD *thd, Alter_info *alter_info, } if (key_part_length > max_key_part_length) { - if (key.type == Key::MULTIPLE) + if (key.type == Key::MULTIPLE && type_handler->type_can_have_key_part()) { key_part_length= max_key_part_length; /* not a critical problem */ From e240da3b1943c876e5431c3b5b54374f67661c62 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 6 Feb 2025 21:46:53 +0100 Subject: [PATCH 209/213] MDEV-35146 Vector-related error messages worth improving when possible use THD::push_warning_truncated_value_for_field() to push the truncated warning consistently with other data types --- mysql-test/main/vector.test | 6 +++--- mysql-test/main/vector2.result | 17 ++++++++++++++++- mysql-test/main/vector2.test | 17 ++++++++++++++--- sql/sql_type_vector.cc | 10 +++------- 4 files changed, 36 insertions(+), 14 deletions(-) diff --git a/mysql-test/main/vector.test b/mysql-test/main/vector.test index 969686dd59a..4da1aeb4b95 100644 --- a/mysql-test/main/vector.test +++ b/mysql-test/main/vector.test @@ -122,11 +122,11 @@ insert t1 (v) values (x'e360d63ebe554f3fcdbc523f4522193f5236083d'), select id,vec_distance_euclidean(v, x'b047263c9f87233Fcfd27e3eae493e3f0329f43e') d from t1 order by d limit 5; ---error ER_TRUNCATED_WRONG_VALUE_FOR_FIELD +--error ER_TRUNCATED_WRONG_VALUE insert t1 (v) values (''); ---error ER_TRUNCATED_WRONG_VALUE_FOR_FIELD +--error ER_TRUNCATED_WRONG_VALUE insert t1 (v) values (x'1234'); ---error ER_TRUNCATED_WRONG_VALUE_FOR_FIELD +--error ER_TRUNCATED_WRONG_VALUE insert t1 (v) values (x'12345678'); drop table t1; diff --git a/mysql-test/main/vector2.result b/mysql-test/main/vector2.result index e1ed40d0774..71cf329ce54 100644 --- a/mysql-test/main/vector2.result +++ b/mysql-test/main/vector2.result @@ -231,7 +231,7 @@ create table t (v vector(2) not null); insert ignore into t values (1); Warnings: Warning 4078 Cannot cast 'int' as 'vector' in assignment of `test`.`t`.`v` -Warning 1366 Incorrect vector value: '1' for column `test`.`t`.`v` at row 1 +Warning 1292 Incorrect vector value: '1' for column `test`.`t`.`v` at row 1 select hex(v) from t; hex(v) 0000000000000000 @@ -408,4 +408,19 @@ t CREATE TABLE `t` ( KEY `v` (`v`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci drop table t; +# +# MDEV-35146 Vector-related error messages worth improving when possible +# +create table t (a vector(64) not null default ''); +ERROR 42000: Invalid default value for 'a' +show warnings; +Level Code Message +Warning 1292 Incorrect vector value: '' for column ``.``.`a` at row 0 +Error 1067 Invalid default value for 'a' +create table t (a inet6 not null default ''); +ERROR 42000: Invalid default value for 'a' +show warnings; +Level Code Message +Warning 1292 Incorrect inet6 value: '' for column ``.``.`a` at row 0 +Error 1067 Invalid default value for 'a' # End of 11.7 tests diff --git a/mysql-test/main/vector2.test b/mysql-test/main/vector2.test index d63583f9c07..e0c570e5303 100644 --- a/mysql-test/main/vector2.test +++ b/mysql-test/main/vector2.test @@ -22,9 +22,9 @@ insert t1 values (1, 1.1); insert t1 values (1, 1e1); --error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION insert t1 values (1, now()); ---error ER_TRUNCATED_WRONG_VALUE_FOR_FIELD +--error ER_TRUNCATED_WRONG_VALUE insert t1 values (1, repeat(x'56', 10)); ---error ER_TRUNCATED_WRONG_VALUE_FOR_FIELD +--error ER_TRUNCATED_WRONG_VALUE insert t1 values (1, repeat(x'66', 40)); insert t1 values (1, repeat(x'56', 40)); select * from t1; @@ -155,7 +155,7 @@ drop table t1; --echo # create table t1 (a blob); insert t1 values (1); ---error ER_TRUNCATED_WRONG_VALUE_FOR_FIELD +--error ER_TRUNCATED_WRONG_VALUE alter table t1 modify a vector(2); update t1 set a=x'5555555555555555'; alter table t1 modify a vector(2); @@ -298,4 +298,15 @@ create table t (v vector(8), key(v)); show create table t; drop table t; + +--echo # +--echo # MDEV-35146 Vector-related error messages worth improving when possible +--echo # +--error ER_INVALID_DEFAULT +create table t (a vector(64) not null default ''); +show warnings; +--error ER_INVALID_DEFAULT +create table t (a inet6 not null default ''); +show warnings; + --echo # End of 11.7 tests diff --git a/sql/sql_type_vector.cc b/sql/sql_type_vector.cc index 6a5c698eb96..b8d7f385c5d 100644 --- a/sql/sql_type_vector.cc +++ b/sql/sql_type_vector.cc @@ -276,13 +276,9 @@ Field::Copy_func *Field_vector::get_copy_func(const Field *from) const int Field_vector::report_wrong_value(const ErrConv &val) { - THD *thd= table->in_use; - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, - ER_THD(thd, ER_TRUNCATED_WRONG_VALUE_FOR_FIELD), - "vector", val.ptr(), table->s->db.str, - table->s->table_name.str, field_name.str, - thd->get_stmt_da()->current_row_for_warning()); + get_thd()->push_warning_truncated_value_for_field( + Sql_condition::WARN_LEVEL_WARN, "vector", val.ptr(), + table->s->db.str, table->s->table_name.str, field_name.str); reset(); return 1; } From 55d1f6c2292b511f490e2a97e33af79f2ec2b105 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 13 Nov 2024 16:46:29 +0400 Subject: [PATCH 210/213] MDEV-35069 IMPORT TABLESPACE does not work for tables with vector, although allowed Propagate discard/import tablespace request to hlindexes. Let FLUSH TABLES ... FOR EXPORT open/lock hlindexes, so that InnoDB prepares hlindexes for export. Moved reset_hlindexes() to external_lock(F_UNLCK), so that hlindexes are available for export until UNLOCK TABLES. Closes #3631 --- mysql-test/main/vector_innodb.result | 35 ++++++++++++++++++++++++++++ mysql-test/main/vector_innodb.test | 35 ++++++++++++++++++++++++++++ sql/handler.cc | 5 ++-- sql/sql_base.cc | 2 +- sql/sql_reload.cc | 3 +++ sql/sql_table.cc | 17 ++++++++++++++ sql/table.h | 2 +- 7 files changed, 95 insertions(+), 4 deletions(-) diff --git a/mysql-test/main/vector_innodb.result b/mysql-test/main/vector_innodb.result index f308b8a93dd..4dc018c9fec 100644 --- a/mysql-test/main/vector_innodb.result +++ b/mysql-test/main/vector_innodb.result @@ -285,4 +285,39 @@ pk 2 drop view v; drop table t; +# +# MDEV-35069 - IMPORT TABLESPACE does not work for tables with vector, +# although allowed +# +create table t1 (id int auto_increment primary key, v vector(5) not null, vector index (v) m=5) engine=InnoDB; +insert t1 (v) values (x'e360d63ebe554f3fcdbc523f4522193f5236083d'), +(x'f511303f72224a3fdd05fe3eb22a133ffae86a3f'), +(x'f09baa3ea172763f123def3e0c7fe53e288bf33e'), +(x'b97a523f2a193e3eb4f62e3f2d23583e9dd60d3f'), +(x'f7c5df3e984b2b3e65e59d3d7376db3eac63773e'), +(x'de01453ffa486d3f10aa4d3fdd66813c71cb163f'), +(x'76edfc3e4b57243f10f8423fb158713f020bda3e'), +(x'56926c3fdf098d3e2c8c5e3d1ad4953daa9d0b3e'), +(x'7b713f3e5258323f80d1113d673b2b3f66e3583f'), +(x'6ca1d43e9df91b3fe580da3e1c247d3f147cf33e'); +create table t2 like t1; +alter table t2 discard tablespace; +select id,vec_distance_euclidean(v, x'B047263c9f87233fcfd27e3eae493e3f0329f43e') d from t2 order by d limit 3; +ERROR HY000: Tablespace has been discarded for table `t2` +flush table t1 for export; +db.opt +t1#i#01.cfg +t1#i#01.ibd +t1.cfg +t1.frm +t1.ibd +t2.frm +unlock tables; +alter table t2 import tablespace; +select id,vec_distance_euclidean(v, x'B047263c9f87233fcfd27e3eae493e3f0329f43e') d from t2 order by d limit 3; +id d +9 0.47199 +10 0.50690 +3 0.58656 +drop table t1, t2; # End of 11.7 tests diff --git a/mysql-test/main/vector_innodb.test b/mysql-test/main/vector_innodb.test index 60e1f8ac7d6..ff56599e093 100644 --- a/mysql-test/main/vector_innodb.test +++ b/mysql-test/main/vector_innodb.test @@ -285,4 +285,39 @@ select pk from v order by vec_distance_euclidean(v, 0x30303030) limit 2; drop view v; drop table t; +--echo # +--echo # MDEV-35069 - IMPORT TABLESPACE does not work for tables with vector, +--echo # although allowed +--echo # +let $datadir=`select @@datadir`; +create table t1 (id int auto_increment primary key, v vector(5) not null, vector index (v) m=5) engine=InnoDB; +insert t1 (v) values (x'e360d63ebe554f3fcdbc523f4522193f5236083d'), + (x'f511303f72224a3fdd05fe3eb22a133ffae86a3f'), + (x'f09baa3ea172763f123def3e0c7fe53e288bf33e'), + (x'b97a523f2a193e3eb4f62e3f2d23583e9dd60d3f'), + (x'f7c5df3e984b2b3e65e59d3d7376db3eac63773e'), + (x'de01453ffa486d3f10aa4d3fdd66813c71cb163f'), + (x'76edfc3e4b57243f10f8423fb158713f020bda3e'), + (x'56926c3fdf098d3e2c8c5e3d1ad4953daa9d0b3e'), + (x'7b713f3e5258323f80d1113d673b2b3f66e3583f'), + (x'6ca1d43e9df91b3fe580da3e1c247d3f147cf33e'); +create table t2 like t1; +alter table t2 discard tablespace; +--error ER_TABLESPACE_DISCARDED +select id,vec_distance_euclidean(v, x'B047263c9f87233fcfd27e3eae493e3f0329f43e') d from t2 order by d limit 3; + +flush table t1 for export; +--list_files $datadir/test/ +--copy_file $datadir/test/t1.ibd $datadir/test/t2.ibd +--copy_file $datadir/test/t1.cfg $datadir/test/t2.cfg +--copy_file $datadir/test/t1#i#01.ibd $datadir/test/t2#i#01.ibd +--copy_file $datadir/test/t1#i#01.cfg $datadir/test/t2#i#01.cfg +unlock tables; + +alter table t2 import tablespace; +--replace_regex /(\.\d{5})\d+/\1/ +select id,vec_distance_euclidean(v, x'B047263c9f87233fcfd27e3eae493e3f0329f43e') d from t2 order by d limit 3; + +drop table t1, t2; + --echo # End of 11.7 tests diff --git a/sql/handler.cc b/sql/handler.cc index cc93963eade..9ca2fee591c 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -7667,6 +7667,9 @@ int handler::ha_external_lock(THD *thd, int lock_type) } } + if (lock_type == F_UNLCK) + (void) table->unlock_hlindexes(); + /* We cache the table flags if the locking succeeded. Otherwise, we keep them as they were when they were fetched in ha_open(). @@ -7741,8 +7744,6 @@ int handler::ha_reset() delete lookup_handler; lookup_handler= this; } - if (table->reset_hlindexes()) - return 1; DBUG_RETURN(reset()); } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 8da9d2cfb92..17b529464f3 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -9896,7 +9896,7 @@ int TABLE::open_hlindexes_for_write() return 0; } -int TABLE::reset_hlindexes() +int TABLE::unlock_hlindexes() { if (hlindex && hlindex->in_use) { diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc index 3b583cea0a5..8b1d3a3f6c7 100644 --- a/sql/sql_reload.cc +++ b/sql/sql_reload.cc @@ -641,6 +641,9 @@ bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables) table_list->table && table_list->table->file->extra(HA_EXTRA_FLUSH)) goto error_reset_bits; + if (table_list->table && + table_list->table->open_hlindexes_for_write()) + goto error_reset_bits; } } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 3d29d1115b3..26f6787c512 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6082,6 +6082,23 @@ int mysql_discard_or_import_tablespace(THD *thd, DBUG_RETURN(-1); } + DBUG_ASSERT(table_list->table->s->hlindexes() <= 1); + for (uint i= table_list->table->s->keys; i < table_list->table->s->total_keys; i++) + { + if (table_list->table->hlindex_open(i)) + { + thd->tablespace_op= FALSE; + DBUG_RETURN(-1); + } + } + for (uint i= table_list->table->s->keys; i < table_list->table->s->total_keys; i++) + { + error= table_list->table->hlindex->file-> + ha_discard_or_import_tablespace(discard); + if (unlikely(error)) + goto err; + } + error= table_list->table->file->ha_discard_or_import_tablespace(discard); THD_STAGE_INFO(thd, stage_end); diff --git a/sql/table.h b/sql/table.h index f5e4e37db8e..898a67de6d1 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1806,7 +1806,7 @@ public: int hlindexes_on_update(); int hlindexes_on_delete(const uchar *buf); int hlindexes_on_delete_all(bool truncate); - int reset_hlindexes(); + int unlock_hlindexes(); void prepare_triggers_for_insert_stmt_or_event(); bool prepare_triggers_for_delete_stmt_or_event(); From 2b17265ae279ac5cf007aa8d84265a4f96bba3db Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 9 Feb 2025 17:10:05 +0100 Subject: [PATCH 211/213] MDEV-35186 IGNORED attribute has no effect on vector keys --- mysql-test/main/vector2.result | 12 ++++++++++++ mysql-test/main/vector2.test | 8 ++++++++ sql/item_vectorfunc.cc | 3 ++- sql/table.cc | 2 +- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/vector2.result b/mysql-test/main/vector2.result index 71cf329ce54..1d3ccbea13d 100644 --- a/mysql-test/main/vector2.result +++ b/mysql-test/main/vector2.result @@ -423,4 +423,16 @@ show warnings; Level Code Message Warning 1292 Incorrect inet6 value: '' for column ``.``.`a` at row 0 Error 1067 Invalid default value for 'a' +# +# MDEV-35186 IGNORED attribute has no effect on vector keys +# +create table t (a vector(1) not null, vector(a) ignored); +show index in t; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Ignored +t 1 a 1 a A NULL NULL NULL VECTOR YES +insert into t values (0x00000000),(0x00000000); +explain select vec_totext(a) from t order by vec_distance_euclidean(a,0x00000000) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t ALL NULL NULL NULL NULL 2 Using filesort +drop table t; # End of 11.7 tests diff --git a/mysql-test/main/vector2.test b/mysql-test/main/vector2.test index e0c570e5303..ca50dd5427e 100644 --- a/mysql-test/main/vector2.test +++ b/mysql-test/main/vector2.test @@ -309,4 +309,12 @@ show warnings; create table t (a inet6 not null default ''); show warnings; +--echo # +--echo # MDEV-35186 IGNORED attribute has no effect on vector keys +--echo # +create table t (a vector(1) not null, vector(a) ignored); +show index in t; +insert into t values (0x00000000),(0x00000000); +explain select vec_totext(a) from t order by vec_distance_euclidean(a,0x00000000) limit 1; +drop table t; --echo # End of 11.7 tests diff --git a/sql/item_vectorfunc.cc b/sql/item_vectorfunc.cc index 1179855ce80..2a3a7704b64 100644 --- a/sql/item_vectorfunc.cc +++ b/sql/item_vectorfunc.cc @@ -32,7 +32,8 @@ key_map Item_func_vec_distance_common::part_of_sortkey() const Field *f= item->field; KEY *keyinfo= f->table->s->key_info; for (uint i= f->table->s->keys; i < f->table->s->total_keys; i++) - if (keyinfo[i].algorithm == HA_KEY_ALG_VECTOR && f->key_start.is_set(i) + if (!keyinfo[i].is_ignored && keyinfo[i].algorithm == HA_KEY_ALG_VECTOR + && f->key_start.is_set(i) && mhnsw_uses_distance(f->table, keyinfo + i, this)) map.set_bit(i); } diff --git a/sql/table.cc b/sql/table.cc index 9fadee37cb6..2c81cadad8b 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2214,7 +2214,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, if (extra2.index_flags.str) extra_index_flags_present= TRUE; - for (uint i= 0; i < share->keys; i++, keyinfo++) + for (uint i= 0; i < share->total_keys; i++, keyinfo++) { if (extra_index_flags_present) { From 2d971709a8b96ebd71c4a5d2ca74ee6f72ad0355 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 10 Feb 2025 15:25:09 +0100 Subject: [PATCH 212/213] MDEV-36026 Problem with INSERT SELECT on NOT NULL columns while having BEFORE UPDATE trigger MDEV-8605 and MDEV-19761 didn't handle INSERT (columns) SELECT followup for a69da0c31e9 --- mysql-test/main/trigger_null.result | 15 +++++++++++++++ mysql-test/main/trigger_null.test | 11 +++++++++++ sql/sql_insert.cc | 1 + 3 files changed, 27 insertions(+) diff --git a/mysql-test/main/trigger_null.result b/mysql-test/main/trigger_null.result index 4e4a99f22a3..42122e59e2c 100644 --- a/mysql-test/main/trigger_null.result +++ b/mysql-test/main/trigger_null.result @@ -399,4 +399,19 @@ Warnings: Warning 1364 Field 'c5' doesn't have a default value drop table t1; set sql_mode=default; +# +# MDEV-36026 Problem with INSERT SELECT on NOT NULL columns while having BEFORE UPDATE trigger +# +create table t1 (b int(11) not null); +create trigger t1bu before update on t1 for each row begin end; +insert t1 (b) select 1 union select 2; +create trigger trgi before insert on t1 for each row set new.b=ifnull(new.b,10); +insert t1 (b) select NULL union select 11; +select * from t1; +b +1 +2 +10 +11 +drop table t1; # End of 10.5 tests diff --git a/mysql-test/main/trigger_null.test b/mysql-test/main/trigger_null.test index 3aa39ded586..935152e376a 100644 --- a/mysql-test/main/trigger_null.test +++ b/mysql-test/main/trigger_null.test @@ -425,4 +425,15 @@ insert into t1 (c) values (1); drop table t1; set sql_mode=default; +--echo # +--echo # MDEV-36026 Problem with INSERT SELECT on NOT NULL columns while having BEFORE UPDATE trigger +--echo # +create table t1 (b int(11) not null); +create trigger t1bu before update on t1 for each row begin end; +insert t1 (b) select 1 union select 2; +create trigger trgi before insert on t1 for each row set new.b=ifnull(new.b,10); +insert t1 (b) select NULL union select 11; +select * from t1; +drop table t1; + --echo # End of 10.5 tests diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index d19821a28e6..759d7750805 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -4248,6 +4248,7 @@ select_insert::prepare(List &values, SELECT_LEX_UNIT *u) int select_insert::prepare2(JOIN *) { DBUG_ENTER("select_insert::prepare2"); + switch_to_nullable_trigger_fields(*fields, table); if (table->validate_default_values_of_unset_fields(thd)) DBUG_RETURN(1); if (thd->lex->describe) From 80067a69feaeb5df30abb1bfaf7d4e713ccbf027 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Mon, 10 Feb 2025 22:22:39 +0200 Subject: [PATCH 213/213] MDEV-36057: Assertion failure on 2nd execution of parameterized PS Followup to fix for MDEV-35318: In Prepared_statement::execute_loop(), if we enter this function with lex->needs_reprepare=true, we need to re-prepare the statement. We also need to call set_parameters() to get PS parameter values. We failed to do this and that's the bug. Note that we need to also handle the other reprepare scenario: when we get into Prepared_statement::execute_loop(), call set_parameters() and then hit a "DDL was changed" error with reprepare_observer, we should NOT call set_parameters() again. The parameters have already been transferred to the reprepared statement in Prepared_statement::reprepare()|swap_parameter_array(). --- mysql-test/main/create.result | 12 ++++++++++++ mysql-test/main/create.test | 14 ++++++++++++++ sql/sql_prepare.cc | 7 +++++-- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/create.result b/mysql-test/main/create.result index 55521c18b76..46d8d68121c 100644 --- a/mysql-test/main/create.result +++ b/mysql-test/main/create.result @@ -2116,4 +2116,16 @@ Warnings: Note 1051 Unknown table 'test.tmp' DROP PROCEDURE sp1; DROP TABLE t; +# +# MDEV-36057: Assertion failure or unexpected outcome upon 2nd execution +# of parameterized PS (continues the above) +# +CREATE TABLE t (a INT); +INSERT INTO t VALUES (1),(2); +PREPARE stmt FROM 'UPDATE t SET a = 3 WHERE a IN (SELECT "" UNION SELECT ?)'; +EXECUTE stmt USING 4; +ERROR 22007: Truncated incorrect DECIMAL value: '' +EXECUTE stmt USING 4; +ERROR 22007: Truncated incorrect DECIMAL value: '' +DROP TABLE t; # End of 11.7 Test diff --git a/mysql-test/main/create.test b/mysql-test/main/create.test index 1213c8be6e0..bb0c6347f2e 100644 --- a/mysql-test/main/create.test +++ b/mysql-test/main/create.test @@ -1987,4 +1987,18 @@ call sp1(); DROP PROCEDURE sp1; DROP TABLE t; +--echo # +--echo # MDEV-36057: Assertion failure or unexpected outcome upon 2nd execution +--echo # of parameterized PS (continues the above) +--echo # +CREATE TABLE t (a INT); +INSERT INTO t VALUES (1),(2); + +PREPARE stmt FROM 'UPDATE t SET a = 3 WHERE a IN (SELECT "" UNION SELECT ?)'; +--error ER_TRUNCATED_WRONG_VALUE +EXECUTE stmt USING 4; +--error ER_TRUNCATED_WRONG_VALUE +EXECUTE stmt USING 4; +DROP TABLE t; + --echo # End of 11.7 Test diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 1fa872b8d55..0488b6de558 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -4390,6 +4390,7 @@ Prepared_statement::execute_loop(String *expanded_query, Reprepare_observer reprepare_observer; bool error; iterations= FALSE; + bool params_are_set= false; /* - In mysql_sql_stmt_execute() we hide all "external" Items @@ -4415,8 +4416,10 @@ Prepared_statement::execute_loop(String *expanded_query, return TRUE; } - if (set_parameters(expanded_query, packet, packet_end)) +reexecute: + if (!params_are_set && set_parameters(expanded_query, packet, packet_end)) return TRUE; + params_are_set= true; #ifdef WITH_WSREP if (thd->wsrep_delayed_BF_abort) { @@ -4424,7 +4427,7 @@ Prepared_statement::execute_loop(String *expanded_query, return TRUE; } #endif /* WITH_WSREP */ -reexecute: + // Make sure that reprepare() did not create any new Items. DBUG_ASSERT(thd->free_list == NULL);