List:Commits« Previous MessageNext Message »
From:Dao-Gang.Qu Date:November 27 2009 3:34am
Subject:bzr commit into mysql-pe branch (Dao-Gang.Qu:3683) WL#5142
View as plain text  
#At file:///home/daogangqu/mysql/bzrwork/wl5142/mysql-pe/ based on revid:jorgen.loland@stripped

 3683 Dao-Gang.Qu@stripped	2009-11-27
      WL#5142 FLUSH LOGS should take optional arguments for which log(s) to flush
      
      Support to flush individual logs, so that user can selectively flush 
      the logs and avoid necessary flushes of all the logs.
      
      Flush individual logs as following:
      flush error logs
      flush engine logs
      flush general logs
      flush slow logs
      flush binary logs
      flush relay logs
      
      Flush multiple logs separated by comma in one statement is also supported 
      as following:
      flush slow logs, binary logs;
      flush error logs, engine logs, general logs, relay logs;
     @ mysql-test/suite/rpl/r/rpl_flush_logs.result
        Test result for WL#5142.
     @ mysql-test/suite/rpl/t/rpl_flush_logs.test
        Added the test file to verify if the 'flush individual log' 
        statement works fine.
     @ sql/log.cc
        Added the two functions to flush slow and general log.
     @ sql/sql_parse.cc
        Added code to flush specified logs against the option.
     @ sql/sql_yacc.yy
        Added code to parse the 'flush * log' statement syntax and 
        set its option to Lex->type.

    added:
      mysql-test/suite/rpl/r/rpl_flush_logs.result
      mysql-test/suite/rpl/t/rpl_flush_logs-master.opt
      mysql-test/suite/rpl/t/rpl_flush_logs.test
    modified:
      include/mysql_com.h
      sql/lex.h
      sql/log.cc
      sql/log.h
      sql/sql_parse.cc
      sql/sql_yacc.yy
=== modified file 'include/mysql_com.h'
--- a/include/mysql_com.h	2009-11-02 15:16:58 +0000
+++ b/include/mysql_com.h	2009-11-27 03:34:05 +0000
@@ -128,6 +128,12 @@ enum enum_server_command
 					   thread */
 #define REFRESH_MASTER          128     /* Remove all bin logs in the index
 					   and truncate the index */
+#define REFRESH_ERROR_LOG       256 /* Rotate only the erorr log */
+#define REFRESH_ENGINE_LOG      512 /* Flush all storage engine logs */
+#define REFRESH_BINARY_LOG     1024 /* Flush the binary log */
+#define REFRESH_RELAY_LOG      2048 /* Flush the relay log */
+#define REFRESH_GENERAL_LOG    4096 /* Flush the general log */
+#define REFRESH_SLOW_LOG       8192 /* Flush the slow query log */
 
 /* The following can't be set with mysql_refresh() */
 #define REFRESH_READ_LOCK	16384	/* Lock tables for read */

=== added file 'mysql-test/suite/rpl/r/rpl_flush_logs.result'
--- a/mysql-test/suite/rpl/r/rpl_flush_logs.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_flush_logs.result	2009-11-27 03:34:05 +0000
@@ -0,0 +1,67 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+# Make sure the 'master_log.err-old' file does not
+# exist before execute 'flush error logs' statement.
+# Test if support 'flush error logs' statement.
+flush error logs;
+# Check the 'master_log.err-old' file is created
+# after executed 'flush error logs' statement.
+# Make sure binary logs was not be flushed
+# after execute 'flush error logs' statement.
+# Make sure relay logs was not be flushed 
+# after execute 'flush error logs' statement.
+# Make sure the 'slave-relay-bin.000004' file does not
+# exist before execute 'flush relay logs' statement.
+# Test if support 'flush relay logs' statement.
+flush relay logs;
+# Check the 'slave-relay-bin.000004' file is created
+# after executed 'flush relay logs' statement.
+# Make sure binary logs was not be flushed
+# after execute 'flush relay logs' statement.
+# Test if support 'flush slow logs' statement.
+flush slow logs;
+# Make sure binary logs was not be flushed
+# after execute 'flush slow logs' statement.
+# Test if support 'flush general logs' statement.
+flush general logs;
+# Make sure binary logs was not be flushed
+# after execute 'flush general logs' statement.
+# Test if support 'flush engine logs' statement.
+flush engine logs;
+# Make sure binary logs was not be flushed
+# after execute 'flush engine logs' statement.
+# Make sure the 'master-bin.000002' file does not
+# exist before execute 'flush binary logs' statement.
+# Test if support 'flush binary logs' statement.
+flush binary logs;
+# Check the 'master-bin.000002' file is created
+# after executed 'flush binary logs' statement.
+# Make sure the 'slave-relay-bin.000007' file does not exist
+# exist before execute 'flush error logs, relay logs' statement.
+# Make sure the 'master_log.err-old' file does not exist
+# before execute 'flush error logs, relay logs' statement.
+# Test if support to combine all kinds of logs into one statement.
+flush error logs, relay logs;
+# Check the 'master_log.err-old' file is created
+# after executed 'flush error logs, relay logs' statement.
+# Make sure binary logs was not be flushed
+# after execute 'flush error logs, relay logs' statement.
+# Check the 'slave-relay-bin.000007' file is created after
+# execute 'flush error logs, relay logs' statement.
+# Make sure the 'slave-relay-bin.000008' and 'slave-relay-bin.000009' 
+# files do not exist before execute 'flush error logs, relay logs' 
+# statement.
+# Make sure the 'master_log.err-old' file does not exist
+# before execute 'flush logs' statement.
+# Test if 'flush logs' statement works fine and flush all the logs.
+flush logs;
+# Check the 'master_log.err-old' file is created
+# after executed 'flush logs' statement.
+# Check 'master-bin.000003' is created
+# after execute 'flush logs' statement.
+# Check the 'slave-relay-bin.000008' and 'slave-relay-bin.000009' 
+# files are created after execute 'flush logs' statement.

