mirror of
https://github.com/MariaDB/server.git
synced 2025-01-28 01:34:17 +01:00
Don't use row level logging on optimize or repair table.
(Fixes core dump in rpl_failed_optimize.test) Ensure we end active transcations if we do an admin command (like optimize, repair etc) mysql-test/extra/rpl_tests/rpl_failed_optimize.test: Added extra test + drop of table at end of test mysql-test/lib/mtr_report.pl: Fail if mysqld asserts or prints stack mysql-test/mysql-test-run.sh: Fail if mysqld asserts or prints stack mysql-test/r/exampledb.result: Cleanup of events_tests (as this caused a lot of problems if it didn't work) mysql-test/r/innodb.result: Extra test to see that we can do an optimize table on an active transaction mysql-test/r/rpl_failed_optimize.result: Added extra test + drop of table at end of test mysql-test/t/exampledb.test: Cleanup of events_tests (as this caused a lot of problems if it didn't work) mysql-test/t/innodb.test: Extra test to see that we can do an optimize table on an active transaction sql/handler.cc: Don't use row level logging on optimize or repair table. sql/log.cc: Simplify code (no logic changes) sql/mysql_priv.h: Added prototype sql/sql_base.cc: Better name for define sql/sql_class.cc: Indentation fix sql/sql_parse.cc: Make end_active_trans() global sql/sql_table.cc: Ensure we end active transcations if we do an admin command (like optimize, repair etc)
This commit is contained in:
parent
d1b6779ade
commit
3995b06b40
15 changed files with 92 additions and 42 deletions
|
@ -17,3 +17,8 @@ OPTIMIZE TABLE non_existing;
|
|||
sync_slave_with_master;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
connection master;
|
||||
select * from t1;
|
||||
commit;
|
||||
drop table t1;
|
||||
|
|
|
@ -218,7 +218,8 @@ sub mtr_report_stats ($) {
|
|||
# We report different types of problems in order
|
||||
foreach my $pattern ( "^Warning:", "^Error:", "^==.* at 0x",
|
||||
"InnoDB: Warning", "missing DBUG_RETURN",
|
||||
"mysqld: Warning")
|
||||
"mysqld: Warning",
|
||||
"Attempting backtrace", "Assertion .* failed" )
|
||||
{
|
||||
foreach my $errlog ( sort glob("$::opt_vardir/log/*.err") )
|
||||
{
|
||||
|
@ -232,7 +233,8 @@ sub mtr_report_stats ($) {
|
|||
# Skip some non fatal warnings from the log files
|
||||
if ( /Warning:\s+Table:.* on (delete|rename)/ or
|
||||
/Warning:\s+Setting lower_case_table_names=2/ or
|
||||
/Warning:\s+One can only use the --user.*root/ )
|
||||
/Warning:\s+One can only use the --user.*root/ or
|
||||
/InnoDB: Warning: we did not need to do crash recovery/)
|
||||
{
|
||||
next; # Skip these lines
|
||||
}
|
||||
|
|
|
@ -1073,13 +1073,13 @@ report_stats () {
|
|||
#
|
||||
$RM -f $MY_LOG_DIR/warnings $MY_LOG_DIR/warnings.tmp
|
||||
# Remove some non fatal warnings from the log files
|
||||
$SED -e 's!Warning: Table:.* on delete!!g' -e 's!Warning: Setting lower_case_table_names=2!!g' -e 's!Warning: One can only use the --user.*root!!g' \
|
||||
$SED -e 's!Warning: Table:.* on delete!!g' -e 's!Warning: Setting lower_case_table_names=2!!g' -e 's!Warning: One can only use the --user.*root!!g' -e 's|InnoDB: Warning: we did not need to do crash recovery||g' \
|
||||
$MY_LOG_DIR/*.err \
|
||||
| $SED -e 's!Warning: Table:.* on rename!!g' \
|
||||
> $MY_LOG_DIR/warnings.tmp
|
||||
|
||||
# Find errors
|
||||
for i in "^Warning:" "^Error:" "^==.* at 0x" "InnoDB: Warning" "missing DBUG_RETURN" "mysqld: Warning"
|
||||
for i in "^Warning:" "^Error:" "^==.* at 0x" "InnoDB: Warning" "missing DBUG_RETURN" "mysqld: Warning" "Attempting backtrace" "Assertion .* failed"
|
||||
do
|
||||
if $GREP "$i" $MY_LOG_DIR/warnings.tmp >> $MY_LOG_DIR/warnings
|
||||
then
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
drop database if exists events_test;
|
||||
drop database if exists events_test2;
|
||||
drop table if exists t1;
|
||||
CREATE TABLE t1 (
|
||||
Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL,
|
||||
|
|
|
@ -3457,3 +3457,10 @@ a
|
|||
drop table t2, t1;
|
||||
create table t1 (g geometry not null, spatial gk(g)) engine=innodb;
|
||||
ERROR HY000: The used table type doesn't support SPATIAL indexes
|
||||
CREATE TABLE t1 ( a int ) ENGINE=innodb;
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES (1);
|
||||
OPTIMIZE TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 optimize status OK
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -18,3 +18,8 @@ Table Op Msg_type Msg_text
|
|||
test.non_existing optimize error Table 'test.non_existing' doesn't exist
|
||||
Warnings:
|
||||
Error 1146 Table 'test.non_existing' doesn't exist
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
commit;
|
||||
drop table t1;
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
-- source include/have_exampledb.inc
|
||||
|
||||
--disable_warnings
|
||||
# Clean up if event's test fails
|
||||
drop database if exists events_test;
|
||||
drop database if exists events_test2;
|
||||
|
||||
drop table if exists t1;
|
||||
--enable_warnings
|
||||
|
||||
|
|
|
@ -2500,3 +2500,13 @@ drop table t2, t1;
|
|||
#
|
||||
--error ER_TABLE_CANT_HANDLE_SPKEYS
|
||||
create table t1 (g geometry not null, spatial gk(g)) engine=innodb;
|
||||
|
||||
#
|
||||
# Test optimize on table with open transaction
|
||||
#
|
||||
|
||||
CREATE TABLE t1 ( a int ) ENGINE=innodb;
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES (1);
|
||||
OPTIMIZE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -3264,10 +3264,11 @@ int handler::ha_external_lock(THD *thd, int lock_type)
|
|||
locking combined with row-based replication needs to be looked
|
||||
over. Ideally, no such special handling should be needed.
|
||||
*/
|
||||
switch (thd->lex->sql_command)
|
||||
{
|
||||
switch (thd->lex->sql_command) {
|
||||
case SQLCOM_TRUNCATE:
|
||||
case SQLCOM_ALTER_TABLE:
|
||||
case SQLCOM_OPTIMIZE:
|
||||
case SQLCOM_REPAIR:
|
||||
DBUG_RETURN(0);
|
||||
default:
|
||||
break;
|
||||
|
|
18
sql/log.cc
18
sql/log.cc
|
@ -2879,23 +2879,27 @@ bool MYSQL_LOG::write(Log_event *event_info)
|
|||
binlog_trx_data *const trx_data=
|
||||
(binlog_trx_data*) thd->ha_data[binlog_hton.slot];
|
||||
IO_CACHE *trans_log= &trx_data->trans_log;
|
||||
bool trans_log_in_use= my_b_tell(trans_log) != 0;
|
||||
|
||||
if (event_info->get_cache_stmt() && !my_b_tell(trans_log))
|
||||
if (event_info->get_cache_stmt() && !trans_log_in_use)
|
||||
trans_register_ha(thd,
|
||||
thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN),
|
||||
(thd->options &
|
||||
(OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)),
|
||||
&binlog_hton);
|
||||
|
||||
if (event_info->get_cache_stmt() || my_b_tell(trans_log))
|
||||
if (event_info->get_cache_stmt() || trans_log_in_use)
|
||||
{
|
||||
DBUG_PRINT("info", ("Using trans_log"));
|
||||
file= trans_log;
|
||||
}
|
||||
/*
|
||||
Note: as Mats suggested, for all the cases above where we write to
|
||||
TODO as Mats suggested, for all the cases above where we write to
|
||||
trans_log, it sounds unnecessary to lock LOCK_log. We should rather
|
||||
test first if we want to write to trans_log, and if not, lock
|
||||
LOCK_log. TODO.
|
||||
LOCK_log.
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
DBUG_PRINT("info",("event type=%d",event_info->get_type_code()));
|
||||
DBUG_PRINT("info",("event type: %d",event_info->get_type_code()));
|
||||
|
||||
/*
|
||||
No check for auto events flag here - this write method should
|
||||
|
|
|
@ -558,6 +558,7 @@ enum enum_mysql_completiontype {
|
|||
};
|
||||
|
||||
bool begin_trans(THD *thd);
|
||||
bool end_active_trans(THD *thd);
|
||||
int end_trans(THD *thd, enum enum_mysql_completiontype completion);
|
||||
|
||||
Item *negate_expression(THD *thd, Item *expr);
|
||||
|
|
|
@ -288,13 +288,13 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key,
|
|||
|
||||
if (!(share= alloc_table_share(table_list, key, key_length)))
|
||||
{
|
||||
#ifdef NOT_YET
|
||||
#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
|
||||
pthread_mutex_unlock(&LOCK_open);
|
||||
#endif
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
#ifdef NOT_YET
|
||||
#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
|
||||
// We need a write lock to be able to add a new entry
|
||||
pthread_mutex_unlock(&LOCK_open);
|
||||
pthread_mutex_lock(&LOCK_open);
|
||||
|
@ -331,19 +331,19 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key,
|
|||
|
||||
if (my_hash_insert(&table_def_cache, (byte*) share))
|
||||
{
|
||||
#ifdef NOT_YET
|
||||
#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
|
||||
pthread_mutex_unlock(&LOCK_open);
|
||||
(void) pthread_mutex_unlock(&share->mutex);
|
||||
#endif
|
||||
free_table_share(share);
|
||||
DBUG_RETURN(0); // return error
|
||||
}
|
||||
#ifdef NOT_YET
|
||||
#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
|
||||
pthread_mutex_unlock(&LOCK_open);
|
||||
#endif
|
||||
if (open_table_def(thd, share, db_flags))
|
||||
{
|
||||
#ifdef NOT_YET
|
||||
#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
|
||||
/*
|
||||
No such table or wrong table definition file
|
||||
Lock first the table cache and then the mutex.
|
||||
|
@ -372,7 +372,7 @@ found:
|
|||
|
||||
/* We must do a lock to ensure that the structure is initialized */
|
||||
(void) pthread_mutex_lock(&share->mutex);
|
||||
#ifdef NOT_YET
|
||||
#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
|
||||
pthread_mutex_unlock(&LOCK_open);
|
||||
#endif
|
||||
if (share->error)
|
||||
|
@ -540,7 +540,7 @@ void release_table_share(TABLE_SHARE *share, enum release_type type)
|
|||
DBUG_VOID_RETURN;
|
||||
|
||||
|
||||
#ifdef NOT_YET
|
||||
#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
|
||||
if (to_be_deleted)
|
||||
{
|
||||
/*
|
||||
|
@ -1069,7 +1069,7 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived)
|
|||
handled either before writing a query log event (inside
|
||||
binlog_query()) or when preparing a pending event.
|
||||
*/
|
||||
thd->binlog_flush_pending_rows_event(true);
|
||||
thd->binlog_flush_pending_rows_event(TRUE);
|
||||
mysql_unlock_tables(thd, thd->lock);
|
||||
thd->lock=0;
|
||||
}
|
||||
|
|
|
@ -2688,8 +2688,7 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype,
|
|||
DBUG_ENTER("THD::binlog_query");
|
||||
DBUG_ASSERT(query && mysql_bin_log.is_open());
|
||||
|
||||
switch (qtype)
|
||||
{
|
||||
switch (qtype) {
|
||||
case THD::MYSQL_QUERY_TYPE:
|
||||
/*
|
||||
Using this query type is a conveniece hack, since we have been
|
||||
|
|
|
@ -137,7 +137,7 @@ static void unlock_locked_tables(THD *thd)
|
|||
}
|
||||
|
||||
|
||||
static bool end_active_trans(THD *thd)
|
||||
bool end_active_trans(THD *thd)
|
||||
{
|
||||
int error=0;
|
||||
DBUG_ENTER("end_active_trans");
|
||||
|
@ -2961,8 +2961,7 @@ end_with_restore_list:
|
|||
thd->enable_slow_log= opt_log_slow_admin_statements;
|
||||
if (end_active_trans(thd))
|
||||
goto error;
|
||||
else
|
||||
res = mysql_create_index(thd, first_table, lex->key_list);
|
||||
res= mysql_create_index(thd, first_table, lex->key_list);
|
||||
break;
|
||||
|
||||
#ifdef HAVE_REPLICATION
|
||||
|
@ -3069,18 +3068,16 @@ end_with_restore_list:
|
|||
/* ALTER TABLE ends previous transaction */
|
||||
if (end_active_trans(thd))
|
||||
goto error;
|
||||
else
|
||||
{
|
||||
thd->enable_slow_log= opt_log_slow_admin_statements;
|
||||
res= mysql_alter_table(thd, select_lex->db, lex->name,
|
||||
&lex->create_info,
|
||||
first_table, lex->create_list,
|
||||
lex->key_list,
|
||||
select_lex->order_list.elements,
|
||||
(ORDER *) select_lex->order_list.first,
|
||||
lex->duplicates, lex->ignore, &lex->alter_info,
|
||||
1);
|
||||
}
|
||||
|
||||
thd->enable_slow_log= opt_log_slow_admin_statements;
|
||||
res= mysql_alter_table(thd, select_lex->db, lex->name,
|
||||
&lex->create_info,
|
||||
first_table, lex->create_list,
|
||||
lex->key_list,
|
||||
select_lex->order_list.elements,
|
||||
(ORDER *) select_lex->order_list.first,
|
||||
lex->duplicates, lex->ignore, &lex->alter_info,
|
||||
1);
|
||||
break;
|
||||
}
|
||||
#endif /*DONT_ALLOW_SHOW_COMMANDS*/
|
||||
|
@ -3207,7 +3204,7 @@ end_with_restore_list:
|
|||
check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, 0))
|
||||
goto error; /* purecov: inspected */
|
||||
thd->enable_slow_log= opt_log_slow_admin_statements;
|
||||
res = mysql_analyze_table(thd, first_table, &lex->check_opt);
|
||||
res= mysql_analyze_table(thd, first_table, &lex->check_opt);
|
||||
/* ! we write after unlocking the table */
|
||||
if (!res && !lex->no_write_to_binlog)
|
||||
{
|
||||
|
@ -3512,8 +3509,7 @@ end_with_restore_list:
|
|||
goto error; /* purecov: inspected */
|
||||
if (end_active_trans(thd))
|
||||
goto error;
|
||||
else
|
||||
res = mysql_drop_index(thd, first_table, &lex->alter_info);
|
||||
res= mysql_drop_index(thd, first_table, &lex->alter_info);
|
||||
break;
|
||||
case SQLCOM_SHOW_PROCESSLIST:
|
||||
if (!thd->security_ctx->priv_user[0] &&
|
||||
|
|
|
@ -3898,6 +3898,8 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||
int result_code;
|
||||
DBUG_ENTER("mysql_admin_table");
|
||||
|
||||
if (end_active_trans(thd))
|
||||
DBUG_RETURN(1);
|
||||
field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2));
|
||||
item->maybe_null = 1;
|
||||
field_list.push_back(item = new Item_empty_string("Op", 10));
|
||||
|
@ -3948,6 +3950,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||
{
|
||||
switch ((*prepare_func)(thd, table, check_opt)) {
|
||||
case 1: // error, message written to net
|
||||
ha_autocommit_or_rollback(thd, 1);
|
||||
close_thread_tables(thd);
|
||||
continue;
|
||||
case -1: // error, message could be written to net
|
||||
|
@ -3989,6 +3992,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||
View opening can be interrupted in the middle of process so some
|
||||
tables can be left opening
|
||||
*/
|
||||
ha_autocommit_or_rollback(thd, 1);
|
||||
close_thread_tables(thd);
|
||||
if (protocol->write())
|
||||
goto err;
|
||||
|
@ -4013,6 +4017,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||
length= my_snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
|
||||
table_name);
|
||||
protocol->store(buff, length, system_charset_info);
|
||||
ha_autocommit_or_rollback(thd, 0);
|
||||
close_thread_tables(thd);
|
||||
table->table=0; // For query cache
|
||||
if (protocol->write())
|
||||
|
@ -4058,6 +4063,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||
(table->table->file->ha_check_for_upgrade(check_opt) ==
|
||||
HA_ADMIN_NEEDS_ALTER))
|
||||
{
|
||||
ha_autocommit_or_rollback(thd, 1);
|
||||
close_thread_tables(thd);
|
||||
tmp_disable_binlog(thd); // binlogging is done by caller if wanted
|
||||
result_code= mysql_recreate_table(thd, table, 0);
|
||||
|
@ -4144,6 +4150,7 @@ send_result_message:
|
|||
"try with alter", so here we close the table, do an ALTER TABLE,
|
||||
reopen the table and do ha_innobase::analyze() on it.
|
||||
*/
|
||||
ha_autocommit_or_rollback(thd, 0);
|
||||
close_thread_tables(thd);
|
||||
TABLE_LIST *save_next_local= table->next_local,
|
||||
*save_next_global= table->next_global;
|
||||
|
@ -4151,6 +4158,7 @@ send_result_message:
|
|||
tmp_disable_binlog(thd); // binlogging is done by caller if wanted
|
||||
result_code= mysql_recreate_table(thd, table, 0);
|
||||
reenable_binlog(thd);
|
||||
ha_autocommit_or_rollback(thd, 0);
|
||||
close_thread_tables(thd);
|
||||
if (!result_code) // recreation went ok
|
||||
{
|
||||
|
@ -4238,6 +4246,7 @@ send_result_message:
|
|||
query_cache_invalidate3(thd, table->table, 0);
|
||||
}
|
||||
}
|
||||
ha_autocommit_or_rollback(thd, 0);
|
||||
close_thread_tables(thd);
|
||||
table->table=0; // For query cache
|
||||
if (protocol->write())
|
||||
|
@ -4246,7 +4255,9 @@ send_result_message:
|
|||
|
||||
send_eof(thd);
|
||||
DBUG_RETURN(FALSE);
|
||||
|
||||
err:
|
||||
ha_autocommit_or_rollback(thd, 1);
|
||||
close_thread_tables(thd); // Shouldn't be needed
|
||||
if (table)
|
||||
table->table=0;
|
||||
|
@ -4701,7 +4712,9 @@ mysql_discard_or_import_tablespace(THD *thd,
|
|||
if (error)
|
||||
goto err;
|
||||
write_bin_log(thd, FALSE, thd->query, thd->query_length);
|
||||
|
||||
err:
|
||||
ha_autocommit_or_rollback(thd, error);
|
||||
close_thread_tables(thd);
|
||||
thd->tablespace_op=FALSE;
|
||||
|
||||
|
@ -6388,7 +6401,8 @@ bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list,
|
|||
}
|
||||
|
||||
|
||||
bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
|
||||
bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
|
||||
HA_CHECK_OPT *check_opt)
|
||||
{
|
||||
TABLE_LIST *table;
|
||||
List<Item> field_list;
|
||||
|
|
Loading…
Add table
Reference in a new issue