List:Commits« Previous MessageNext Message »
From:Davi Arnaut Date:February 20 2008 2:03pm
Subject:Re: bk commit into 5.0 tree (davi:1.2583) BUG#28386
View as plain text  
Hi Konstantin,

Konstantin Osipov wrote:
> * Davi Arnaut <davi@stripped> [07/12/21 14:02]:
>> ChangeSet@stripped, 2007-12-21 08:49:53-02:00, davi@stripped +5 -0
>>   Bug#28386 the general log is incomplete
> 
> Hi Davi,
> 
> Please see below.
> 
>> +static void log_refresh_cmd(THD *thd, ulong options)
>> +{
>> +  char buff[512];
>> +  String str(buff,(uint32) sizeof(buff), system_charset_info);
>> +  static struct {
>> +    ulong option;
>> +    const char *str;
>> +  } const refresh_opt[]= {
>> +    { REFRESH_GRANT, "PRIVILEGES, " },
>> +    { REFRESH_LOG, "LOGS, " },
>> +    { REFRESH_TABLES, "TABLES, " },
>> +    { REFRESH_HOSTS, "HOSTS, " },
>> +    { REFRESH_STATUS, "STATUS, " },
>> +    { REFRESH_THREADS, "THREADS, " },
>> +    { REFRESH_SLAVE, "SLAVE, " },
>> +    { REFRESH_MASTER, "MASTER, " },
>> +    { REFRESH_READ_LOCK, "TABLES WITH READ LOCK, " },
>> +    { REFRESH_QUERY_CACHE, "QUERY CACHE, " },
>> +    { REFRESH_QUERY_CACHE_FREE, "QUERY CACHE FREE, " },
>> +    { REFRESH_DES_KEY_FILE, "DES_KEY_FILE, " },
>> +    { REFRESH_USER_RESOURCES, "USER_RESOURCES, " }
>> +  };
>> +
>> +  str.length(0);
>> +
>> +  for (uint i= 0; i < array_elements(refresh_opt); i++)
>> +  {
>> +    if (refresh_opt[i].option & options)
>> +      str.append(refresh_opt[i].str);
>> +  }
>> +
>> +  if (str.is_empty())
>> +    mysql_log.write(thd, thd->command, NullS);
>> +  else
>> +    mysql_log.write(thd, thd->command, "%.*s",
>> +                    str.length() - 2, str.c_ptr_quick());
>> +}
> 
> I'm not sure this change can be classified as a bug fix. It is not
> very extensible (no compile-time check that one doesn't forget to
> add an option name when a new REFRESH option is added).
> I would exclude this change from the patch.

The bug reporter (which is a costumer) is complaining that COM_REFRESH
is logged but doesn't show what was being refreshed.

