Commit 49ae1996 authored by Monty's avatar Monty

Added support for ANALYZE TABLE to S3 tables

Other things
- Cleaned up error messages for CHECK, REPAIR and OPTIMIZE
parent 6bdc03eb
...@@ -55,6 +55,36 @@ update t1 set b=100 where a=1; ...@@ -55,6 +55,36 @@ update t1 set b=100 where a=1;
ERROR HY000: Table 't1' is read only ERROR HY000: Table 't1' is read only
delete from t1 where a>10; delete from t1 where a>10;
ERROR HY000: Table 't1' is read only 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;
Table Op Msg_type Msg_text
database.t1 check status Table 'database.t1' is read only
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; alter table t1 engine=aria;
show create table t1; show create table t1;
Table Create Table Table Create Table
......
...@@ -34,6 +34,31 @@ insert into t1 values (1,1); ...@@ -34,6 +34,31 @@ insert into t1 values (1,1);
update t1 set b=100 where a=1; update t1 set b=100 where a=1;
--error ER_OPEN_AS_READONLY --error ER_OPEN_AS_READONLY
delete from t1 where a>10; 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;
--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; alter table t1 engine=aria;
show create table t1; show create table t1;
select * from t1 limit 10; select * from t1 limit 10;
......
...@@ -56,14 +56,15 @@ ALTER TABLE t2 TRUNCATE PARTITION p3; ...@@ -56,14 +56,15 @@ ALTER TABLE t2 TRUNCATE PARTITION p3;
ERROR HY000: Table 't2' is read only ERROR HY000: Table 't2' is read only
ALTER TABLE t2 ANALYZE PARTITION p3; ALTER TABLE t2 ANALYZE PARTITION p3;
Table Op Msg_type Msg_text 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; SELECT count(*) FROM t2;
count(*) count(*)
6 6
ALTER TABLE t2 CHECK PARTITION p3; ALTER TABLE t2 CHECK PARTITION p3;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
s3.t2 check error Subpartition p3sp0 returned error s3.t2 check status Table 's3.t2' is read only
s3.t2 check error Unknown - internal error 165 during operation
SELECT count(*) FROM t2; SELECT count(*) FROM t2;
count(*) count(*)
6 6
......
...@@ -1509,7 +1509,8 @@ int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt, ...@@ -1509,7 +1509,8 @@ int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt,
/* print a line which partition the error belongs to */ /* print a line which partition the error belongs to */
if (error != HA_ADMIN_NOT_IMPLEMENTED && if (error != HA_ADMIN_NOT_IMPLEMENTED &&
error != HA_ADMIN_ALREADY_DONE && 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, "error", print_admin_msg(thd, MYSQL_ERRMSG_SIZE, "error",
table_share->db.str, table->alias, table_share->db.str, table->alias,
......
...@@ -114,6 +114,10 @@ class Protocol ...@@ -114,6 +114,10 @@ class Protocol
{ return store_longlong((longlong) from, 1); } { return store_longlong((longlong) from, 1); }
inline bool store(String *str) inline bool store(String *str)
{ return store((char*) str->ptr(), str->length(), str->charset()); } { return store((char*) str->ptr(), str->length(), str->charset()); }
inline bool store(const LEX_CSTRING *from, CHARSET_INFO *cs)
{
return store(from->str, from->length, cs);
}
virtual bool prepare_for_send(uint num_columns) virtual bool prepare_for_send(uint num_columns)
{ {
......
...@@ -32,6 +32,9 @@ ...@@ -32,6 +32,9 @@
#include "sql_admin.h" #include "sql_admin.h"
#include "sql_statistics.h" #include "sql_statistics.h"
#include "wsrep_mysqld.h" #include "wsrep_mysqld.h"
const LEX_CSTRING msg_status= {STRING_WITH_LEN("status")};
/* Prepare, run and cleanup for mysql_recreate_table() */ /* Prepare, run and cleanup for mysql_recreate_table() */
static bool admin_recreate_table(THD *thd, TABLE_LIST *table_list) static bool admin_recreate_table(THD *thd, TABLE_LIST *table_list)
...@@ -472,6 +475,21 @@ static bool wsrep_toi_replication(THD *thd, TABLE_LIST *tables) ...@@ -472,6 +475,21 @@ static bool wsrep_toi_replication(THD *thd, TABLE_LIST *tables)
} }
#endif /* WITH_WSREP */ #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);
}
/* /*
RETURN VALUES RETURN VALUES
FALSE Message sent to net (admin operation went ok) FALSE Message sent to net (admin operation went ok)
...@@ -555,7 +573,8 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, ...@@ -555,7 +573,8 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
for (table= tables; table; table= table->next_local) for (table= tables; table; table= table->next_local)
{ {
char table_name[SAFE_NAME_LEN*2+2]; char table_name_buff[SAFE_NAME_LEN*2+2];
LEX_CSTRING table_name= { table_name_buff, 0};
const char *db= table->db.str; const char *db= table->db.str;
bool fatal_error=0; bool fatal_error=0;
bool open_error; bool open_error;
...@@ -565,7 +584,8 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, ...@@ -565,7 +584,8 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
DBUG_PRINT("admin", ("table: '%s'.'%s'", db, table->table_name.str)); DBUG_PRINT("admin", ("table: '%s'.'%s'", db, table->table_name.str));
DEBUG_SYNC(thd, "admin_command_kill_before_modify"); DEBUG_SYNC(thd, "admin_command_kill_before_modify");
strxmov(table_name, db, ".", table->table_name.str, NullS); table_name.length= strxmov(table_name_buff, db, ".", table->table_name.str,
NullS) - table_name_buff;
thd->open_options|= extra_open_options; thd->open_options|= extra_open_options;
table->lock_type= lock_type; table->lock_type= lock_type;
/* /*
...@@ -651,12 +671,12 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, ...@@ -651,12 +671,12 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
size_t length; size_t length;
DBUG_PRINT("admin", ("sending non existent partition error")); DBUG_PRINT("admin", ("sending non existent partition error"));
protocol->prepare_for_resend(); protocol->prepare_for_resend();
protocol->store(table_name, system_charset_info); protocol->store(&table_name, system_charset_info);
protocol->store(operator_name, system_charset_info); protocol->store(operator_name, system_charset_info);
protocol->store(STRING_WITH_LEN("error"), system_charset_info); protocol->store(STRING_WITH_LEN("error"), system_charset_info);
length= my_snprintf(buff, sizeof(buff), length= my_snprintf(buff, sizeof(buff),
ER_THD(thd, ER_DROP_PARTITION_NON_EXISTENT), ER_THD(thd, ER_DROP_PARTITION_NON_EXISTENT),
table_name); table_name.str);
protocol->store(buff, length, system_charset_info); protocol->store(buff, length, system_charset_info);
if(protocol->write()) if(protocol->write())
goto err; goto err;
...@@ -732,20 +752,17 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, ...@@ -732,20 +752,17 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
goto send_result; 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 */ /* purecov: begin inspected */
char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE];
size_t length;
enum_sql_command save_sql_command= lex->sql_command; enum_sql_command save_sql_command= lex->sql_command;
LEX_CSTRING error_clex_str= { STRING_WITH_LEN("error") };
DBUG_PRINT("admin", ("sending error message")); DBUG_PRINT("admin", ("sending error message"));
protocol->prepare_for_resend(); protocol->prepare_for_resend();
protocol->store(table_name, system_charset_info); protocol->store(&table_name, system_charset_info);
protocol->store(operator_name, system_charset_info); protocol->store(operator_name, system_charset_info);
protocol->store(STRING_WITH_LEN("error"), system_charset_info); send_read_only_warning(thd, &error_clex_str, &table_name);
length= my_snprintf(buff, sizeof(buff), ER_THD(thd, ER_OPEN_AS_READONLY),
table_name);
protocol->store(buff, length, system_charset_info);
trans_commit_stmt(thd); trans_commit_stmt(thd);
trans_commit(thd); trans_commit(thd);
close_thread_tables(thd); close_thread_tables(thd);
...@@ -800,7 +817,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, ...@@ -800,7 +817,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
/* purecov: begin inspected */ /* purecov: begin inspected */
DBUG_PRINT("admin", ("sending crashed warning")); DBUG_PRINT("admin", ("sending crashed warning"));
protocol->prepare_for_resend(); protocol->prepare_for_resend();
protocol->store(table_name, system_charset_info); protocol->store(&table_name, system_charset_info);
protocol->store(operator_name, system_charset_info); protocol->store(operator_name, system_charset_info);
protocol->store(STRING_WITH_LEN("warning"), system_charset_info); protocol->store(STRING_WITH_LEN("warning"), system_charset_info);
protocol->store(STRING_WITH_LEN("Table is marked as crashed"), protocol->store(STRING_WITH_LEN("Table is marked as crashed"),
...@@ -871,6 +888,15 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, ...@@ -871,6 +888,15 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
if (compl_result_code == HA_ADMIN_OK && collect_eis) 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 Here we close and reopen table in read mode because operation of
collecting statistics is long and it will be better do not block collecting statistics is long and it will be better do not block
...@@ -978,9 +1004,9 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, ...@@ -978,9 +1004,9 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
else else
{ {
protocol->prepare_for_resend(); protocol->prepare_for_resend();
protocol->store(table_name, system_charset_info); protocol->store(&table_name, system_charset_info);
protocol->store(operator_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"), protocol->store(STRING_WITH_LEN("Engine-independent statistics collected"),
system_charset_info); system_charset_info);
if (protocol->write()) if (protocol->write())
...@@ -1007,7 +1033,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, ...@@ -1007,7 +1033,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
while ((err= it++)) while ((err= it++))
{ {
protocol->prepare_for_resend(); protocol->prepare_for_resend();
protocol->store(table_name, system_charset_info); protocol->store(&table_name, system_charset_info);
protocol->store((char*) operator_name, system_charset_info); protocol->store((char*) operator_name, system_charset_info);
protocol->store(warning_level_names[err->get_level()].str, protocol->store(warning_level_names[err->get_level()].str,
warning_level_names[err->get_level()].length, warning_level_names[err->get_level()].length,
...@@ -1019,7 +1045,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, ...@@ -1019,7 +1045,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
thd->get_stmt_da()->clear_warning_info(thd->query_id); thd->get_stmt_da()->clear_warning_info(thd->query_id);
} }
protocol->prepare_for_resend(); protocol->prepare_for_resend();
protocol->store(table_name, system_charset_info); protocol->store(&table_name, system_charset_info);
protocol->store(operator_name, system_charset_info); protocol->store(operator_name, system_charset_info);
send_result_message: send_result_message:
...@@ -1042,32 +1068,32 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, ...@@ -1042,32 +1068,32 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
char buf[MYSQL_ERRMSG_SIZE]; char buf[MYSQL_ERRMSG_SIZE];
size_t length= my_snprintf(buf, sizeof(buf), size_t length= my_snprintf(buf, sizeof(buf),
ER_THD(thd, ER_BAD_TABLE_ERROR), ER_THD(thd, ER_BAD_TABLE_ERROR),
table_name); table_name.str);
protocol->store(STRING_WITH_LEN("note"), system_charset_info); protocol->store(STRING_WITH_LEN("note"), system_charset_info);
protocol->store(buf, length, system_charset_info); protocol->store(buf, length, system_charset_info);
} }
break; break;
case HA_ADMIN_OK: 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); protocol->store(STRING_WITH_LEN("OK"), system_charset_info);
break; break;
case HA_ADMIN_FAILED: 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"), protocol->store(STRING_WITH_LEN("Operation failed"),
system_charset_info); system_charset_info);
break; break;
case HA_ADMIN_REJECT: 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"), protocol->store(STRING_WITH_LEN("Operation need committed state"),
system_charset_info); system_charset_info);
open_for_modify= FALSE; open_for_modify= FALSE;
break; break;
case HA_ADMIN_ALREADY_DONE: 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"), protocol->store(STRING_WITH_LEN("Table is already up to date"),
system_charset_info); system_charset_info);
break; break;
...@@ -1147,7 +1173,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, ...@@ -1147,7 +1173,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
} }
/* Start a new row for the final status row */ /* Start a new row for the final status row */
protocol->prepare_for_resend(); protocol->prepare_for_resend();
protocol->store(table_name, system_charset_info); protocol->store(&table_name, system_charset_info);
protocol->store(operator_name, system_charset_info); protocol->store(operator_name, system_charset_info);
if (result_code) // either mysql_recreate_table or analyze failed if (result_code) // either mysql_recreate_table or analyze failed
{ {
...@@ -1168,7 +1194,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, ...@@ -1168,7 +1194,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
goto err; goto err;
/* Start off another row for HA_ADMIN_FAILED */ /* Start off another row for HA_ADMIN_FAILED */
protocol->prepare_for_resend(); protocol->prepare_for_resend();
protocol->store(table_name, system_charset_info); protocol->store(&table_name, system_charset_info);
protocol->store(operator_name, system_charset_info); protocol->store(operator_name, system_charset_info);
} }
thd->clear_error(); thd->clear_error();
...@@ -1212,7 +1238,11 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, ...@@ -1212,7 +1238,11 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
fatal_error=1; fatal_error=1;
break; break;
} }
case HA_ERR_TABLE_READONLY:
{
send_read_only_warning(thd, &msg_status, &table_name);
break;
}
default: // Probably HA_ADMIN_INTERNAL_ERROR default: // Probably HA_ADMIN_INTERNAL_ERROR
{ {
char buf[MYSQL_ERRMSG_SIZE]; char buf[MYSQL_ERRMSG_SIZE];
......
...@@ -46,7 +46,7 @@ class ha_s3 final :public ha_maria ...@@ -46,7 +46,7 @@ class ha_s3 final :public ha_maria
} }
int check(THD *, HA_CHECK_OPT *) override int check(THD *, HA_CHECK_OPT *) override
{ {
DBUG_ENTER("delete_row"); DBUG_ENTER("check");
DBUG_RETURN(HA_ERR_TABLE_READONLY); DBUG_RETURN(HA_ERR_TABLE_READONLY);
} }
int analyze(THD *, HA_CHECK_OPT *) override int analyze(THD *, HA_CHECK_OPT *) override
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment