在mysql中,frm的意思為“表定義”,是描述數據表結構的文件。frm文件是用來保存每個數據表的元數據信息,包括表結構的定義等。frm文件跟數據庫存儲引擎無關,也就是任何存儲引擎的數據表都必須有frm文件,命名方式為“數據表名.frm”。
本教程操作環境:windows7系統、mysql8版本、Dell G3電腦。
在mysql中,frm的意思為“表定義”,是描述數據表結構的文件。
在MYSQL中建立任何一張數據表,在其數據目錄對應的數據庫目錄下都有對應表的.frm文件,.frm文件是用來保存每個數據表的元數據(meta)信息,包括表結構的定義等。
.frm文件跟數據庫存儲引擎無關,也就是任何存儲引擎的數據表都必須有.frm文件,命名方式為數據表名.frm,如user.frm. .frm文件可以用來在數據庫崩潰時恢復表結構。
通常frm文件是不會損壞的,但是如果出現特殊情況出現frm文件損壞也不要放棄希望,例如下面報錯:
150821?16:31:27?[ERROR]?/usr/local/mysql51/libexec/mysqld:?Incorrect?information?in?file:?'./t/test1.frm'
當修復MyISAM和InnoDB表時,MySQL服務會首先去調用frm文件,所以我們只能通過修復frm文件進行后面的數據恢復。
MySQL通過sql/table.cc的create_frm()函數創建frm文件,創建出來的frm文件是二進制文件,需要通過hexdump解析成16進制來分析。
create_frm()函數對frm文件頭部定義的代碼
/*?Create?a?.frm?file?*/ File?create_frm(THD?*thd,?const?char?*name,?const?char?*db, ????????????????const?char?*table,?uint?reclength,?uchar?*fileinfo, ??????????HA_CREATE_INFO?*create_info,?uint?keys,?KEY?*key_info) { ??register?File?file; ??ulong?length; ??uchar?fill[IO_SIZE]; ??int?create_flags=?O_RDWR?|?O_TRUNC; ??ulong?key_comment_total_bytes=?0; ??uint?i; ??if?(create_info->options?&?HA_LEX_CREATE_TMP_TABLE) ????create_flags|=?O_EXCL?|?O_NOFOLLOW; ??/*?Fix?this?when?we?have?new?.frm?files;??Current?limit?is?4G?rows?(QQ)?*/ ??if?(create_info->max_rows?>?UINT_MAX32) ????create_info->max_rows=?UINT_MAX32; ??if?(create_info->min_rows?>?UINT_MAX32) ????create_info->min_rows=?UINT_MAX32; ??if?((file=?mysql_file_create(key_file_frm, ???????????????????????????????name,?CREATE_MODE,?create_flags,?MYF(0)))?>=?0) ??{ ????uint?key_length,?tmp_key_length,?tmp,?csid; ????bzero((char*)?fileinfo,64); ????/*?header?*/ ????fileinfo[0]=(uchar)?254; ????fileinfo[1]=?1; ????fileinfo[2]=?FRM_VER+3+?test(create_info->varchar); ????fileinfo[3]=?(uchar)?ha_legacy_type( ??????????ha_checktype(thd,ha_legacy_type(create_info->db_type),0,0)); ????fileinfo[4]=1; ????int2store(fileinfo+6,IO_SIZE);????????/*?Next?block?starts?here?*/ ????/* ??????Keep?in?sync?with?pack_keys()?in?unireg.cc ??????For?each?key: ??????8?bytes?for?the?key?header ??????9?bytes?for?each?key-part?(MAX_REF_PARTS) ??????NAME_LEN?bytes?for?the?name ??????1?byte?for?the?NAMES_SEP_CHAR?(before?the?name) ??????For?all?keys: ??????6?bytes?for?the?header ??????1?byte?for?the?NAMES_SEP_CHAR?(after?the?last?name) ??????9?extra?bytes?(padding?for?safety??alignment?) ????*/ ????for?(i=?0;?i??0)); ??????if?(key_info[i].flags?&?HA_USES_COMMENT) ????????key_comment_total_bytes?+=?2?+?key_info[i].comment.length; ????} ????key_length=?keys?*?(8?+?MAX_REF_PARTS?*?9?+?NAME_LEN?+?1)?+?16 ????????????????+?key_comment_total_bytes; ????length=?next_io_size((ulong)?(IO_SIZE+key_length+reclength+ ??????????????????????????????????create_info->extra_size)); ????int4store(fileinfo+10,length); ????tmp_key_length=?(key_length?max_rows); ????int4store(fileinfo+22,create_info->min_rows); ????/*?fileinfo[26]?is?set?in?mysql_create_frm()?*/ ????fileinfo[27]=2;????????????????//?Use?long?pack-fields ????/*?fileinfo[28?&?29]?is?set?to?key_info_length?in?mysql_create_frm()?*/ ????create_info->table_options|=HA_OPTION_LONG_BLOB_PTR;?//?Use?portable?blob?pointers ????int2store(fileinfo+30,create_info->table_options); ????fileinfo[32]=0;????????????????//?No?filename?anymore ????fileinfo[33]=5;?????????????????????????????//?Mark?for?5.0?frm?file ????int4store(fileinfo+34,create_info->avg_row_length); ????csid=?(create_info->default_table_charset?? ???????????create_info->default_table_charset->number?:?0); ????fileinfo[38]=?(uchar)?csid; ????/* ??????In?future?versions,?we?will?store?in?fileinfo[39]?the?values?of?the ??????TRANSACTIONAL?and?PAGE_CHECKSUM?clauses?of?CREATE?TABLE. ????*/ ????fileinfo[39]=?0; ????fileinfo[40]=?(uchar)?create_info->row_type; ????/*?Next?few?bytes?where?for?RAID?support?*/ ????fileinfo[41]=?(uchar)?(csid?>>?8); ????fileinfo[42]=?0; ????fileinfo[43]=?0; ????fileinfo[44]=?0; ????fileinfo[45]=?0; ????fileinfo[46]=?0; ????int4store(fileinfo+47,?key_length); ????tmp=?MYSQL_VERSION_ID;??????????//?Store?to?avoid?warning?from?int4store ????int4store(fileinfo+51,?tmp); ????int4store(fileinfo+55,?create_info->extra_size); ????/* ??????59-60?is?reserved?for?extra_rec_buf_length, ??????61?for?default_part_db_type ????*/ ????int2store(fileinfo+62,?create_info->key_block_size); ????bzero(fill,IO_SIZE); ????for?(;?length?>?IO_SIZE?;?length-=?IO_SIZE) ????{ ??????if?(mysql_file_write(file,?fill,?IO_SIZE,?MYF(MY_WME?|?MY_NABP))) ??????{ ????????(void)?mysql_file_close(file,?MYF(0)); ????????(void)?mysql_file_delete(key_file_frm,?name,?MYF(0)); ????return(-1); ??????} ????} ??} ??else ??{ ????if?(my_errno?==?ENOENT) ??????my_error(ER_BAD_DB_ERROR,MYF(0),db); ????else ??????my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno); ??} ??return?(file); }?/*?create_frm?*/
open_binary_frm()函數對對frm索引部分定義的代碼
for?(i=0?;?i?table=?0;???????????????????????????//?Updated?in?open_frm ????if?(new_frm_ver?>=?3) ????{ ??????keyinfo->flags=???????(uint)?uint2korr(strpos)?^?HA_NOSAME; ??????keyinfo->key_length=?(uint)?uint2korr(strpos+2); ??????keyinfo->key_parts=??(uint)?strpos[4]; ??????keyinfo->algorithm=??(enum?ha_key_alg)?strpos[5]; ??????keyinfo->block_size=?uint2korr(strpos+6); ??????strpos+=8; ????} ????else ????{ ??????keyinfo->flags=?????((uint)?strpos[0])?^?HA_NOSAME; ??????keyinfo->key_length=?(uint)?uint2korr(strpos+1); ??????keyinfo->key_parts=??(uint)?strpos[3]; ??????keyinfo->algorithm=?HA_KEY_ALG_UNDEF; ??????strpos+=4; ????} ????keyinfo->key_part=?????key_part; ????keyinfo->rec_per_key=?rec_per_key; ????for?(j=keyinfo->key_parts?;?j--?;?key_part++) ????{ ??????*rec_per_key++=0; ??????key_part->fieldnr=????(uint16)?(uint2korr(strpos)?&?FIELD_NR_MASK); ??????key_part->offset=?(uint)?uint2korr(strpos+2)-1; ??????key_part->key_type=????(uint)?uint2korr(strpos+5); ??????//?key_part->field=????(Field*)?0;????//?Will?be?fixed?later ??????if?(new_frm_ver?>=?1) ??????{ ????key_part->key_part_flag=?*(strpos+4); ????key_part->length=????(uint)?uint2korr(strpos+7); ????strpos+=9; ??????} ??????else ??????{ ????key_part->length=????*(strpos+4); ????key_part->key_part_flag=0; ????if?(key_part->length?>?128) ????{ ??????key_part->length&=127;????????/*?purecov:?inspected?*/ ??????key_part->key_part_flag=HA_REVERSE_SORT;?/*?purecov:?inspected?*/ ????} ????strpos+=7; ??????} ??????key_part->store_length=key_part->length; ????} ??} ??keynames=(char*)?key_part; ??strpos+=?(strmov(keynames,?(char?*)?strpos)?-?keynames)+1; ??//reading?index?comments ??for?(keyinfo=?share->key_info,?i=0;?i?flags?&?HA_USES_COMMENT) ????{ ??????keyinfo->comment.length=?uint2korr(strpos); ??????keyinfo->comment.str=?strmake_root(&share->mem_root,?(char*)?strpos+2, ?????????????????????????????????????????keyinfo->comment.length); ??????strpos+=?2?+?keyinfo->comment.length; ????}? ????DBUG_ASSERT(test(keyinfo->flags?&?HA_USES_COMMENT)?==? ???????????????(keyinfo->comment.length?>?0)); ??}
hexdump是Linux下的一個二進制文件查看工具,可以將二進制文件轉換為ASCII、10進制、16進制或8進制進行查看。
hexdump?參數 -C?每一字節以16進制顯示,一行共16個字節,顯示十六進制存儲的文本內容 -b?每一字節以八進制顯示,一行共16個字節,一行開始以十六進制顯示偏移值; ??0000000?177?105?114?106?002?001?001?000?000?000?000?000?000?000?000?000 -c?每一字節以ASCII字符顯示,其余同上; ??0000000?177?E?L?F?002?001?001? 99久久国产精品免费一区二区 | 精品免费tv久久久久久久| 精品久久久久久久久免费影院| 99热热久久这里只有精品68| 国产999精品久久久久久| 久久久久久亚洲精品无码| 一本综合久久国产二区| 久久久久人妻一区精品性色av| 久久99精品国产99久久6男男| 久久狠狠一本精品综合网| 色偷偷91久久综合噜噜噜噜| 一本色道久久HEZYO无码| 亚洲精品高清国产一久久| 一级做a爰片久久毛片毛片| 国内精品伊人久久久久av一坑| 九九久久精品无码专区| 亚洲精品美女久久久久99| 精品久久久久久久中文字幕| 97视频久久久| 久久精品国产亚洲Aⅴ香蕉| www性久久久com| 久久精品aⅴ无码中文字字幕不卡| 四虎亚洲国产成人久久精品| 精品久久久久久久久中文字幕| 国产成人无码精品久久久性色| 东京热TOKYO综合久久精品| 久久久久一本毛久久久| 久久国产亚洲精品无码| 精品人妻伦一二三区久久| 久久精品无码免费不卡| 久久精品国产99国产精品澳门| 国产精品成人久久久久三级午夜电影| 久久久这里只有精品加勒比| 国内精品伊人久久久久AV影院| 久久精品夜色噜噜亚洲A∨| 久久久久亚洲AV成人片| 亚洲国产成人久久笫一页 | 精品久久久噜噜噜久久久| 狠狠色丁香婷婷综合久久来来去| 久久久女人与动物群交毛片| 国产精品久久毛片完整版|