Home > Large Scale Data Process > MySQL概览–系统架构和关键数据结构

MySQL概览–系统架构和关键数据结构

      近期在研究HandlerSocket的相关源码,其命名也正是因为handler这一重要的数据结构,handlerSocket的简单点说就是越过mysql的SQL层,直接通过handler操作底层的存储引擎,由于减少了SQL Parse,Opentable等消耗,并且直接利用handler通过索引index进行查询和更新操作,因此有较高的性能,近期在公司组内做了一次关于handlerSocket调研的分享,主要包括handler协议解析,handlerSocket关键代码和原理,innoDB关键特性等主题内容,当然mysql的系统架构和关键数据结构也是该次分享的基础内容之一,也因为这次分享,本人很荣幸的拿到starbucks的消费券以资奖励.本文主要讲下理解HandlerSocket原理以及mysql的必须知晓的相关系统架构和关键数据结构。

 

MySQL关键模块和流程

image

上述步骤不多做详述,图片来源于《Understanding MySQL Internals》,详细的各模块功能和描述,请详细查看书籍,这里给出仅仅说明一下mysql大致的系统架构和流程.

 

Mysql关键数据结构

 

•THD 线程描述符(sql/sql_class.h)

MySQL Server层 和用户连接的线程对象,包含处理用户请求时需要的相关数据。

NET net; // 客户连接描述符
TABLE* open_tables  
Protocol *protocol; // 当前的协议
Protocol_text protocol_text; // 普通协议
Protocol_binary protocol_binary; // 二进制协议
HASH user_vars; //用户变量的hash值
String packet; // 网络IO时所用的缓存
String convert_buffer; // 字符集转换所用的缓存
struct sockaddr_in remote; //客户端socket地址 
THR_LOCK_INFO lock_info; // 当前线程的锁信息
pthread_mutex_t LOCK_thd_data; //thd的mutex锁,保护THD数据(thd->query, thd->query_length)不会被其余线程访问到。
Statement_map stmt_map; //prepared statements和stored routines 会被重复利用
LEX *lex; //语法树描述符

 

其中特别的注意到:

TABLE* open_tables  
被查询引用的非临时和非Handler Open表image
TABLE* handler_tables
TABLE* temporary_tables
TABLE* derived_tablesimage

 

•NET 网络连接描述(sql/mysql_com.h)

该类在HandlerSocket中没有用到
Vio *vio; //底层的网络I/O socket描述符
unsigned char *buff,*buff_end,*write_pos,*read_pos; //缓存相关
unsigned long remain_in_buf,length, buf_length, where_b;
unsigned long max_packet,max_packet_size; //当前值;最大值
unsigned int pkt_nr,compress_pkt_nr; //当前(未)压缩包的顺序值
my_bool compress; //是否压缩
unsigned int write_timeout, read_timeout, retry_count; //最大等待时间
unsigned int *return_status; //thd中的服务器状态
unsigned char reading_or_writing;/*1 代表读, 2 代表写, 0代表无状态 */
unsigned int last_errno; //返回给客户端的错误号
unsigned char error;
/*0:执行成功
1:在协议层有逻辑错误
2:系统调用或标准库出错
3:特例,表示缓存不能装下当前这么大的包
*/ 

•TABLE 数据库表描述符(sql/table.h)

/*每一个table的共享结构St_table_share*/
Field **field; /* 指向数据域的指针*/
KEY *key_info; /* 数据库中key的信息*/ 
TYPELIB  keynames;/*通过keyname查找keynum(OPENINDEX)*/
TYPELIB  fieldnames /*通过fieldname找fieldnumber*/
handler *file; //指向这张表在storage engine中的handler的指针
THD *in_use; /* 使用这张表的thread号 */
byte *record[2] ;
/*每次找到的记录会先写入record[0],如需要修改则将要修改的原记录在record[1]中,利用field.store()会默认将更新的field写入record[0]中,逐一修改,具体见handler分析*/

•Field 字段描述符(sql/field.h)

/*域描述符,是各种字段的抽象基类*/
uchar *ptr; // 记录中数据域的位置
uchar *null_ptr; // 记录 null_bit 位置的byte
TABLE *table; // 指向表的指针
TABLE *orig_table; // 指向原表的指针
const char **table_name, *field_name;

/* 数据域是下列key的一部分 */
key_map key_start, part_of_key, part_of_key_not_clustered;
key_map part_of_sortkey;
/*以下操作将要insert\Update的值先设置到field中,这些field会默认填充到table.record[0]中*/
int store(const char *from, uintlength, CHARSET_INFO *cs)
void store_time(TIME*ltime,timestamp_type t_type) 

•handler SQL层与Storage的接口

/*可通过table->file得到,innoDB等存储引擎将会实现handler的子类,以提供具体的write、update操作实现,但是handler中的ha_write_row等已经实现整体的逻辑,如先write_row,再binlog_log_row()*/
int  ha_open(const char *name, int mode, int test_if_locked)  /*tbname.frm文件*/
int  ha_index_init(uint idx)   
/*为下面的操作准备索引初始化,在find操作中使用了,但是在insert中没有使用*/
int ha_rnd_init(bool scan)  /*初始化为随机位置访问,scan决定是否全表扫描*/
int ha_write_row(uchar *buf);	
/*先write_row,再binlog_log_row(),binlog写入是在handler中完成的*/

该类也是实现自己的StorageEngine必须实现的,具体的StorageEngine的写法本文不深入研究,有兴趣请查看《Understanding.Mysql.Internals》 和《Expert MySQL》,下面简单列一下InnoDB需要实现的关键接口

virtual int write_row(byte * buf)			/*buf通常是table->record[0]*/
virtual int update_row
(const byte *old_data, byte * new_data)   /*record[1],record[0]*/
virtual int delete_row(const byte * buf)  /*record[0]*/
virtual int index_read(byte * buf, const
byte * key,uint key_len, enum ha_rkey_
function find_flag);					/*根据findflag找到第一匹配记录*/
virtual int index_prev(byte * buf);
/*根据当前索引的顺序,写入上一个record到buffer中*/
virtual int index_next(byte * buf);
/*根据当前索引的顺序,写入下一个record到buffer中*/
virtual int index_next_same
(byte *buf, const byte *key, uint keylen);/*从当前位置再找一个满足等于key的*/

本文只是有个粗略的介绍,分享下自己阅读代码和书籍的经验,只能对mysql的系统结构有个大致的描述,并且指出mysql源码研究必要的一些基础数据结构。如果读者想要深入研究mysql,请阅读上文中提到的两本书,并且务必请阅读源码。

  1. No comments yet.
  1. No trackbacks yet.

Leave a comment