=== added file 'mysql-test/suite/rpl/t/rpl_flush_logs-master.opt'
--- a/mysql-test/suite/rpl/t/rpl_flush_logs-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_flush_logs-master.opt	2009-11-27 03:34:05 +0000
@@ -0,0 +1 @@
+--log-error=$MYSQLTEST_VARDIR/tmp/master_log.err

=== added file 'mysql-test/suite/rpl/t/rpl_flush_logs.test'
--- a/mysql-test/suite/rpl/t/rpl_flush_logs.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_flush_logs.test	2009-11-27 03:34:05 +0000
@@ -0,0 +1,177 @@
+#
+# WL#5124
+# This test verifies if the 'flush individual logs' statement 
+# works fine.  
+#
+
+--source include/master-slave.inc
+--source include/have_binlog_format_statement.inc
+connection master;
+
+# Test 'flush error logs' statement.
+--echo # Make sure the 'master_log.err-old' file does not
+--echo # exist before execute 'flush error logs' statement.
+--error 1
+file_exists $MYSQLTEST_VARDIR/tmp/master_log.err-old;
+
+--echo # Test if support 'flush error logs' statement.
+flush error logs;
+
+--echo # Check the 'master_log.err-old' file is created
+--echo # after executed 'flush error logs' statement.
+file_exists $MYSQLTEST_VARDIR/tmp/master_log.err-old;
+file_exists $MYSQLTEST_VARDIR/tmp/master_log.err;
+
+--echo # Make sure binary logs was not be flushed
+--echo # after execute 'flush error logs' statement.
+--error 1
+file_exists $MYSQLTEST_VARDIR/mysqld.1/data/master-bin.000002;
+
+sync_slave_with_master;
+connection slave;
+--echo # Make sure relay logs was not be flushed 
+--echo # after execute 'flush error logs' statement.
+--error 1
+file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000004;
+
+
+# Test 'flush relay logs' statement.
+--echo # Make sure the 'slave-relay-bin.000004' file does not
+--echo # exist before execute 'flush relay logs' statement.
+--error 1
+file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000004;
+
+connection master;
+--echo # Test if support 'flush relay logs' statement.
+flush relay logs;
+
+sync_slave_with_master;
+connection slave;
+--echo # Check the 'slave-relay-bin.000004' file is created
+--echo # after executed 'flush relay logs' statement.
+file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000004;
+
+connection master;
+--echo # Make sure binary logs was not be flushed
+--echo # after execute 'flush relay logs' statement.
+--error 1
+file_exists $MYSQLTEST_VARDIR/mysqld.1/data/master-bin.000002;
+
+
+# Test 'flush slow logs' statement.
+--echo # Test if support 'flush slow logs' statement.
+flush slow logs;
+
+--echo # Make sure binary logs was not be flushed
+--echo # after execute 'flush slow logs' statement.
+--error 1
+file_exists $MYSQLTEST_VARDIR/mysqld.1/data/master-bin.000002;
+
+
+# Test 'flush general logs' statement.
+--echo # Test if support 'flush general logs' statement.
+flush general logs;
+
+--echo # Make sure binary logs was not be flushed
+--echo # after execute 'flush general logs' statement.
+--error 1
+file_exists $MYSQLTEST_VARDIR/mysqld.1/data/master-bin.000002;
+
+
+# Test 'flush engine logs' statement.
+--echo # Test if support 'flush engine logs' statement.
+flush engine logs;
+
+--echo # Make sure binary logs was not be flushed
+--echo # after execute 'flush engine logs' statement.
+--error 1
+file_exists $MYSQLTEST_VARDIR/mysqld.1/data/master-bin.000002;
+
+
+# Test 'flush binary logs' statement.
+--echo # Make sure the 'master-bin.000002' file does not
+--echo # exist before execute 'flush binary logs' statement.
+--error 1
+file_exists $MYSQLTEST_VARDIR/mysqld.1/data/master-bin.000002;
+
+--echo # Test if support 'flush binary logs' statement.
+flush binary logs;
+
+--echo # Check the 'master-bin.000002' file is created
+--echo # after executed 'flush binary logs' statement.
+file_exists $MYSQLTEST_VARDIR/mysqld.1/data/master-bin.000002;
+file_exists $MYSQLTEST_VARDIR/mysqld.1/data/master-bin.000001;
+
+
+# Test 'flush error logs, relay logs' statement
+sync_slave_with_master;
+connection slave;
+--echo # Make sure the 'slave-relay-bin.000007' file does not exist
+--echo # exist before execute 'flush error logs, relay logs' statement.
+--error 1
+file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000007;
+
+connection master;
+remove_file $MYSQLTEST_VARDIR/tmp/master_log.err-old;
+
+--echo # Make sure the 'master_log.err-old' file does not exist
+--echo # before execute 'flush error logs, relay logs' statement.
+--error 1
+file_exists $MYSQLTEST_VARDIR/tmp/master_log.err-old;
+
+--echo # Test if support to combine all kinds of logs into one statement.
+flush error logs, relay logs;
+
+--echo # Check the 'master_log.err-old' file is created
+--echo # after executed 'flush error logs, relay logs' statement.
+file_exists $MYSQLTEST_VARDIR/tmp/master_log.err-old;
+file_exists $MYSQLTEST_VARDIR/tmp/master_log.err;
+
+--echo # Make sure binary logs was not be flushed
+--echo # after execute 'flush error logs, relay logs' statement.
+--error 1
+file_exists $MYSQLTEST_VARDIR/mysqld.1/data/master-bin.000003;
+
+sync_slave_with_master;
+connection slave;
+--echo # Check the 'slave-relay-bin.000007' file is created after
+--echo # execute 'flush error logs, relay logs' statement.
+file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000007;
+
+
+# Test 'flush logs' statement
+--echo # Make sure the 'slave-relay-bin.000008' and 'slave-relay-bin.000009' 
+--echo # files do not exist before execute 'flush error logs, relay logs' 
+--echo # statement.
+--error 1
+file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000008;
+--error 1
+file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000009;
+
+connection master;
+remove_file $MYSQLTEST_VARDIR/tmp/master_log.err-old;
+
+--echo # Make sure the 'master_log.err-old' file does not exist
+--echo # before execute 'flush logs' statement.
+--error 1
+file_exists $MYSQLTEST_VARDIR/tmp/master_log.err-old;
+
+--echo # Test if 'flush logs' statement works fine and flush all the logs.
+flush logs;
+
+--echo # Check the 'master_log.err-old' file is created
+--echo # after executed 'flush logs' statement.
+file_exists $MYSQLTEST_VARDIR/tmp/master_log.err-old;
+file_exists $MYSQLTEST_VARDIR/tmp/master_log.err;
+
+--echo # Check 'master-bin.000003' is created
+--echo # after execute 'flush logs' statement.
+file_exists $MYSQLTEST_VARDIR/mysqld.1/data/master-bin.000003;
+
+sync_slave_with_master;
+connection slave;
+--echo # Check the 'slave-relay-bin.000008' and 'slave-relay-bin.000009' 
+--echo # files are created after execute 'flush logs' statement.
+file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000008;
+file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000009;
+

