Commit 0c4e184b authored by unknown's avatar unknown
Browse files

WL#3015: Logging Improvements - No Restarts(ver N4)

Added slow_query_log & general_log global upadatable variables.
Added slow-query-log & general-log startup options.
Added log_output, general_log_file, slow_query_log_file global updatable variables.


mysql-test/r/show_check.result:
  WL#3015: Logging Improvements - No Restarts
  result fix
sql/log.cc:
  WL#3015: Logging Improvements - No Restarts
  added methods to LOGGER class
  void deactivate_log_handlers(THD* thd, uint log_type);
  bool activate_log_handlers(THD* thd, uint log_type);
  added methods to Log_to_file_event_handler:
  TABLE_LIST *get_mysql_slow_log()
  TABLE_LIST *get_mysql_log()
sql/log.h:
  WL#3015: Logging Improvements - No Restarts
  added methods to LOGGER class
  void deactivate_log_handlers(THD* thd, uint log_type);
  bool activate_log_handlers(THD* thd, uint log_type);
  added methods to Log_to_file_event_handler:
  TABLE_LIST *get_mysql_slow_log()
  TABLE_LIST *get_mysql_log()
sql/mysql_priv.h:
  WL#3015: Logging Improvements - No Restarts
sql/mysqld.cc:
  WL#3015: Logging Improvements - No Restarts
  added 'slow-query-log' & 'general-log' options
sql/set_var.cc:
  WL#3015: Logging Improvements - No Restarts
  added 'slow_query_log' & 'general_log' updatable variables
  added 'log_output', 'general_log_file', 'slow_query_log_file' updatable variables
sql/set_var.h:
  WL#3015: Logging Improvements - No Restarts
  new class sys_var_log_state
  new class sys_var_log_output
sql/share/errmsg.txt:
  WL#3015: Logging Improvements - No Restarts
  added error message
sql/sql_delete.cc:
  WL#3015: Logging Improvements - No Restarts
  'truncate table slow_log|general', keep status of logs
