1
0
mirror of https://github.com/MariaDB/server.git synced 2025-12-24 11:21:21 +03:00

BUG#36197: flush tables (or little table cache) can cause crash on slave

When flushing tables, there were a slight chance that the flush was occuring
between processing of two table map events. Since the tables are opened
one by one, it might result in that the tables were not valid and that sub-
sequent locking of tables would cause the slave to crash.

The problem is solved by opening and locking all tables at once using
simple_open_n_lock_tables(). Also, the patch contain a change to open_tables()
so that pre-locking only takes place when the trg_event_map is not zero, which
was not the case before (this caused the lock to be placed in thd->locked_tables
instead of thd->lock since the assumption was that triggers would be called
later and therefore the tables should be pre-locked).


mysql-test/suite/rpl/r/rpl_found_rows.result:
  Result change
mysql-test/suite/rpl/r/rpl_row_inexist_tbl.result:
  Result change
mysql-test/suite/rpl/t/rpl_found_rows.test:
  Adding drop of table that was created in test.
mysql-test/suite/rpl/t/rpl_slave_status.test:
  Adding waits for slave start and stop to ensure that test works.
sql/log_event.cc:
  Replacing table-by-table open and lock with a single call
  to simple_open_n_lock_tables(), which in turn required some
  changes to other code.
sql/log_event_old.cc:
  Replacing table-by-table open and lock with a single call
  to simple_open_n_lock_tables(), which in turn required some
  changes to other code.
sql/sql_base.cc:
  Extending check inside open_tables() so that pre-locking in only done if
  tables->trg_egent_map is non-zero.
mysql-test/include/wait_for_slave_sql_to_start.inc:
  New BitKeeper file ``mysql-test/include/wait_for_slave_sql_to_start.inc''
This commit is contained in:
unknown
2008-05-12 19:50:53 +02:00
parent 02c00f95bf
commit dac6ffb958
8 changed files with 113 additions and 212 deletions

View File

@@ -4367,6 +4367,11 @@ bool fix_merge_after_open(TABLE_LIST *old_child_list, TABLE_LIST **old_last,
prelocking it won't do such precaching and will simply reuse table list
which is already built.
If any table has a trigger and start->trg_event_map is non-zero
the final lock will end up in thd->locked_tables, otherwise, the
lock will be placed in thd->lock. See also comments in
st_lex::set_trg_event_type_for_tables().
RETURN
0 - OK
-1 - error
@@ -4579,7 +4584,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
process its triggers since they never will be activated.
*/
if (!thd->prelocked_mode && !thd->lex->requires_prelocking() &&
tables->table->triggers &&
tables->trg_event_map && tables->table->triggers &&
tables->lock_type >= TL_WRITE_ALLOW_WRITE)
{
if (!query_tables_last_own)