mysql存储过程执行追踪
mysql存储过程执行跟踪 ? ? ? ?学习mysql存储过程执行解析过程,执行一下存储过程 ? ? ? ?create procedure aa() ? ? ? ? ? ?begin ? ? ? ? ? ? ? ? declare x varchar(10); ? ? ? ? ? ? ? ? select count(*) from test where aaa = x ; ? ? ? ? ? ?end ? ? ?
mysql存储过程执行跟踪? ? ? ?学习mysql存储过程执行解析过程,执行一下存储过程
? ? ? ?create procedure aa()
? ? ? ? ? ?begin
? ? ? ? ? ? ? ? declare x varchar(10);
? ? ? ? ? ? ? ? select count(*) from test where aaa = x ;
? ? ? ? ? ?end
? ? ? 在JOIN::exec上设个断点,跟踪一下
? ? ? 执行堆栈如下:
#0 ?JOIN::exec (this=0x900e548) at sql_select.cc:2311
#1 ?0x08268373 in mysql_select (thd=0xb53d2fd0, rref_pointer_array=0x9005984, tables=0x9006040, wild_num=0, fields=@0x9005914, conds=0x90065f8, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=2147765760, result=0x900c698, unit=0x90055ec, select_lex=0x9005880) at sql_select.cc:3067
#2 ?0x0826887d in handle_select (thd=0xb53d2fd0, lex=0x9005590, result=0x900c698, setup_tables_done_option=0) at sql_select.cc:310
#3 ?0x081e1af7 in execute_sqlcom_select (thd=0xb53d2fd0, all_tables=0x9006040) at sql_parse.cc:4943
#4 ?0x081e432f in mysql_execute_command (thd=0xb53d2fd0) at sql_parse.cc:2157
#5 ?0x0835c987 in sp_instr_stmt::exec_core (this=0x90066f0, thd=0xb53d2fd0, nextp=0xb54912d0) at sp_head.cc:2927
#6 ?0x0835cbd1 in sp_lex_keeper::reset_lex_and_exec_core (this=0x9006718, thd=0xb53d2fd0, nextp=0xb54912d0, open_tables=false, instr=0x90066f0) at sp_head.cc:2751
#7 ?0x08363962 in sp_instr_stmt::execute (this=0x90066f0, thd=0xb53d2fd0, nextp=0xb54912d0) at sp_head.cc:2864
#8 ?0x08360f89 in sp_head::execute (this=0x9004560, thd=0xb53d2fd0) at sp_head.cc:1248
#9 ?0x08361a53 in sp_head::execute_procedure (this=0x9004560, thd=0xb53d2fd0, args=0xb53d44bc) at sp_head.cc:1989
#10 0x081e966a in mysql_execute_command (thd=0xb53d2fd0) at sql_parse.cc:4401
#11 0x081ebbfa in mysql_parse (thd=0xb53d2fd0, inBuf=0x8fdfa58 "call aa()", length=9, found_semicolon=0xb5491f14) at sql_parse.cc:5958
#12 0x081ecae6 in dispatch_command (command=COM_QUERY, thd=0xb53d2fd0, packet=0xb53f35c9 "call aa()", packet_length=9) at sql_parse.cc:1049
#13 0x081eddaa in do_command (thd=0xb53d2fd0) at sql_parse.cc:731
#14 0x081dd5a7 in handle_one_connection (arg=0xb53d2fd0) at sql_connect.cc:1146
#15 0x4dfe92db in start_thread (arg=0xb5492790) at pthread_create.c:296
#16 0x006cf14e in clone () from /lib/libc.so.
? ? 具体代码
? ? 在sql_parse.cc中
? ? ?case SQLCOM_CALL:
? ? ? ? ....
? ? ? ? sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &thd->sp_proc_cache, TRUE)) -------此处对存储过程进行解析
? ? ? ? ?....
? ? ? ? ?res= sp->execute_procedure(thd, &lex->value_list); -------执行存储过程
? ? }
?
? ? bool?sp_head::execute_procedure(THD *thd, List
? ? ?....
? ? ?//前面对参数进行一些处理
? ? ? ?if (!err_status)
? ? ? ? ? ? ? ? ? ? ? ?err_status= execute(thd);//具体执行存储过程
? ? ? ? ? ? ? ...对出参进行处理
? ? }
? ??
? ?bool ??sp_head::execute(THD *thd){
?...
?
do
? ? ? ? {
? ? ? ? ? ? ? sp_instr *i;
? ? ? ? ? ? ? uint hip;
? ? ? ? ? ? ? i = get_instr(ip);// Returns NULL when we're done.
? ? ? ? ? ? ? err_status= i->execute(thd, &ip); //执行存储过程中的每一个语句,每个具体语句都解析为sp_instr的子类
? ? ? ?}while (!err_status && !thd->killed && !thd->is_fatal_error);
? ? ? ?//上面循环其实就是一个sql的执行引擎,不断读入执行,直到结束
? }
? ?
? ? ?int?sp_instr_stmt::exec_core(THD *thd, uint *nextp)
? ? {
?MYSQL_QUERY_EXEC_START(thd->query,
? ? ? ? ? ? ? ? ? ? ? ? ?thd->thread_id,
? ? ? ? ? ? ? ? ? ? ? ? ?(char *) (thd->db ? thd->db: ""),
? ? ? ? ? ? ? ? ? ? ? ? ?thd->security_ctx->priv_user,
? ? ? ? ? ? ? ? ? ? ? ? ?(char *) thd->security_ctx->host_or_ip,
? ? ? ? ? ? ? ? ? ? ? ? ?3);
? ? ? ? ? int res= mysql_execute_command(thd); //对每一个sql进行执行。这里就和普通的sql是一样了
? ? ? ? ? MYSQL_QUERY_EXEC_DONE(res);
? ? ? ? ? *nextp= m_ip+1; //将上面ip推进到下一条语句,让上面的循环执行下一个语句
? ? ? ? ? ?return res;
? ?}
?
看一下解析器解析的中where?
?
where aaa = x?
|
|--> where Item_func_eq ?-----表示这是个等于条件操作
? ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/ Item_field ----代表字段aaa
? ? ? ? ? ?|-----> Item** args -----|
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \ Item_sp_local--代表变量x
解析在sql_yacc.yy中
simple_ident:
? ? ? ? ? ident
? ? ? ? ? {
? ? ? ? ? ? THD *thd= YYTHD;
? ? ? ? ? ? LEX *lex= thd->lex;
? ? ? ? ? ? Lex_input_stream *lip= YYLIP;
? ? ? ? ? ? sp_variable_t *spv;
? ? ? ? ? ? sp_pcontext *spc = lex->spcont;
? ? ? ? ? ? if (spc && (spv = spc->find_variable(&$1))) //判断语句中是否有变量
? ? ? ? ? ? {
? ? ? ? ? ? ? /* We're compiling a stored procedure and found a variable */
? ? ? ? ? ? ? if (! lex->parsing_options.allows_variable)
? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
? ? ? ? ? ? ? ? MYSQL_YYABORT;
? ? ? ? ? ? ? }
?
? ? ? ? ? ? ? Item_splocal *splocal;
? ? ? ? ? ? ? splocal= new (thd->mem_root)
? ? ? ? ? ? ? ? ? ? ? ? ?Item_splocal($1,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? spv->offset, spv->type,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? lip->get_tok_start_prev() - lex->sphead->m_tmp_query,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? lip->get_tok_end() - lip->get_tok_start_prev());
? ? ? ? ? ? ? if (splocal == NULL)
? ? ? ? ? ? ? ? MYSQL_YYABORT;
#ifndef DBUG_OFF
? ? ? ? ? ? ? splocal->m_sp= lex->sphead;
#endif
? ? ? ? ? ? ? $$= splocal;
? ? ? ? ? ? ? lex->safe_to_cache_query=0;
? ? ? ? ? ? }
? ? ? ? ? ? else
? ? ? ? ? ? {
? ? ? ? ? ? ? SELECT_LEX *sel= Select;
? ? ? ? ? ? ? if ((sel->parsing_place != IN_HAVING) ||
? ? ? ? ? ? ? ? ? (sel->get_in_sum_expr() > 0))
? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? $$= new (thd->mem_root) Item_field(Lex->current_context(),
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?NullS, NullS, $1.str);
? ? ? ? ? ? ? }
? ? ? ? ? ? ? else
? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? $$= new (thd->mem_root) Item_ref(Lex->current_context(),
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?NullS, NullS, $1.str);
? ? ? ? ? ? ? }
? ? ? ? ? ? ? if ($$ == NULL)
? ? ? ? ? ? ? ? MYSQL_YYABORT;
? ? ? ? ? ? }
? ? ? ? ? }
? ? ? ? | simple_ident_q { $$= $1; }
? ? ? ? ;
?
?

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