>> +
>>  void thd_init_client_charset(THD *thd, uint cs_number)
>>  {
>>    /*
>> @@ -2079,7 +2117,7 @@ bool dispatch_command(enum enum_server_c
>>      ulong options= (ulong) (uchar) packet[0];
>>      if (check_global_access(thd,RELOAD_ACL))
>>        break;
>> -    mysql_log.write(thd,command,NullS);
>> +    log_refresh_cmd(thd, options);
>>      if (!reload_acl_and_cache(thd, options, (TABLE_LIST*) 0, &not_used))
>>        send_ok(thd);
>>      break;
>> @@ -2159,6 +2197,7 @@ bool dispatch_command(enum enum_server_c
>>    }
>>    case COM_PING:
>>      statistic_increment(thd->status_var.com_other, &LOCK_status);
>> +    mysql_log.write(thd, command, NullS);
> 
> I believe not logging COM_PING in the general log is intentional.
> COM_PING may be generated by a heartbeat service. 
> Since we don't provide a way to fine-tune what gets into the
> general log, people may complain  when this is added.
> 
> E.g. when we changed behaviour of --log-slow-admin-statements
> many screamed loudly.
> 
> I think this should not be part of the patch.

OK.

>> @@ -2458,6 +2458,11 @@ void mysql_stmt_reset(THD *thd, char *pa
>>  
>>    stmt->state= Query_arena::PREPARED;
>>  
>> +  /* Don't print if inside a stored procedure. */
>> +  if (thd->spcont == NULL)
>> +    mysql_log.write(thd, thd->command, "[%lu] %.*s", stmt->id,
>> +                    stmt->name.length, stmt->name.str);
>> +
> 
> OK, but mysql_stmt_reset can never be called from a stored
> procedure. Thus no need to check for thd->spcont. You could add a
> comment instead.

OK.

>>    send_ok(thd);
>>  
>>    DBUG_VOID_RETURN;
>> @@ -2543,6 +2548,8 @@ void mysql_stmt_get_longdata(THD *thd, c
>>    uint param_number;
>>    Prepared_statement *stmt;
>>    Item_param *param;
>> +  char *extra_data;
>> +  ulong extra_length;
>>  #ifndef EMBEDDED_LIBRARY
>>    char *packet_end= packet + packet_length - 1;
>>  #endif
>> @@ -2582,15 +2589,29 @@ void mysql_stmt_get_longdata(THD *thd, c
>>    param= stmt->param_array[param_number];
>>  
>>  #ifndef EMBEDDED_LIBRARY
>> -  if (param->set_longdata(packet, (ulong) (packet_end - packet)))
>> +  extra_data= packet;
>> +  extra_length= (ulong) (packet_end - packet);
>>  #else
>> -  if (param->set_longdata(thd->extra_data, thd->extra_length))
>> +  extra_data= thd->extra_data;
>> +  extra_length= thd->extra_length;
>>  #endif
>> +
>> +  if (param->set_longdata(extra_data, extra_length))
>>    {
>>      stmt->state= Query_arena::ERROR;
>>      stmt->last_errno= ER_OUTOFMEMORY;
>>      sprintf(stmt->last_error, ER(ER_OUTOFMEMORY), 0);
>>    }
>> +
>> +  /* Don't print if inside a stored procedure. */
>> +  if (thd->spcont == NULL)
>> +  {
>> +    const char fmt[]= "[%lu] %.*s %.*b";
>> +    mysql_log.write(thd, thd->command, fmt, stmt->id,
>> +                    stmt->name.length, stmt->name.str,
>> +                    extra_length, extra_data);
>> +  }
> 
> OK, but please do not log the argument. It can be
> binary, to start with.
> Once again, this code is never executed in a stored procedure.

OK.

>>    DBUG_VOID_RETURN;
>>  }
>>  
>> @@ -3064,6 +3085,12 @@ bool Prepared_statement::deallocate()
>>      my_error(ER_PS_NO_RECURSION, MYF(0));
>>      return TRUE;
>>    }
>> +
>> +  /* Don't print if inside a stored procedure. */
>> +  if (thd->spcont == NULL)
>> +    mysql_log.write(thd, thd->command, "[%lu] %.*s", id,
>> +                    name.length, name.str);
> 
> OK. This code is never executed in a stored procedure. 

OK.

>> +static FILE *open_master_log(void)
>> +{
>> +  FILE *log_file;
>> +  char *master_log_filename;
>> +
>> +  master_log_filename = (char *) malloc(strlen(opt_vardir) +
> strlen("/log/master.log") + 1);
>> +  strcpy(master_log_filename, opt_vardir);
>> +  strcat(master_log_filename, "/log/master.log");
>> +  printf("Opening '%s'\n", master_log_filename);
>> +  log_file= my_fopen(master_log_filename, (int) (O_RDONLY | O_BINARY),
> MYF(MY_WME));
>> +  free(master_log_filename);
>> +
>> +  return log_file;
>> +}
>> +
>>  /*
>>    Bug#17667: An attacker has the opportunity to bypass query logging.
>>  
>> @@ -15067,7 +15082,6 @@ static void test_bug17667()
>>  
>>    struct buffer_and_length *statement_cursor;
>>    FILE *log_file;
>> -  char *master_log_filename;
>>  
>>    myheader("test_bug17667");
>>  
>> @@ -15109,12 +15123,7 @@ static void test_bug17667()
>>    rc= mysql_query(mysql, "flush logs");
>>    myquery(rc);
>>  
>> -  master_log_filename = (char *) malloc(strlen(opt_vardir) +
> strlen("/log/master.log") + 1);
>> -  strcpy(master_log_filename, opt_vardir);
>> -  strcat(master_log_filename, "/log/master.log");
>> -  printf("Opening '%s'\n", master_log_filename);
>> -  log_file= my_fopen(master_log_filename, (int) (O_RDONLY | O_BINARY),
> MYF(MY_WME));
>> -  free(master_log_filename);
>> +  log_file= open_master_log();
>>  
>>    if (log_file != NULL) {
>>  
>> @@ -16152,6 +16161,89 @@ static void test_bug31669()
>>    DBUG_VOID_RETURN;
>>  }
>>  
>> +static void test_bug28386()
>> +{
>> +  int rc;
>> +  uint i;
>> +  MYSQL_STMT *stmt;
>> +  FILE *log_file;
>> +  char buffer[MAX_TEST_QUERY_LENGTH*2], *line;
>> +  struct {
>> +    const char *str;
>> +    size_t len;
>> +    int found;
>> +  } tokens[] = {
>> +    { "Close stmt", 0, 0 },
>> +    { "Reset stmt", 0, 0 },
>> +    { "Long Data", 0, 0 },
>> +    { "Ping", 0, 0 },
>> +    { "Refresh", 0, 0 },
>> +    { "PRIVILEGES, STATUS", 0, 0 }
>> +  };
>> +  DBUG_ENTER("test_bug28386");
>> +  myheader("test_bug28386");
>> +
>> +  sleep(30);
> 
> Ouch!

Oops, left over from the debug phase, not intended to be here.

> 
> Why don't you use the approach from the other test:
> 
> /* Make sure the server has written the logs to disk before
>  * reading it */
> rc= mysql_query(mysql, "flush logs");
> myquery(rc);
> 

OK.

> 
> Or rather. Add the test case to 5.1 only. Use logging-to-tables
> feature and write the test case in SQL.

OK.

[..]

> 
> To sum up:
> 
>  - OK to push the approved parts. Not approved parts in my view
>    more close in nature to a feature request, and they need 
>    to be thought through before getting in. I recommend that you
>    open a separate bug report for them (feature request).
>    Not approved:
>     - logging arguments of LONGDATA
>     - logging COM_PING
>     - logging arguments of COM_REFRESH

This one (COM_REFRESH) I think it's worthwhile since it's close to
useless if it doesn't log the arguments because it can be so many
different things.

>  - please rewrite the test in SQL.
>  - I would like to take a look at the patch before you push.

OK.

Regards,

-- 
Davi Arnaut, Software Engineer
MySQL Inc, www.mysql.com

Are you MySQL certified?  www.mysql.com/certification
Thread
bk commit into 5.0 tree (davi:1.2583) BUG#28386Davi Arnaut21 Dec
  • Re: bk commit into 5.0 tree (davi:1.2583) BUG#28386Konstantin Osipov20 Feb
    • Re: bk commit into 5.0 tree (davi:1.2583) BUG#28386Davi Arnaut20 Feb