diff -ruN mysql-5.0.67-original/include/mysql_com.h mysql-5.0.67/include/mysql_com.h --- mysql-5.0.67-original/include/mysql_com.h 2008-08-04 05:19:12.000000000 -0700 +++ mysql-5.0.67/include/mysql_com.h 2008-10-02 18:33:44.614070000 -0700 @@ -106,6 +106,7 @@ thread */ #define REFRESH_MASTER 128 /* Remove all bin logs in the index and truncate the index */ +#define REFRESH_SLOW_QUERY_LOG 4096 /* Flush slow query log and rotate*/ /* The following can't be set with mysql_refresh() */ #define REFRESH_READ_LOCK 16384 /* Lock tables for read */ diff -ruN mysql-5.0.67-original/mysql-test/r/slow_query_log.result mysql-5.0.67/mysql-test/r/slow_query_log.result --- mysql-5.0.67-original/mysql-test/r/slow_query_log.result 1969-12-31 16:00:00.000000000 -0800 +++ mysql-5.0.67/mysql-test/r/slow_query_log.result 2008-10-02 18:34:05.507002000 -0700 @@ -0,0 +1,8 @@ +test-slow.log.000001 +flush logs; +test-slow.log.000001 +test-slow.log.000002 +flush slow query logs; +test-slow.log.000001 +test-slow.log.000002 +test-slow.log.000003 diff -ruN mysql-5.0.67-original/mysql-test/t/slow_query_log-master.opt mysql-5.0.67/mysql-test/t/slow_query_log-master.opt --- mysql-5.0.67-original/mysql-test/t/slow_query_log-master.opt 1969-12-31 16:00:00.000000000 -0800 +++ mysql-5.0.67/mysql-test/t/slow_query_log-master.opt 2008-10-02 18:34:35.928649000 -0700 @@ -0,0 +1 @@ +--log-slow-queries=test-slow.log --long-query-time=0 diff -ruN mysql-5.0.67-original/mysql-test/t/slow_query_log.test mysql-5.0.67/mysql-test/t/slow_query_log.test --- mysql-5.0.67-original/mysql-test/t/slow_query_log.test 1969-12-31 16:00:00.000000000 -0800 +++ mysql-5.0.67/mysql-test/t/slow_query_log.test 2008-10-02 18:34:35.930651000 -0700 @@ -0,0 +1,7 @@ +# Test to test slow query rotation functions + +--exec find $MYSQLTEST_VARDIR/master-data -name "test-slow.log.*" -printf "%f\n" | sort +flush logs; +--exec find $MYSQLTEST_VARDIR/master-data -name "test-slow.log.*" -printf "%f\n" | sort +flush slow query logs; +--exec find $MYSQLTEST_VARDIR/master-data -name "test-slow.log.*" -printf "%f\n" | sort diff -ruN mysql-5.0.67-original/sql/lex.h mysql-5.0.67/sql/lex.h --- mysql-5.0.67-original/sql/lex.h 2008-08-04 05:20:07.000000000 -0700 +++ mysql-5.0.67/sql/lex.h 2008-10-02 18:35:49.580921000 -0700 @@ -442,6 +442,7 @@ { "SIGNED", SYM(SIGNED_SYM)}, { "SIMPLE", SYM(SIMPLE_SYM)}, { "SLAVE", SYM(SLAVE)}, + { "SLOW", SYM(SLOW_SYM)}, { "SNAPSHOT", SYM(SNAPSHOT_SYM)}, { "SMALLINT", SYM(SMALLINT)}, { "SOME", SYM(ANY_SYM)}, diff -ruN mysql-5.0.67-original/sql/log.cc mysql-5.0.67/sql/log.cc --- mysql-5.0.67-original/sql/log.cc 2008-08-04 05:20:07.000000000 -0700 +++ mysql-5.0.67/sql/log.cc 2008-10-02 18:35:56.891937000 -0700 @@ -406,7 +406,8 @@ :bytes_written(0), last_time(0), query_start(0), name(0), prepared_xids(0), log_type(LOG_CLOSED), file_id(1), open_count(1), write_error(FALSE), inited(FALSE), need_start_event(TRUE), - description_event_for_exec(0), description_event_for_queue(0) + description_event_for_exec(0), description_event_for_queue(0), + is_sequenced(false) { /* We don't want to initialize LOCK_Log here as such initialization depends on @@ -502,6 +503,11 @@ return log_name; } +void MYSQL_LOG::set_sequenced_flag(bool is_sequenced_arg) +{ + is_sequenced = is_sequenced_arg; +} + bool MYSQL_LOG::open_index_file(const char *index_file_name_arg, const char *log_name) { @@ -756,6 +762,44 @@ DBUG_RETURN(1); } +/* + Open a (new) sequenced log file. + + DESCRIPTION + - If binary logs, also open the index file and register the new + file name in it + - When calling this when the file is in use, you must have a locks + on LOCK_log and LOCK_index. + + RETURN VALUES + FALSE ok + TRUE error +*/ +bool MYSQL_LOG::open_sequenced(const char *log_name, + enum_log_type log_type, + enum cache_type io_cache_type_arg, + bool no_auto_events_arg, ulong max_size, + bool null_created) +{ + char new_name[FN_REFLEN]; + fn_format(new_name, log_name, mysql_data_home, "", 4); + // Find the unique filename next in sequence. The sequence number is + // appended to the end of the filename, similar to binlogs. + if (find_uniq_filename(new_name)) + { + sql_print_error(ER(ER_NO_UNIQUE_LOGFILE), log_name); + return TRUE; + } + + if (open(log_name, log_type, new_name, io_cache_type_arg, + no_auto_events_arg, max_size, null_created)) + { + sql_print_error("Could not open %s.", new_name); + return TRUE; + } + + return FALSE; +} int MYSQL_LOG::get_current_log(LOG_INFO* linfo) { @@ -1449,18 +1493,23 @@ NOTE The new file name is stored last in the index file + + RETURN VALUES + FALSE ok + TRUE Some error occured */ -void MYSQL_LOG::new_file(bool need_lock) +bool MYSQL_LOG::new_file(bool need_lock) { char new_name[FN_REFLEN], *new_name_ptr, *old_name; enum_log_type save_log_type; + bool return_value = false; DBUG_ENTER("MYSQL_LOG::new_file"); if (!is_open()) { DBUG_PRINT("info",("log is closed")); - DBUG_VOID_RETURN; + DBUG_RETURN(TRUE); } if (need_lock) @@ -1496,8 +1545,10 @@ We have to do this here and not in open as we want to store the new file name in the current binary log file. */ - if (generate_new_name(new_name, name)) + if (generate_new_name(new_name, name)) { + return_value = true; goto end; + } new_name_ptr=new_name; if (log_type == LOG_BIN) @@ -1539,8 +1590,14 @@ trigger temp tables deletion on slaves. */ - open(old_name, save_log_type, new_name_ptr, - io_cache_type, no_auto_events, max_size, 1); + if(is_sequenced) { + return_value |= open_sequenced(old_name, save_log_type, io_cache_type, + no_auto_events, max_size, 1); + } + else { + return_value |= open(old_name, save_log_type, new_name_ptr, + io_cache_type, no_auto_events, max_size, 1); + } my_free(old_name,MYF(0)); end: @@ -1548,7 +1605,7 @@ pthread_mutex_unlock(&LOCK_log); pthread_mutex_unlock(&LOCK_index); - DBUG_VOID_RETURN; + DBUG_RETURN(return_value); } @@ -2297,6 +2354,12 @@ } } VOID(pthread_mutex_unlock(&LOCK_log)); + + + // Rotate the slow log if it exceeds max_binlog_size. + if (is_sequenced && my_b_tell(&log_file) >= max_binlog_size) + new_file(1); + DBUG_RETURN(error); } @@ -3342,4 +3405,3 @@ "--tc-heuristic-recover={commit|rollback}"); return 1; } - diff -ruN mysql-5.0.67-original/sql/mysqld.cc mysql-5.0.67/sql/mysqld.cc --- mysql-5.0.67-original/sql/mysqld.cc 2008-08-04 05:20:07.000000000 -0700 +++ mysql-5.0.67/sql/mysqld.cc 2008-10-02 18:36:03.501895000 -0700 @@ -3343,8 +3343,10 @@ unireg_abort(1); } - if (opt_slow_log) + if (opt_slow_log) { + mysql_slow_log.set_sequenced_flag(true); mysql_slow_log.open_slow_log(opt_slow_logname); + } #ifdef HAVE_REPLICATION if (opt_log_slave_updates && replicate_same_server_id) diff -ruN mysql-5.0.67-original/sql/sql_class.h mysql-5.0.67/sql/sql_class.h --- mysql-5.0.67-original/sql/sql_class.h 2008-08-04 05:20:09.000000000 -0700 +++ mysql-5.0.67/sql/sql_class.h 2008-10-02 18:36:13.865446000 -0700 @@ -238,6 +238,18 @@ bool no_auto_events; friend class Log_event; + // If true, the log will have sequence numbers appended to the filename, + // and will increment each time the log are flushed. If false, it will + // simply reopen the same filename. + bool is_sequenced; + + /* Open the current sequence file */ + bool open_sequenced(const char *log_name, + enum_log_type log_type, + enum cache_type io_cache_type_arg, + bool no_auto_events_arg, ulong max_size, + bool null_created); + public: /* These describe the log's format. This is used only for relay logs. @@ -305,12 +317,18 @@ bool open_slow_log(const char *log_name) { char buf[FN_REFLEN]; - return open(generate_name(log_name, "-slow.log", 0, buf), + if(is_sequenced) { + return open_sequenced(generate_name(log_name, "-slow.log", 0, buf), + LOG_NORMAL, WRITE_CACHE, 0, 0, 0); + } + else { + return open(generate_name(log_name, "-slow.log", 0, buf), LOG_NORMAL, 0, WRITE_CACHE, 0, 0, 0); + } } bool open_index_file(const char *index_file_name_arg, const char *log_name); - void new_file(bool need_lock); + bool new_file(bool need_lock); bool write(THD *thd, enum enum_server_command command, const char *format, ...) ATTRIBUTE_FORMAT(printf, 4, 5); bool write(THD *thd, const char *query, uint query_length, @@ -361,6 +379,7 @@ inline void unlock_index() { pthread_mutex_unlock(&LOCK_index);} inline IO_CACHE *get_index_file() { return &index_file;} inline uint32 get_open_count() { return open_count; } + void set_sequenced_flag(bool is_sequenced_arg); }; /* @@ -2513,4 +2532,3 @@ void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var); void mark_transaction_to_rollback(THD *thd, bool all); - diff -ruN mysql-5.0.67-original/sql/sql_parse.cc mysql-5.0.67/sql/sql_parse.cc --- mysql-5.0.67-original/sql/sql_parse.cc 2008-08-04 05:20:10.000000000 -0700 +++ mysql-5.0.67/sql/sql_parse.cc 2008-10-02 18:36:23.244987000 -0700 @@ -4317,6 +4317,15 @@ if (check_global_access(thd,RELOAD_ACL)) goto error; + if(lex->type & REFRESH_SLOW_QUERY_LOG) { + /* We are only flushing slow query log */ + if(mysql_slow_log.new_file(1)) + goto error; + + send_ok(thd); + break; + } + /* reload_acl_and_cache() will tell us if we are allowed to write to the binlog or not. @@ -8002,4 +8011,3 @@ } DBUG_RETURN(0); } - diff -ruN mysql-5.0.67-original/sql/sql_yacc.yy mysql-5.0.67/sql/sql_yacc.yy --- mysql-5.0.67-original/sql/sql_yacc.yy 2008-08-04 05:20:12.000000000 -0700 +++ mysql-5.0.67/sql/sql_yacc.yy 2008-10-02 18:36:31.820838000 -0700 @@ -907,6 +907,7 @@ %token SIGNED_SYM %token SIMPLE_SYM %token SLAVE +%token SLOW_SYM %token SMALLINT %token SNAPSHOT_SYM %token SOUNDS_SYM @@ -7520,6 +7521,7 @@ | LOGS_SYM { Lex->type|= REFRESH_LOG; } | STATUS_SYM { Lex->type|= REFRESH_STATUS; } | SLAVE { Lex->type|= REFRESH_SLAVE; } + | SLOW_SYM QUERY_SYM LOGS_SYM { Lex->type |= REFRESH_SLOW_QUERY_LOG; } | MASTER_SYM { Lex->type|= REFRESH_MASTER; } | DES_KEY_FILE { Lex->type|= REFRESH_DES_KEY_FILE; } | RESOURCES { Lex->type|= REFRESH_USER_RESOURCES; };