MySQL是一个开源的关系型数据库管理系统。1)创建数据库和表:使用CREATEDATABASE和CREATETABLE命令。2)基本操作:INSERT、UPDATE、DELETE和SELECT。3)高级操作:JOIN、子查询和事务处理。4)调试技巧:检查语法、数据类型和权限。5)优化建议:使用索引、避免SELECT*和使用事务。

可以通过以下步骤打开 phpMyAdmin:1. 登录网站控制面板;2. 找到并点击 phpMyAdmin 图标;3. 输入 MySQL 凭据;4. 点击 "登录"。

MySQL是一种开源的关系型数据库管理系统,主要用于快速、可靠地存储和检索数据。其工作原理包括客户端请求、查询解析、执行查询和返回结果。使用示例包括创建表、插入和查询数据,以及高级功能如JOIN操作。常见错误涉及SQL语法、数据类型和权限问题,优化建议包括使用索引、优化查询和分表分区。

选择MySQL的原因是其性能、可靠性、易用性和社区支持。1.MySQL提供高效的数据存储和检索功能,支持多种数据类型和高级查询操作。2.采用客户端-服务器架构和多种存储引擎,支持事务和查询优化。3.易于使用,支持多种操作系统和编程语言。4.拥有强大的社区支持,提供丰富的资源和解决方案。

Redis 使用单线程架构,以提供高性能、简单性和一致性。它利用 I/O 多路复用、事件循环、非阻塞 I/O 和共享内存来提高并发性,但同时存在并发性受限、单点故障和不适合写密集型工作负载的局限性。

MySQL在数据库和编程中的地位非常重要,它是一个开源的关系型数据库管理系统,广泛应用于各种应用场景。1)MySQL提供高效的数据存储、组织和检索功能,支持Web、移动和企业级系统。2)它使用客户端-服务器架构,支持多种存储引擎和索引优化。3)基本用法包括创建表和插入数据,高级用法涉及多表JOIN和复杂查询。4)常见问题如SQL语法错误和性能问题可以通过EXPLAIN命令和慢查询日志调试。5)性能优化方法包括合理使用索引、优化查询和使用缓存,最佳实践包括使用事务和PreparedStatemen

MySQL和SQL是开发者必备技能。1.MySQL是开源的关系型数据库管理系统,SQL是用于管理和操作数据库的标准语言。2.MySQL通过高效的数据存储和检索功能支持多种存储引擎,SQL通过简单语句完成复杂数据操作。3.使用示例包括基本查询和高级查询,如按条件过滤和排序。4.常见错误包括语法错误和性能问题,可通过检查SQL语句和使用EXPLAIN命令优化。5.性能优化技巧包括使用索引、避免全表扫描、优化JOIN操作和提升代码可读性。

构建 SQL 数据库涉及 10 个步骤:选择 DBMS;安装 DBMS;创建数据库;创建表;插入数据;检索数据;更新数据;删除数据;管理用户;备份数据库。
