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.
parent acaede97
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
......@@ -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;
......
--log-output=TABLE,FILE --log --general-log=0 --log-slow-queries --slow-query-log=0
-- 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
......@@ -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,8 +254,10 @@ bool Log_to_csv_event_handler::reopen_log_table(uint log_type)
void Log_to_csv_event_handler::cleanup()
{
close_log_table(QUERY_LOG_GENERAL, FALSE);
close_log_table(QUERY_LOG_SLOW, FALSE);
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,8 +532,10 @@ void Log_to_file_event_handler::cleanup()
void Log_to_file_event_handler::flush()
{
/* reopen log files */
mysql_log.new_file(1);
mysql_slow_log.new_file(1);
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,23 +668,29 @@ bool LOGGER::flush_logs(THD *thd)
Here we use one of the logger handler THD's. Simply because it
seems appropriate.
*/
lock_and_wait_for_table_name(table_log_handler->general_log_thd,
&close_slow_log);
lock_and_wait_for_table_name(table_log_handler->general_log_thd,
&close_general_log);
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,
while reopening tables.
*/
logger.lock();
/*
Deny others from logging to general and slow log,
while reopening tables.
*/
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 */
logger.unlock();
}
/* 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));
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_log)
{
close_log_table(QUERY_LOG_GENERAL, TRUE);
query_cache_invalidate3(thd, close_general_log, 0);
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,
......
......@@ -438,6 +438,8 @@ public:
CHARSET_INFO *client_cs);
void flush();
void init_pthread_objects();
MYSQL_LOG *get_mysql_slow_log() { return &mysql_slow_log; }
MYSQL_LOG *get_mysql_log() { return &mysql_log; }
};
......@@ -510,8 +512,21 @@ public:
void init_error_log(uint error_log_printer);
void init_slow_log(uint slow_log_printer);
void init_general_log(uint general_log_printer);
};
void deactivate_log_handler(THD* thd, uint log_type);
bool activate_log_handler(THD* thd, uint log_type);
MYSQL_LOG *get_slow_log_file_handler()
{
if (file_log_handler)
return file_log_handler->get_mysql_slow_log();
return NULL;
}
MYSQL_LOG *get_log_file_handler()
{
if (file_log_handler)
return file_log_handler->get_mysql_log();
return NULL;
}
};
enum enum_binlog_format {
BINLOG_FORMAT_STMT= 0, // statement-based
......
......@@ -1167,6 +1167,7 @@ bool rename_temporary_table(THD* thd, TABLE *table, const char *new_db,
void remove_db_from_cache(const char *db);
void flush_tables();
bool is_equal(const LEX_STRING *a, const LEX_STRING *b);
char *make_default_log_name(char *buff,const char* log_ext);
#ifdef WITH_PARTITION_STORAGE_ENGINE
uint fast_alter_partition_table(THD *thd, TABLE *table,
......@@ -1514,7 +1515,9 @@ extern bool opt_endinfo, using_udf_functions;
extern my_bool locked_in_memory;
extern bool opt_using_transactions, mysqld_embedded;
extern bool using_update_log, opt_large_files, server_id_supplied;
extern bool opt_log, opt_update_log, opt_bin_log, opt_slow_log, opt_error_log;
extern bool opt_update_log, opt_bin_log, opt_error_log;
extern my_bool opt_log, opt_slow_log;
extern uint log_output_options;
extern my_bool opt_log_queries_not_using_indexes;
extern bool opt_disable_networking, opt_skip_show_db;
extern my_bool opt_character_set_client_handshake;
......@@ -1536,6 +1539,8 @@ extern my_bool opt_enable_shared_memory;
extern char *default_tz_name;
extern my_bool opt_large_pages;
extern uint opt_large_page_size;
extern char *opt_logname, *opt_slow_logname;
extern const char *log_output_str;
extern MYSQL_LOG mysql_bin_log;
extern LOGGER logger;
......@@ -1582,6 +1587,7 @@ extern TABLE *unused_tables;
extern const char* any_db;
extern struct my_option my_long_options[];
extern const LEX_STRING view_type;
extern TYPELIB log_output_typelib;
/* optional things, have_* variables */
......
......@@ -302,16 +302,15 @@ arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
{&Arg_comparator::compare_row, &Arg_comparator::compare_e_row},
{&Arg_comparator::compare_decimal, &Arg_comparator::compare_e_decimal}};
const char *log_output_names[] =
{ "NONE", "FILE", "TABLE", NullS};
const char *log_output_names[] = { "NONE", "FILE", "TABLE", NullS};
static const unsigned int log_output_names_len[]= { 4, 4, 5, 0 };
TYPELIB log_output_typelib= {array_elements(log_output_names)-1,"",
log_output_names, NULL};
log_output_names,
(unsigned int *) log_output_names_len};
/* static variables */
/* the default log output is log tables */
static const char *log_output_str= "TABLE";
static ulong log_output_options= LOG_TABLE;
static bool lower_case_table_names_used= 0;
static bool volatile select_thread_in_use, signal_thread_in_use;
static bool volatile ready_to_exit;
......@@ -342,7 +341,9 @@ static my_bool opt_sync_bdb_logs;
/* Global variables */
bool opt_log, opt_update_log, opt_bin_log, opt_slow_log;
bool opt_update_log, opt_bin_log;
my_bool opt_log, opt_slow_log;
uint log_output_options;
my_bool opt_log_queries_not_using_indexes= 0;
bool opt_error_log= IF_WIN(1,0);
bool opt_disable_networking=0, opt_skip_show_db=0;
......@@ -520,6 +521,7 @@ ulong thread_id=1L,current_pid;
ulong slow_launch_threads = 0, sync_binlog_period;
ulong expire_logs_days = 0;
ulong rpl_recovery_rank=0;
const char *log_output_str= "TABLE";
double log_10[32]; /* 10 potences */
time_t start_time;
......@@ -1229,6 +1231,8 @@ void clean_up(bool print_message)
free_defaults(defaults_argv);
my_free(sys_init_connect.value, MYF(MY_ALLOW_ZERO_PTR));
my_free(sys_init_slave.value, MYF(MY_ALLOW_ZERO_PTR));
my_free(sys_var_general_log_path.value, MYF(MY_ALLOW_ZERO_PTR));
my_free(sys_var_slow_log_path.value, MYF(MY_ALLOW_ZERO_PTR));
free_tmpdir(&mysql_tmpdir_list);
#ifdef HAVE_REPLICATION
my_free(slave_load_tmpdir,MYF(MY_ALLOW_ZERO_PTR));
......@@ -2607,6 +2611,7 @@ static bool init_global_datetime_format(timestamp_type format_type,
static int init_common_variables(const char *conf_file_name, int argc,
char **argv, const char **groups)
{
char buff[FN_REFLEN];
umask(((~my_umask) & 0666));
my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
tzset(); // Set tzname
......@@ -2763,6 +2768,16 @@ static int init_common_variables(const char *conf_file_name, int argc,
else
sys_init_slave.value=my_strdup("",MYF(0));
if (!opt_logname)
opt_logname= make_default_log_name(buff, ".log");
sys_var_general_log_path.value= my_strdup(opt_logname, MYF(0));
sys_var_general_log_path.value_length= strlen(opt_logname);
if (!opt_slow_logname)
opt_slow_logname= make_default_log_name(buff, "-slow.log");
sys_var_slow_log_path.value= my_strdup(opt_slow_logname, MYF(0));
sys_var_slow_log_path.value_length= strlen(opt_slow_logname);
if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1))
return 1;
if (my_database_names_init())
......@@ -4815,7 +4830,9 @@ enum options_mysqld
OPT_TABLE_LOCK_WAIT_TIMEOUT,
OPT_PLUGIN_DIR,
OPT_LOG_OUTPUT,
OPT_PORT_OPEN_TIMEOUT
OPT_PORT_OPEN_TIMEOUT,
OPT_GENERAL_LOG,
OPT_SLOW_LOG
};
......@@ -5044,6 +5061,9 @@ Disable with --skip-bdb (will save memory).",
"Set up signals usable for debugging",
(gptr*) &opt_debugging, (gptr*) &opt_debugging,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"general-log", OPT_GENERAL_LOG,
"Enable|disable general log", (gptr*) &opt_log,
(gptr*) &opt_log, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_LARGE_PAGES
{"large-pages", OPT_ENABLE_LARGE_PAGES, "Enable support for large pages. \
Disable with --skip-large-pages.",
......@@ -5613,6 +5633,9 @@ replicating a LOAD DATA INFILE command.",
"Tells the slave thread to continue replication when a query returns an error from the provided list.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"slow-query-log", OPT_SLOW_LOG,
"Enable|disable slow query log", (gptr*) &opt_slow_log,
(gptr*) &opt_slow_log, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"socket", OPT_SOCKET, "Socket file to use for connection.",
(gptr*) &mysqld_unix_port, (gptr*) &mysqld_unix_port, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
......@@ -6922,6 +6945,7 @@ static void mysql_init_variables(void)
opt_skip_slave_start= opt_reckless_slave = 0;
mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0;
opt_log= opt_update_log= opt_slow_log= 0;
log_output_options= find_bit_type(log_output_str, &log_output_typelib);
opt_bin_log= 0;
opt_disable_networking= opt_skip_show_db=0;
opt_logname= opt_update_logname= opt_binlog_index_name= opt_slow_logname= 0;
......
......@@ -55,6 +55,7 @@
#include <my_getopt.h>
#include <thr_alarm.h>
#include <myisam.h>
#include <my_dir.h>
#include "event_scheduler.h"
......@@ -164,6 +165,11 @@ static byte *get_error_count(THD *thd);
static byte *get_warning_count(THD *thd);
static byte *get_prepared_stmt_count(THD *thd);
static byte *get_tmpdir(THD *thd);
static int sys_check_log_path(THD *thd, set_var *var);
static bool sys_update_general_log_path(THD *thd, set_var * var);
static void sys_default_general_log_path(THD *thd, enum_var_type type);
static bool sys_update_slow_log_path(THD *thd, set_var * var);
static void sys_default_slow_log_path(THD *thd, enum_var_type type);
/*
Variable definition list
......@@ -679,6 +685,22 @@ sys_var_have_variable sys_have_row_based_replication("have_row_based_replication
/* Global read-only variable describing server license */
sys_var_const_str sys_license("license", STRINGIFY_ARG(LICENSE));
/* Global variables which enable|disable logging */
sys_var_log_state sys_var_general_log("general_log", &opt_log,
QUERY_LOG_GENERAL);
sys_var_log_state sys_var_slow_query_log("slow_query_log", &opt_slow_log,
QUERY_LOG_SLOW);
sys_var_str sys_var_general_log_path("general_log_file", sys_check_log_path,
sys_update_general_log_path,
sys_default_general_log_path,
opt_logname);
sys_var_str sys_var_slow_log_path("slow_query_log_file", sys_check_log_path,
sys_update_slow_log_path,
sys_default_slow_log_path,
opt_slow_logname);
sys_var_log_output sys_var_log_output_state("log_output", &log_output_options,
&log_output_typelib, 0);
#ifdef HAVE_REPLICATION
static int show_slave_skip_errors(THD *thd, SHOW_VAR *var, char *buff)
{
......@@ -777,6 +799,8 @@ SHOW_VAR init_vars[]= {
{"ft_min_word_len", (char*) &ft_min_word_len, SHOW_LONG},
{"ft_query_expansion_limit",(char*) &ft_query_expansion_limit, SHOW_LONG},
{"ft_stopword_file", (char*) &ft_stopword_file, SHOW_CHAR_PTR},
{sys_var_general_log.name, (char*) &opt_log, SHOW_MY_BOOL},
{sys_var_general_log_path.name, (char*) &sys_var_general_log_path, SHOW_SYS},
{sys_group_concat_max_len.name, (char*) &sys_group_concat_max_len, SHOW_SYS},
{sys_have_archive_db.name, (char*) &have_archive_db, SHOW_HAVE},
{sys_have_berkeley_db.name, (char*) &have_berkeley_db, SHOW_HAVE},
......@@ -854,6 +878,7 @@ SHOW_VAR init_vars[]= {
{"log_bin", (char*) &opt_bin_log, SHOW_BOOL},
{sys_trust_function_creators.name,(char*) &sys_trust_function_creators, SHOW_SYS},
{"log_error", (char*) log_error_file, SHOW_CHAR},
{sys_var_log_output_state.name, (char*) &sys_var_log_output_state, SHOW_SYS},
{sys_log_queries_not_using_indexes.name,
(char*) &sys_log_queries_not_using_indexes, SHOW_SYS},
#ifdef HAVE_REPLICATION
......@@ -977,6 +1002,8 @@ SHOW_VAR init_vars[]= {
{sys_slave_trans_retries.name,(char*) &sys_slave_trans_retries, SHOW_SYS},
#endif
{sys_slow_launch_time.name, (char*) &sys_slow_launch_time, SHOW_SYS},
{sys_var_slow_query_log.name, (char*) &opt_slow_log, SHOW_MY_BOOL},
{sys_var_slow_log_path.name, (char*) &sys_var_slow_log_path, SHOW_SYS},
#ifdef HAVE_SYS_UN_H
{"socket", (char*) &mysqld_unix_port, SHOW_CHAR_PTR},
#endif
......@@ -2509,6 +2536,195 @@ end:
}
bool sys_var_log_state::update(THD *thd, set_var *var)
{
bool res= 0;
pthread_mutex_lock(&LOCK_global_system_variables);
if (!var->save_result.ulong_value)
logger.deactivate_log_handler(thd, log_type);
else
{
if ((res= logger.activate_log_handler(thd, log_type)))
{
my_error(ER_CANT_ACTIVATE_LOG, MYF(0),
log_type == QUERY_LOG_GENERAL ? "general" :
"slow query");
goto err;
}
}
err:
pthread_mutex_unlock(&LOCK_global_system_variables);
return res;
}
void sys_var_log_state::set_default(THD *thd, enum_var_type type)
{
pthread_mutex_lock(&LOCK_global_system_variables);
logger.deactivate_log_handler(thd, log_type);
pthread_mutex_unlock(&LOCK_global_system_variables);
}
static int sys_check_log_path(THD *thd, set_var *var)
{
char path[FN_REFLEN];
MY_STAT f_stat;
const char *var_path= var->value->str_value.ptr();
bzero(&f_stat, sizeof(MY_STAT));
(void) unpack_filename(path, var_path);
if (my_stat(path, &f_stat, MYF(0)))
{
/* Check if argument is a file and we have 'write' permission */
if (!MY_S_ISREG(f_stat.st_mode) ||
!(f_stat.st_mode & MY_S_IWRITE))
return -1;
}
else
{
/*
Check if directory exists and
we have permission to create file & write to file
*/
(void) dirname_part(path, var_path);
if (my_access(path, (F_OK|W_OK)))
return -1;
}
return 0;
}
bool update_sys_var_str_path(THD *thd, sys_var_str *var_str,
set_var *var, const char *log_ext,
bool log_state, uint log_type)
{
MYSQL_LOG *file_log;
char buff[FN_REFLEN];
char *res= 0, *old_value=(char *)(var ? var->value->str_value.ptr() : 0);
bool result= 0;
uint str_length= (var ? var->value->str_value.length() : 0);
switch (log_type) {
case QUERY_LOG_SLOW:
file_log= logger.get_slow_log_file_handler();
break;
case QUERY_LOG_GENERAL:
file_log= logger.get_log_file_handler();
break;
default:
DBUG_ASSERT(0);
}
if (!old_value)
{
old_value= make_default_log_name(buff, log_ext);
str_length= strlen(old_value);
}
if (!(res= my_strndup((byte*)old_value, str_length, MYF(MY_FAE+MY_WME))))
{
result= 1;
goto err;
}
pthread_mutex_lock(&LOCK_global_system_variables);
logger.lock();
if (file_log && log_state)
file_log->close(0);
old_value= var_str->value;
var_str->value= res;
var_str->value_length= str_length;
my_free(old_value, MYF(MY_ALLOW_ZERO_PTR));
if (file_log && log_state)
file_log->open_query_log(sys_var_general_log_path.value);
logger.unlock();
pthread_mutex_unlock(&LOCK_global_system_variables);
err:
return result;
}
static bool sys_update_general_log_path(THD *thd, set_var * var)
{
return update_sys_var_str_path(thd, &sys_var_general_log_path,
var, ".log", opt_log, QUERY_LOG_GENERAL);
}
static void sys_default_general_log_path(THD *thd, enum_var_type type)
{
(void) update_sys_var_str_path(thd, &sys_var_general_log_path,
0, ".log", opt_log, QUERY_LOG_GENERAL);
}
static bool sys_update_slow_log_path(THD *thd, set_var * var)
{
return update_sys_var_str_path(thd, &sys_var_slow_log_path,
var, "-slow.log", opt_slow_log,
QUERY_LOG_SLOW);
}
static void sys_default_slow_log_path(THD *thd, enum_var_type type)
{
(void) update_sys_var_str_path(thd, &sys_var_slow_log_path,
0, "-slow.log", opt_slow_log,
QUERY_LOG_SLOW);
}
bool sys_var_log_output::update(THD *thd, set_var *var)
{
pthread_mutex_lock(&LOCK_global_system_variables);
logger.lock();
logger.init_slow_log(var->save_result.ulong_value);
logger.init_general_log(var->save_result.ulong_value);
*value= var->save_result.ulong_value;
logger.unlock();
pthread_mutex_unlock(&LOCK_global_system_variables);
return 0;
}
void sys_var_log_output::set_default(THD *thd, enum_var_type type)
{
pthread_mutex_lock(&LOCK_global_system_variables);
logger.lock();
logger.init_slow_log(LOG_TABLE);
logger.init_general_log(LOG_TABLE);
*value= LOG_TABLE;
logger.unlock();
pthread_mutex_unlock(&LOCK_global_system_variables);
}
byte *sys_var_log_output::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
{
char buff[256];
String tmp(buff, sizeof(buff), &my_charset_latin1);
ulong length;
ulong val= *value;
tmp.length(0);
for (uint i= 0; val; val>>= 1, i++)
{
if (val & 1)
{
tmp.append(log_output_typelib.type_names[i],
log_output_typelib.type_lengths[i]);
tmp.append(',');
}
}
if ((length= tmp.length()))
length--;
return (byte*) thd->strmake(tmp.ptr(), length);
}
/*****************************************************************************
Functions to handle SET NAMES and SET CHARACTER SET
*****************************************************************************/
......
......@@ -262,7 +262,7 @@ public:
class sys_var_enum :public sys_var
{
uint *value;
uint *value;
TYPELIB *enum_names;
public:
sys_var_enum(const char *name_arg, uint *value_arg,
......@@ -772,6 +772,38 @@ public:
};
class sys_var_log_state :public sys_var_bool_ptr
{
uint log_type;
public:
sys_var_log_state(const char *name_arg, my_bool *value_arg, uint log_type_arg)
:sys_var_bool_ptr(name_arg, value_arg), log_type(log_type_arg) {}
bool update(THD *thd, set_var *var);
void set_default(THD *thd, enum_var_type type);
};
class sys_var_log_output :public sys_var
{
uint *value;
TYPELIB *enum_names;
public:
sys_var_log_output(const char *name_arg, uint *value_arg,
TYPELIB *typelib, sys_after_update_func func)
:sys_var(name_arg,func), value(value_arg), enum_names(typelib)
{}
bool check(THD *thd, set_var *var)
{
return check_set(thd, var, enum_names);
}
bool update(THD *thd, set_var *var);
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
bool check_update_type(Item_result type) { return 0; }
void set_default(THD *thd, enum_var_type type);
SHOW_TYPE type() { return SHOW_CHAR; }
};
/* Variable that you can only read from */
class sys_var_readonly: public sys_var
......@@ -1068,6 +1100,8 @@ CHARSET_INFO *get_old_charset_by_name(const char *old_name);
gptr find_named(I_List<NAMED_LIST> *list, const char *name, uint length,
NAMED_LIST **found);
extern sys_var_str sys_var_general_log_path, sys_var_slow_log_path;
/* key_cache functions */
KEY_CACHE *get_key_cache(LEX_STRING *cache_name);
KEY_CACHE *get_or_create_key_cache(const char *name, uint length);
......
......@@ -5832,3 +5832,5 @@ ER_EVENT_SET_VAR_ERROR
ER_PARTITION_MERGE_ERROR
eng "MyISAM Merge handler cannot be used in partitioned tables"
swe "MyISAM Merge kan inte anndas i en partitionerad tabell"
ER_CANT_ACTIVATE_LOG
eng "Cannot activate '%-.64s' log."
......@@ -931,7 +931,8 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
/* close log tables in use */
if (!my_strcasecmp(system_charset_info, table_list->db, "mysql"))
{
if (!my_strcasecmp(system_charset_info, table_list->table_name,
if (opt_log &&
!my_strcasecmp(system_charset_info, table_list->table_name,
"general_log"))
{
lock_logger= 1;
......@@ -940,7 +941,8 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
closed_log_tables= closed_log_tables | QUERY_LOG_GENERAL;
}
else
if (!my_strcasecmp(system_charset_info, table_list->table_name,
if (opt_slow_log &&
!my_strcasecmp(system_charset_info, table_list->table_name,
"slow_log"))
{
lock_logger= 1;
......@@ -981,10 +983,10 @@ end:
unlock_table_name(thd, table_list);
VOID(pthread_mutex_unlock(&LOCK_open));
if (closed_log_tables & QUERY_LOG_SLOW)
if (opt_slow_log && (closed_log_tables & QUERY_LOG_SLOW))
logger.reopen_log_table(QUERY_LOG_SLOW);
if (closed_log_tables & QUERY_LOG_GENERAL)
if (opt_log && (closed_log_tables & QUERY_LOG_GENERAL))
logger.reopen_log_table(QUERY_LOG_GENERAL);
if (lock_logger)
logger.unlock();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment