Commit b8d44950 authored by Andrei Elkin's avatar Andrei Elkin
Browse files

Bug#36443 Server crashes when executing insert when insert trigger on table

                        
      The crash appeared to be a result of allocating an instance of Discrete_interval 
      automatically that that was referred in out-of-declaration scope.
                        
      Fixed with correcting backing up and restoring scheme of
      auto_inc_intervals_forced, introduced by bug#33029, by means of shallow copying;
      added simulation code that forces executing those fixes of the former bug that
      targeted at master-and-slave having incompatible bug#33029-prone versions.
parent a757d1c1
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
create table `t1` (`id` int not null auto_increment primary key);
create trigger `trg` before insert on `t1` for each row begin end;
set @@global.debug="+d,simulate_bug33029";
stop slave;
start slave;
insert into `t1` values ();
select * from t1;
id
1
+25 −0
Original line number Diff line number Diff line
#
# Bug #36443 Server crashes when executing insert when insert trigger on table
#
# Emulating the former bug#33029 situation to see that there is no crash anymore.
# 


source include/master-slave.inc;

create table `t1` (`id` int not null auto_increment primary key);
create trigger `trg` before insert on `t1` for each row begin end;

sync_slave_with_master;
set @@global.debug="+d,simulate_bug33029";

stop slave;
start slave;

connection master;

insert into `t1` values ();

sync_slave_with_master;
select * from t1;
+1 −0
Original line number Diff line number Diff line
@@ -4136,6 +4136,7 @@ bool rpl_master_erroneous_autoinc(THD *thd)
  if (active_mi && active_mi->rli.sql_thd == thd)
  {
    Relay_log_info *rli= &active_mi->rli;
    DBUG_EXECUTE_IF("simulate_bug33029", return TRUE;);
    return rpl_master_has_bug(rli, 33029, FALSE);
  }
  return FALSE;
+4 −4
Original line number Diff line number Diff line
@@ -2882,8 +2882,8 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
   */
  if (rpl_master_erroneous_autoinc(this))
  {
    backup->auto_inc_intervals_forced= auto_inc_intervals_forced;
    auto_inc_intervals_forced.empty();
    DBUG_ASSERT(backup->auto_inc_intervals_forced.nb_elements() == 0);
    auto_inc_intervals_forced.swap(&backup->auto_inc_intervals_forced);
  }
#endif
  
@@ -2931,8 +2931,8 @@ void THD::restore_sub_statement_state(Sub_statement_state *backup)
   */
  if (rpl_master_erroneous_autoinc(this))
  {
    auto_inc_intervals_forced= backup->auto_inc_intervals_forced;
    backup->auto_inc_intervals_forced.empty();
    backup->auto_inc_intervals_forced.swap(&auto_inc_intervals_forced);
    DBUG_ASSERT(backup->auto_inc_intervals_forced.nb_elements() == 0);
  }
#endif

+32 −21
Original line number Diff line number Diff line
@@ -314,31 +314,22 @@ class Discrete_intervals_list {
  */
  Discrete_interval        *current;
  uint                  elements; // number of elements

  /* helper function for copy construct and assignment operator */
  void copy_(const Discrete_intervals_list& from)
  {
    for (Discrete_interval *i= from.head; i; i= i->next)
  void set_members(Discrete_interval *h, Discrete_interval *t,
                   Discrete_interval *c, uint el)
  {  
      Discrete_interval j= *i;
      append(&j);
    }
    head= h;
    tail= t;
    current= c;
    elements= el;
  }
  void operator=(Discrete_intervals_list &);  /* prevent use of these */
  Discrete_intervals_list(const Discrete_intervals_list &);

public:
  Discrete_intervals_list() : head(NULL), current(NULL), elements(0) {};
  Discrete_intervals_list(const Discrete_intervals_list& from)
  {
    copy_(from);
  }
  void operator=(const Discrete_intervals_list& from)
  {
    empty();
    copy_(from);
  }
  void empty_no_free()
  {
    head= current= NULL;
    elements= 0;
    set_members(NULL, NULL, NULL, 0);
  }
  void empty()
  {
@@ -350,7 +341,24 @@ class Discrete_intervals_list {
    }
    empty_no_free();
  }

  void copy_shallow(const Discrete_intervals_list * dli)
  {
    head= dli->get_head();
    tail= dli->get_tail();
    current= dli->get_current();
    elements= dli->nb_elements();
  }
  void swap (Discrete_intervals_list * dli)
  {
    Discrete_interval *h, *t, *c;
    uint el;
    h= dli->get_head();
    t= dli->get_tail();
    c= dli->get_current();
    el= dli->nb_elements();
    dli->copy_shallow(this);
    set_members(h, t, c, el);
  }
  const Discrete_interval* get_next()
  {
    Discrete_interval *tmp= current;
@@ -364,4 +372,7 @@ class Discrete_intervals_list {
  ulonglong minimum()     const { return (head ? head->minimum() : 0); };
  ulonglong maximum()     const { return (head ? tail->maximum() : 0); };
  uint      nb_elements() const { return elements; }
  Discrete_interval* get_head() const { return head; };
  Discrete_interval* get_tail() const { return tail; };
  Discrete_interval* get_current() const { return current; };
};