summaryrefslogtreecommitdiff
path: root/sql/event_db_repository.cc
diff options
context:
space:
mode:
authorKonstantin Osipov <kostja@sun.com>2010-07-27 14:25:53 +0400
committerKonstantin Osipov <kostja@sun.com>2010-07-27 14:25:53 +0400
commitec2c3bf2c1c27e4401c767a6cdcb3172453ff42c (patch)
treedaa2c75e6ac3ede954eb788e81dd95c711da1569 /sql/event_db_repository.cc
parentc67cf159e928fe63582a4233d130dada0f866cb7 (diff)
downloadmariadb-git-ec2c3bf2c1c27e4401c767a6cdcb3172453ff42c.tar.gz
A pre-requisite patch for the fix for Bug#52044.
This patch also fixes Bug#55452 "SET PASSWORD is replicated twice in RBR mode". The goal of this patch is to remove the release of metadata locks from close_thread_tables(). This is necessary to not mistakenly release the locks in the course of a multi-step operation that involves multiple close_thread_tables() or close_tables_for_reopen(). On the same token, move statement commit outside close_thread_tables(). Other cleanups: Cleanup COM_FIELD_LIST. Don't call close_thread_tables() in COM_SHUTDOWN -- there are no open tables there that can be closed (we leave the locked tables mode in THD destructor, and this close_thread_tables() won't leave it anyway). Make open_and_lock_tables() and open_and_lock_tables_derived() call close_thread_tables() upon failure. Remove the calls to close_thread_tables() that are now unnecessary. Simplify the back off condition in Open_table_context. Streamline metadata lock handling in LOCK TABLES implementation. Add asserts to ensure correct life cycle of statement transaction in a session. Remove a piece of dead code that has also become redundant after the fix for Bug 37521.
Diffstat (limited to 'sql/event_db_repository.cc')
-rw-r--r--sql/event_db_repository.cc74
1 files changed, 31 insertions, 43 deletions
diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc
index b7c01f10066..d47f1641bb0 100644
--- a/sql/event_db_repository.cc
+++ b/sql/event_db_repository.cc
@@ -518,17 +518,20 @@ Event_db_repository::table_scan_all_for_i_s(THD *thd, TABLE *schema_table,
*/
bool
-Event_db_repository::fill_schema_events(THD *thd, TABLE_LIST *tables,
+Event_db_repository::fill_schema_events(THD *thd, TABLE_LIST *i_s_table,
const char *db)
{
- TABLE *schema_table= tables->table;
- TABLE *event_table= NULL;
+ TABLE *schema_table= i_s_table->table;
+ Open_tables_backup open_tables_backup;
+ TABLE_LIST event_table;
int ret= 0;
DBUG_ENTER("Event_db_repository::fill_schema_events");
DBUG_PRINT("info",("db=%s", db? db:"(null)"));
- if (open_event_table(thd, TL_READ, &event_table))
+ event_table.init_one_table("mysql", 5, "event", 5, "event", TL_READ);
+
+ if (open_system_tables_for_read(thd, &event_table, &open_tables_backup))
DBUG_RETURN(TRUE);
/*
@@ -541,11 +544,11 @@ Event_db_repository::fill_schema_events(THD *thd, TABLE_LIST *tables,
every single row's `db` with the schema which we show.
*/
if (db)
- ret= index_read_for_db_for_i_s(thd, schema_table, event_table, db);
+ ret= index_read_for_db_for_i_s(thd, schema_table, event_table.table, db);
else
- ret= table_scan_all_for_i_s(thd, schema_table, event_table);
+ ret= table_scan_all_for_i_s(thd, schema_table, event_table.table);
- close_thread_tables(thd);
+ close_system_tables(thd, &open_tables_backup);
DBUG_PRINT("info", ("Return code=%d", ret));
DBUG_RETURN(ret);
@@ -584,10 +587,7 @@ Event_db_repository::open_event_table(THD *thd, enum thr_lock_type lock_type,
tables.init_one_table("mysql", 5, "event", 5, "event", lock_type);
if (open_and_lock_tables(thd, &tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
- {
- close_thread_tables(thd);
DBUG_RETURN(TRUE);
- }
*table= tables.table;
tables.table->use_all_columns();
@@ -700,7 +700,8 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data,
end:
if (table)
- close_thread_tables(thd);
+ close_mysql_tables(thd);
+
thd->variables.sql_mode= saved_mode;
DBUG_RETURN(test(ret));
}
@@ -811,7 +812,8 @@ Event_db_repository::update_event(THD *thd, Event_parse_data *parse_data,
end:
if (table)
- close_thread_tables(thd);
+ close_mysql_tables(thd);
+
thd->variables.sql_mode= saved_mode;
DBUG_RETURN(test(ret));
}
@@ -865,7 +867,7 @@ Event_db_repository::drop_event(THD *thd, LEX_STRING db, LEX_STRING name,
end:
if (table)
- close_thread_tables(thd);
+ close_mysql_tables(thd);
DBUG_RETURN(test(ret));
}
@@ -934,33 +936,13 @@ Event_db_repository::find_named_event(LEX_STRING db, LEX_STRING name,
void
Event_db_repository::drop_schema_events(THD *thd, LEX_STRING schema)
{
- DBUG_ENTER("Event_db_repository::drop_schema_events");
- drop_events_by_field(thd, ET_FIELD_DB, schema);
- DBUG_VOID_RETURN;
-}
-
-
-/**
- Drops all events which have a specific value of a field.
-
- @pre The thread handle has no open tables.
-
- @param[in,out] thd Thread
- @param[in,out] table mysql.event TABLE
- @param[in] field Which field of the row to use for matching
- @param[in] field_value The value that should match
-*/
-
-void
-Event_db_repository::drop_events_by_field(THD *thd,
- enum enum_events_table_field field,
- LEX_STRING field_value)
-{
int ret= 0;
TABLE *table= NULL;
READ_RECORD read_record_info;
- DBUG_ENTER("Event_db_repository::drop_events_by_field");
- DBUG_PRINT("enter", ("field=%d field_value=%s", field, field_value.str));
+ enum enum_events_table_field field= ET_FIELD_DB;
+ MDL_ticket *mdl_savepoint= thd->mdl_context.mdl_savepoint();
+ DBUG_ENTER("Event_db_repository::drop_schema_events");
+ DBUG_PRINT("enter", ("field=%d schema=%s", field, schema.str));
if (open_event_table(thd, TL_WRITE, &table))
DBUG_VOID_RETURN;
@@ -979,7 +961,7 @@ Event_db_repository::drop_events_by_field(THD *thd,
get_field(thd->mem_root,
table->field[ET_FIELD_NAME])));
- if (!sortcmp_lex_string(et_field_lex, field_value, system_charset_info))
+ if (!sortcmp_lex_string(et_field_lex, schema, system_charset_info))
{
DBUG_PRINT("info", ("Dropping"));
if ((ret= table->file->ha_delete_row(table->record[0])))
@@ -989,6 +971,11 @@ Event_db_repository::drop_events_by_field(THD *thd,
}
end_read_record(&read_record_info);
close_thread_tables(thd);
+ /*
+ Make sure to only release the MDL lock on mysql.event, not other
+ metadata locks DROP DATABASE might have acquired.
+ */
+ thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
DBUG_VOID_RETURN;
}
@@ -1026,7 +1013,7 @@ Event_db_repository::load_named_event(THD *thd, LEX_STRING dbname,
else if ((ret= etn->load_from_row(thd, table)))
my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0), "event");
- close_thread_tables(thd);
+ close_mysql_tables(thd);
}
thd->variables.sql_mode= saved_mode;
@@ -1104,7 +1091,8 @@ update_timing_fields_for_event(THD *thd,
end:
if (table)
- close_thread_tables(thd);
+ close_mysql_tables(thd);
+
/* Restore the state of binlog format */
DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
if (save_binlog_row_based)
@@ -1151,7 +1139,7 @@ Event_db_repository::check_system_tables(THD *thd)
if (table_intact.check(tables.table, &mysql_db_table_def))
ret= 1;
- close_thread_tables(thd);
+ close_mysql_tables(thd);
}
/* Check mysql.user */
tables.init_one_table("mysql", 5, "user", 4, "user", TL_READ);
@@ -1171,7 +1159,7 @@ Event_db_repository::check_system_tables(THD *thd)
event_priv_column_position);
ret= 1;
}
- close_thread_tables(thd);
+ close_mysql_tables(thd);
}
/* Check mysql.event */
tables.init_one_table("mysql", 5, "event", 5, "event", TL_READ);
@@ -1185,7 +1173,7 @@ Event_db_repository::check_system_tables(THD *thd)
{
if (table_intact.check(tables.table, &event_table_def))
ret= 1;
- close_thread_tables(thd);
+ close_mysql_tables(thd);
}
DBUG_RETURN(test(ret));