免费注册 查看新帖 |

Chinaunix

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

为MySQL添加审计功能 (patch已发布) [复制链接]

论坛徽章:
1
数据库技术版块每日发帖之星
日期:2016-03-12 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-07-08 15:49 |只看该作者 |倒序浏览
MySQL有Slow Log,可以记录下慢语句的查询,但是对于想记录所有的查询,可能还是有困难(general log 无视)。MySQL 5.1的Slow Log可以精确到0.0001(大概是这个),不过这个我没去试,因为我的系统是MySQL 4.0.26的,而且不打算升级。这样的话,只能自食其力,更改源代码了。

我浏览了下源代码,发现其实,现在的问题在于,4.0 MySQL最少只能记录2秒的语句,哪怕你设置为0,默认最少还是1秒(〉1)。

第一步 vi mysqld.cc
找到如下:struct my_option my_long_options[]
这个就是MySQL读取配置文件的结构,默认值也是在这里设置的。找到long_query_time,把倒数第5个值,由1改为0,就是把最小可设置值设为0
至于my_option这个结构的定义在my_getopt.h文件中,我这里贴出来
struct my_option
{
  const char *name;                     /* Name of the option */
  int        id;                        /* unique id or short option */
  const char *comment;                  /* option comment, for autom. --help */
  gptr       *value;                    /* The variable value */
  gptr       *u_max_value;              /* The user def. max variable value */
  const char **str_values;              /* Pointer to possible values */
  ulong     var_type;
  enum get_opt_arg_type arg_type;
  longlong   def_value;                 /* Default value */
  longlong   min_value;                 /* Min allowed value */
  longlong   max_value;                 /* Max allowed value */
  longlong   sub_size;                  /* Subtract this from given value */
  long       block_size;                /* Value should be a mult. of this */
  int        app_type;                  /* To be used by an application */
};


第二步 vi sql_parse.cc 搜索mysql_slow_log
找到如下
  if (!slow_command && !thd->user_time) // do not log 'slow_command' queries
  {
    thd->proc_info="logging slow query";

    if ((ulong) (thd->start_time - thd->time_after_lock) >
        thd->variables.long_query_time ||
        ((thd->lex.select_lex.options &
          (QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED)) &&
         (specialflag & SPECIAL_LONG_LOG_FORMAT)))
    {
      long_query_count++;
      mysql_slow_log.write(thd, thd->query, thd->query_length, start_of_query);
    }
  }