parent 07703f17
Loading
Loading
Loading
Loading
+155 −0
Original line number Diff line number Diff line
set global general_log= OFF;
truncate table mysql.general_log;
truncate table mysql.slow_log;
show global variables
where Variable_name = 'log' or Variable_name = 'log_slow_queries' or
Variable_name = 'general_log' or Variable_name = 'slow_query_log';
Variable_name	Value
general_log	OFF
log	OFF
log_slow_queries	OFF
slow_query_log	OFF
flush logs;
set global general_log= ON;
create table t1(f1 int);
select * from mysql.general_log;
event_time	user_host	thread_id	server_id	command_type	argument
TIMESTAMP	root[root] @ localhost []	#	1	Query	create table t1(f1 int)
TIMESTAMP	root[root] @ localhost []	#	1	Query	select * from mysql.general_log
set global general_log= OFF;
drop table t1;
select * from mysql.general_log;
event_time	user_host	thread_id	server_id	command_type	argument
TIMESTAMP	root[root] @ localhost []	#	1	Query	create table t1(f1 int)
TIMESTAMP	root[root] @ localhost []	#	1	Query	select * from mysql.general_log
TIMESTAMP	root[root] @ localhost []	#	1	Query	set global general_log= OFF
set global general_log= ON;
flush logs;
show global variables
where Variable_name = 'log' or Variable_name = 'log_slow_queries' or
Variable_name = 'general_log' or Variable_name = 'slow_query_log';
Variable_name	Value
general_log	ON
log	ON
log_slow_queries	OFF
slow_query_log	OFF
set session long_query_time=1;
select sleep(2);
sleep(2)
0
select * from mysql.slow_log;
start_time	user_host	query_time	lock_time	rows_sent	rows_examined	db	last_insert_id	insert_id	server_id	sql_text
set global slow_query_log= ON;
set session long_query_time=1;
select sleep(2);
sleep(2)
0
select * from mysql.slow_log;
start_time	user_host	query_time	lock_time	rows_sent	rows_examined	db	last_insert_id	insert_id	server_id	sql_text
TIMESTAMP,	root[root] @ localhost []	USER_HOST,	QUERY_TIME	1	0	test	0	0	1	select sleep(2)
show global variables
where Variable_name = 'log' or Variable_name = 'log_slow_queries' or
Variable_name = 'general_log' or Variable_name = 'slow_query_log';
Variable_name	Value
general_log	ON
log	ON
log_slow_queries	ON
slow_query_log	ON
set global general_log= ON;
set global general_log= OFF;
set global general_log= OFF;
set global slow_query_log= ON;
set global slow_query_log= OFF;
set global slow_query_log= OFF;
set global general_log= ON;
truncate table mysql.general_log;
create table t1(f1 int);
drop table t1;
select * from mysql.general_log;
event_time	user_host	thread_id	server_id	command_type	argument
TIMESTAMP	root[root] @ localhost []	#	1	Query	create table t1(f1 int)
TIMESTAMP	root[root] @ localhost []	#	1	Query	drop table t1
TIMESTAMP	root[root] @ localhost []	#	1	Query	select * from mysql.general_log
set global general_log= OFF;
truncate table mysql.general_log;
select * from mysql.general_log;
event_time	user_host	thread_id	server_id	command_type	argument
set global general_log= ON;
show global variables
where Variable_name = 'log' or Variable_name = 'log_slow_queries' or
Variable_name = 'general_log' or Variable_name = 'slow_query_log';
Variable_name	Value
general_log	ON
log	ON
log_slow_queries	OFF
slow_query_log	OFF
show variables like 'general_log_file';
Variable_name	Value
general_log_file	#
show variables like 'slow_query_log_file';
Variable_name	Value
slow_query_log_file	#
show variables like 'log_output';
Variable_name	Value
log_output	FILE,TABLE
set global general_log_file='/not exiting path/log.master';
ERROR 42000: Variable 'general_log_file' can't be set to the value of '/not exiting path/log.master'
set global general_log_file='/tmp';
ERROR 42000: Variable 'general_log_file' can't be set to the value of '/tmp'
set global general_log_file='';
ERROR 42000: Variable 'general_log_file' can't be set to the value of ''
show variables like 'general_log_file';
Variable_name	Value
general_log_file	#
set global general_log= OFF;
set global general_log_file='/tmp/log.master';
set global general_log= ON;
create table t1(f1 int);
drop table t1;
set global general_log= OFF;
set global general_log_file=default;
set global general_log= ON;
create table t1(f1 int);
drop table t1;
show variables like 'general_log_file';
Variable_name	Value
general_log_file	#
show variables like 'slow_query_log_file';
Variable_name	Value
slow_query_log_file	#
set global general_log= default;
set global slow_query_log= default;
set global general_log_file= default;
set global slow_query_log_file= default;
show variables like 'general_log';
Variable_name	Value
general_log	OFF
show variables like 'slow_query_log';
Variable_name	Value
slow_query_log	OFF
set global general_log=ON;
set global log_output=default;
show variables like 'log_output';
Variable_name	Value
log_output	TABLE
set global general_log=OFF;
set global log_output=FILE;
truncate table mysql.general_log;
show variables like 'log_output';
Variable_name	Value
log_output	FILE
set global general_log=ON;
create table t1(f1 int);
select * from mysql.general_log;
event_time	user_host	thread_id	server_id	command_type	argument
set global general_log=OFF;
set global log_output="FILE,TABLE";
show variables like 'log_output';
Variable_name	Value
log_output	FILE,TABLE
set global general_log=ON;
drop table t1;
select * from mysql.general_log;
event_time	user_host	thread_id	server_id	command_type	argument
TIMESTAMP	root[root] @ localhost []	#	1	Query	drop table t1
TIMESTAMP	root[root] @ localhost []	#	1	Query	select * from mysql.general_log
+7 −13
Original line number Diff line number Diff line
@@ -148,14 +148,12 @@ flush tables;
show open tables;
Database	Table	In_use	Name_locked
mysql	general_log	1	0
mysql	slow_log	1	0
create table t1(n int);
insert into t1 values (1);
show open tables;
Database	Table	In_use	Name_locked
mysql	general_log	1	0
mysql	slow_log	1	0
test	t1	0	0
mysql	general_log	1	0
drop table t1;
create table t1 (a int not null, b VARCHAR(10), INDEX (b) ) AVG_ROW_LENGTH=10 CHECKSUM=1 COMMENT="test" ENGINE=MYISAM MIN_ROWS=10 MAX_ROWS=100 PACK_KEYS=1 DELAY_KEY_WRITE=1 ROW_FORMAT=fixed;
show create table t1;
@@ -568,23 +566,21 @@ SELECT 1 FROM mysql.db, mysql.proc, mysql.user, mysql.time_zone, mysql.time_zone
1
SHOW OPEN TABLES;
Database	Table	In_use	Name_locked
mysql	proc	0	0
mysql	db	0	0
test	urkunde	0	0
mysql	time_zone	0	0
mysql	db	0	0
mysql	general_log	1	0
test	txt1	0	0
mysql	slow_log	1	0
mysql	proc	0	0
test	tyt2	0	0
mysql	general_log	1	0
mysql	user	0	0
mysql	time_zone_name	0	0
SHOW OPEN TABLES FROM mysql;
Database	Table	In_use	Name_locked
mysql	proc	0	0
mysql	time_zone	0	0
mysql	db	0	0
mysql	slow_log	1	0
mysql	time_zone	0	0
mysql	general_log	1	0
mysql	proc	0	0
mysql	user	0	0
mysql	time_zone_name	0	0
SHOW OPEN TABLES FROM mysql LIKE 'u%';
@@ -598,16 +594,14 @@ test tyt2 0 0
mysql	time_zone_name	0	0
SHOW OPEN TABLES LIKE '%o%';
Database	Table	In_use	Name_locked
mysql	proc	0	0
mysql	time_zone	0	0
mysql	slow_log	1	0
mysql	general_log	1	0
mysql	proc	0	0
mysql	time_zone_name	0	0
FLUSH TABLES;
SHOW OPEN TABLES;
Database	Table	In_use	Name_locked
mysql	general_log	1	0
mysql	slow_log	1	0
DROP TABLE txt1;
DROP TABLE tyt2;
DROP TABLE urkunde;
+1 −0
Original line number Diff line number Diff line
--log-output=TABLE,FILE --log --general-log=0 --log-slow-queries --slow-query-log=0
+122 −0
Original line number Diff line number Diff line
-- source include/not_embedded.inc
--source include/have_csv.inc

