http://www.web008.net

美高梅手机版修改代码实现你的第一个Mysql版本

 

51ak带你看MYSQL5.7源码3:修改代码实现你的第一个Mysql版本,51akmysql5.7

 

从事DBA工作多年

MYSQL源码也是头一次接触

尝试记录下自己看MYSQL5.7源码的历程

 

目录:

51ak带你看MYSQL5.7源码1:main入口函数

51ak带你看MYSQL5.7源码2:编译现有的代码

 51ak带你看MYSQL5.7源码3:修改代码实现你的第一个Mysql版本

 

 

经过开发和测试环境部署

现在到了我们动手的时候了,万事开头难,首先我们实现个小功能

今天我们准备实现这样一个功能:数据永远也不会被DELETE掉

 

当你把这个版本的MYSQL放到线上环境以后,就永远不用担心有人来DELETE你的数据了

 

思路很简单:顺腾摸瓜找到Delete所在的FUNC在函数开头就返回一个OK

问题来了,怎么找到这个函数?

有两种:一种很有灵性的同学,可能一眼就看到了sql/sql_delete.cc 这个文件 ,猜到是这个文件 

另一种方法就是基础一点,我们顺着这样的代码一层一层找到这里也行。

dispatch_command
|->mysql_parse
  |->mysql_execute_command
    ->mysql_update/mysql_delete
为了快速上手,我们用第一种方法,直接打开sql/sql_delete.cc 
找到这个方法:

bool Sql_cmd_delete::execute(THD *thd)
{
  DBUG_ASSERT(thd->lex->sql_command == SQLCOM_DELETE);

  LEX *const lex= thd->lex;
  SELECT_LEX *const select_lex= lex->select_lex;
  SELECT_LEX_UNIT *const unit= lex->unit;
  TABLE_LIST *const first_table= select_lex->get_table_list();
  TABLE_LIST *const all_tables= first_table;

  if (delete_precheck(thd, all_tables))
    return true;
  DBUG_ASSERT(select_lex->offset_limit == 0);
  unit->set_limit(select_lex);

  /* Push ignore / strict error handler */
  Ignore_error_handler ignore_handler;
  Strict_error_handler strict_handler;
  if (thd->lex->is_ignore())
    thd->push_internal_handler(&ignore_handler);
  else if (thd->is_strict_mode())
    thd->push_internal_handler(&strict_handler);
 

/*注:我们要改的就是这里,直接返回一个true,而把真正要执行的地方给注释掉了*/
  bool res =true;
  /*MYSQL_DELETE_START(const_cast<char*>(thd->query().str));
  bool res = mysql_delete(thd, unit->select_limit_cnt);
  MYSQL_DELETE_DONE(res, (ulong) thd->get_row_count_func());
  */

  /* Pop ignore / strict error handler */
  if (thd->lex->is_ignore() || thd->is_strict_mode())
    thd->pop_internal_handler();

  return res;
}

 

好了,代码就改这一个小地方,现在去编译运行

然后建 一个测试表往里写几条数据,然后尝试各种DELETE语句,接下来就是见证奇迹的时候了,你会发现数据永远不能被DELETE掉了。。

mysql> select * from t1;
+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
|  4 |
|  5 |
+----+
5 rows in set (0.00 sec)

mysql> delete from t1 where id=2;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from t1;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+----+
5 rows in set (0.00 sec)

 

怎么样,小小的一个改动,就让你再也不担心数据被删除了,感觉很酷有没有

看到这里的同学,现在你已经有了第一个自定义版 的MYSQL了,还不赶紧打包发布到线上去!!

让那些RD同学感受一下来自DBA的控制力吧。

 

可能有好事的同学会问,这只防了DELETE,没防TRUNCATE和DROP啊。。。

这样问的同学,我觉得你不够有灵性。。

 

 

好,今天到此为止

 

从事DBA工作多年 MYSQL源码也是头一次接触 尝试记录下自己看MYSQL5.7源码...

 

当你把这个版本的MYSQL放到线上环境以后,就永远不用担心有人来DELETE你的数据了

mysql> select * from t1;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+----+
5 rows in set (0.00 sec)

 

mysql> select * from t1;
+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
|  4 |
|  5 |
+----+
5 rows in set (0.00 sec)

mysql> delete from t1 where id=2;
Query OK, 0 rows affected (0.00 sec)

让那些RD同学感受一下来自DBA的控制力吧。

从事DBA工作多年

 

问题来了,怎么找到这个函数?

有两种:一种很有灵性的同学,可能一眼就看到了sql/sql_delete.cc 这个文件 ,猜到是这个文件 

 

 

51ak带你看MYSQL5.7源码4:实现SQL黑名单功能(2018-04-11)

尝试记录下自己看MYSQL5.7源码的历程

dispatch_command
|->mysql_parse
  |->mysql_execute_command
    ->mysql_update/mysql_delete
为了快速上手,我们用第一种方法,直接打开sql/sql_delete.cc 
找到这个方法:

bool Sql_cmd_delete::execute(THD *thd)
{
  DBUG_ASSERT(thd->lex->sql_command == SQLCOM_DELETE);

  LEX *const lex= thd->lex;
  SELECT_LEX *const select_lex= lex->select_lex;
  SELECT_LEX_UNIT *const unit= lex->unit;
  TABLE_LIST *const first_table= select_lex->get_table_list();
  TABLE_LIST *const all_tables= first_table;

  if (delete_precheck(thd, all_tables))
    return true;
  DBUG_ASSERT(select_lex->offset_limit == 0);
  unit->set_limit(select_lex);

  /* Push ignore / strict error handler */
  Ignore_error_handler ignore_handler;
  Strict_error_handler strict_handler;
  if (thd->lex->is_ignore())
    thd->push_internal_handler(&ignore_handler);
  else if (thd->is_strict_mode())
    thd->push_internal_handler(&strict_handler);
 

/*注:我们要改的就是这里,直接返回一个true,而把真正要执行的地方给注释掉了*/
  bool res =true;
  /*MYSQL_DELETE_START(const_cast<char*>(thd->query().str));
  bool res = mysql_delete(thd, unit->select_limit_cnt);
  MYSQL_DELETE_DONE(res, (ulong) thd->get_row_count_func());
  */

  /* Pop ignore / strict error handler */
  if (thd->lex->is_ignore() || thd->is_strict_mode())
    thd->pop_internal_handler();

  return res;
}

 

好,今天到此为止

现在到了我们动手的时候了,万事开头难,首先我们实现个小功能

 

目录:

郑重声明:本文版权归美高梅163888所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。