这是记录Slow Log的,将〉号改为>=,这样就能记录0秒的语句了
    if ((ulong) (thd->start_time - thd->time_after_lock) >=

OK,接下去编译MySQL,将MySQL的配置文件中long-query-time设为0,就能记录下所有的SQL,有IP,USER,耗时

这套系统,在我的生产环境中已经用了半年,十分稳定,并没有带来什么特别的影响。当然审计功能消耗磁盘,建议磁盘至少RAID0,看了下5.1的代码,其实也可以这么做。不过5.1已经精确到毫秒了,是否有必要大家看着办吧。

当然这个审计功能十分简单,并不能对指定用户或者IP进行记录,其实大同小异,相信动手能力强的兄弟,定能自己解决。但是这套系统,对于我来说,已经够用了。

广告时间:如果大家喜欢这篇文章的话,也请多多支持本人开发的MySQL客户端,iMySQL-Front,主页 code.google.com/p/imysql-front

[ 本帖最后由 qlks 于 2008-7-14 13:39 编辑 ]

audit.zip

722 Bytes, 下载次数: 94

论坛徽章:
1
白银圣斗士
日期:2015-11-23 08:33:04
2 [报告]
发表于 2008-07-08 16:13 |只看该作者

论坛徽章:
0
3 [报告]
发表于 2008-07-08 18:50 |只看该作者
看了网上的slow_log的patch,他们改动的比较多。 不知道具体比你改的多那些功能。有空研究研究  

论坛徽章:
0
4 [报告]
发表于 2008-07-08 19:11 |只看该作者
传说中的牛人?

论坛徽章:
1
数据库技术版块每日发帖之星
日期:2016-03-12 06:20:00
5 [报告]
发表于 2008-07-09 11:11 |只看该作者
原帖由 7islands 于 2008-7-8 18:50 发表
看了网上的slow_log的patch,他们改动的比较多。 不知道具体比你改的多那些功能。有空研究研究  


Peter的Slow_Log Patch好像已经被5.1接受了,现在5.1就是用这个的,具体不清楚
而且那个改动比较多,需要自定义一个时间结构
这个只需改动2处,而且改动极其简单

论坛徽章:
8
综合交流区版块每周发帖之星
日期:2015-12-02 15:03:53数据库技术版块每日发帖之星
日期:2015-10-02 06:20:00IT运维版块每日发帖之星
日期:2015-10-02 06:20:00IT运维版块每日发帖之星
日期:2015-09-14 06:20:00金牛座
日期:2014-10-10 11:23:34CU十二周年纪念徽章
日期:2013-10-24 15:41:34酉鸡
日期:2013-10-19 10:17:1315-16赛季CBA联赛之北京
日期:2017-03-06 15:12:44
6 [报告]
发表于 2008-07-10 15:48 |只看该作者
原帖由 qlks 于 2008-7-9 11:11 发表


Peter的Slow_Log Patch好像已经被5.1接受了,现在5.1就是用这个的,具体不清楚
而且那个改动比较多,需要自定义一个时间结构
这个只需改动2处,而且改动极其简单



佩服
在linux不管玩什么,只要玩到修改源代码的级别,就是大牛了

论坛徽章:
1
数据库技术版块每日发帖之星
日期:2016-03-12 06:20:00
7 [报告]
发表于 2008-07-14 12:10 |只看该作者
pacth制作好了,可以看到修改的地方很小,也很简单
大家可以试试看

论坛徽章:
0
8 [报告]
发表于 2010-09-24 23:38 |只看该作者
回复 1# qlks


   

更新一下5.1+版本的修改步骤,很简单:

第一步:没变。按qlks大牛说的步骤

mysqld.cc文件查找结构体my_option my_long_options[],并在其中的参数设置值搜索:long_query_time参数值,修改倒数第5个值,如下红色的值,其实默认就为0值
  {"long_query_time", OPT_LONG_QUERY_TIME,
   "Log all queries that have taken more than long_query_time seconds to "
   "execute. The argument will be treated as a decimal value with "
   "microsecond precision.",
   &long_query_time, &long_query_time, 0, GET_DOUBLE,
   REQUIRED_ARG, 10, 0, LONG_TIMEOUT, 0, 0, 0}


说明:long_query_time的这些值,是根据结构体my_option定义的,见文件my_getopt.h,如下:
struct my_option
{
  const char *name;                     /* 参数名 */
  int        id;                        /* 参数id或参数名简称 */
  const char *comment;                  /* 注释 */
  void       *value;                    /* 参数值 */
  void       *u_max_value;              /* The user def. max variable value */
  struct st_typelib *typelib;           /* Pointer to possible values */
  ulong      var_type;                  /* Must match the variable type */
  enum get_opt_arg_type arg_type;
  longlong   def_value;                 /* 默认值 */
  longlong   min_value;                 /* Min allowed value */
  longlong   max_value;                 /* Max allowed value */
  longlong   sub_size;                  /* Subtract this from given value */
  long       block_size;                /* Value should be a mult. of this */
  void       *app_type;                 /* To be used by an application */
};



第二步:变化比较大。在sql_parse.cc中搜索log_slow_statement方法:
  1. void log_slow_statement(THD *thd)
  2. {
  3.   DBUG_ENTER("log_slow_statement");

  4.   /*
  5.     The following should never be true with our current code base,
  6.     but better to keep this here so we don't accidently try to log a
  7.     statement in a trigger or stored function
  8.   */
  9.   if (unlikely(thd->in_sub_stmt))
  10.     DBUG_VOID_RETURN;                           // Don't set time for sub stmt

  11.   /*
  12.     Do not log administrative statements unless the appropriate option is
  13.     set.
  14.   */
  15.   if (thd->enable_slow_log)
  16.   {
  17.     ulonglong end_utime_of_query= thd->current_utime();
  18.     thd_proc_info(thd, "logging slow query");

  19.     if (((end_utime_of_query - thd->utime_after_lock) >
  20.          thd->variables.long_query_time ||
  21.          ((thd->server_status &
  22.            (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) &&
  23.           opt_log_queries_not_using_indexes &&
  24.            !(sql_command_flags[thd->lex->sql_command] & CF_STATUS_COMMAND))) &&
  25.         thd->examined_row_count >= thd->variables.min_examined_row_limit)
  26.     {
  27.       thd_proc_info(thd, "logging slow query");
  28.       thd->status_var.long_query_count++;
  29.       slow_log_print(thd, thd->query(), thd->query_length(),
  30.                      end_utime_of_query);
  31.     }
  32.   }
  33.   DBUG_VOID_RETURN;
  34. }
复制代码
修改if中的第一个条件中end_utime_of_query - thd->utime_after_lock) > thd->variables.long_query_timeend_utime_of_query - thd->utime_after_lock) >= thd->variables.long_query_time


其它说明见lz的说明。。。

论坛徽章:
1
数据库技术版块每日发帖之星
日期:2016-03-12 06:20:00
9 [报告]
发表于 2010-09-30 23:16 |只看该作者
呵呵,看见自己当年最初修改的一个patch真是怀念啊

justin033,看看你能不能将slow log这个进行扩展
通过添加MySQL新的参数方式,来记录指定用户,或者IP的慢查询

论坛徽章:
0
10 [报告]
发表于 2010-10-01 11:43 |只看该作者
Peter的Slow_Log Patch好像已经被5.1接受了,现在5.1就是用这个的,具体不清楚
而且那个改动比较多,需 ...
qlks 发表于 2008-07-09 11:11


这个patch在5.1.38中有包含吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP