十一:引數binlog_row_image(筆記)

gaopengtttt發表於2019-07-09

歡迎關注我的《深入理解MySQL主從原理 32講 》,如下:

image.png
如果圖片不能顯示可檢視下面連結:
https://www.jianshu.com/p/d636215d767f

一、設定過程

插入前先呼叫TABLE::mark_columns_per_binlog_row_image函式
函式中有image的詳細設定

/*
  Mark columns according the binlog row image option.
  When logging in RBR, the user can select whether to
  log partial or full rows, depending on the table
  definition, and the value of binlog_row_image.
  Semantics of the binlog_row_image are the following 
  (PKE - primary key equivalent, ie, PK fields if PK 
  exists, all fields otherwise):
  binlog_row_image= MINIMAL
    - This marks the PKE fields in the read_set
    - This marks all fields where a value was specified
      in the write_set
  binlog_row_image= NOBLOB
    - This marks PKE + all non-blob fields in the read_set
    - This marks all fields where a value was specified
      and all non-blob fields in the write_set
  binlog_row_image= FULL
    - all columns in the read_set
    - all columns in the write_set
  This marking is done without resetting the original 
  bitmaps. This means that we will strip extra fields in
  the read_set at binlogging time (for those cases that 
  we only want to log a PK and we needed other fields for
  execution).
 */
void TABLE::mark_columns_per_binlog_row_image()
{
  DBUG_ENTER("mark_columns_per_binlog_row_image");
  DBUG_ASSERT(read_set->bitmap);
  DBUG_ASSERT(write_set->bitmap);
  /**
    If in RBR we may need to mark some extra columns,
    depending on the binlog-row-image command line argument.
   */
  if ((mysql_bin_log.is_open() && in_use &&
       in_use->is_current_stmt_binlog_format_row() &&
       !ha_check_storage_engine_flag(s->db_type(), HTON_NO_BINLOG_ROW_OPT)))
  {
    THD *thd= current_thd;
    /* if there is no PK, then mark all columns for the BI. */
    if (s->primary_key >= MAX_KEY)
      bitmap_set_all(read_set);
    switch (thd->variables.binlog_row_image)
    {
      case BINLOG_ROW_IMAGE_FULL:
        if (s->primary_key < MAX_KEY)
          bitmap_set_all(read_set); //記錄全部欄位
        bitmap_set_all(write_set); //記錄全部欄位,前面write_set應該只是記錄了 修改了哪些欄位   點陣圖 初始化初始4位元組
        break;
      case BINLOG_ROW_IMAGE_NOBLOB:
        /* for every field that is not set, mark it unless it is a blob */
        for (Field **ptr=field ; *ptr ; ptr++)
        {
          Field *my_field= *ptr;
          /* 
            bypass blob fields. These can be set or not set, we don't care.
            Later, at binlogging time, if we don't need them in the before 
            image, we will discard them.
            If set in the AI, then the blob is really needed, there is 
            nothing we can do about it.
           */
          if ((s->primary_key < MAX_KEY) && 
              ((my_field->flags & PRI_KEY_FLAG) || 
              (my_field->type() != MYSQL_TYPE_BLOB)))
            bitmap_set_bit(read_set, my_field->field_index);
          if (my_field->type() != MYSQL_TYPE_BLOB)
            bitmap_set_bit(write_set, my_field->field_index);
        }
        break;
      case BINLOG_ROW_IMAGE_MINIMAL:
        /* mark the primary key if available in the read_set */
        if (s->primary_key < MAX_KEY)
          mark_columns_used_by_index_no_reset(s->primary_key, read_set); //只記錄主鍵或者非空唯一鍵的 欄位
        break;
      default: 
        DBUG_ASSERT(FALSE);
    }
    file->column_bitmaps_signal();
  }
  DBUG_VOID_RETURN;
}

二、過濾過程

THD::binlog_prepare_row_images還會準備image

binlog_log_row 上層介面 記錄 binlog
-> Write_rows_log_event::binlog_row_logging_function 
  -> THD::binlog_write_row(THD::binlog_delete_row)
     ->THD::binlog_prepare_row_images 準備前印象點陣圖 如果沒有主鍵/非空唯一鍵 則不考慮記錄全欄位
       pack_row 通過點陣圖準備好行
       THD::binlog_prepare_pending_rows_event 
         -> 判斷是否需要新建一個EVENT 大約8K左右,
            如果新建 新建後寫event到 log buffer
         ->否則在當前event中寫入   
       add_row_data(row_data, len); 將資料加入到EVENT

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2649953/,如需轉載,請註明出處,否則將追究法律責任。

相關文章