WL#5142: FLUSH LOGS should take optional arguments for which log(s) to flush

Affects: Server-5.5   —   Status: Complete   —   Priority: Medium

Rationale:
This is the work for BUG#14104.

Support for flushing individual logs, so that the user can
selectively flush a subset of the server logs.

Flush of individual logs is done according to the 
following syntax:

  FLUSH <log_category> LOGS;

The syntax is extended so that the user is able to flush a
subset of logs:

  FLUSH [log_category LOGS,];

where log_category is one of:
  SLOW
  ERROR
  BINARY
  ENGINE
  GENERAL
  RELAY.

Testing:
The tests provided by the developer, together with the overall testing of the
source tree, covers the new feature.  QA approved.  -- Serge, 2010-01-19
Support for flushing individual logs requires two
implementation efforts. These are listed as tasks: 

Task #1
-------
     
  Adding support for 'flush * logs' statement syntax to
  sql/sql_yacc.yy.


Task #2
-------
     
  Change server so that logs specified by the user can be
  flushed independently, ie, make mysqld act on specific
  log files according to user request. This is done as
  follows:

  a. Flush binary logs 

     - It causes new binary log file to be created. The
       sequence number of the new binary log file is
       incremented by one relative to the previous file.
       It also safely closes and reopens the binary log 
       index file.

  b. Flush error logs 
          
     - If the server is writing error log to a named
       file (for example, if it was started with the
       --log-error option), it renames the current error log
       file to a file with the same name but with additional
       suffix of "-old", and creates a new empty error log
       file.

     - No renaming occurs if the --log-error option was not 
       given. If you do not specify --log-error, or 
       (on Windows) if you use the --console option, 
       errors are written to stderr, the standard error 
       output. Usually this is your terminal.

  c. Flush general logs

     - Closes and reopens the general log file.

  d. Flush slow logs

     - Closes and reopens the slow log file.

  e. Flush engine logs

     - Flushes engine logs to disk.

  f. Flush relay logs 

     - Create two new relay log files, the sequence number of
       the every relay log file is incremented by one
       relative to the previous file. The relay log index file 
       is closed and reopened too.

  All the above statements except 'Flush binary log' are
  binary logged unless one uses NO_WRITE_TO_BINLOG.


The 'flush individual logs' function is designed by the following two steps:


1. Adding support of 'flush * logs' statement syntax to sql/sql_yacc.yy 
as following code:

+++ sql/sql_yacc.yy     2009-11-16 04:25:45 +0000
@@ -11248,6 +11252,18 @@
           opt_table_list {}
         | TABLES WITH READ_SYM LOCK_SYM
           { Lex->type|= REFRESH_TABLES | REFRESH_READ_LOCK; }
+        | ERROR_SYM LOGS_SYM
+          { Lex->type|= REFRESH_ERROR_LOG; }
+        | ENGINE_SYM LOGS_SYM
+          { Lex->type|= REFRESH_ENGINE_LOG; } 
+        | GENERAL LOGS_SYM
+          { Lex->type|= REFRESH_GENERAL_LOG; }
+        | SLOW LOGS_SYM
+          { Lex->type|= REFRESH_SLOW_LOG; }
+        | BINARY LOGS_SYM
+          { Lex->type|= REFRESH_BINARY_LOG; }
+        | RELAY LOGS_SYM
+          { Lex->type|= REFRESH_RELAY_LOG; }
         | QUERY_SYM CACHE_SYM


2. Flush specified logs when executing the 'flush * log' statement 
as the following code:

+++ sql/sql_parse.cc    2009-11-16 04:11:28 +0000
@@ -6839,6 +6839,57 @@
     reset_mqh((LEX_USER *)NULL, TRUE);
   }
 #endif
+  if (options & REFRESH_ERROR_LOG)
+  {
+    if (flush_error_log())
+      result= 1;
+  }
+
+  if (options & REFRESH_SLOW_LOG)
+  {
+    MYSQL_QUERY_LOG *mysql_slow_log;
+
+    if (opt_slow_log)
+    {
+      mysql_slow_log= logger.get_slow_log_file_handler();
+      mysql_slow_log->reopen_file();
+    }
+  }
+
+  if (options & REFRESH_GENERAL_LOG)
+  {
+    MYSQL_QUERY_LOG *mysql_log;
+
+    if (opt_log);
+    {
+      mysql_log= logger.get_log_file_handler();
+      mysql_log->reopen_file();
+    }
+  }
+
+  if (options & REFRESH_ENGINE_LOG)
+  {
+    if (ha_flush_logs(NULL))
+      result= 1;
+  }
+
+  if (options & REFRESH_BINARY_LOG)
+  {
+    if ( mysql_bin_log.is_open() )
+    {
+      mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
+    }
+  }
+
+  if (options & REFRESH_RELAY_LOG)
+  {
+#ifdef HAVE_REPLICATION
+    pthread_mutex_lock(&LOCK_active_mi);
+    rotate_relay_log(active_mi);
+    pthread_mutex_unlock(&LOCK_active_mi);
+#endif
+  }
+
   if (options & REFRESH_LOG)