技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> MySQL --> 探索MySQL源代码-在show processlist里添加字段

探索MySQL源代码-在show processlist里添加字段

浏览:1460次  出处信息

    show processlist是诊断MySQL常用的命令,它会列出THD对象里所有的线程当前状况。

    下面将为show processlist添加一个新的列,表示当前连接查询之后返回的行数,字段名为my_row_count。

    当你要修改一个命令的时候,最好从sql/sql_yacc.yy出发,根据命令的关键字语法匹配到后续的动作。打开sql/sql_yacc.yy后搜索关键字show:,就找到了所有show命令的语法规则。继续往下找就能看到,

| opt_full PROCESSLIST_SYM
{ Lex->sql_command= SQLCOM_SHOW_PROCESSLIST;}
| ....

    找到了相应的sql命令SQLCOM_SHOW_PROCESSLIST,命令对应的行为呢?

    我们来到sql/sql_parse.cc的dispatch_command函数,这是所有命令和查询的总路口,搜索关键字SQLCOM_SHOW_PROCESSLIST会发现,

case SQLCOM_SHOW_PROCESSLIST:
if (!thd->security_ctx->priv_user[0] && check_global_access(thd,PROCESS_ACL))
    break;
mysqld_list_processes(thd, (thd->security_ctx->master_access & PROCESS_ACL ? NullS :
thd->security_ctx->priv_user), lex->verbose);
break;

    是的msyqld_list_processes就是服务端处理show processlist 的函数。如果你配置好cscope和ctag,这里就可以很方便的快速切换进入这个函数。

    进入mysqld_list_processes(sql/sql_show.cc)之后,可以看到这个函数还是比较简单,先是往field_list插入一些item,这些item就是show processlist的字段title, 很熟悉把。这里我们添加一个字段名my_row_count。

field_list.push_back(field=new Item_empty_string("Info",max_query_length));
field->maybe_null=1;
/* start */
field_list.push_back(field=new Item_int("my_row_count", MY_INT32_NUM_DECIMAL_DIGITS));
field->maybe_null=1;
/* end */
if (protocol->send_fields(&field_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
DBUG_VOID_RETURN;

    可以看到上面代码最后的send_fields就是把字段名发送给客户端。

     接下来就是从tmp对象(THD)把内容复制给thd_info对象(thread_info)。

thd_info->query=(char*) thd->strmake(tmp->query,length);
}
/* start */
thd_info->my_row_count = tmp->my_row_count;
/* end */
pthread_mutex_unlock(&tmp->LOCK_thd_data);

    接下来把thd_info 打包到protocol,随后就发送出去了。

protocol->store(thd_info->query, system_charset_info);
/*start*/    
protocol->store((ulonglong) thd_info->my_row_count);
/*end*/
if (protocol->write())
 ....

    好了show processlist 函数添加的新列就结束了。接下来我们要填充my_row_count的值, 这就涉及到为THD类的添加新的成员。

    打开sql/sql_class.h,查找关键字sent_row_count,然后添加一个my_row_count成员。

ha_rows    sent_row_count;
/* start */
ha_rows  my_row_count;
/* end */

    再打开sql/sql_class.cc 为my_row_count赋初值。

cuted_fields= sent_row_count= row_count=my_row_count =  0L;

    接着在sql/sql_class.cc 为每次select进行累加,找到函数 bool select_send::send_data(List &items)

thd->sent_row_count++;
/* start */
thd->my_row_count++;
/* end */

    好了,重新make &&sudo make install,这里花费时间比较长,因为sql_class被修改,很多lib、binary需要重新编译。

    编译后就可以看到

mysql> show processlist;
+----+------+-----------------+------+---------+------+-------+------------------+--------------+
| Id | User | Host            | db   | Command | Time | State | Info             | my_row_count |
+----+------+-----------------+------+---------+------+-------+------------------+--------------+
|  3 | root | localhost:39325 | NULL | Query   |    0 | NULL  | show processlist |            3 |
+----+------+-----------------+------+---------+------+-------+------------------+--------------+
1 row in set (0.00 sec)

mysql> insert into test.dddd values(1);
Query OK, 1 row affected (0.10 sec)

mysql> select * from test.dddd;
+------+
| a    |
+------+
|    1 |
|    1 |
|    1 |
+------+
3 rows in set (0.00 sec)

mysql> show processlist;
+----+------+-----------------+------+---------+------+-------+------------------+--------------+
| Id | User | Host            | db   | Command | Time | State | Info             | my_row_count |
+----+------+-----------------+------+---------+------+-------+------------------+--------------+
|  3 | root | localhost:39325 | NULL | Query   |    0 | NULL  | show processlist |            6 |
+----+------+-----------------+------+---------+------+-------+------------------+--------------+
1 row in set (0.00 sec)

建议继续学习:

  1. MySQL processlist中最哪些状态要引起关注    (阅读:1231)
  2. MySQL processlist中哪些状态要引起关注    (阅读:889)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1