--disable_ps_protocol
set global general_log= OFF;
truncate table mysql.general_log;
truncate table mysql.slow_log;
show global variables
where Variable_name = 'log' or Variable_name = 'log_slow_queries' or
Variable_name = 'general_log' or Variable_name = 'slow_query_log';
flush logs;
set global general_log= ON;
create table t1(f1 int);
--replace_column 1 TIMESTAMP 3 #
select * from mysql.general_log;
set global general_log= OFF;
drop table t1;
--replace_column 1 TIMESTAMP 3 #
select * from mysql.general_log;
set global general_log= ON;
flush logs;
show global variables
where Variable_name = 'log' or Variable_name = 'log_slow_queries' or
Variable_name = 'general_log' or Variable_name = 'slow_query_log';

connect (con1,localhost,root,,);
connection con1;
set session long_query_time=1;
select sleep(2);
--replace_column 1 TIMESTAMP, 3 USER_HOST, 4 QUERY_TIME
select * from mysql.slow_log;
connection default;

set global slow_query_log= ON;
connection con1;
set session long_query_time=1;
select sleep(2);
--replace_column 1 TIMESTAMP, 3 USER_HOST, 4 QUERY_TIME
select * from mysql.slow_log;
disconnect con1;
connection default;
show global variables
where Variable_name = 'log' or Variable_name = 'log_slow_queries' or
Variable_name = 'general_log' or Variable_name = 'slow_query_log';

set global general_log= ON;
set global general_log= OFF;
set global general_log= OFF;
set global slow_query_log= ON;
set global slow_query_log= OFF;
set global slow_query_log= OFF;

set global general_log= ON;
truncate table mysql.general_log;
create table t1(f1 int);
drop table t1;
--replace_column 1 TIMESTAMP 3 #
select * from mysql.general_log;
set global general_log= OFF;
truncate table mysql.general_log;
--replace_column 1 TIMESTAMP 3 #
select * from mysql.general_log;
set global general_log= ON;
show global variables
where Variable_name = 'log' or Variable_name = 'log_slow_queries' or
Variable_name = 'general_log' or Variable_name = 'slow_query_log';

--replace_column 2 #
show variables like 'general_log_file';
--replace_column 2 #
show variables like 'slow_query_log_file';
show variables like 'log_output';

--error 1231
set global general_log_file='/not exiting path/log.master';
--error 1231
set global general_log_file='/tmp';
--error 1231
set global general_log_file='';
--replace_column 2 #
show variables like 'general_log_file';
set global general_log= OFF;
set global general_log_file='/tmp/log.master';
set global general_log= ON;
create table t1(f1 int);
drop table t1;
set global general_log= OFF;
set global general_log_file=default;
set global general_log= ON;
create table t1(f1 int);
drop table t1;
--replace_column 2 #
show variables like 'general_log_file';
--replace_column 2 #
show variables like 'slow_query_log_file';

