视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
mysqlcreatetable过程_MySQL
2020-11-09 18:38:25 责编:小采
文档


bitsCN.com

mysql create table过程

粗略了解mysql create table的过程:

Cpp代码

create table的调用路径如下(5.1.58):

do_command(sql_parse.cc)

->dispatch_command(sql_parse.cc)

->mysql_parse(sql_parse.cc)

->mysql_execute_command(sql_parse.cc)

->mysql_create_table(sql_table.cc)

->mysql_create_table_nolock(sql_table.cc),这里会持有LOCK_open

->rea_create_table(unireg.cc)

->mysql_create_frm(unireg.cc)

->ha_create_table(handler.cc)

->handler::ha_create(handler.cc)

->ha_innodb::create(handler/ha_innodb.cc)

->create_table_def(handler/ha_innodb.cc),

->row_create_table_for_mysql(row/row0mysql.c)

->create_clustered_index_when_no_primary(handler/ha_innodb.cc)..when no primary key is defined..

->row_create_index_for_mysql(row/row0mysql.c)

->create_index(hanler/ha_innodb.cc)

->row_table_add_foreign_constraints(row/row0mysql.c)

mysql_create_table函数一开始就去持有LOCK_lock_db mutex,对creating_table++,这个值对应Com_create_table。

接下来rea_create_table首先会调用mysql_create_frm创建server层的表定义文件,然后调用ha_create_table,相应的存储引擎会创建所需要的内容。对于innodb,则是先创建innodb层的表定义,再去创建索引,创建索引的时候,如果表定义不包含主键,则自动为该表创建主键;这也是为什么建议innodb的表的都带上主键。

如果是create table like,执行过程有所不同:

Cpp代码

create table...like...的调用路径如下(5.1.58):

...同上...

->mysql_execute_command(sql_parse.cc)

->mysql_create_like_table(sql_table.cc),这里需要打开源表并持有LOCK_open直到创建完frm文件

->my_copy(mysys/my_copy.c)/mysql_create_like_schema_frm(sql_table.cc)

->ha_create_table(handler.cc)

...同上...

如果是create table like,则execute command的时候会调用mysql_create_like_table,这里会打开源表(like之后的表,open_tables());之后开始开始创建新的表定义文件,创建新的表定义文件前会持有LOCK_open,创建完就释放;如果源表是information_schema的表,则通过mysql_create_like_schema_frm()创建,其它的则通过my_copy(),直接copy源表的frm文件。剩下的过程就交给了存储引擎,同普通的create table 一样。create table like...的执行过程中也没有对源表加锁,但是整个过程持有LOCK_open。

如果是create table ...select,处理过程如下:

Cpp代码

create table...select...的调用路径如下(5.1.58):

...同上...

->mysql_execute_command(sql_parse.cc)

-open_and_lock_tables()--这里对select的表加表锁,直到整个statement完成

->handle_select(sql_select.cc)

->mysql_select(sql_select.cc)

->JOIN::prepare(sql_select.cc,697)--这里开始create table的过程

->select_create::prepare(sql_insert.cc)

->create_table_from_items(sql_insert.cc,3762)

->mysql_create_table_no_lock(sql_table.cc)

...同上(create table...)...

->JOIN::optimize(sql_select.cc)

->JOIN::exec(sql_select.cc)--实际的select的过程

->do_select(sql_select.cc)

->sub_select(sql_select.cc)

->evaluate_join_record(sql_select.cc,11585)

->end_send(sql_select.cc,12369)

->select_insert::send_data(sql_insert.cc)--插入数据的过程

->write_record(sql_insert.cc)

->handler::ha_write_row(handler.cc)

->write_row(handler/ha_innodb.cc)

第一次看到这个逻辑,感觉有些tricky,create table竟然是在大名鼎鼎的mysql_select()过程中完成的,难道mysql认为create table...select...是select的一种特例。

create table...select...整体上分为2个过程:建表;插入数据。创建表的过程是整个select的prepare()过程中完成的(new JOIN的时候,result被初始化为select_create类型的,几个相关类的继承关系:select_result<-select_result_interceptor<-select_insert<-select_create;JOIN::prepare()->select_create::prepare())。而insert的过程,则是在JOIN:exec的内完成的,具体的则是在send data的时候。

需要注意的是,select的表是会被加表锁的,直到整个操作完成(dispatch_command操作的最后会有close_thread_tables)

上面基本上是5.1 create table的处理逻辑了,5.5的处理过程也大致相同。

bitsCN.com

下载本文
显示全文
专题