[MY-011526]系列二 GTID_SET生成

1.GTID_SET正常生成涉及到的堆棧信息

-do_command(THD*)

--dispatch_command(THD*,COM_DATA const*,enum_server_command)

---mysql_parse(THD*,Parser_state*)

----mysql_execute_command(THD*,bool)

-----trans_commit_stmt(THD*,bool)

------ha_commit_trans(THD*,bool,bool)

-------MYSQL_BIN_LOG::commit(THD*,bool)

--------MYSQL_BIN_LOG::ordered_commit(THD*,bool,bool)

---------MYSQL_BIN_LOG::process_commit_stage_queue(THD*,THD*)

----------Gtid_state::update_commit_group(THD*)

-----------Gtid_state::update_gtids_impl_own_gtid(THD*,bool)

------------Gtid_set::_add_gtid(Gtid const&)

-------------Gtid_set::_add_gtid(int,long long)

--------------Gtid_set::add_gno_interval(Interval_iterator *ivitp, rpl_gno start,rpl_gno end, Free_intervals_lock *lock)

1.1 GNO

/// Type of GNO, the second (numeric) component of GTID

typedef long long int rpl_gno;

1.2 Gtid_set::_add_gtid函數

  void_add_gtid(rpl_sidnosidno,rpl_gnogno) {

    add_gno_interval(&ivit, gno, gno +1, &lock);

  }

1.3Gtid_set::add_gno_interval函數

voidGtid_set::add_gno_interval(Interval_iterator*ivitp,rpl_gnostart,

                                                                                  rpl_gnoend,Free_intervals_lock*lock) {

  while((iv = ivit.get()) !=NULL) {

       iv->start= start;

      if(iv->end< end) iv->end= end;

      *ivitp = ivit;

    }

  }

 

2.GTID_SET異常處理涉及到的堆棧信息

-Gtid_set::add_gno_interval(Interval_iterator *ivitp, rpl_gno start,rpl_gno end, Free_intervals_lock *lock)

--Gtid_set::get_free_interval(Interval **out)

---Gtid_set::create_new_chunk(int size)

----Gtid_set::add_interval_memory_lock_taken(int n_ivs,Interval *ivs)

2.1結構體Interval_chunk

/*

   Contains a list of intervals allocated by this Gtid_set. When a

    method of this class needs a new interval and there are no more

    free intervals, a new Interval_chunk is allocated and the

    intervals of it are added to the list of free intervals.

  */

  struct Interval_chunk {

    Interval_chunk *next;

    Interval intervals[1];

  };

2.2 Gtid_set::add_gno_interval關於GTID_SET異常處理部分

void  Gtid_set::add_gno_interval(Interval_iterator*ivitp,rpl_gnostart,

                                                                             rpl_gnoend,Free_intervals_lock*lock) {

    /*

    We come here if the interval cannot be combined with any existing

    interval: it is after the previous interval (if any) and before

    the current interval (if any). So we allocate a new interval and

    insert it at the current position.

  */

  Interval*new_iv;

  lock->lock_if_not_locked();

  get_free_interval(&new_iv);

  new_iv->start= start;

  new_iv->end= end;

  ivit.insert(new_iv);

  *ivitp = ivit;

  DBUG_VOID_RETURN;

}

2.3 Gtid_set::get_free_interval函數

void Gtid_set::get_free_interval(Interval**out) {

  if(ivit.get() ==NULL|| simulate_failure)create_new_chunk(CHUNK_GROW_SIZE)

}

2.4Gtid_set::create_new_chunk函數

void Gtid_set::create_new_chunk(int size) {

    /*

    Try to allocate the new chunk in MAX_NEW_CHUNK_ALLOCATE_TRIES

    tries when encountering 'out of memory' situation.

  */

  while (i < MAX_NEW_CHUNK_ALLOCATE_TRIES) {

    /*

      Allocate the new chunk. one element is already pre-allocated, so

      we only add size-1 elements to the size of the struct.

    */

    new_chunk = (Interval_chunk*)my_malloc(

        key_memory_Gtid_set_Interval_chunk,

        sizeof(Interval_chunk) +sizeof(Interval) * (size -1),MYF(MY_WME));

    }

  }

  // add the intervals in the chunk to the list of free intervals

  add_interval_memory_lock_taken(size, new_chunk->intervals);

}

2.5 Gtid_set::add_interval_memory_lock_taken函數

void Gtid_set::add_interval_memory_lock_taken(intn_ivs,Interval*ivs) {

  // make ivs a linked list

  for(inti =0; i < n_ivs -1; i++) ivs[i].next= &(ivs[i +1]);

  Interval_iterator ivit(this);

  ivs[n_ivs -1].next= ivit.get();

  // add intervals to list of free intervals

  ivit.set(&(ivs[0]));

}

3結論

以上是GTID_SET正常生成以及異常後重新生成的方式堆棧信息,歡迎各位指正!

附圖:斷點調試截圖

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章