Merge pchardin@bk-internal.mysql.com:/home/bk/mysql-5.1-runtime
into mysql.com:/home/cps/mysql/devel/5.1-rename-bug
This commit is contained in:
commit
eda71e24c3
@ -218,3 +218,71 @@ unlock tables;
|
|||||||
use mysql;
|
use mysql;
|
||||||
lock tables general_log read local, help_category read local;
|
lock tables general_log read local, help_category read local;
|
||||||
unlock tables;
|
unlock tables;
|
||||||
|
use mysql;
|
||||||
|
RENAME TABLE general_log TO renamed_general_log;
|
||||||
|
ERROR HY000: Cannot rename 'general_log'. When logging enabled, rename to/from log table must rename two tables: the log table to an archive table and another table back to 'general_log'
|
||||||
|
RENAME TABLE slow_log TO renamed_slow_log;
|
||||||
|
ERROR HY000: Cannot rename 'slow_log'. When logging enabled, rename to/from log table must rename two tables: the log table to an archive table and another table back to 'slow_log'
|
||||||
|
truncate table general_log;
|
||||||
|
select * from general_log;
|
||||||
|
event_time user_host thread_id server_id command_type argument
|
||||||
|
TIMESTAMP USER_HOST THREAD_ID 1 Query select * from general_log
|
||||||
|
truncate table slow_log;
|
||||||
|
select * from slow_log;
|
||||||
|
start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text
|
||||||
|
create table general_log_new like general_log;
|
||||||
|
rename table general_log TO renamed_general_log, general_log_new TO general_log;
|
||||||
|
create table slow_log_new like slow_log;
|
||||||
|
rename table slow_log TO renamed_slow_log, slow_log_new TO slow_log;
|
||||||
|
rename table general_log TO general_log_new, renamed_general_log TO general_log, slow_log to renamed_slow_log;
|
||||||
|
ERROR HY000: Cannot rename 'slow_log'. When logging enabled, rename to/from log table must rename two tables: the log table to an archive table and another table back to 'slow_log'
|
||||||
|
select * from general_log;
|
||||||
|
event_time user_host thread_id server_id command_type argument
|
||||||
|
TIMESTAMP USER_HOST THREAD_ID 1 Query create table slow_log_new like slow_log
|
||||||
|
TIMESTAMP USER_HOST THREAD_ID 1 Query rename table slow_log TO renamed_slow_log, slow_log_new TO slow_log
|
||||||
|
TIMESTAMP USER_HOST THREAD_ID 1 Query rename table general_log TO general_log_new, renamed_general_log TO general_log, slow_log to renamed_slow_log
|
||||||
|
TIMESTAMP USER_HOST THREAD_ID 1 Query select * from general_log
|
||||||
|
select * from renamed_general_log;
|
||||||
|
event_time user_host thread_id server_id command_type argument
|
||||||
|
TIMESTAMP USER_HOST THREAD_ID 1 Query select * from general_log
|
||||||
|
TIMESTAMP USER_HOST THREAD_ID 1 Query truncate table slow_log
|
||||||
|
TIMESTAMP USER_HOST THREAD_ID 1 Query select * from slow_log
|
||||||
|
TIMESTAMP USER_HOST THREAD_ID 1 Query create table general_log_new like general_log
|
||||||
|
TIMESTAMP USER_HOST THREAD_ID 1 Query rename table general_log TO renamed_general_log, general_log_new TO general_log
|
||||||
|
select * from slow_log;
|
||||||
|
start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text
|
||||||
|
select * from renamed_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 general_log='OFF';
|
||||||
|
RENAME TABLE general_log TO general_log2;
|
||||||
|
set global slow_query_log='OFF';
|
||||||
|
RENAME TABLE slow_log TO slow_log2;
|
||||||
|
set global general_log='ON';
|
||||||
|
ERROR HY000: Cannot activate 'general' log
|
||||||
|
set global slow_query_log='ON';
|
||||||
|
ERROR HY000: Cannot activate 'slow query' log
|
||||||
|
RENAME TABLE general_log2 TO general_log;
|
||||||
|
RENAME TABLE slow_log2 TO slow_log;
|
||||||
|
set global general_log='ON';
|
||||||
|
set global slow_query_log='ON';
|
||||||
|
flush logs;
|
||||||
|
flush logs;
|
||||||
|
drop table renamed_general_log, renamed_slow_log;
|
||||||
|
use test;
|
||||||
|
use mysql;
|
||||||
|
repair table general_log;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
mysql.general_log repair status OK
|
||||||
|
repair table slow_log;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
mysql.slow_log repair status OK
|
||||||
|
create table general_log_new like general_log;
|
||||||
|
create table slow_log_new like slow_log;
|
||||||
|
show tables like "%log%";
|
||||||
|
Tables_in_mysql (%log%)
|
||||||
|
general_log
|
||||||
|
general_log_new
|
||||||
|
slow_log
|
||||||
|
slow_log_new
|
||||||
|
drop table slow_log_new, general_log_new;
|
||||||
|
use test;
|
||||||
|
@ -314,6 +314,89 @@ use mysql;
|
|||||||
lock tables general_log read local, help_category read local;
|
lock tables general_log read local, help_category read local;
|
||||||
unlock tables;
|
unlock tables;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #17544 Cannot do atomic log rotate and
|
||||||
|
# Bug #21785 Server crashes after rename of the log table
|
||||||
|
#
|
||||||
|
|
||||||
|
use mysql;
|
||||||
|
# Should result in error
|
||||||
|
--error ER_CANT_RENAME_LOG_TABLE
|
||||||
|
RENAME TABLE general_log TO renamed_general_log;
|
||||||
|
--error ER_CANT_RENAME_LOG_TABLE
|
||||||
|
RENAME TABLE slow_log TO renamed_slow_log;
|
||||||
|
|
||||||
|
#check rotate logs
|
||||||
|
truncate table general_log;
|
||||||
|
--replace_column 1 TIMESTAMP 2 USER_HOST 3 THREAD_ID
|
||||||
|
select * from general_log;
|
||||||
|
|
||||||
|
truncate table slow_log;
|
||||||
|
--replace_column 1 TIMESTAMP 2 USER_HOST
|
||||||
|
select * from slow_log;
|
||||||
|
|
||||||
|
create table general_log_new like general_log;
|
||||||
|
rename table general_log TO renamed_general_log, general_log_new TO general_log;
|
||||||
|
|
||||||
|
create table slow_log_new like slow_log;
|
||||||
|
rename table slow_log TO renamed_slow_log, slow_log_new TO slow_log;
|
||||||
|
|
||||||
|
# check that rename checks more then first table in the list
|
||||||
|
--error ER_CANT_RENAME_LOG_TABLE
|
||||||
|
rename table general_log TO general_log_new, renamed_general_log TO general_log, slow_log to renamed_slow_log;
|
||||||
|
|
||||||
|
# now check the content of tables
|
||||||
|
--replace_column 1 TIMESTAMP 2 USER_HOST 3 THREAD_ID
|
||||||
|
select * from general_log;
|
||||||
|
--replace_column 1 TIMESTAMP 2 USER_HOST 3 THREAD_ID
|
||||||
|
select * from renamed_general_log;
|
||||||
|
|
||||||
|
# the content of the slow log is empty, but we will try a select anyway
|
||||||
|
--replace_column 1 TIMESTAMP 2 USER_HOST
|
||||||
|
select * from slow_log;
|
||||||
|
--replace_column 1 TIMESTAMP 2 USER_HOST
|
||||||
|
select * from renamed_slow_log;
|
||||||
|
|
||||||
|
# check that we can do whatever we want with disabled log
|
||||||
|
set global general_log='OFF';
|
||||||
|
RENAME TABLE general_log TO general_log2;
|
||||||
|
|
||||||
|
set global slow_query_log='OFF';
|
||||||
|
RENAME TABLE slow_log TO slow_log2;
|
||||||
|
|
||||||
|
# this should fail
|
||||||
|
--error ER_CANT_ACTIVATE_LOG
|
||||||
|
set global general_log='ON';
|
||||||
|
--error ER_CANT_ACTIVATE_LOG
|
||||||
|
set global slow_query_log='ON';
|
||||||
|
|
||||||
|
RENAME TABLE general_log2 TO general_log;
|
||||||
|
RENAME TABLE slow_log2 TO slow_log;
|
||||||
|
|
||||||
|
# this should work
|
||||||
|
set global general_log='ON';
|
||||||
|
set global slow_query_log='ON';
|
||||||
|
# now check flush logs
|
||||||
|
flush logs;
|
||||||
|
flush logs;
|
||||||
|
drop table renamed_general_log, renamed_slow_log;
|
||||||
|
use test;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #21966 Strange warnings on repair of the log tables
|
||||||
|
#
|
||||||
|
|
||||||
|
use mysql;
|
||||||
|
# check that no warning occurs on repair of the log tables
|
||||||
|
repair table general_log;
|
||||||
|
repair table slow_log;
|
||||||
|
# check that no warning occurs on "create like" for the log tables
|
||||||
|
create table general_log_new like general_log;
|
||||||
|
create table slow_log_new like slow_log;
|
||||||
|
show tables like "%log%";
|
||||||
|
drop table slow_log_new, general_log_new;
|
||||||
|
use test;
|
||||||
|
|
||||||
# kill all connections
|
# kill all connections
|
||||||
disconnect con1;
|
disconnect con1;
|
||||||
disconnect con2;
|
disconnect con2;
|
||||||
|
@ -1483,8 +1483,9 @@ bool handler::check_if_log_table_locking_is_allowed(uint sql_command,
|
|||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Deny locking of the log tables, which is incompatible with
|
Deny locking of the log tables, which is incompatible with
|
||||||
concurrent insert. Unless called from a logger THD:
|
concurrent insert. The routine is not called if the table is
|
||||||
general_log_thd or slow_log_thd.
|
being locked from a logger THD (general_log_thd or slow_log_thd)
|
||||||
|
or from a privileged thread (see log.cc for details)
|
||||||
*/
|
*/
|
||||||
if (table->s->log_table &&
|
if (table->s->log_table &&
|
||||||
sql_command != SQLCOM_TRUNCATE &&
|
sql_command != SQLCOM_TRUNCATE &&
|
||||||
|
@ -975,6 +975,10 @@ public:
|
|||||||
thd Handler of the thread, trying to lock the table
|
thd Handler of the thread, trying to lock the table
|
||||||
table Table handler to check
|
table Table handler to check
|
||||||
count Number of locks already granted to the table
|
count Number of locks already granted to the table
|
||||||
|
called_by_privileged_thread TRUE if called from a logger THD
|
||||||
|
(general_log_thd or slow_log_thd)
|
||||||
|
or by a privileged thread, which
|
||||||
|
has the right to lock log tables.
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
Check whether a handler allows to lock the table. For instance,
|
Check whether a handler allows to lock the table. For instance,
|
||||||
@ -990,7 +994,7 @@ public:
|
|||||||
virtual bool check_if_locking_is_allowed(uint sql_command,
|
virtual bool check_if_locking_is_allowed(uint sql_command,
|
||||||
ulong type, TABLE *table,
|
ulong type, TABLE *table,
|
||||||
uint count,
|
uint count,
|
||||||
bool called_by_logger_thread)
|
bool called_by_privileged_thread)
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -691,7 +691,8 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
|
|||||||
check_if_locking_is_allowed(thd->lex->sql_command, thd->lex->type,
|
check_if_locking_is_allowed(thd->lex->sql_command, thd->lex->type,
|
||||||
table_ptr[i], count,
|
table_ptr[i], count,
|
||||||
(thd == logger.get_general_log_thd()) ||
|
(thd == logger.get_general_log_thd()) ||
|
||||||
(thd == logger.get_slow_log_thd())))
|
(thd == logger.get_slow_log_thd()) ||
|
||||||
|
(thd == logger.get_privileged_thread())))
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
238
sql/log.cc
238
sql/log.cc
@ -173,6 +173,33 @@ public:
|
|||||||
|
|
||||||
handlerton *binlog_hton;
|
handlerton *binlog_hton;
|
||||||
|
|
||||||
|
|
||||||
|
/* Check if a given table is opened log table */
|
||||||
|
int check_if_log_table(uint db_len, const char *db, uint table_name_len,
|
||||||
|
const char *table_name, uint check_if_opened)
|
||||||
|
{
|
||||||
|
if (db_len == 5 &&
|
||||||
|
!(lower_case_table_names ?
|
||||||
|
my_strcasecmp(system_charset_info, db, "mysql") :
|
||||||
|
strcmp(db, "mysql")))
|
||||||
|
{
|
||||||
|
if (table_name_len == 11 && !(lower_case_table_names ?
|
||||||
|
my_strcasecmp(system_charset_info,
|
||||||
|
table_name, "general_log") :
|
||||||
|
strcmp(table_name, "general_log")) &&
|
||||||
|
(!check_if_opened || logger.is_log_table_enabled(QUERY_LOG_GENERAL)))
|
||||||
|
return QUERY_LOG_GENERAL;
|
||||||
|
else
|
||||||
|
if (table_name_len == 8 && !(lower_case_table_names ?
|
||||||
|
my_strcasecmp(system_charset_info, table_name, "slow_log") :
|
||||||
|
strcmp(table_name, "slow_log")) &&
|
||||||
|
(!check_if_opened ||logger.is_log_table_enabled(QUERY_LOG_SLOW)))
|
||||||
|
return QUERY_LOG_SLOW;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Open log table of a given type (general or slow log)
|
Open log table of a given type (general or slow log)
|
||||||
|
|
||||||
@ -273,6 +300,12 @@ bool Log_to_csv_event_handler::open_log_table(uint log_table_type)
|
|||||||
my_pthread_setspecific_ptr(THR_MALLOC, 0);
|
my_pthread_setspecific_ptr(THR_MALLOC, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
After a log table was opened, we should clear privileged thread
|
||||||
|
flag (which allows locking of a log table by a special thread, usually
|
||||||
|
the one who closed log tables temporarily).
|
||||||
|
*/
|
||||||
|
privileged_thread= 0;
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,6 +322,8 @@ Log_to_csv_event_handler::Log_to_csv_event_handler()
|
|||||||
/* logger thread always works with mysql database */
|
/* logger thread always works with mysql database */
|
||||||
slow_log_thd->db= my_strdup("mysql", MYF(0));;
|
slow_log_thd->db= my_strdup("mysql", MYF(0));;
|
||||||
slow_log_thd->db_length= 5;
|
slow_log_thd->db_length= 5;
|
||||||
|
/* no privileged thread exists at the moment */
|
||||||
|
privileged_thread= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -341,6 +376,7 @@ bool Log_to_csv_event_handler::reopen_log_table(uint log_table_type)
|
|||||||
return open_log_table(log_table_type);
|
return open_log_table(log_table_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Log_to_csv_event_handler::cleanup()
|
void Log_to_csv_event_handler::cleanup()
|
||||||
{
|
{
|
||||||
if (opt_log)
|
if (opt_log)
|
||||||
@ -395,9 +431,6 @@ bool Log_to_csv_event_handler::
|
|||||||
filled by the Logger (=> no need to load default ones).
|
filled by the Logger (=> no need to load default ones).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* log table entries are not replicated at the moment */
|
|
||||||
tmp_disable_binlog(current_thd);
|
|
||||||
|
|
||||||
/* Set current time. Required for CURRENT_TIMESTAMP to work */
|
/* Set current time. Required for CURRENT_TIMESTAMP to work */
|
||||||
general_log_thd->start_time= event_time;
|
general_log_thd->start_time= event_time;
|
||||||
|
|
||||||
@ -406,21 +439,36 @@ bool Log_to_csv_event_handler::
|
|||||||
default value (which is CURRENT_TIMESTAMP).
|
default value (which is CURRENT_TIMESTAMP).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
table->field[1]->store(user_host, user_host_len, client_cs);
|
/* check that all columns exist */
|
||||||
|
if (!table->field[1] || !table->field[2] || !table->field[3] ||
|
||||||
|
!table->field[4] || !table->field[5])
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* do a write */
|
||||||
|
if (table->field[1]->store(user_host, user_host_len, client_cs) ||
|
||||||
|
table->field[2]->store((longlong) thread_id, TRUE) ||
|
||||||
|
table->field[3]->store((longlong) server_id, TRUE) ||
|
||||||
|
table->field[4]->store(command_type, command_type_len, client_cs) ||
|
||||||
|
table->field[5]->store(sql_text, sql_text_len, client_cs))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* mark tables as not null */
|
||||||
table->field[1]->set_notnull();
|
table->field[1]->set_notnull();
|
||||||
table->field[2]->store((longlong) thread_id, TRUE);
|
|
||||||
table->field[2]->set_notnull();
|
table->field[2]->set_notnull();
|
||||||
table->field[3]->store((longlong) server_id, TRUE);
|
|
||||||
table->field[3]->set_notnull();
|
table->field[3]->set_notnull();
|
||||||
table->field[4]->store(command_type, command_type_len, client_cs);
|
|
||||||
table->field[4]->set_notnull();
|
table->field[4]->set_notnull();
|
||||||
table->field[5]->store(sql_text, sql_text_len, client_cs);
|
|
||||||
table->field[5]->set_notnull();
|
table->field[5]->set_notnull();
|
||||||
|
|
||||||
|
/* log table entries are not replicated at the moment */
|
||||||
|
tmp_disable_binlog(current_thd);
|
||||||
|
|
||||||
table->file->ha_write_row(table->record[0]);
|
table->file->ha_write_row(table->record[0]);
|
||||||
|
|
||||||
reenable_binlog(current_thd);
|
reenable_binlog(current_thd);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
err:
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -469,9 +517,6 @@ bool Log_to_csv_event_handler::
|
|||||||
if (unlikely(!logger.is_log_tables_initialized))
|
if (unlikely(!logger.is_log_tables_initialized))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* log table entries are not replicated at the moment */
|
|
||||||
tmp_disable_binlog(current_thd);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Set start time for CURRENT_TIMESTAMP to the start of the query.
|
Set start time for CURRENT_TIMESTAMP to the start of the query.
|
||||||
This will be default value for the field[0]
|
This will be default value for the field[0]
|
||||||
@ -484,19 +529,30 @@ bool Log_to_csv_event_handler::
|
|||||||
default value.
|
default value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (!table->field[1] || !table->field[2] || !table->field[3] ||
|
||||||
|
!table->field[4] || !table->field[5] || !table->field[6] ||
|
||||||
|
!table->field[7] || !table->field[8] || !table->field[9] ||
|
||||||
|
!table->field[10])
|
||||||
|
goto err;
|
||||||
|
|
||||||
/* store the value */
|
/* store the value */
|
||||||
table->field[1]->store(user_host, user_host_len, client_cs);
|
if (table->field[1]->store(user_host, user_host_len, client_cs))
|
||||||
|
goto err;
|
||||||
|
|
||||||
if (query_start_arg)
|
if (query_start_arg)
|
||||||
{
|
{
|
||||||
/* fill in query_time field */
|
/* fill in query_time field */
|
||||||
table->field[2]->store(query_time, TRUE);
|
if (table->field[2]->store(query_time, TRUE))
|
||||||
|
goto err;
|
||||||
/* lock_time */
|
/* lock_time */
|
||||||
table->field[3]->store(lock_time, TRUE);
|
if (table->field[3]->store(lock_time, TRUE))
|
||||||
|
goto err;
|
||||||
/* rows_sent */
|
/* rows_sent */
|
||||||
table->field[4]->store((longlong) thd->sent_row_count, TRUE);
|
if (table->field[4]->store((longlong) thd->sent_row_count, TRUE))
|
||||||
|
goto err;
|
||||||
/* rows_examined */
|
/* rows_examined */
|
||||||
table->field[5]->store((longlong) thd->examined_row_count, TRUE);
|
if (table->field[5]->store((longlong) thd->examined_row_count, TRUE))
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -509,14 +565,18 @@ bool Log_to_csv_event_handler::
|
|||||||
/* fill database field */
|
/* fill database field */
|
||||||
if (thd->db)
|
if (thd->db)
|
||||||
{
|
{
|
||||||
table->field[6]->store(thd->db, thd->db_length, client_cs);
|
if (table->field[6]->store(thd->db, thd->db_length, client_cs))
|
||||||
|
goto err;
|
||||||
table->field[6]->set_notnull();
|
table->field[6]->set_notnull();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt)
|
if (thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt)
|
||||||
{
|
{
|
||||||
table->field[7]->store((longlong)
|
if (table->
|
||||||
thd->first_successful_insert_id_in_prev_stmt_for_binlog, TRUE);
|
field[7]->store((longlong)
|
||||||
|
thd->first_successful_insert_id_in_prev_stmt_for_binlog,
|
||||||
|
TRUE))
|
||||||
|
goto err;
|
||||||
table->field[7]->set_notnull();
|
table->field[7]->set_notnull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,16 +588,23 @@ bool Log_to_csv_event_handler::
|
|||||||
*/
|
*/
|
||||||
if (thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements() > 0)
|
if (thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements() > 0)
|
||||||
{
|
{
|
||||||
table->field[8]->store((longlong)
|
if (table->
|
||||||
thd->auto_inc_intervals_in_cur_stmt_for_binlog.minimum(), TRUE);
|
field[8]->store((longlong)
|
||||||
|
thd->auto_inc_intervals_in_cur_stmt_for_binlog.minimum(), TRUE))
|
||||||
|
goto err;
|
||||||
table->field[8]->set_notnull();
|
table->field[8]->set_notnull();
|
||||||
}
|
}
|
||||||
|
|
||||||
table->field[9]->store((longlong) server_id, TRUE);
|
if (table->field[9]->store((longlong) server_id, TRUE))
|
||||||
|
goto err;
|
||||||
table->field[9]->set_notnull();
|
table->field[9]->set_notnull();
|
||||||
|
|
||||||
/* sql_text */
|
/* sql_text */
|
||||||
table->field[10]->store(sql_text,sql_text_len, client_cs);
|
if (table->field[10]->store(sql_text,sql_text_len, client_cs))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* log table entries are not replicated at the moment */
|
||||||
|
tmp_disable_binlog(current_thd);
|
||||||
|
|
||||||
/* write the row */
|
/* write the row */
|
||||||
table->file->ha_write_row(table->record[0]);
|
table->file->ha_write_row(table->record[0]);
|
||||||
@ -545,6 +612,8 @@ bool Log_to_csv_event_handler::
|
|||||||
reenable_binlog(current_thd);
|
reenable_binlog(current_thd);
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
err:
|
||||||
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Log_to_csv_event_handler::
|
bool Log_to_csv_event_handler::
|
||||||
@ -733,61 +802,48 @@ bool LOGGER::reopen_log_table(uint log_table_type)
|
|||||||
return table_log_handler->reopen_log_table(log_table_type);
|
return table_log_handler->reopen_log_table(log_table_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LOGGER::reopen_log_tables()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
we use | and not || here, to ensure that both reopen_log_table
|
||||||
|
are called, even if the first one fails
|
||||||
|
*/
|
||||||
|
if ((opt_slow_log && logger.reopen_log_table(QUERY_LOG_SLOW)) |
|
||||||
|
(opt_log && logger.reopen_log_table(QUERY_LOG_GENERAL)))
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LOGGER::tmp_close_log_tables(THD *thd)
|
||||||
|
{
|
||||||
|
table_log_handler->tmp_close_log_tables(thd);
|
||||||
|
}
|
||||||
|
|
||||||
bool LOGGER::flush_logs(THD *thd)
|
bool LOGGER::flush_logs(THD *thd)
|
||||||
{
|
{
|
||||||
TABLE_LIST close_slow_log, close_general_log;
|
int rc= 0;
|
||||||
|
|
||||||
/* reopen log tables */
|
|
||||||
bzero((char*) &close_slow_log, sizeof(TABLE_LIST));
|
|
||||||
close_slow_log.alias= close_slow_log.table_name=(char*) "slow_log";
|
|
||||||
close_slow_log.table_name_length= 8;
|
|
||||||
close_slow_log.db= (char*) "mysql";
|
|
||||||
close_slow_log.db_length= 5;
|
|
||||||
|
|
||||||
bzero((char*) &close_general_log, sizeof(TABLE_LIST));
|
|
||||||
close_general_log.alias= close_general_log.table_name=(char*) "general_log";
|
|
||||||
close_general_log.table_name_length= 11;
|
|
||||||
close_general_log.db= (char*) "mysql";
|
|
||||||
close_general_log.db_length= 5;
|
|
||||||
|
|
||||||
/* lock tables, in the case they are enabled */
|
|
||||||
if (logger.is_log_tables_initialized)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
This will lock and wait for all but the logger thread to release the
|
|
||||||
tables. Then we could reopen log tables. Then release the name locks.
|
|
||||||
|
|
||||||
NOTE: in fact, the first parameter used in lock_and_wait_for_table_name()
|
|
||||||
and table_log_handler->flush() could be any non-NULL THD, as the
|
|
||||||
underlying code makes certain assumptions about this.
|
|
||||||
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,
|
Now we lock logger, as nobody should be able to use logging routines while
|
||||||
while reopening tables.
|
log tables are closed
|
||||||
*/
|
*/
|
||||||
logger.lock();
|
logger.lock();
|
||||||
|
if (logger.is_log_tables_initialized)
|
||||||
|
table_log_handler->tmp_close_log_tables(thd); // the locking happens here
|
||||||
|
|
||||||
/* reopen log files */
|
/* reopen log files */
|
||||||
file_log_handler->flush();
|
file_log_handler->flush();
|
||||||
|
|
||||||
/* flush tables, in the case they are enabled */
|
/* reopen tables in the case they were enabled */
|
||||||
if (logger.is_log_tables_initialized)
|
if (logger.is_log_tables_initialized)
|
||||||
table_log_handler->flush(table_log_handler->general_log_thd,
|
{
|
||||||
&close_slow_log, &close_general_log);
|
if (reopen_log_tables())
|
||||||
|
rc= TRUE;
|
||||||
|
}
|
||||||
/* end of log flush */
|
/* end of log flush */
|
||||||
logger.unlock();
|
logger.unlock();
|
||||||
return FALSE;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1095,31 +1151,50 @@ void LOGGER::deactivate_log_handler(THD *thd, uint log_type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Log_to_csv_event_handler::flush(THD *thd, TABLE_LIST *close_slow_log,
|
/*
|
||||||
TABLE_LIST *close_general_log)
|
Close log tables temporarily. The thread which closed
|
||||||
|
them this way can lock them in any mode it needs.
|
||||||
|
NOTE: one should call logger.lock() before entering this
|
||||||
|
function.
|
||||||
|
*/
|
||||||
|
void Log_to_csv_event_handler::tmp_close_log_tables(THD *thd)
|
||||||
{
|
{
|
||||||
|
TABLE_LIST close_slow_log, close_general_log;
|
||||||
|
|
||||||
|
/* fill lists, we will need to perform operations on tables */
|
||||||
|
bzero((char*) &close_slow_log, sizeof(TABLE_LIST));
|
||||||
|
close_slow_log.alias= close_slow_log.table_name=(char*) "slow_log";
|
||||||
|
close_slow_log.table_name_length= 8;
|
||||||
|
close_slow_log.db= (char*) "mysql";
|
||||||
|
close_slow_log.db_length= 5;
|
||||||
|
|
||||||
|
bzero((char*) &close_general_log, sizeof(TABLE_LIST));
|
||||||
|
close_general_log.alias= close_general_log.table_name=(char*) "general_log";
|
||||||
|
close_general_log.table_name_length= 11;
|
||||||
|
close_general_log.db= (char*) "mysql";
|
||||||
|
close_general_log.db_length= 5;
|
||||||
|
|
||||||
|
privileged_thread= thd;
|
||||||
|
|
||||||
VOID(pthread_mutex_lock(&LOCK_open));
|
VOID(pthread_mutex_lock(&LOCK_open));
|
||||||
|
/*
|
||||||
|
NOTE: in fact, the first parameter used in query_cache_invalidate3()
|
||||||
|
could be any non-NULL THD, as the underlying code makes certain
|
||||||
|
assumptions about this.
|
||||||
|
Here we use one of the logger handler THD's. Simply because it
|
||||||
|
seems appropriate.
|
||||||
|
*/
|
||||||
if (opt_log)
|
if (opt_log)
|
||||||
{
|
{
|
||||||
close_log_table(QUERY_LOG_GENERAL, TRUE);
|
close_log_table(QUERY_LOG_GENERAL, TRUE);
|
||||||
query_cache_invalidate3(thd, close_general_log, 0);
|
query_cache_invalidate3(general_log_thd, &close_general_log, 0);
|
||||||
unlock_table_name(thd, close_general_log);
|
|
||||||
}
|
}
|
||||||
if (opt_slow_log)
|
if (opt_slow_log)
|
||||||
{
|
{
|
||||||
close_log_table(QUERY_LOG_SLOW, TRUE);
|
close_log_table(QUERY_LOG_SLOW, TRUE);
|
||||||
query_cache_invalidate3(thd, close_slow_log, 0);
|
query_cache_invalidate3(general_log_thd, &close_slow_log, 0);
|
||||||
unlock_table_name(thd, close_slow_log);
|
|
||||||
}
|
}
|
||||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||||
/*
|
|
||||||
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 */
|
/* the parameters are unused for the log tables */
|
||||||
@ -1187,16 +1262,15 @@ void Log_to_csv_event_handler::
|
|||||||
THD *log_thd, *curr= current_thd;
|
THD *log_thd, *curr= current_thd;
|
||||||
TABLE_LIST *table;
|
TABLE_LIST *table;
|
||||||
|
|
||||||
|
if (!logger.is_log_table_enabled(log_table_type))
|
||||||
|
return; /* do nothing */
|
||||||
|
|
||||||
switch (log_table_type) {
|
switch (log_table_type) {
|
||||||
case QUERY_LOG_GENERAL:
|
case QUERY_LOG_GENERAL:
|
||||||
if (!logger.is_general_log_table_enabled())
|
|
||||||
return; /* do nothing */
|
|
||||||
log_thd= general_log_thd;
|
log_thd= general_log_thd;
|
||||||
table= &general_log;
|
table= &general_log;
|
||||||
break;
|
break;
|
||||||
case QUERY_LOG_SLOW:
|
case QUERY_LOG_SLOW:
|
||||||
if (!logger.is_slow_log_table_enabled())
|
|
||||||
return; /* do nothing */
|
|
||||||
log_thd= slow_log_thd;
|
log_thd= slow_log_thd;
|
||||||
table= &slow_log;
|
table= &slow_log;
|
||||||
break;
|
break;
|
||||||
|
49
sql/log.h
49
sql/log.h
@ -404,6 +404,9 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int check_if_log_table(uint db_len, const char *db, uint table_name_len,
|
||||||
|
const char *table_name, uint check_if_opened);
|
||||||
|
|
||||||
class Log_to_csv_event_handler: public Log_event_handler
|
class Log_to_csv_event_handler: public Log_event_handler
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -412,6 +415,16 @@ class Log_to_csv_event_handler: public Log_event_handler
|
|||||||
THD's of the query. The reason is the locking order and duration.
|
THD's of the query. The reason is the locking order and duration.
|
||||||
*/
|
*/
|
||||||
THD *general_log_thd, *slow_log_thd;
|
THD *general_log_thd, *slow_log_thd;
|
||||||
|
/*
|
||||||
|
This is for the thread, which called tmp_close_log_tables. The thread
|
||||||
|
will be allowed to write-lock the log tables (as it explicitly disabled
|
||||||
|
logging). This is used for such operations as REPAIR, which require
|
||||||
|
exclusive lock on the log tables.
|
||||||
|
NOTE: there can be only one priviliged thread, as one should
|
||||||
|
lock logger with logger.lock() before calling tmp_close_log_tables().
|
||||||
|
So no other thread could get privileged status at the same time.
|
||||||
|
*/
|
||||||
|
THD *privileged_thread;
|
||||||
friend class LOGGER;
|
friend class LOGGER;
|
||||||
TABLE_LIST general_log, slow_log;
|
TABLE_LIST general_log, slow_log;
|
||||||
|
|
||||||
@ -436,13 +449,20 @@ public:
|
|||||||
const char *command_type, uint command_type_len,
|
const char *command_type, uint command_type_len,
|
||||||
const char *sql_text, uint sql_text_len,
|
const char *sql_text, uint sql_text_len,
|
||||||
CHARSET_INFO *client_cs);
|
CHARSET_INFO *client_cs);
|
||||||
bool flush(THD *thd, TABLE_LIST *close_slow_Log,
|
void tmp_close_log_tables(THD *thd);
|
||||||
TABLE_LIST* close_general_log);
|
|
||||||
void close_log_table(uint log_type, bool lock_in_use);
|
void close_log_table(uint log_type, bool lock_in_use);
|
||||||
bool reopen_log_table(uint log_type);
|
bool reopen_log_table(uint log_type);
|
||||||
|
THD* get_privileged_thread()
|
||||||
|
{
|
||||||
|
return privileged_thread;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* type of the log table */
|
||||||
|
#define QUERY_LOG_SLOW 1
|
||||||
|
#define QUERY_LOG_GENERAL 2
|
||||||
|
|
||||||
class Log_to_file_event_handler: public Log_event_handler
|
class Log_to_file_event_handler: public Log_event_handler
|
||||||
{
|
{
|
||||||
MYSQL_QUERY_LOG mysql_log;
|
MYSQL_QUERY_LOG mysql_log;
|
||||||
@ -498,13 +518,18 @@ public:
|
|||||||
{}
|
{}
|
||||||
void lock() { (void) pthread_mutex_lock(&LOCK_logger); }
|
void lock() { (void) pthread_mutex_lock(&LOCK_logger); }
|
||||||
void unlock() { (void) pthread_mutex_unlock(&LOCK_logger); }
|
void unlock() { (void) pthread_mutex_unlock(&LOCK_logger); }
|
||||||
bool is_general_log_table_enabled()
|
void tmp_close_log_tables(THD *thd);
|
||||||
|
bool is_log_table_enabled(uint log_table_type)
|
||||||
{
|
{
|
||||||
return table_log_handler && table_log_handler->general_log.table != 0;
|
switch (log_table_type) {
|
||||||
}
|
case QUERY_LOG_SLOW:
|
||||||
bool is_slow_log_table_enabled()
|
return table_log_handler && table_log_handler->slow_log.table != 0;
|
||||||
{
|
case QUERY_LOG_GENERAL:
|
||||||
return table_log_handler && table_log_handler->slow_log.table != 0;
|
return table_log_handler && table_log_handler->general_log.table != 0;
|
||||||
|
default:
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
return FALSE; /* make compiler happy */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
We want to initialize all log mutexes as soon as possible,
|
We want to initialize all log mutexes as soon as possible,
|
||||||
@ -542,6 +567,7 @@ public:
|
|||||||
|
|
||||||
void close_log_table(uint log_type, bool lock_in_use);
|
void close_log_table(uint log_type, bool lock_in_use);
|
||||||
bool reopen_log_table(uint log_type);
|
bool reopen_log_table(uint log_type);
|
||||||
|
bool reopen_log_tables();
|
||||||
|
|
||||||
/* we use this function to setup all enabled log event handlers */
|
/* we use this function to setup all enabled log event handlers */
|
||||||
int set_handlers(uint error_log_printer,
|
int set_handlers(uint error_log_printer,
|
||||||
@ -564,6 +590,13 @@ public:
|
|||||||
return file_log_handler->get_mysql_log();
|
return file_log_handler->get_mysql_log();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
THD* get_privileged_thread()
|
||||||
|
{
|
||||||
|
if (table_log_handler)
|
||||||
|
return table_log_handler->get_privileged_thread();
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
enum enum_binlog_format {
|
enum enum_binlog_format {
|
||||||
|
@ -1451,10 +1451,6 @@ typedef void (*sql_print_message_func)(const char *format, ...)
|
|||||||
ATTRIBUTE_FORMAT(printf, 1, 2);
|
ATTRIBUTE_FORMAT(printf, 1, 2);
|
||||||
extern sql_print_message_func sql_print_message_handlers[];
|
extern sql_print_message_func sql_print_message_handlers[];
|
||||||
|
|
||||||
/* type of the log table */
|
|
||||||
#define QUERY_LOG_SLOW 1
|
|
||||||
#define QUERY_LOG_GENERAL 2
|
|
||||||
|
|
||||||
int error_log_print(enum loglevel level, const char *format,
|
int error_log_print(enum loglevel level, const char *format,
|
||||||
va_list args);
|
va_list args);
|
||||||
|
|
||||||
|
@ -6004,4 +6004,6 @@ ER_BAD_LOG_STATEMENT
|
|||||||
ger "Sie können eine Logtabelle nicht '%s', wenn Loggen angeschaltet ist"
|
ger "Sie können eine Logtabelle nicht '%s', wenn Loggen angeschaltet ist"
|
||||||
ER_NON_INSERTABLE_TABLE
|
ER_NON_INSERTABLE_TABLE
|
||||||
eng "The target table %-.100s of the %s is not insertable-into"
|
eng "The target table %-.100s of the %s is not insertable-into"
|
||||||
|
ER_CANT_RENAME_LOG_TABLE
|
||||||
|
eng "Cannot rename '%s'. When logging enabled, rename to/from log table must rename two tables: the log table to an archive table and another table back to '%s'"
|
||||||
|
|
||||||
|
@ -913,28 +913,16 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
|
|||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint log_type= check_if_log_table(table_list->db_length, table_list->db,
|
||||||
|
table_list->table_name_length,
|
||||||
|
table_list->table_name, 1);
|
||||||
/* close log tables in use */
|
/* close log tables in use */
|
||||||
if (!my_strcasecmp(system_charset_info, table_list->db, "mysql"))
|
if (log_type)
|
||||||
{
|
{
|
||||||
if (opt_log &&
|
lock_logger= 1;
|
||||||
!my_strcasecmp(system_charset_info, table_list->table_name,
|
logger.lock();
|
||||||
"general_log"))
|
logger.close_log_table(log_type, FALSE);
|
||||||
{
|
closed_log_tables= closed_log_tables | log_type;
|
||||||
lock_logger= 1;
|
|
||||||
logger.lock();
|
|
||||||
logger.close_log_table(QUERY_LOG_GENERAL, FALSE);
|
|
||||||
closed_log_tables= closed_log_tables | QUERY_LOG_GENERAL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (opt_slow_log &&
|
|
||||||
!my_strcasecmp(system_charset_info, table_list->table_name,
|
|
||||||
"slow_log"))
|
|
||||||
{
|
|
||||||
lock_logger= 1;
|
|
||||||
logger.lock();
|
|
||||||
logger.close_log_table(QUERY_LOG_SLOW, FALSE);
|
|
||||||
closed_log_tables= closed_log_tables | QUERY_LOG_SLOW;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the .frm extension AIX 5.2 64-bit compiler bug (BUG#16155): this
|
// Remove the .frm extension AIX 5.2 64-bit compiler bug (BUG#16155): this
|
||||||
|
@ -35,7 +35,10 @@ static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list);
|
|||||||
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
|
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
|
||||||
{
|
{
|
||||||
bool error= 1;
|
bool error= 1;
|
||||||
TABLE_LIST *ren_table= 0;
|
TABLE_LIST *ren_table= 0, *new_table;
|
||||||
|
int to_table;
|
||||||
|
char *rename_log_table[2]= {NULL, NULL};
|
||||||
|
int disable_logs= 0;
|
||||||
DBUG_ENTER("mysql_rename_tables");
|
DBUG_ENTER("mysql_rename_tables");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -52,6 +55,96 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
|
|||||||
|
|
||||||
if (wait_if_global_read_lock(thd,0,1))
|
if (wait_if_global_read_lock(thd,0,1))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
|
if (logger.is_log_table_enabled(QUERY_LOG_GENERAL) ||
|
||||||
|
logger.is_log_table_enabled(QUERY_LOG_SLOW))
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
Rules for rename of a log table:
|
||||||
|
|
||||||
|
IF 1. Log tables are enabled
|
||||||
|
AND 2. Rename operates on the log table and nothing is being
|
||||||
|
renamed to the log table.
|
||||||
|
DO 3. Throw an error message.
|
||||||
|
ELSE 4. Perform rename.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (to_table= 0, ren_table= table_list; ren_table;
|
||||||
|
to_table= 1 - to_table, ren_table= ren_table->next_local)
|
||||||
|
{
|
||||||
|
int log_table_rename= 0;
|
||||||
|
|
||||||
|
if ((log_table_rename=
|
||||||
|
check_if_log_table(ren_table->db_length, ren_table->db,
|
||||||
|
ren_table->table_name_length,
|
||||||
|
ren_table->table_name, 1)))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Log table encoutered we will need to disable and lock logs
|
||||||
|
for duration of rename.
|
||||||
|
*/
|
||||||
|
disable_logs= TRUE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
as we use log_table_rename as an array index, we need it to start
|
||||||
|
with 0, while QUERY_LOG_SLOW == 1 and QUERY_LOG_GENERAL == 2.
|
||||||
|
So, we shift the value to start with 0;
|
||||||
|
*/
|
||||||
|
log_table_rename--;
|
||||||
|
if (rename_log_table[log_table_rename])
|
||||||
|
{
|
||||||
|
if (to_table)
|
||||||
|
rename_log_table[log_table_rename]= NULL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Two renames of "log_table TO" w/o rename "TO log_table" in
|
||||||
|
between.
|
||||||
|
*/
|
||||||
|
my_error(ER_CANT_RENAME_LOG_TABLE, MYF(0), ren_table->table_name,
|
||||||
|
ren_table->table_name);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (to_table)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Attempt to rename a table TO log_table w/o renaming
|
||||||
|
log_table TO some table.
|
||||||
|
*/
|
||||||
|
my_error(ER_CANT_RENAME_LOG_TABLE, MYF(0), ren_table->table_name,
|
||||||
|
ren_table->table_name);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* save the name of the log table to report an error */
|
||||||
|
rename_log_table[log_table_rename]= ren_table->table_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rename_log_table[0] || rename_log_table[1])
|
||||||
|
{
|
||||||
|
if (rename_log_table[0])
|
||||||
|
my_error(ER_CANT_RENAME_LOG_TABLE, MYF(0), rename_log_table[0],
|
||||||
|
rename_log_table[0]);
|
||||||
|
else
|
||||||
|
my_error(ER_CANT_RENAME_LOG_TABLE, MYF(0), rename_log_table[1],
|
||||||
|
rename_log_table[1]);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disable_logs)
|
||||||
|
{
|
||||||
|
logger.lock();
|
||||||
|
logger.tmp_close_log_tables(thd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VOID(pthread_mutex_lock(&LOCK_open));
|
VOID(pthread_mutex_lock(&LOCK_open));
|
||||||
if (lock_table_names(thd, table_list))
|
if (lock_table_names(thd, table_list))
|
||||||
goto err;
|
goto err;
|
||||||
@ -95,6 +188,13 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
|
|||||||
|
|
||||||
err:
|
err:
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
|
/* enable logging back if needed */
|
||||||
|
if (disable_logs)
|
||||||
|
{
|
||||||
|
if (logger.reopen_log_tables())
|
||||||
|
error= TRUE;
|
||||||
|
logger.unlock();
|
||||||
|
}
|
||||||
start_waiting_global_read_lock(thd);
|
start_waiting_global_read_lock(thd);
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
102
sql/sql_table.cc
102
sql/sql_table.cc
@ -1639,11 +1639,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
|
|
||||||
/* Disable drop of enabled log tables */
|
/* Disable drop of enabled log tables */
|
||||||
if (share && share->log_table &&
|
if (share && share->log_table &&
|
||||||
((!my_strcasecmp(system_charset_info, table->table_name,
|
check_if_log_table(table->db_length, table->db,
|
||||||
"general_log") && opt_log &&
|
table->table_name_length, table->table_name, 1))
|
||||||
logger.is_general_log_table_enabled()) ||
|
|
||||||
(!my_strcasecmp(system_charset_info, table->table_name, "slow_log")
|
|
||||||
&& opt_slow_log && logger.is_slow_log_table_enabled())))
|
|
||||||
{
|
{
|
||||||
my_error(ER_BAD_LOG_STATEMENT, MYF(0), "DROP");
|
my_error(ER_BAD_LOG_STATEMENT, MYF(0), "DROP");
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
@ -4043,7 +4040,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||||||
Item *item;
|
Item *item;
|
||||||
Protocol *protocol= thd->protocol;
|
Protocol *protocol= thd->protocol;
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
int result_code;
|
int result_code, disable_logs= 0;
|
||||||
DBUG_ENTER("mysql_admin_table");
|
DBUG_ENTER("mysql_admin_table");
|
||||||
|
|
||||||
if (end_active_trans(thd))
|
if (end_active_trans(thd))
|
||||||
@ -4088,6 +4085,23 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||||||
thd->no_warnings_for_error= no_warnings_for_error;
|
thd->no_warnings_for_error= no_warnings_for_error;
|
||||||
if (view_operator_func == NULL)
|
if (view_operator_func == NULL)
|
||||||
table->required_type=FRMTYPE_TABLE;
|
table->required_type=FRMTYPE_TABLE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
If we want to perform an admin operation on the log table
|
||||||
|
(E.g. rename) and lock_type >= TL_READ_NO_INSERT disable
|
||||||
|
log tables
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (check_if_log_table(table->db_length, table->db,
|
||||||
|
table->table_name_length,
|
||||||
|
table->table_name, 1) &&
|
||||||
|
lock_type >= TL_READ_NO_INSERT)
|
||||||
|
{
|
||||||
|
disable_logs= 1;
|
||||||
|
logger.lock();
|
||||||
|
logger.tmp_close_log_tables(thd);
|
||||||
|
}
|
||||||
|
|
||||||
open_and_lock_tables(thd, table);
|
open_and_lock_tables(thd, table);
|
||||||
thd->no_warnings_for_error= 0;
|
thd->no_warnings_for_error= 0;
|
||||||
table->next_global= save_next_global;
|
table->next_global= save_next_global;
|
||||||
@ -4404,11 +4418,24 @@ send_result_message:
|
|||||||
}
|
}
|
||||||
|
|
||||||
send_eof(thd);
|
send_eof(thd);
|
||||||
|
if (disable_logs)
|
||||||
|
{
|
||||||
|
if (logger.reopen_log_tables())
|
||||||
|
my_error(ER_CANT_ACTIVATE_LOG, MYF(0));
|
||||||
|
logger.unlock();
|
||||||
|
}
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
ha_autocommit_or_rollback(thd, 1);
|
ha_autocommit_or_rollback(thd, 1);
|
||||||
close_thread_tables(thd); // Shouldn't be needed
|
close_thread_tables(thd); // Shouldn't be needed
|
||||||
|
/* enable logging back if needed */
|
||||||
|
if (disable_logs)
|
||||||
|
{
|
||||||
|
if (logger.reopen_log_tables())
|
||||||
|
my_error(ER_CANT_ACTIVATE_LOG, MYF(0));
|
||||||
|
logger.unlock();
|
||||||
|
}
|
||||||
if (table)
|
if (table)
|
||||||
table->table=0;
|
table->table=0;
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
@ -4573,6 +4600,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
|
|||||||
{
|
{
|
||||||
TABLE *tmp_table;
|
TABLE *tmp_table;
|
||||||
char src_path[FN_REFLEN], dst_path[FN_REFLEN], tmp_path[FN_REFLEN];
|
char src_path[FN_REFLEN], dst_path[FN_REFLEN], tmp_path[FN_REFLEN];
|
||||||
|
char src_table_name_buff[FN_REFLEN], src_db_name_buff[FN_REFLEN];
|
||||||
uint dst_path_length;
|
uint dst_path_length;
|
||||||
char *db= table->db;
|
char *db= table->db;
|
||||||
char *table_name= table->table_name;
|
char *table_name= table->table_name;
|
||||||
@ -4609,13 +4637,6 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
|
|||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bzero((gptr)&src_tables_list, sizeof(src_tables_list));
|
|
||||||
src_tables_list.db= src_db;
|
|
||||||
src_tables_list.table_name= src_table;
|
|
||||||
|
|
||||||
if (lock_and_wait_for_table_name(thd, &src_tables_list))
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
if ((tmp_table= find_temporary_table(thd, src_db, src_table)))
|
if ((tmp_table= find_temporary_table(thd, src_db, src_table)))
|
||||||
strxmov(src_path, tmp_table->s->path.str, reg_ext, NullS);
|
strxmov(src_path, tmp_table->s->path.str, reg_ext, NullS);
|
||||||
else
|
else
|
||||||
@ -4642,6 +4663,34 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lower_case_table_names)
|
||||||
|
{
|
||||||
|
if (src_db)
|
||||||
|
{
|
||||||
|
strmake(src_db_name_buff, src_db,
|
||||||
|
min(sizeof(src_db_name_buff) - 1, table_ident->db.length));
|
||||||
|
my_casedn_str(files_charset_info, src_db_name_buff);
|
||||||
|
src_db= src_db_name_buff;
|
||||||
|
}
|
||||||
|
if (src_table)
|
||||||
|
{
|
||||||
|
strmake(src_table_name_buff, src_table,
|
||||||
|
min(sizeof(src_table_name_buff) - 1, table_ident->table.length));
|
||||||
|
my_casedn_str(files_charset_info, src_table_name_buff);
|
||||||
|
src_table= src_table_name_buff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bzero((gptr)&src_tables_list, sizeof(src_tables_list));
|
||||||
|
src_tables_list.db= src_db;
|
||||||
|
src_tables_list.db_length= table_ident->db.length;
|
||||||
|
src_tables_list.lock_type= TL_READ;
|
||||||
|
src_tables_list.table_name= src_table;
|
||||||
|
src_tables_list.alias= src_table;
|
||||||
|
|
||||||
|
if (simple_open_n_lock_tables(thd, &src_tables_list))
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Validate the destination table
|
Validate the destination table
|
||||||
|
|
||||||
@ -4788,9 +4837,6 @@ table_exists:
|
|||||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
|
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
pthread_mutex_lock(&LOCK_open);
|
|
||||||
unlock_table_name(thd, &src_tables_list);
|
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5179,33 +5225,23 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
LINT_INIT(index_add_buffer);
|
LINT_INIT(index_add_buffer);
|
||||||
LINT_INIT(index_drop_buffer);
|
LINT_INIT(index_drop_buffer);
|
||||||
|
|
||||||
if (table_list && table_list->db &&
|
if (table_list && table_list->db && table_list->table_name)
|
||||||
!my_strcasecmp(system_charset_info, table_list->db, "mysql") &&
|
|
||||||
table_list->table_name)
|
|
||||||
{
|
{
|
||||||
enum enum_table_kind { NOT_LOG_TABLE= 1, GENERAL_LOG, SLOW_LOG }
|
int table_kind= 0;
|
||||||
table_kind= NOT_LOG_TABLE;
|
|
||||||
|
|
||||||
if (!my_strcasecmp(system_charset_info, table_list->table_name,
|
table_kind= check_if_log_table(table_list->db_length, table_list->db,
|
||||||
"general_log"))
|
table_list->table_name_length,
|
||||||
table_kind= GENERAL_LOG;
|
table_list->table_name, 0);
|
||||||
else
|
|
||||||
if (!my_strcasecmp(system_charset_info, table_list->table_name,
|
|
||||||
"slow_log"))
|
|
||||||
table_kind= SLOW_LOG;
|
|
||||||
|
|
||||||
/* Disable alter of enabled log tables */
|
/* Disable alter of enabled log tables */
|
||||||
if ((table_kind == GENERAL_LOG && opt_log &&
|
if (table_kind && logger.is_log_table_enabled(table_kind))
|
||||||
logger.is_general_log_table_enabled()) ||
|
|
||||||
(table_kind == SLOW_LOG && opt_slow_log &&
|
|
||||||
logger.is_slow_log_table_enabled()))
|
|
||||||
{
|
{
|
||||||
my_error(ER_BAD_LOG_STATEMENT, MYF(0), "ALTER");
|
my_error(ER_BAD_LOG_STATEMENT, MYF(0), "ALTER");
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable alter of log tables to unsupported engine */
|
/* Disable alter of log tables to unsupported engine */
|
||||||
if ((table_kind == GENERAL_LOG || table_kind == SLOW_LOG) &&
|
if (table_kind &&
|
||||||
(lex_create_info->used_fields & HA_CREATE_USED_ENGINE) &&
|
(lex_create_info->used_fields & HA_CREATE_USED_ENGINE) &&
|
||||||
(!lex_create_info->db_type || /* unknown engine */
|
(!lex_create_info->db_type || /* unknown engine */
|
||||||
!(lex_create_info->db_type->flags & HTON_SUPPORT_LOG_TABLES)))
|
!(lex_create_info->db_type->flags & HTON_SUPPORT_LOG_TABLES)))
|
||||||
|
19
sql/table.cc
19
sql/table.cc
@ -363,25 +363,24 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags)
|
|||||||
error= open_binary_frm(thd, share, head, file);
|
error= open_binary_frm(thd, share, head, file);
|
||||||
*root_ptr= old_root;
|
*root_ptr= old_root;
|
||||||
|
|
||||||
if (share->db.length == 5 &&
|
if (share->db.length == 5 && !(lower_case_table_names ?
|
||||||
!my_strcasecmp(system_charset_info, share->db.str, "mysql"))
|
my_strcasecmp(system_charset_info, share->db.str, "mysql") :
|
||||||
|
strcmp(share->db.str, "mysql")))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
We can't mark all tables in 'mysql' database as system since we don't
|
We can't mark all tables in 'mysql' database as system since we don't
|
||||||
allow to lock such tables for writing with any other tables (even with
|
allow to lock such tables for writing with any other tables (even with
|
||||||
other system tables) and some privilege tables need this.
|
other system tables) and some privilege tables need this.
|
||||||
*/
|
*/
|
||||||
if (!my_strcasecmp(system_charset_info, share->table_name.str, "proc"))
|
if (!(lower_case_table_names ?
|
||||||
|
my_strcasecmp(system_charset_info, share->table_name.str, "proc") :
|
||||||
|
strcmp(share->table_name.str, "proc")))
|
||||||
share->system_table= 1;
|
share->system_table= 1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!my_strcasecmp(system_charset_info, share->table_name.str,
|
share->log_table= check_if_log_table(share->db.length, share->db.str,
|
||||||
"general_log"))
|
share->table_name.length,
|
||||||
share->log_table= QUERY_LOG_GENERAL;
|
share->table_name.str, 0);
|
||||||
else
|
|
||||||
if (!my_strcasecmp(system_charset_info, share->table_name.str,
|
|
||||||
"slow_log"))
|
|
||||||
share->log_table= QUERY_LOG_SLOW;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
error_given= 1;
|
error_given= 1;
|
||||||
|
@ -826,9 +826,9 @@ void ha_tina::update_status()
|
|||||||
bool ha_tina::check_if_locking_is_allowed(uint sql_command,
|
bool ha_tina::check_if_locking_is_allowed(uint sql_command,
|
||||||
ulong type, TABLE *table,
|
ulong type, TABLE *table,
|
||||||
uint count,
|
uint count,
|
||||||
bool called_by_logger_thread)
|
bool called_by_privileged_thread)
|
||||||
{
|
{
|
||||||
if (!called_by_logger_thread)
|
if (!called_by_privileged_thread)
|
||||||
return check_if_log_table_locking_is_allowed(sql_command, type, table);
|
return check_if_log_table_locking_is_allowed(sql_command, type, table);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -265,7 +265,7 @@ err:
|
|||||||
bool ha_myisam::check_if_locking_is_allowed(uint sql_command,
|
bool ha_myisam::check_if_locking_is_allowed(uint sql_command,
|
||||||
ulong type, TABLE *table,
|
ulong type, TABLE *table,
|
||||||
uint count,
|
uint count,
|
||||||
bool called_by_logger_thread)
|
bool called_by_privileged_thread)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
To be able to open and lock for reading system tables like 'mysql.proc',
|
To be able to open and lock for reading system tables like 'mysql.proc',
|
||||||
@ -283,10 +283,10 @@ bool ha_myisam::check_if_locking_is_allowed(uint sql_command,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Deny locking of the log tables, which is incompatible with
|
Deny locking of the log tables, which is incompatible with
|
||||||
concurrent insert. Unless called from a logger THD:
|
concurrent insert. Unless called from a logger THD (general_log_thd
|
||||||
general_log_thd or slow_log_thd.
|
or slow_log_thd) or by a privileged thread.
|
||||||
*/
|
*/
|
||||||
if (!called_by_logger_thread)
|
if (!called_by_privileged_thread)
|
||||||
return check_if_log_table_locking_is_allowed(sql_command, type, table);
|
return check_if_log_table_locking_is_allowed(sql_command, type, table);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user