• unknown's avatar
    Fix for bug #12704 "Server crashes during trigger execution". · d5303b8a
    unknown authored
    This bug occurs when some trigger for table used by DML statement is created
    or changed while statement was waiting in lock_tables(). In this situation
    prelocking set which we have calculated becames invalid which can easily lead
    to errors and even in some cases to crashes.
    
    With proposed patch we no longer silently reopen tables in lock_tables(),
    instead caller of lock_tables() becomes responsible for reopening tables and
    recalculation of prelocking set.
    
    
    mysql-test/t/trigger.test:
      Added tests for bug #12704 "Server crashes during trigger execution".
      Unfortunately these tests rely on the order in which tables are locked
      by statement so they are non-determenistic and therefore should be disabled.
    sql/lock.cc:
      mysql_lock_tables():
        Now instead of always reopening altered or dropped tables by itself
        mysql_lock_tables() can notify upper level and rely on caller doing this.
    sql/mysql_priv.h:
      Now mysql_lock_tables() can either reopen deleted or altered tables by itself
      or notify caller about such situation through 'need_reopen' argument and rely
      on it in this.
      Also lock_tables() has new 'need_reopen' out parameter through which it
      notifies caller that some tables were altered or dropped so he needs to reopen
      them (and rebuild prelocking set some triggers may change or simply appear).
    sql/sp.cc:
      sp_add_used_routine():
        To be able to restore LEX::sroutines_list to its state right after parsing
        we now adjust  LEX::sroutines_list_own_last/sroutines_list_own_elements when
        we add directly used routine.
      sp_remove_not_own_routines():
        Added procedure for restoring LEX::sroutines/sroutines_list to their state
        right after parsing (by throwing out non-directly used routines).
      sp_cache_routines_and_add_tables_for_view()/sp_update_stmt_used_routines():
        We should use LEX::sroutines_list instead of LEX::sroutines as source of
        routines used by view, since LEX::sroutines is not availiable for view
        on second attempt to open it (see comment in open_tables() about it).
    sql/sp.h:
      sp_remove_not_own_routines():
        Added procedure for restoring LEX::sroutines/sroutines_list to their state
        right after parsing (by throwing out non-directly used routines).
    sql/sp_head.cc:
      Removed assert which is no longer always true.
    sql/sql_base.cc:
      reopen_table():
        When we re-open table and do shallow copy of TABLE object we should adjust
        pointers to it in associated Table_triggers_list object. Removed nil
        operation.
      open_tables():
        Now this function is able to rebuild prelocking set for statement if it is
        needed. It also correctly handles FLUSH TABLES which may occur during its
        execution.
      lock_tables():
        Instead of allowing mysql_lock_tables() to silently reopen altered or dropped
        tables let us notify caller and rely on that it will do reopen itself.
        This solves the problem when trigger suddenly appears or changed during
        mysq_lock_tables().
      close_tables_for_reopen():
        Added routine for properly preparing for reopening of tables and recalculation
        of set of prelocked tables.
    sql/sql_handler.cc:
      Here we let mysql_lock_tables() to reopen dropped or altered tables by itself.
    sql/sql_insert.cc:
      Here we let mysql_lock_tables() to reopen dropped or altered tables by itself.
    sql/sql_lex.cc:
      LEX:
        Added 'sroutines_list_own_last' and 'sroutines_list_own_elements' members
        which are used for keeping state in which 'sroutines_list' was right after
        statement parsing (and for restoring of this list to this state).
    sql/sql_lex.h:
      LEX:
        Added 'sroutines_list_own_last' and 'sroutines_list_own_elements' members
        which are used for keeping state in which 'sroutines_list' was right after
        statement parsing (and for restoring of this list to this state).
        Added chop_off_not_own_tables() method to simplify throwing away list
        of implicitly used (prelocked) tables.
    sql/sql_prepare.cc:
      Now instead of silently reopening altered or dropped tables in
      lock_tables() we notify caller and rely on that the caller will
      reopen tables.
    sql/sql_table.cc:
      Here we let mysql_lock_tables() to reopen dropped or altered tables by itself.
    sql/sql_trigger.cc:
      Added Table_triggers_list::set_table() method to adjust Table_triggers_list
      to new pointer to TABLE instance.
    sql/sql_trigger.h:
      Added Table_triggers_list::set_table() method to adjust Table_triggers_list
      to new pointer to TABLE instance.
    sql/sql_update.cc:
      Now instead of silently reopening altered or dropped tables in
      lock_tables() we notify caller and rely on that the caller will
      reopen tables.
    d5303b8a
lock.cc 29.6 KB