set global general_log= default;
set global slow_query_log= default;
set global general_log_file= default;
set global slow_query_log_file= default;
show variables like 'general_log';
show variables like 'slow_query_log';
set global general_log=ON;
set global log_output=default;
show variables like 'log_output';
set global general_log=OFF;
set global log_output=FILE;
truncate table mysql.general_log;
show variables like 'log_output';
set global general_log=ON;
create table t1(f1 int);
--replace_column 1 TIMESTAMP 3 #
select * from mysql.general_log;
set global general_log=OFF;
set global log_output="FILE,TABLE";
show variables like 'log_output';
set global general_log=ON;
drop table t1;
--replace_column 1 TIMESTAMP 3 #
select * from mysql.general_log;

--enable_ps_protocol
+157 −36
Original line number Diff line number Diff line
@@ -37,9 +37,6 @@
#define MAX_USER_HOST_SIZE 512
#define MAX_TIME_SIZE 32

/* we need this for log files intialization */
extern char *opt_logname, *opt_slow_logname;

LOGGER logger;

MYSQL_LOG mysql_bin_log;
@@ -63,6 +60,13 @@ sql_print_message_func sql_print_message_handlers[3] =
};


char *make_default_log_name(char *buff,const char* log_ext)
{
  strmake(buff, glob_hostname, FN_REFLEN-5);
  return fn_format(buff, buff, mysql_data_home, log_ext,
                   MYF(MY_UNPACK_FILENAME|MY_APPEND_EXT));
}

/*
  This is a POD. Please keep it that way!

@@ -250,7 +254,9 @@ bool Log_to_csv_event_handler::reopen_log_table(uint log_type)

void Log_to_csv_event_handler::cleanup()
{
  if (opt_log)
    close_log_table(QUERY_LOG_GENERAL, FALSE);
  if (opt_slow_log)
    close_log_table(QUERY_LOG_SLOW, FALSE);
  logger.is_log_tables_initialized= FALSE;
}
@@ -505,10 +511,10 @@ bool Log_to_file_event_handler::init()
  if (!is_initialized)
  {
    if (opt_slow_log)
      mysql_slow_log.open_slow_log(opt_slow_logname);
      mysql_slow_log.open_slow_log(sys_var_slow_log_path.value);

    if (opt_log)
      mysql_log.open_query_log(opt_logname);
      mysql_log.open_query_log(sys_var_general_log_path.value);

    is_initialized= TRUE;
  }
@@ -526,7 +532,9 @@ void Log_to_file_event_handler::cleanup()
void Log_to_file_event_handler::flush()
{
  /* reopen log files */
  if (opt_log)
    mysql_log.new_file(1);
  if (opt_slow_log)
    mysql_slow_log.new_file(1);
}

@@ -647,10 +655,7 @@ bool LOGGER::flush_logs(THD *thd)
  close_general_log.db= (char*) "mysql";
  close_general_log.db_length= 5;

  /* reopen log files */
  file_log_handler->flush();

  /* flush tables, in the case they are enabled */
  /* lock tables, in the case they are enabled */
  if (logger.is_log_tables_initialized)
  {
    /*
@@ -663,10 +668,13 @@ bool LOGGER::flush_logs(THD *thd)
      Here we use one of the logger handler THD's. Simply because it
      seems appropriate.
    */
    if (opt_slow_log)
      lock_and_wait_for_table_name(table_log_handler->general_log_thd,
				   &close_slow_log);
    if (opt_log)
      lock_and_wait_for_table_name(table_log_handler->general_log_thd,
				   &close_general_log);
  }

  /*
    Deny others from logging to general and slow log,
@@ -674,12 +682,15 @@ bool LOGGER::flush_logs(THD *thd)
  */
  logger.lock();

  /* reopen log files */
  file_log_handler->flush();

  /* flush tables, in the case they are enabled */
  if (logger.is_log_tables_initialized)
    table_log_handler->flush(table_log_handler->general_log_thd,
                             &close_slow_log, &close_general_log);

    /* end of log tables flush */
  /* end of log flush */
  logger.unlock();
  }
  return FALSE;
}

@@ -727,6 +738,11 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length,
      return 0;

    lock();
    if (!opt_slow_log)
    {
      unlock();
      return 0;
    }

    /* fill in user_host value: the format is "%s[%s] @ %s [%s]" */
    user_host_len= strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
@@ -801,6 +817,11 @@ bool LOGGER::general_log_print(THD *thd, enum enum_server_command command,
      id=0;                                     /* Log from connect handler */

    lock();
    if (!opt_log)
    {
      unlock();
      return 0;
    }
    time_t current_time= time(NULL);

    user_host_len= strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
@@ -904,26 +925,126 @@ void LOGGER::init_general_log(uint general_log_printer)
}


bool LOGGER::activate_log_handler(THD* thd, uint log_type)
{
  bool res= 0;
  lock();
  switch (log_type) {
  case QUERY_LOG_SLOW:
    if (!opt_slow_log)
    {
      if ((res= reopen_log_table(log_type)))
        goto err;
      file_log_handler->get_mysql_slow_log()->
        open_query_log(sys_var_slow_log_path.value);
      init_slow_log(log_output_options);
      opt_slow_log= TRUE;
    }
    break;
  case QUERY_LOG_GENERAL:
    if (!opt_log)
    {
      if ((res= reopen_log_table(log_type)))
        goto err;
      file_log_handler->get_mysql_log()->
        open_query_log(sys_var_general_log_path.value);
      init_general_log(log_output_options);
      opt_log= TRUE;
    }
    break;
  default:
    DBUG_ASSERT(0);
  }
err:
  unlock();
  return res;
}


void LOGGER::deactivate_log_handler(THD *thd, uint log_type)
{
  TABLE_LIST *table_list;
  my_bool *tmp_opt= 0;
  MYSQL_LOG *file_log;
  THD *log_thd;

  switch (log_type) {
  case QUERY_LOG_SLOW:
    table_list= &table_log_handler->slow_log;
    tmp_opt= &opt_slow_log;
    file_log= file_log_handler->get_mysql_slow_log();
    log_thd= table_log_handler->slow_log_thd;
    break;
  case QUERY_LOG_GENERAL:
    table_list= &table_log_handler->general_log;
    tmp_opt= &opt_log;
    file_log= file_log_handler->get_mysql_log();
    log_thd= table_log_handler->general_log_thd;
    break;
  default:
    DBUG_ASSERT(0);
  }

  if (!(*tmp_opt))
    return;

  if (is_log_tables_initialized)
    lock_and_wait_for_table_name(log_thd, table_list);
  lock();

  if (is_log_tables_initialized)
  {
    VOID(pthread_mutex_lock(&LOCK_open));
    close_log_table(log_type, TRUE);
    table_list->table= 0;
    query_cache_invalidate3(log_thd, table_list, 0);
    unlock_table_name(log_thd, table_list);
    VOID(pthread_mutex_unlock(&LOCK_open));
  }
  file_log->close(0);
  *tmp_opt= FALSE;
  unlock();
}


bool Log_to_csv_event_handler::flush(THD *thd, TABLE_LIST *close_slow_log,
                                     TABLE_LIST *close_general_log)
{
  VOID(pthread_mutex_lock(&LOCK_open));
  if (opt_log)
  {
    close_log_table(QUERY_LOG_GENERAL, TRUE);
  close_log_table(QUERY_LOG_SLOW, TRUE);
  close_general_log->next_local= close_slow_log;
    query_cache_invalidate3(thd, close_general_log, 0);
  unlock_table_name(thd, close_slow_log);
    unlock_table_name(thd, close_general_log);
  }
  if (opt_slow_log)
  {
    close_log_table(QUERY_LOG_SLOW, TRUE);
    query_cache_invalidate3(thd, close_slow_log, 0);
    unlock_table_name(thd, close_slow_log);
  }
  VOID(pthread_mutex_unlock(&LOCK_open));
  return reopen_log_table(QUERY_LOG_SLOW) ||
         reopen_log_table(QUERY_LOG_GENERAL);
  /*
    we use | and not || here, to ensure that both reopen_log_table
    are called, even if the first one fails
  */
  if ((opt_slow_log && reopen_log_table(QUERY_LOG_SLOW)) |
      (opt_log && reopen_log_table(QUERY_LOG_GENERAL)))
    return 1;
  return 0;
}

/* the parameters are unused for the log tables */
bool Log_to_csv_event_handler::init()
{
  /* we always open log tables. even if the logging is disabled */
  return (open_log_table(QUERY_LOG_GENERAL) || open_log_table(QUERY_LOG_SLOW));
  /*
    we use | and not || here, to ensure that both open_log_table
    are called, even if the first one fails
  */
  if ((opt_log && open_log_table(QUERY_LOG_GENERAL)) |
      (opt_slow_log && open_log_table(QUERY_LOG_SLOW)))
    return 1;
  return 0;
}

int LOGGER::set_handlers(uint error_log_printer,
Loading