diff --git a/mysql-test/suite/s3/basic.result b/mysql-test/suite/s3/basic.result index cf7d7377d92..ac391ba3574 100644 --- a/mysql-test/suite/s3/basic.result +++ b/mysql-test/suite/s3/basic.result @@ -2,23 +2,25 @@ drop table if exists t1; # # Test simple create of s3 table # -create or replace table t1 (a int, b int, key (a)) engine=aria; -insert into t1 select seq,seq+10 from seq_1_to_10000; +create or replace table t1 (a int, b int, c varchar(1000), key (a), key(c)) engine=aria; +insert into t1 select seq, seq+10, repeat(char(65+ mod(seq, 20)),mod(seq,1000)) from seq_1_to_10000; alter table t1 engine=s3; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, - KEY `a` (`a`) + `c` varchar(1000) DEFAULT NULL, + KEY `a` (`a`), + KEY `c` (`c`) ) ENGINE=S3 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 select * from information_schema.tables where table_schema="database" and table_name="t1";; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY -def # t1 BASE TABLE S3 10 Page 10000 33 335872 # 122880 0 NULL # # # latin1_swedish_ci NULL page_checksum=1 9007199254732800 # +def # t1 BASE TABLE S3 10 Page 10000 567 5677056 # 761856 0 NULL # # # latin1_swedish_ci NULL page_checksum=1 2305843009213685760 # show table status like "t1"; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary -t1 S3 10 Page 10000 33 335872 # 122880 0 NULL # # # latin1_swedish_ci NULL page_checksum=1 # N -select * from t1 limit 10; +t1 S3 10 Page 10000 567 5677056 # 761856 0 NULL # # # latin1_swedish_ci NULL page_checksum=1 # N +select a,b from t1 limit 10; a b 1 11 2 12 @@ -33,7 +35,7 @@ a b select count(*) from t1; count(*) 10000 -select * from t1 where a between 10 and 20; +select a,b from t1 where a between 10 and 20; a b 10 20 11 21 @@ -55,15 +57,53 @@ update t1 set b=100 where a=1; ERROR HY000: Table 't1' is read only delete from t1 where a>10; ERROR HY000: Table 't1' is read only +# +# Analyze, repair, optimize and check table +# +set @@use_stat_tables='never'; +truncate mysql.table_stats; +check table t1 fast; +Table Op Msg_type Msg_text +database.t1 check status Table is already up to date +check table t1 quick; +Table Op Msg_type Msg_text +database.t1 check status OK +check table t1 extended; +Table Op Msg_type Msg_text +database.t1 check status OK +analyze table t1; +Table Op Msg_type Msg_text +database.t1 analyze status Table 'database.t1' is read only +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +database.t1 analyze status Table 'database.t1' is read only +database.t1 analyze status Engine-independent statistics collected +database.t1 analyze status OK +repair table t1; +Table Op Msg_type Msg_text +database.t1 repair Error Table 't1' is read only +database.t1 repair status Operation failed +optimize table t1; +Table Op Msg_type Msg_text +database.t1 optimize Error Table 't1' is read only +database.t1 optimize status Operation failed +select * from mysql.table_stats; +db_name table_name cardinality +database t1 10000 +# +# Converting table back to Aria +# alter table t1 engine=aria; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, - KEY `a` (`a`) + `c` varchar(1000) DEFAULT NULL, + KEY `a` (`a`), + KEY `c` (`c`) ) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 -select * from t1 limit 10; +select a,b from t1 limit 10; a b 1 11 2 12 diff --git a/mysql-test/suite/s3/basic.test b/mysql-test/suite/s3/basic.test index 91183841a62..99c2d8adb5d 100644 --- a/mysql-test/suite/s3/basic.test +++ b/mysql-test/suite/s3/basic.test @@ -13,8 +13,8 @@ drop table if exists t1; --echo # Test simple create of s3 table --echo # -create or replace table t1 (a int, b int, key (a)) engine=aria; -insert into t1 select seq,seq+10 from seq_1_to_10000; +create or replace table t1 (a int, b int, c varchar(1000), key (a), key(c)) engine=aria; +insert into t1 select seq, seq+10, repeat(char(65+ mod(seq, 20)),mod(seq,1000)) from seq_1_to_10000; alter table t1 engine=s3; show create table t1; @@ -23,9 +23,9 @@ show create table t1; --eval select * from information_schema.tables where table_schema="$database" and table_name="t1"; --replace_column 8 # 12 # 13 # 14 # 19 # show table status like "t1"; -select * from t1 limit 10; +select a,b from t1 limit 10; select count(*) from t1; -select * from t1 where a between 10 and 20; +select a,b from t1 where a between 10 and 20; --replace_column 9 # explain select * from t1 where a between 10 and 20; --error ER_OPEN_AS_READONLY @@ -34,9 +34,38 @@ insert into t1 values (1,1); update t1 set b=100 where a=1; --error ER_OPEN_AS_READONLY delete from t1 where a>10; + + +--echo # +--echo # Analyze, repair, optimize and check table +--echo # + +set @@use_stat_tables='never'; +truncate mysql.table_stats; +--replace_result $database database +check table t1 fast; +--replace_result $database database +check table t1 quick; +--replace_result $database database +check table t1 extended; +--replace_result $database database +analyze table t1; +--replace_result $database database +analyze table t1 persistent for all; +--replace_result $database database +repair table t1; +--replace_result $database database +optimize table t1; +--replace_result $database database +select * from mysql.table_stats; + +--echo # +--echo # Converting table back to Aria +--echo # + alter table t1 engine=aria; show create table t1; -select * from t1 limit 10; +select a,b from t1 limit 10; select count(*) from t1; delete from t1 where a=1; drop table t1; diff --git a/mysql-test/suite/s3/partition.result b/mysql-test/suite/s3/partition.result index 3cfa33e99eb..818316bc89d 100644 --- a/mysql-test/suite/s3/partition.result +++ b/mysql-test/suite/s3/partition.result @@ -54,14 +54,15 @@ ALTER TABLE t2 TRUNCATE PARTITION p3; ERROR HY000: Table 't2' is read only ALTER TABLE t2 ANALYZE PARTITION p3; Table Op Msg_type Msg_text -s3.t2 analyze error Table 's3.t2' is read only +s3.t2 analyze status Table 's3.t2' is read only +s3.t2 analyze status Engine-independent statistics collected +s3.t2 analyze status OK SELECT count(*) FROM t2; count(*) 6 ALTER TABLE t2 CHECK PARTITION p3; Table Op Msg_type Msg_text -s3.t2 check error Subpartition p3sp0 returned error -s3.t2 check error Unknown - internal error 165 during operation +s3.t2 check status OK SELECT count(*) FROM t2; count(*) 6 diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index 4056935b6d6..bdc001fbe25 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -164,18 +164,18 @@ typedef struct st_simple_key_cache_cb size_t key_cache_mem_size; /* specified size of the cache memory */ size_t allocated_mem_size; /* size of the memory actually allocated */ uint key_cache_block_size; /* size of the page buffer of a cache block */ - ulong min_warm_blocks; /* min number of warm blocks; */ - ulong age_threshold; /* age threshold for hot blocks */ + size_t min_warm_blocks; /* min number of warm blocks; */ + size_t age_threshold; /* age threshold for hot blocks */ ulonglong keycache_time; /* total number of block link operations */ uint hash_entries; /* max number of entries in the hash table */ uint changed_blocks_hash_size; /* Number of hash buckets for file blocks */ int hash_links; /* max number of hash links */ int hash_links_used; /* number of hash links currently used */ int disk_blocks; /* max number of blocks in the cache */ - ulong blocks_used; /* maximum number of concurrently used blocks */ - ulong blocks_unused; /* number of currently unused blocks */ - ulong blocks_changed; /* number of currently dirty blocks */ - ulong warm_blocks; /* number of blocks in warm sub-chain */ + size_t blocks_used; /* maximum number of concurrently used blocks */ + size_t blocks_unused; /* number of currently unused blocks */ + size_t blocks_changed; /* number of currently dirty blocks */ + size_t warm_blocks; /* number of blocks in warm sub-chain */ ulong cnt_for_resize_op; /* counter to block resize operation */ long blocks_available; /* number of blocks available in the LRU chain */ HASH_LINK **hash_root; /* arr. of entries into hash table buckets */ @@ -478,7 +478,7 @@ int init_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, size_t use_mem, uint division_limit, uint age_threshold, uint changed_blocks_hash_size) { - ulong blocks, hash_links; + size_t blocks, hash_links; size_t length; int error; DBUG_ENTER("init_simple_key_cache"); @@ -519,8 +519,8 @@ int init_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, DBUG_PRINT("info", ("key_cache_block_size: %u", key_cache_block_size)); - blocks= (ulong) (use_mem / (sizeof(BLOCK_LINK) + 2 * sizeof(HASH_LINK) + - sizeof(HASH_LINK*) * 5/4 + key_cache_block_size)); + blocks= use_mem / (sizeof(BLOCK_LINK) + 2 * sizeof(HASH_LINK) + + sizeof(HASH_LINK*) * 5/4 + key_cache_block_size); /* Changed blocks hash needs to be a power of 2 */ changed_blocks_hash_size= my_round_up_to_next_power(MY_MAX(changed_blocks_hash_size, @@ -532,7 +532,7 @@ int init_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, for ( ; ; ) { /* Set my_hash_entries to the next bigger 2 power */ - if ((keycache->hash_entries= next_power(blocks)) < blocks * 5/4) + if ((keycache->hash_entries= next_power((uint)blocks)) < blocks * 5/4) keycache->hash_entries<<= 1; hash_links= 2 * blocks; #if defined(MAX_THREADS) @@ -543,8 +543,8 @@ int init_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, ALIGN_SIZE(hash_links * sizeof(HASH_LINK)) + ALIGN_SIZE(sizeof(HASH_LINK*) * keycache->hash_entries) + - sizeof(BLOCK_LINK*)* (changed_blocks_hash_size*2))) + - ((size_t) blocks * keycache->key_cache_block_size) > use_mem && blocks > 8) + sizeof(BLOCK_LINK*)* ((size_t)changed_blocks_hash_size*2))) + + (blocks * keycache->key_cache_block_size) > use_mem && blocks > 8) blocks--; keycache->allocated_mem_size= blocks * keycache->key_cache_block_size; if ((keycache->block_mem= my_large_malloc(&keycache->allocated_mem_size, @@ -584,7 +584,7 @@ int init_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, } keycache->blocks_unused= blocks; keycache->disk_blocks= (int) blocks; - keycache->hash_links= hash_links; + keycache->hash_links= (int)hash_links; keycache->hash_links_used= 0; keycache->free_hash_list= NULL; keycache->blocks_used= keycache->blocks_changed= 0; @@ -4854,7 +4854,7 @@ static int cache_empty(SIMPLE_KEY_CACHE_CB *keycache) } if (errcnt) { - fprintf(stderr, "blocks: %d used: %lu\n", + fprintf(stderr, "blocks: %d used: %zu\n", keycache->disk_blocks, keycache->blocks_used); fprintf(stderr, "hash_links: %d used: %d\n", keycache->hash_links, keycache->hash_links_used); diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 4cb9ca9179a..1aa917d525b 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -1523,7 +1523,8 @@ int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt, /* print a line which partition the error belongs to */ if (error != HA_ADMIN_NOT_IMPLEMENTED && error != HA_ADMIN_ALREADY_DONE && - error != HA_ADMIN_TRY_ALTER) + error != HA_ADMIN_TRY_ALTER && + error != HA_ERR_TABLE_READONLY) { print_admin_msg(thd, MYSQL_ERRMSG_SIZE, &msg_error, table_share->db.str, table->alias, diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc index e59a2ed6a58..81d52c4bffe 100644 --- a/sql/signal_handler.cc +++ b/sql/signal_handler.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2011, 2012, Oracle and/or its affiliates. - Copyright (c) 2011, 2014, SkySQL Ab. + Copyright (c) 2011, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -174,19 +174,19 @@ extern "C" sig_handler handle_fatal_signal(int sig) my_safe_printf_stderr("Server version: %s\n", server_version); if (dflt_key_cache) - my_safe_printf_stderr("key_buffer_size=%lu\n", - (ulong) dflt_key_cache->key_cache_mem_size); + my_safe_printf_stderr("key_buffer_size=%zu\n", + dflt_key_cache->key_cache_mem_size); - my_safe_printf_stderr("read_buffer_size=%ld\n", - (long) global_system_variables.read_buff_size); + my_safe_printf_stderr("read_buffer_size=%lu\n", + global_system_variables.read_buff_size); my_safe_printf_stderr("max_used_connections=%lu\n", - (ulong) max_used_connections); + max_used_connections); if (thread_scheduler) - my_safe_printf_stderr("max_threads=%u\n", - (uint) thread_scheduler->max_threads + - (uint) extra_max_connections); + my_safe_printf_stderr("max_threads=%lu\n", + thread_scheduler->max_threads + + extra_max_connections); my_safe_printf_stderr("thread_count=%u\n", THD_count::value()); @@ -195,11 +195,10 @@ extern "C" sig_handler handle_fatal_signal(int sig) my_safe_printf_stderr("It is possible that mysqld could use up to \n" "key_buffer_size + " "(read_buffer_size + sort_buffer_size)*max_threads = " - "%lu K bytes of memory\n", - (ulong) + "%zu K bytes of memory\n", (dflt_key_cache->key_cache_mem_size + (global_system_variables.read_buff_size + - global_system_variables.sortbuff_size) * + (size_t)global_system_variables.sortbuff_size) * (thread_scheduler->max_threads + extra_max_connections) + (max_connections + extra_max_connections) * sizeof(THD)) / 1024); diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index 9c13c8cb1cd..839ea083e5c 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -33,6 +33,7 @@ #include "sql_statistics.h" #include "wsrep_mysqld.h" +const LEX_CSTRING msg_status= {STRING_WITH_LEN("status")}; const LEX_CSTRING msg_repair= { STRING_WITH_LEN("repair") }; const LEX_CSTRING msg_assign_to_keycache= { STRING_WITH_LEN("assign_to_keycache") }; @@ -490,6 +491,20 @@ static bool wsrep_toi_replication(THD *thd, TABLE_LIST *tables) #endif /* WITH_WSREP */ +static void send_read_only_warning(THD *thd, const LEX_CSTRING *msg_status, + const LEX_CSTRING *table_name) +{ + Protocol *protocol= thd->protocol; + char buf[MYSQL_ERRMSG_SIZE]; + size_t length; + length= my_snprintf(buf, sizeof(buf), + ER_THD(thd, ER_OPEN_AS_READONLY), + table_name->str); + protocol->store(msg_status, system_charset_info); + protocol->store(buf, length, system_charset_info); +} + + /** Collect field names of result set that will be sent to a client @@ -774,20 +789,16 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, goto send_result; } - if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify) + if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify && + operator_func != &handler::ha_analyze) { /* purecov: begin inspected */ - char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE]; - size_t length; enum_sql_command save_sql_command= lex->sql_command; DBUG_PRINT("admin", ("sending error message")); protocol->prepare_for_resend(); protocol->store(&table_name, system_charset_info); protocol->store(operator_name, system_charset_info); - protocol->store(&error_clex_str, system_charset_info); - length= my_snprintf(buff, sizeof(buff), ER_THD(thd, ER_OPEN_AS_READONLY), - table_name.str); - protocol->store(buff, length, system_charset_info); + send_read_only_warning(thd, &error_clex_str, &table_name); trans_commit_stmt(thd); trans_commit(thd); close_thread_tables(thd); @@ -923,6 +934,15 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, if (compl_result_code == HA_ADMIN_OK && collect_eis) { + if (result_code == HA_ERR_TABLE_READONLY) + { + protocol->prepare_for_resend(); + protocol->store(&table_name, system_charset_info); + protocol->store(operator_name, system_charset_info); + send_read_only_warning(thd, &msg_status, &table_name); + (void) protocol->write(); + result_code= HA_ADMIN_OK; + } /* Here we close and reopen table in read mode because operation of collecting statistics is long and it will be better do not block @@ -1032,7 +1052,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, protocol->prepare_for_resend(); protocol->store(&table_name, system_charset_info); protocol->store(operator_name, system_charset_info); - protocol->store(STRING_WITH_LEN("status"), system_charset_info); + protocol->store(&msg_status, system_charset_info); protocol->store(STRING_WITH_LEN("Engine-independent statistics collected"), system_charset_info); if (protocol->write()) @@ -1102,25 +1122,25 @@ send_result_message: break; case HA_ADMIN_OK: - protocol->store(STRING_WITH_LEN("status"), system_charset_info); + protocol->store(&msg_status, system_charset_info); protocol->store(STRING_WITH_LEN("OK"), system_charset_info); break; case HA_ADMIN_FAILED: - protocol->store(STRING_WITH_LEN("status"), system_charset_info); + protocol->store(&msg_status, system_charset_info); protocol->store(STRING_WITH_LEN("Operation failed"), system_charset_info); break; case HA_ADMIN_REJECT: - protocol->store(STRING_WITH_LEN("status"), system_charset_info); + protocol->store(&msg_status, system_charset_info); protocol->store(STRING_WITH_LEN("Operation need committed state"), system_charset_info); open_for_modify= FALSE; break; case HA_ADMIN_ALREADY_DONE: - protocol->store(STRING_WITH_LEN("status"), system_charset_info); + protocol->store(&msg_status, system_charset_info); protocol->store(STRING_WITH_LEN("Table is already up to date"), system_charset_info); break; @@ -1265,7 +1285,11 @@ send_result_message: fatal_error=1; break; } - + case HA_ERR_TABLE_READONLY: + { + send_read_only_warning(thd, &msg_status, &table_name); + break; + } default: // Probably HA_ADMIN_INTERNAL_ERROR { char buf[MYSQL_ERRMSG_SIZE]; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index a758196feea..954d53b9d72 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -4901,11 +4901,13 @@ void destroy_thd(MYSQL_THD thd) extern "C" pthread_key(struct st_my_thread_var *, THR_KEY_mysys); MYSQL_THD create_background_thd() { - DBUG_ASSERT(!current_thd); + auto save_thd = current_thd; + set_current_thd(nullptr); + auto save_mysysvar= pthread_getspecific(THR_KEY_mysys); /* - Allocate new mysys_var specifically this THD, + Allocate new mysys_var specifically new THD, so that e.g safemalloc, DBUG etc are happy. */ pthread_setspecific(THR_KEY_mysys, 0); @@ -4913,7 +4915,8 @@ MYSQL_THD create_background_thd() auto thd_mysysvar= pthread_getspecific(THR_KEY_mysys); auto thd= new THD(0); pthread_setspecific(THR_KEY_mysys, save_mysysvar); - thd->set_psi(PSI_CALL_get_thread()); + thd->set_psi(nullptr); + set_current_thd(save_thd); /* Workaround the adverse effect of incrementing thread_count diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index 60912ac7777..3a041ba11db 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -3344,11 +3344,11 @@ static void btr_cur_prefetch_siblings(const buf_block_t *block, if (prev == FIL_NULL); else if (space->acquire()) buf_read_page_background(space, page_id_t(space->id, prev), - block->zip_size(), false); + block->zip_size()); if (next == FIL_NULL); else if (space->acquire()) buf_read_page_background(space, page_id_t(space->id, next), - block->zip_size(), false); + block->zip_size()); } /*************************************************************//** diff --git a/storage/innobase/buf/buf0dump.cc b/storage/innobase/buf/buf0dump.cc index 1a95de2b045..4c20af2a386 100644 --- a/storage/innobase/buf/buf0dump.cc +++ b/storage/innobase/buf/buf0dump.cc @@ -684,7 +684,7 @@ buf_load() } space->reacquire(); - buf_read_page_background(space, dump[i], zip_size, true); + buf_read_page_background(space, dump[i], zip_size); if (buf_load_abort_flag) { if (space) { diff --git a/storage/innobase/buf/buf0rea.cc b/storage/innobase/buf/buf0rea.cc index 52f10cf7582..cbf4afa32ca 100644 --- a/storage/innobase/buf/buf0rea.cc +++ b/storage/innobase/buf/buf0rea.cc @@ -495,14 +495,13 @@ an exclusive lock on the buffer frame. The flag is cleared and the x-lock released by the i/o-handler thread. @param[in,out] space tablespace @param[in] page_id page id -@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0 -@param[in] sync true if synchronous aio is desired */ +@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, bool sync) + ulint zip_size) { dberr_t err; - if (buf_read_page_low(&err, space, sync, BUF_READ_ANY_PAGE, + if (buf_read_page_low(&err, space, false, BUF_READ_ANY_PAGE, page_id, zip_size, false)) { srv_stats.buf_pool_reads.add(1); } diff --git a/storage/innobase/include/buf0rea.h b/storage/innobase/include/buf0rea.h index 87c6b5d7e75..8d6b28194dc 100644 --- a/storage/innobase/include/buf0rea.h +++ b/storage/innobase/include/buf0rea.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, 2020, MariaDB Corporation. +Copyright (c) 2015, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -48,10 +48,9 @@ an exclusive lock on the buffer frame. The flag is cleared and the x-lock released by the i/o-handler thread. @param[in,out] space tablespace @param[in] page_id page id -@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0 -@param[in] sync true if synchronous aio is desired */ +@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, bool sync) + ulint zip_size) MY_ATTRIBUTE((nonnull)); /** Applies a random read-ahead in buf_pool if there are at least a threshold diff --git a/storage/maria/aria_s3_copy.cc b/storage/maria/aria_s3_copy.cc index f324c0896e5..77c41ba4572 100644 --- a/storage/maria/aria_s3_copy.cc +++ b/storage/maria/aria_s3_copy.cc @@ -40,8 +40,10 @@ static const char *opt_s3_host_name= DEFAULT_AWS_HOST_NAME; static const char *opt_database; static const char *opt_s3_bucket="MariaDB"; static my_bool opt_compression, opt_verbose, opt_force, opt_s3_debug; +static my_bool opt_s3_use_http; static ulong opt_operation= OP_IMPOSSIBLE, opt_protocol_version= 1; static ulong opt_block_size; +static ulong opt_s3_port; static char **default_argv=0; static ms3_st *global_s3_client= 0; @@ -65,6 +67,12 @@ static struct my_option my_long_options[] = {"s3_host_name", 'h', "Host name to S3 provider", (char**) &opt_s3_host_name, (char**) &opt_s3_host_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"s3_port", 'p', "Port number to connect to (0 means use default)", + (char**) &opt_s3_port, (char**) &opt_s3_port, 0, GET_ULONG, REQUIRED_ARG, + 0, 0, 65536, 0, 1, 0 }, + {"s3_use_http", 'P', "If true, force use of HTTP protocol", + (char**) &opt_s3_use_http, (char**) &opt_s3_use_http, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"compress", 'c', "Use compression", &opt_compression, &opt_compression, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"op", 'o', "Operation to execute. One of 'from_s3', 'to_s3' or " @@ -196,6 +204,7 @@ int main(int argc, char** argv) { MY_INIT(argv[0]); get_options(&argc,(char***) &argv); + size_t block_size= opt_block_size; s3_init_library(); if (!(global_s3_client= ms3_init(opt_s3_access_key, @@ -207,15 +216,22 @@ int main(int argc, char** argv) my_exit(1); } - { - size_t block_size= opt_block_size; - uint8_t protocol_version= (uint8_t) opt_protocol_version; - ms3_set_option(global_s3_client, MS3_OPT_BUFFER_CHUNK_SIZE, &block_size); + ms3_set_option(global_s3_client, MS3_OPT_BUFFER_CHUNK_SIZE, &block_size); - if (protocol_version) - ms3_set_option(global_s3_client, MS3_OPT_FORCE_PROTOCOL_VERSION, - &protocol_version); + if (opt_protocol_version) + { + uint8_t protocol_version= (uint8_t) opt_protocol_version; + ms3_set_option(global_s3_client, MS3_OPT_FORCE_PROTOCOL_VERSION, + &protocol_version); } + if (opt_s3_port) + { + int port= (int) opt_s3_port; + ms3_set_option(global_s3_client, MS3_OPT_PORT_NUMBER, &port); + } + if (opt_s3_use_http) + ms3_set_option(global_s3_client, MS3_OPT_USE_HTTP, NULL); + for (; *argv ; argv++) { diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 2c8a67998dd..38db0042a83 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -1278,6 +1278,7 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt) if (!file || !param) return HA_ADMIN_INTERNAL_ERROR; unmap_file(file); + register_handler(file); maria_chk_init(param); param->thd= thd; param->op_name= "check"; @@ -1333,14 +1334,18 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt) { ulonglong old_testflag= param->testflag; param->testflag |= T_MEDIUM; - if (!(error= init_io_cache(¶m->read_cache, file->dfile.file, - my_default_record_cache_size, READ_CACHE, - share->pack.header_length, 1, MYF(MY_WME)))) - { + + /* BLOCK_RECORD does not need a cache as it is using the page cache */ + if (file->s->data_file_type != BLOCK_RECORD) + error= init_io_cache(¶m->read_cache, file->dfile.file, + my_default_record_cache_size, READ_CACHE, + share->pack.header_length, 1, MYF(MY_WME)); + if (!error) error= maria_chk_data_link(param, file, MY_TEST(param->testflag & T_EXTEND)); + + if (file->s->data_file_type != BLOCK_RECORD) end_io_cache(¶m->read_cache); - } param->testflag= old_testflag; } } diff --git a/storage/maria/ha_s3.h b/storage/maria/ha_s3.h index e8c7f586a1b..f7bffceb1a7 100644 --- a/storage/maria/ha_s3.h +++ b/storage/maria/ha_s3.h @@ -44,11 +44,6 @@ public: DBUG_ENTER("delete_row"); DBUG_RETURN(HA_ERR_TABLE_READONLY); } - int check(THD *, HA_CHECK_OPT *) override - { - DBUG_ENTER("delete_row"); - DBUG_RETURN(HA_ERR_TABLE_READONLY); - } int analyze(THD *, HA_CHECK_OPT *) override { DBUG_ENTER("analyze"); diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index fed888b1901..c097c6d1e2e 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -414,6 +414,12 @@ int maria_chk_size(HA_CHECK *param, register MARIA_HA *info) char buff[22],buff2[22]; DBUG_ENTER("maria_chk_size"); + if (info->s3) + { + /* We cannot check file sizes for S3 */ + DBUG_RETURN(0); + } + if (!(param->testflag & T_SILENT)) puts("- check file-size"); diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c index 986cacddf0c..cab3fc35ded 100644 --- a/storage/maria/ma_pagecache.c +++ b/storage/maria/ma_pagecache.c @@ -2772,7 +2772,7 @@ retry: #ifdef WITH_S3_STORAGE_ENGINE static void read_big_block(PAGECACHE *pagecache, - PAGECACHE_BLOCK_LINK *block) + PAGECACHE_BLOCK_LINK *block) { int page_st; size_t big_block_size_in_pages; @@ -2810,6 +2810,11 @@ static void read_big_block(PAGECACHE *pagecache, if (block_to_read->status & PCBLOCK_ERROR) { /* We get first block with an error so all operation failed */ + DBUG_PRINT("error", ("Got error when reading first page")); + block->status|= PCBLOCK_ERROR; + block->error= block_to_read->error; + remove_reader(block_to_read); + unreg_request(pagecache, block_to_read, 1); DBUG_VOID_RETURN; } if (block_to_read->status & PCBLOCK_BIG_READ) @@ -3952,7 +3957,6 @@ void pagecache_set_write_on_delete_by_link(PAGECACHE_BLOCK_LINK *block) @retval 0 deleted or was not present at all @retval 1 error - */ static my_bool pagecache_delete_internal(PAGECACHE *pagecache, diff --git a/storage/maria/s3_func.c b/storage/maria/s3_func.c index 9f40790a371..06178c1c0c2 100644 --- a/storage/maria/s3_func.c +++ b/storage/maria/s3_func.c @@ -583,8 +583,8 @@ int aria_copy_from_s3(ms3_st *s3_client, const char *aws_bucket, if (s3_get_object(s3_client, aws_bucket, aws_path, &block, 0, 0)) { - my_printf_error(EE_FILENOTFOUND, "Table %s doesn't exist in s3", MYF(0), - filename); + my_printf_error(EE_FILENOTFOUND, "File %s/%s doesn't exist in s3", MYF(0), + database,filename); goto err; } if (block.length < MARIA_STATE_INFO_SIZE) diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_25684.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_25684.result new file mode 100644 index 00000000000..8d4bea79476 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_25684.result @@ -0,0 +1,18 @@ +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 + +MDEV-25684 Crash in THD::find_temporary_table while calling spider_direct_sql UDF without temporary table created + +connection master_1; +SELECT SPIDER_DIRECT_SQL('SELECT * FROM s', 'non_existing_temporary_table', 'srv "s_2_1"'); +ERROR HY000: Temporary table 'test.non_existing_temporary_table' is not found +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_25684.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_25684.cnf new file mode 100644 index 00000000000..05dfd8a0bce --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_25684.cnf @@ -0,0 +1,3 @@ +!include include/default_mysqld.cnf +!include ../my_1_1.cnf +!include ../my_2_1.cnf diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_25684.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_25684.test new file mode 100644 index 00000000000..243031e52dd --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_25684.test @@ -0,0 +1,19 @@ +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log + +--echo +--echo MDEV-25684 Crash in THD::find_temporary_table while calling spider_direct_sql UDF without temporary table created +--echo + +--connection master_1 +--error 12703 +SELECT SPIDER_DIRECT_SQL('SELECT * FROM s', 'non_existing_temporary_table', 'srv "s_2_1"'); + +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log diff --git a/storage/spider/spd_sys_table.cc b/storage/spider/spd_sys_table.cc index 871dbb77027..69e4d259296 100644 --- a/storage/spider/spd_sys_table.cc +++ b/storage/spider/spd_sys_table.cc @@ -3934,6 +3934,10 @@ TABLE *spider_find_temporary_table( ) { DBUG_ENTER("spider_find_temporary_table"); #ifdef SPIDER_open_temporary_table + if (!thd->has_temporary_tables()) + { + DBUG_RETURN(NULL); + } if (thd->open_temporary_table(table_list)) { DBUG_RETURN(NULL);