我理解的MYISAM引擎之七 check、analyze、optimize、repair 與myisamchk

 

語句 參數 作用 引擎 備註
CHECK TABLE FOR UPGRADE 檢查升級後的不兼容項 MYISAM,INNODB,VIEW a)選項可以疊加使用,從上往下,校驗的內容逐漸增多;
b)check table會自動flush table;
c)   check  table如果在innodb上發現了非2級索引的塊損壞,會導致mysqld進程崩潰https://bugs.mysql.com/bug.php?id=10132
d)   對於innodb,check table 可以並行讀取cluster index,並行讀取值爲min( innodb_parallel_read_threads setting ,the number of index subtree)
e)   對於MYISAM,check table會更新統計信息,如果沒有指定QUICK或者MEDIUM或者EXTEND,默認選項爲MEDIUM
f)    驗證delete連接的邏輯:MYI文件中的文件從37字節開始的8個字節記錄了此表中被標記刪除的記錄,接下來的8個字節記錄了MYD文件中被標記刪除的記錄佔用的空間,再接下來的8個字節記錄了MYD文件中最後一個刪除記錄的偏移地址,通過這個地址在MYD可以找到最後一個被刪除的記錄。同時,每一個被刪除的記錄保存了上一個被刪除和下一個被刪除的記錄的雙向鏈表、當前被刪除記錄佔用空間大小三個數據,刪除校驗的目的就是從鏈表的頭開始一個一個檢查對應的前後鏈接的有效性,以及將所有刪除記錄記錄的刪除空間累加,直到鏈表尾部,最終此空間累積和大小需要等於MYI文件中記錄的大小。
對於dynamic格式的myisam表,每一個被刪除的記錄元數據信息在記錄開始的20個字節中,其中,第一個字節爲標記位,00表示標記刪除,接下來的3字節表示此標記刪除記錄佔用空間大小,接下來的8字節記錄了下一個標記刪除記錄的偏移地址,最後的8字節記錄了上一個標記刪除記錄的偏移地址;
對於fix格式的myisam表,由於行長度固定(MYI文件頭261字節開始的4個字節記錄了行長度pack_reclength),因此MYD中記錄的尋址是通過行號*每行記錄所佔空間大小來確定偏移地址的。刪除鏈表的前後指針均指行號,單行刪除空間即爲行大小,累積刪除空間等於刪除行數*每行所佔空間。MYI文件第285字節記錄了rec_reflength值,也既行號所佔字節數,此記錄從2-8個字節不等,由參數myisam_data_pointer_size控制,當然這個值的範圍是2-7,少了一個字節。
g) EXTENDED與MEDIUM相比,多了掃描全部行的所有索引key的步驟;
h)MEDIUM與CHANGED相比,僅去掉了CHANGED的前置條件,檢查內容一致;
j)QUICK的不掃描行體現在check方法中的判斷,如果沒有指定(顯示或隱式)QUICK的話,會調用mi_check.cc的check_data_link方法,此方法中會讀取整個MYD文件,並校驗數據、計算校驗和。這也是QUICK與CHANGED、MEDIUM、EXTENDED比起來少了的地方;
k)FOR UPGRADE在8.0版本上是自動檢查項了,無論做什麼檢查,都會順帶進行。
l)對於dynamic行格式,如果沒有指定QUICK, MEDIUM, or EXTENDED 選項,則默認執行medium檢查;對於static行格式,如沒有指定任何選項,則默認執行medium檢查,CHANGED與QUICK的檢查項相同;
m)從這一段代碼可以看出,特定情況下,fast到這裏就結束返回了:
下面這兩端代碼均出自ha_myisam.cc文件的int ha_myisam::check(THD *thd, HA_CHECK_OPT *check_opt)方法
  if (!mi_is_crashed(file) &&
      (((param.testflag & T_CHECK_ONLY_CHANGED) &&
        !(share->state.changed &
          (STATE_CHANGED | STATE_CRASHED | STATE_CRASHED_ON_REPAIR)) &&
        share->state.open_count == 0) ||
       ((param.testflag & T_FAST) &&
        (share->state.open_count == (uint)(share->global_changed ? 1 : 0)))))
    return HA_ADMIN_ALREADY_DONE;
而後面還會有下面這些檢查。這些也是fast與CHANGED/MEDIUM/EXTENDED等相比缺少的檢查:
error = chk_status(&param, file);  // Not fatal
  error = chk_size(&param, file);
  if (!error) error |= chk_del(&param, file, param.testflag);
  if (!error) error = chk_key(&param, file);
  if (!error) {
    if ((!(param.testflag & T_QUICK) &&
         ((share->options &
           (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ||
          (param.testflag & (T_EXTEND | T_MEDIUM)))) ||
        mi_is_crashed(file)) {
      uint old_testflag = param.testflag;
      param.testflag |= T_MEDIUM;
      if (!(error = init_io_cache(
                &param.read_cache, file->dfile, my_default_record_cache_size,
                READ_CACHE, share->pack.header_length, true, MYF(MY_WME)))) {
        error = chk_data_link(&param, file, param.testflag & T_EXTEND);
        end_io_cache(&(param.read_cache));
      }
      param.testflag = old_testflag;
    }
  }
h)MEDIUM與EXTENDED主要的不同在mi_check.cc中的int chk_data_link(MI_CHECK *param, MI_INFO *info, int extend)方法的第1151行代碼
if (extend) {
              /* We don't need to lock the key tree here as we don't allow
                 concurrent threads when running myisamchk
              */
              int search_result =
                  (keyinfo->flag & HA_SPATIAL)
                      ? rtree_find_first(info, key, info->lastkey, key_length,
                                         MBR_EQUAL | MBR_DATA)
                      : _mi_search(info, keyinfo, info->lastkey, key_length,
                                   SEARCH_SAME, info->s->state.key_root[key]);
              if (search_result) {
                mi_check_print_error(param,
                                     "Record at: %10s  "
                                     "Can't find key for index: %2d",
                                     llstr(start_recpos, llbuff), key + 1);
                if (error++ > MAXERR || !(param->testflag & T_VERBOSE))
                  goto err2;
              }
            } else
              key_checksum[key] +=
                  mi_byte_checksum((uchar *)info->lastkey, key_length);
QUICK 不掃描行 MYISAM,  INNODB
FAST 僅檢查沒有正常close的表 MYISAM,  VIEW
CHANGED 僅檢查自上一次check後有變化的表
和沒有正常close的表
MYISAM,  VIEW
MEDIUM 根據delete_link掃描MYD數據行行以驗證被標記爲deleted的鏈接是否有效,
會分別計算數據行中的key值和索引文件中的key的校驗和,並進行比較是否相同。
默認選項。

 
MYISAM,  VIEW
EXTENDED 將MEDIUM的計算校驗和驗證數據的方式,換成了掃描所有索引key全部行記錄的方式。 MYISAM,  VIEW
checksum QUICK 當表屬性CHECKSUM=1時,返回已保存的checnsum值
如果指定quick,但是checksum不爲1,那麼返回NULL
MYISAM, a) 用於計算整表的校驗和數據,用來對數據遷移前後的表數據完整性進行校驗
b) 由於校驗和算法問題,實際不同的表內容可能得出相同的校驗和,但是不同的校驗和,表內容一定不同
EXTENDED 實時的一行一行的讀取並計算校驗和 MYISAM,  INNODB
         
analyze    收集表統計信息,   收集統計信息,統計信息結果收集後存儲在information_schema.tables、information_schema.statistics、information_schema.COLUMN_STATISTICS(列直方圖)、information_schema.STATISTICS、information_schema.INNODB_TABLESTATS
         
optimize   重建表。重新組織表數據。釋放表文件空間。 常規支持:MYISAM,INNODB,NDB 1,對於MYISAM引擎:消除碎片,排序索引block,更新統計信息;
2,對於innodb:釋放多餘空間。大量刪除數據後,將磁盤空間釋放回操作系統。默認使用online ddl ,alter table .. Force. 如果啓用skip-new或者 old_alter_table選項,則使用table  copy方法。
3,不支持空間索引。
skip-new啓用後可以支持其他存儲引擎。實際轉換爲alter table。
         
repair table QUICK 只repaired索引數據。支持分區表; MYISAM、CSV、ARCHIVE upgrade升級表,修復損壞的索引,表數據,
2,NO_WRITE_TO_BINLOG、LOCAL不記錄repair table到binglog中。注意與repair table對源表的修改內容不會同步到從庫做區分;
3,USE_FRM,因爲MYI文件header保存了MYISAM表的大量元數據,不使用MYI文件頭,會導致依賴此部分信息的數據丟失,具體如下:
     a)自增列最大值丟失;
     b)delete_link丟失,導致MYD文件中已標記爲刪除的空間不能重用;
     c)MYI文件頭首4個字節標誌了文件版本,不使用這個信息,導致repair table不會進行upgrade檢查升級;
     d)MYI文件中標記了表是否是compress格式,因此對於壓縮格式的表,會解析文件失敗。(但是compress格式的表都是隻讀的,會用到repair的機會渺茫)
     e)如果使用了與表文件不同版本的repair,會報錯。
4,如果設置了avoid_temporal_upgrade 系統變量,則repair不會upgrade表。
5,可通過設置 myisam_max_sort_file_size 、key_buffer_size、myisam_sort_buffer_size、read_buffer_size等系統變量值提高repair效率。
EXTENDED repair索引和數據。支持分區表;
USE_FRM repair索引和數據。但是忽略MYI文件header。僅使用數據字典存儲的表元數據。 MYISAM

此外,MYISAMCHK工具集成了check,analyze,optimize,repair功能於一身,還多了其他功能:

1,按照特定索引順序排序對應的MYD記錄,以增強按照特定索引排序的順序讀性能。-R, --sort-records=#
2,解壓myisampack壓縮的文件。-u, --unpack
3,設置自增列的值。-A, --set-auto-increment[=value]。自增列的值保存在MYI文件頭中。
4,發現特定block中的記錄。-b,  --block-search=#
5,當MYD滿了之後(達到建表時指定的最大文件大小),可以通過重建的方式增大最大大小。-D, --data-file-length=#
6,repair時,僅修改特定索引。-k, --keys-used=#
7,repair時,可自動備份。-B, --backup

myisamchk的全部選項可通過myisamchk --help查看。具體使用時,可設置如下內存參數加快性能,最好設置tmp目錄指向其他目錄,因爲默認的tmpdir使用的是linux操作系統的內存文件系統,相當於完全內存操作。可能造成主機內存不足。
tmpdir                            (No default value)
key-buffer-size                   520192
read-buffer-size                  262136
write-buffer-size                 262136
sort-buffer-size                  2097144
myisam-sort-buffer-size           2097144
sort-key-blocks                   16

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