=== modified file 'sql/lex.h'
--- a/sql/lex.h	2009-10-30 16:34:50 +0000
+++ b/sql/lex.h	2009-11-27 03:34:05 +0000
@@ -198,6 +198,7 @@ static SYMBOL symbols[] = {
   { "ENGINE",		SYM(ENGINE_SYM)},
   { "ENGINES",		SYM(ENGINES_SYM)},
   { "ENUM",		SYM(ENUM)},
+  { "ERROR",            SYM(ERROR_SYM)},
   { "ERRORS",		SYM(ERRORS)},
   { "ESCAPE",		SYM(ESCAPE_SYM)},
   { "ESCAPED",		SYM(ESCAPED)},
@@ -234,6 +235,7 @@ static SYMBOL symbols[] = {
   { "FULL",		SYM(FULL)},
   { "FULLTEXT",		SYM(FULLTEXT_SYM)},
   { "FUNCTION",		SYM(FUNCTION_SYM)},
+  { "GENERAL",          SYM(GENERAL)},
   { "GEOMETRY",		SYM(GEOMETRY_SYM)},
   { "GEOMETRYCOLLECTION",SYM(GEOMETRYCOLLECTION)},
   { "GET_FORMAT",       SYM(GET_FORMAT)},
@@ -446,6 +448,7 @@ static SYMBOL symbols[] = {
   { "REDUNDANT",	SYM(REDUNDANT_SYM)},
   { "REFERENCES",	SYM(REFERENCES)},
   { "REGEXP",		SYM(REGEXP)},
+  { "RELAY",            SYM(RELAY)},
   { "RELAYLOG",         SYM(RELAYLOG_SYM)},
   { "RELAY_LOG_FILE",   SYM(RELAY_LOG_FILE_SYM)},
   { "RELAY_LOG_POS",    SYM(RELAY_LOG_POS_SYM)},
@@ -503,6 +506,7 @@ static SYMBOL symbols[] = {
   { "SIMPLE",		SYM(SIMPLE_SYM)},
   { "SKIP_GAP_EVENT",     SYM(SKIP_GAP_EVENT_SYM)},
   { "SLAVE",            SYM(SLAVE)},
+  { "SLOW",             SYM(SLOW)},
   { "SNAPSHOT",         SYM(SNAPSHOT_SYM)},
   { "SMALLINT",		SYM(SMALLINT)},
   { "SOCKET",		SYM(SOCKET_SYM)},

=== modified file 'sql/log.cc'
--- a/sql/log.cc	2009-11-03 09:42:49 +0000
+++ b/sql/log.cc	2009-11-27 03:34:05 +0000
@@ -1843,6 +1843,72 @@ bool LOGGER::flush_logs(THD *thd)
 
 
 /**
+  Close and reopen the slow log (with locks).
+
+  @returns
+         0   OK
+         1   error
+*/
+bool LOGGER::flush_slow_log()
+{
+  /*
+    Now we lock logger, as nobody should be able to use logging routines while
+    log tables are closed
+  */
+  logger.lock_exclusive();
+  
+  /* Reopen slow log file */
+  MYSQL_QUERY_LOG *mysql_slow_log;
+  if (file_log_handler)
+    mysql_slow_log= file_log_handler->get_mysql_slow_log();
+  else 
+    return 1;
+  if (mysql_slow_log && opt_slow_log)
+    mysql_slow_log->reopen_file();
+  else
+    return 1;
+
+  /* End of log flush */
+  logger.unlock();
+
+  return 0;
+}
+
+
+/**
+  Close and reopen the general log (with locks).
+
+  @returns
+         0   OK
+         1   error
+*/
+bool LOGGER::flush_general_log()
+{
+  /*
+    Now we lock logger, as nobody should be able to use logging routines while
+    log tables are closed
+  */
+  logger.lock_exclusive();
+
+  /* Reopen general log file */
+  MYSQL_QUERY_LOG *mysql_log;
+  if (file_log_handler)
+    mysql_log= file_log_handler->get_mysql_log();
+  else
+    return 1;
+  if (mysql_log && opt_log)
+    mysql_log->reopen_file();
+  else
+    return 1;
+
+  /* End of log flush */
+  logger.unlock();
+
+  return 0;
+}
+
+
+/**
   Close and reopen the backup logs (with locks).
 
   @param[IN]  thd   The current thread.

=== modified file 'sql/log.h'
--- a/sql/log.h	2009-10-26 14:02:26 +0000
+++ b/sql/log.h	2009-11-27 03:34:05 +0000
@@ -736,6 +736,8 @@ public:
   void init_base();
   void init_log_tables();
   bool flush_logs(THD *thd);
+  bool flush_slow_log();
+  bool flush_general_log();
   bool flush_backup_logs(THD *thd);
   bool purge_backup_logs(THD *thd);
   bool purge_backup_logs_before_id(THD *thd, 

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2009-11-03 09:42:49 +0000
+++ b/sql/sql_parse.cc	2009-11-27 03:34:05 +0000
@@ -6847,6 +6847,34 @@ bool reload_acl_and_cache(THD *thd, ulon
       tables.
     */
 
+    options|= REFRESH_BINARY_LOG;
+    options|= REFRESH_RELAY_LOG;
+    options|= REFRESH_SLOW_LOG;
+    options|= REFRESH_GENERAL_LOG;
+    options|= REFRESH_ENGINE_LOG;
+    options|= REFRESH_ERROR_LOG;
+  }
+
+  if (options & REFRESH_ERROR_LOG)
+    if (flush_error_log())
+      result= 1;
+
+  if (options & REFRESH_SLOW_LOG)
+    if (opt_slow_log)
+      if (logger.flush_slow_log())
+        result= 1;
+
+  if (options & REFRESH_GENERAL_LOG)
+    if (opt_log)
+      if (logger.flush_general_log())
+        result= 1;
+
+  if (options & REFRESH_ENGINE_LOG)
+    if (ha_flush_logs(NULL))
+      result= 1;
+
+  if (options & REFRESH_BINARY_LOG)
+  {
     /*
       Writing this command to the binlog may result in infinite loops
       when doing mysqlbinlog|mysql, and anyway it does not really make
@@ -6854,23 +6882,17 @@ bool reload_acl_and_cache(THD *thd, ulon
       than it would help them)
     */
     tmp_write_to_binlog= 0;
-    if( mysql_bin_log.is_open() )
-    {
+    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
-
-    /* flush slow and general logs */
-    logger.flush_logs(thd);
-
-    if (ha_flush_logs(NULL))
-      result=1;
-    if (flush_error_log())
-      result=1;
   }
   /*
     Added support for flushing backup logs.

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2009-11-06 16:34:09 +0000
+++ b/sql/sql_yacc.yy	2009-11-27 03:34:05 +0000
@@ -782,6 +782,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  ENUM
 %token  EQ                            /* OPERATOR */
 %token  EQUAL_SYM                     /* OPERATOR */
+%token  ERROR_SYM
 %token  ERRORS
 %token  ESCAPED
 %token  ESCAPE_SYM                    /* SQL-2003-R */
@@ -817,6 +818,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  FULLTEXT_SYM
 %token  FUNCTION_SYM                  /* SQL-2003-R */
 %token  GE
+%token  GENERAL
 %token  GEOMETRYCOLLECTION
 %token  GEOMETRY_SYM
 %token  GET_FORMAT                    /* MYSQL-FUNC */
@@ -1040,6 +1042,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  REDUNDANT_SYM
 %token  REFERENCES                    /* SQL-2003-R */
 %token  REGEXP
+%token  RELAY
 %token  RELAYLOG_SYM
 %token  RELAY_LOG_FILE_SYM
 %token  RELAY_LOG_POS_SYM
@@ -1099,6 +1102,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  SIMPLE_SYM                    /* SQL-2003-N */
 %token  SKIP_GAP_EVENT_SYM
 %token  SLAVE
+%token  SLOW
 %token  SMALLINT                      /* SQL-2003-R */
 %token  SNAPSHOT_SYM
 %token  SOCKET_SYM
@@ -11248,6 +11252,18 @@ flush_option:
           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
           { Lex->type|= REFRESH_QUERY_CACHE_FREE; }
         | HOSTS_SYM
@@ -12421,6 +12437,7 @@ keyword_sp:
         | ENUM                     {}
         | ENGINE_SYM               {}
         | ENGINES_SYM              {}
+        | ERROR_SYM                {}
         | ERRORS                   {}
         | ESCAPE_SYM               {}
         | EVENT_SYM                {}
@@ -12550,6 +12567,7 @@ keyword_sp:
         | REDO_BUFFER_SIZE_SYM     {}
         | REDOFILE_SYM             {}
         | REDUNDANT_SYM            {}
+        | RELAY                    {}
         | RELAYLOG_SYM             {}
         | RELAY_LOG_FILE_SYM       {}
         | RELAY_LOG_POS_SYM        {}


Attachment: [text/bzr-bundle] bzr/dao-gang.qu@sun.com-20091127033405-ocjay3k7brfvkz2n.bundle
Thread
bzr commit into mysql-pe branch (Dao-Gang.Qu:3683) WL#5142Dao-Gang.Qu27 Nov
  • Re: bzr commit into mysql-pe branch (Dao-Gang.Qu:3683) WL#5142He Zhenxing27 Nov