免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1333 | 回复: 0
打印 上一主题 下一主题

Mysql源代码分析系列(4): 主要调用流程(续) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-02-24 22:45 |只看该作者 |倒序浏览
Mysql源代码分析系列(4): 主要调用流程(续)
在上一篇文章中我们讲到了的mysql_execute_command,这个函数根据解析出来的SQL命令分别调用不同的函数做进一步处理。我们这里先看"INSERT"命令的处理流程。其对应的处理函数是mysql_insert,在sql/sql_insert.cc中,还是很长,大概300多行。
bool mysql_insert(THD *thd,                   TABLE_LIST *table_list,      // 该命令要用到的表                   List &fields,             // 使用的域                   List &values_list,                   List &update_fields,                   List &update_values,                   enum_duplicates duplic,                   bool ignored) {  open_and_lock_tables(thd, table_list);  mysql_prepare_insert(...);
  foreach value in values_list {    write_record(...);  }}其实里面还有很多处理trigger,错误,view之类的,我们暂时都忽略。
// 写数据记录int write_record(THD *thd, TABLE *table,COPY_INFO *info) {  if (info->handle_duplicates == DUP_REPLACE || info->handle_duplicates == DUP_UPDATE) {     table->file->ha_write_row(table->record[0]);     table->file->ha_update_row(table->record[1], table->record[0]));
  } else {     table->file->ha_write_row(table->record[0]);  }}
不用说,这里我们还是省略了好多东西,要注意的是这里调用的table->file->ha_write_row和table->file->ha_update_row。在sql/table.h可以看到table的定义,其中file被定义成handler *file; 那handler是什么?对了,这就是我们前面提到的数据存储抽象层,所有的存储引擎都必须事先这里定义的接口,才能被mysql使用。在这里使用的具体的接口操作是ha_write_row和ha_update_row。这两个函数可以在sql/handler.cc中看到。比如ha_write_row:int handler::ha_write_row(uchar *buf) {  write_row(buf);   // 调用具体的实现  binlog_log_row(table, 0, buf, log_func));  // 写binlog}
下面我们看看在myisam中是怎么实现的文件操作,代码在storage/myisam/ha_myisam.cc中。先看write_row: 723 int ha_myisam::write_row(uchar *buf) 724 { 725   ha_statistic_increment(&SSV::ha_write_count); 726 727   /* If we have a timestamp column, update it to the current time */ 728   if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)      // 如果有timestamp域,写入当前时间。 729     table->timestamp_field->set_time(); 730 731   /* 732     If we have an auto_increment column and we are writing a changed row 733     or a new row, then update the auto_increment value in the record. 734   */ 735   if (table->next_number_field && buf == table->record[0])                   // 更新auto_increment列 736   { 737     int error; 738     if ((error= update_auto_increment())) 739       return error; 740   } 741   return mi_write(file,buf);       // 真正写文件 742 }
再看mi_write函数,很好找,就在storage/myisam/mi_write.c,我们就不再分析下去了,具体实现和myisam使用的文件格式相关,有兴趣的可以参考myisam的相关文档。
结语
写到这里,我们对于mysql执行sql语句的主要调用流程就有了大概的了解,但是真正的难点往往在细节中,我也刻意逃避了这些细节,但是还是应该列一下相关的内容:+ Sql语句的解析和相关数据结构+ Sql语句的描述数据结构+ 执行优化相关算法+ 数据存储殷勤抽象层的定义和交互+ 存储引擎的具体操作和文件格式
必须要提到的是,这些地方的代码都比较难懂,而且核心函数都很长,非常不便与理解,有需要的人可以选一些方面具体深入,但要面面俱到就需要很多时间了。


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/72491/showart_1841886.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP