open_binary_frm
参数uchar* head 是已经分配好内存的64个字节的地址
http://mysql.taobao.org/monthly/2015/08/07/

/** *先从.frm文件读取64字节 *第28和第29字节记录了key_length * *利用lseek定位到第30字节,并读取key_length长度的信息到disk_buff中 *disk_buff[0]代表了索引的个数 keys_num *disk_buff[1]代表了索引中列的个数 key_parts_num * *为了把disk_buff中的信息copy到结构体中,还要分配 keys*sizeof(KEY)+key_parts*sizeof(KEY_PARTS_INFO)大小的内存 key_buff,类型为KEY* * * *做循环 *share->key_info=key_buff; *key_part = key_buff+keys_num; * for(int i=0;i<keys;key_buff++) key_buff->key_length=xxx; xxxxx key_buf->key_part = key_part; for(j=key_buff->key_parts;j>=0;j--,key_part++) key_part->fieldnr=xxx * *share->field = field_ptr //field_ptr为新分配的内存 *share->fileds = xxx; * for(int i=0;i<xxx;field_ptr++ ) * field_ptr=xxx; * */
static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
File file)
{
;
uint new_frm_ver, field_pack_length, new_field_pack_flag;
uint interval_count, interval_parts, read_length, int_length;
uint db_create_options, keys, key_parts, n_length;
uint key_info_length, com_length, null_bit_pos;
uint extra_rec_buf_length;
uint i,j;
bool use_hash;
char *keynames, *names, *comment_pos;
uchar forminfo[];
uchar *record;
uchar *disk_buff, *strpos, *null_flags, *null_pos;
ulong pos, record_offset, *rec_per_key, rec_buff_length;
handler *handler_file= ;
KEY *keyinfo;
KEY_PART_INFO *key_part;
SQL_CRYPT *crypted=;
Field **field_ptr, *reg_field;
const char **interval_array;
enum legacy_db_type legacy_db_type;
my_bitmap_map *bitmaps;
uchar *extra_segment_buff= ;
;
uchar *format_section_fields= ;
DBUG_ENTER("open_binary_frm");
new_field_pack_flag= head[];
new_frm_ver= (head[] - FRM_VER);
field_pack_length= new_frm_ver < ? : ;
disk_buff= ;
error= ;
/* Position of the form in the form file. */
if (!(pos= get_form_pos(file, head)))
goto err; /* purecov: inspected */
mysql_file_seek(file,pos,MY_SEEK_SET,MYF());
,MYF(MY_NABP)))
goto err;
share->frm_version= head[];
share->max_rows= uint4korr(head+);
share->min_rows= uint4korr(head+);
/* Read keyinformation */
key_info_length= (uint) uint2korr(head+28);
mysql_file_seek(file, (), MY_SEEK_SET, MYF());
/** *disk_buff已经被分配了内存,大小为key_info_length */
if (read_string(file,(uchar**) &disk_buff,key_info_length))
goto err; /* purecov: inspected */
] & 0x80)
{
share->keys= keys= (disk_buff[] << ) | (disk_buff[] & 0x7f);
share->key_parts= key_parts= uint2korr(disk_buff+);
}
else
{
share->keys= keys= disk_buff[];
share->key_parts= key_parts= disk_buff[];
}
/** *因为keyinfo是MYSQL服务器这边的结构体,因此需要分配内存 */
n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO);
))))
goto err;
bzero((char*) keyinfo,n_length);
/** *share->key_info代表keyinfo这段内存起始地址 *keyinfo的类型为KEY*,故keyinfo++,意味着数组递增 * */
share->key_info= keyinfo;
key_part= reinterpret_cast<KEY_PART_INFO*>(keyinfo+keys);
strpos=disk_buff+;
if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root,
sizeof(ulong)*key_parts)))
goto err;
; i < keys ; i++, keyinfo++)
{
keyinfo->table= ; // Updated in open_frm
)
{
keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME; //索引长度,索引中列的个数
keyinfo->key_length= ();
keyinfo->key_parts= (];
keyinfo->algorithm= (];
keyinfo->block_size= uint2korr(strpos+);
strpos+=;
}
keyinfo->key_part= key_part;
keyinfo->rec_per_key= rec_per_key;
for (j=keyinfo->key_parts ; j-- ; key_part++)
{
*rec_per_key++=;
key_part->fieldnr= (uint16) (uint2korr(strpos) & FIELD_NR_MASK);
key_part->offset= ()-;
key_part->key_type= ();
}
}
keynames=(char*) key_part;
strpos+= (strmov(keynames, (;
//reading index comments
; i < keys; i++, keyinfo++)
{
if (keyinfo->flags & HA_USES_COMMENT)
{
keyinfo->comment.length= uint2korr(strpos);
keyinfo->comment.str= strmake_root(&share->mem_root, (,
keyinfo->comment.length);
strpos+= + keyinfo->comment.length;
}
}
share->key_block_size= uint2korr(head+);
share->fields= uint2korr(forminfo+);
pos= uint2korr(forminfo+); /* Length of all screens */
n_length= uint2korr(forminfo+);
share->null_fields= uint2korr(forminfo+);
com_length= uint2korr(forminfo+);
if (!(field_ptr = (Field **)
alloc_root(&share->mem_root,
()*sizeof(Field*)+
interval_count*sizeof(TYPELIB)+
(share->fields+interval_parts+
keys+)*sizeof(char *)+
(n_length+int_length+com_length)))))
goto err; /* purecov: inspected */
/** *field_ptr也是刚分配内存的起始地址,赋值给share->field */
share->field= field_ptr;
read_length=(uint) (share->fields * field_pack_length +
pos+ (uint) (n_length+int_length+com_length));
if (read_string(file,(uchar**) &disk_buff,read_length))
goto err; /* purecov: inspected */
strpos= disk_buff+pos;
if (keynames)
fix_type_pointers(&interval_array, &share->keynames, , &keynames);
/* Allocate handler */
if (!(handler_file= get_new_handler(share, thd->mem_root,
share->db_type())))
goto err;
record= share->default_values-; /* Fieldstart = 1 */
if (share->null_field_first)
{
null_flags= null_pos= (uchar*) record+;
null_bit_pos= (db_create_options & HA_OPTION_PACK_RECORD) ? : ;
/*
null_bytes below is only correct under the condition that
there are no bit fields. Correct values is set below after the
table struct is initialized
*/
share->null_bytes= (share->null_fields + null_bit_pos + ) / ;
}
; i < share->fields; i++, strpos+=field_pack_length, field_ptr++)
{
uint pack_flag, interval_nr, unireg_type, recpos, field_length;
enum_field_types field_type;
CHARSET_INFO *charset=NULL;
Field::geometry_type geom_type= Field::GEOM_GEOMETRY;
LEX_STRING comment;
)
{
/* new frm file in 4.1 */
field_length= uint2korr(strpos+);
recpos= uint3korr(strpos+);
pack_flag= uint2korr(strpos+);
unireg_type= (];
interval_nr= (];
);
field_type=(enum_field_types) (];
}
/** *这里的field_ptr其实是个FIELD*的对象 */
*field_ptr= reg_field=
make_field(share, record+recpos,
(uint32) field_length,
null_pos, null_bit_pos,
pack_flag,
field_type,
charset,
geom_type,
(Field::utype) MTYP_TYPENR(unireg_type),
(interval_nr ?
share->intervals+interval_nr- :
(TYPELIB*) ),
share->fieldnames.type_names[i]);
}//循环结束
*field_ptr=; // End marker
/* Fix key->name and key_part->field */
if (key_parts)
{
uint primary_key=(uint) (find_type(primary_key_name, &share->keynames,
FIND_TYPE_NO_PREFIX) - );
longlong ha_option= handler_file->ha_table_flags();
keyinfo= share->key_info;
key_part= keyinfo->key_part;
/** *share->keys本身是个结构体数组, *里面每一个key,设置其name, *key中的key_part也是个结构体数组,其中的filednr为share->filed该数组中的下标 * */
; key < share->keys ; key++,keyinfo++)
{
;
keyinfo->name=(char*) share->keynames.type_names[key];
; i < keyinfo->key_parts ; key_part++,i++)
{
Field *field;
key_part->fieldnr= (uint16) find_field(share->field,share->default_values,(uint) key_part->offset,(uint) key_part->length);
field= key_part->field= share->field[key_part->fieldnr-];
key_part->type= field->key_type();
if (field->null_ptr)
{
key_part->null_offset=(uint) ((uchar*) field->null_ptr -
share->default_values);
key_part->null_bit= field->null_bit;
key_part->store_length+=HA_KEY_NULL_LENGTH;
keyinfo->flags|=HA_NULL_PART_KEY;
keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
keyinfo->key_length+= HA_KEY_NULL_LENGTH;
}
}
share->total_key_length+= keyinfo->key_length;
}
}
/*
the correct null_bytes can now be set, since bitfields have been taken
into account
*/
share->null_bytes= (null_pos - (uchar*) null_flags +
(null_bit_pos + ) / );
share->last_null_bit_pos= null_bit_pos;
share->db_low_byte_first= handler_file->low_byte_first();
share->column_bitmap_size= bitmap_buffer_size(share->fields);
if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
share->column_bitmap_size)))
goto err;
bitmap_init(&share->all_set, bitmaps, share->fields, FALSE);
bitmap_set_all(&share->all_set);
delete handler_file;
my_free(extra_segment_buff);
DBUG_RETURN ();
err:
share->error= error;
share->open_errno= my_errno;
share->errarg= errarg;
my_free(disk_buff);
my_free(extra_segment_buff);
delete crypted;
delete handler_file;
my_hash_free(&share->name_hash);
if (share->ha_data_destroy)
{
share->ha_data_destroy(share->ha_data);
share->ha_data_destroy= NULL;
}
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (share->ha_part_data_destroy)
{
share->ha_part_data_destroy(share->ha_part_data);
share->ha_data_destroy= NULL;
}
#endif /* WITH_PARTITION_STORAGE_ENGINE */
open_table_error(share, error, share->open_errno, errarg);
DBUG_RETURN(error);
} /* open_binary_frm */
open_binary_frm的更多相关文章
- 【MySQL】frm文件解析
官网说明:http://dev.mysql.com/doc/internals/en/frm-file-format.html frm是MySQL表结构定义文件,通常frm文件是不会损坏的,但是如果出 ...
- Innodb加载数据字典 && flush tables
测试了两个case,属于之前blog的遗留问题: innodb如何加载数据字典 flush tables都做了什么操作 先来看下innodb加载数据字典: 首次使用:select * from tt; ...
随机推荐
- ASP.Net 上传进度条的实现方法
对于加载时间比较长的ASP.NET页面,我们可以在客户端浏览器中显示进度条来显示页面正在装载.下面就是具体的实现过程: 新建项目,名字为WebPortal,在项目类型中选择Visual C#项目或者V ...
- hbase表结构设计
非常好的一个ppt HBase Schema design: http://www.slideshare.net/cloudera/5-h-base-schemahbasecon2012
- redis rdb
http://blog.chinaunix.net/uid-1757778-id-3977331.html
- URAL 1586 Threeprime Numbers(DP)
题目链接 题意 : 定义Threeprime为它的任意连续3位上的数字,都构成一个3位的质数. 求对于一个n位数,存在多少个Threeprime数. 思路 : 记录[100, 999]范围内所有素数( ...
- WCF分布式开发步步为赢(3)WCF服务元数据交换、配置及编程开发
今天我们继续WCF分布式开发步步为赢(3)WCF服务元数据交换.配置及编程开发的学习.经过前面两节的学习,我们了解WCF分布式开发的相关的基本的概念和自定义宿主托管服务的完整的开发和配置过程.今天我们 ...
- <Win32_1>深入浅出windows消息机制[转自crocodile_]
上学期学习了Java ,感觉Java写一个窗口真心简单,很易上手,也就难怪很多开发人员选择Java作为自己的开发编程语言.但是由于自身对windows的热爱,让我觉得c.c++语言才是我亲睐的编程语言 ...
- poj 1511(SPFA+邻接表)
题目链接:http://poj.org/problem?id=1511 思路:题目意思很简单就是要求源点到各点的最短路之和,然后再求各点到源点的最短路之和,其实就是建两个图就ok了,其中一个建反图.1 ...
- dom对象详解--document对象(三)
form对象 form对象代表一个HTML表单,在HTML文档中<form>每出现一次,form对象就会被创建.从dom对象层次图看,document.forms对象是当前文档所有for ...
- android模拟器(genymotion)+appium+python 框架执行过程中问题解答
1.case运行过程中中文输入不进去? 答:注意事项 1)需要修改系统编码为utf-8,才能解决中文输入问题,case执行入口文件添加代码如下: import sys reload(sys) sys. ...
- 有N个大小不等的自然数(1--N),请将它们由小到大排序。要求程序算法:时间复杂度为O(n),空间复杂度为O(1)。
#include<stdio.h> int main() { ]={,,,,,,,,}; int i,tmp; ;i<;i++) { ) { tmp=a[i]; a[i]=a[a[i ...