diff --git a/include/m_ctype.h b/include/m_ctype.h index 8673794356a06..215837972eb06 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -27,7 +27,8 @@ enum loglevel { ERROR_LEVEL= 0, WARNING_LEVEL= 1, - INFORMATION_LEVEL= 2 + INFORMATION_LEVEL= 2, + DEBUG_LEVEL= 3 }; #ifdef __cplusplus diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp index 3d57b383f10cc..d589948f526bc 100644 --- a/include/mysql/plugin_audit.h.pp +++ b/include/mysql/plugin_audit.h.pp @@ -128,22 +128,32 @@ void (*logger_init_mutexes)(); LOGGER_HANDLE* (*open)(const char *path, unsigned long long size_limit, + unsigned long long buffer_limit, unsigned int rotations); int (*close)(LOGGER_HANDLE *log); int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr); int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...); int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size); - int (*rotate)(LOGGER_HANDLE *log); + int (*rotate)(LOGGER_HANDLE *log, const unsigned int n_rotations); + int (*rename_file)(LOGGER_HANDLE *log, const char *path); + int (*resize_buffer)(LOGGER_HANDLE *log, unsigned long long buffer_limit); + int (*resize_size)(LOGGER_HANDLE *log, unsigned long long size_limit); + int (*flush)(LOGGER_HANDLE *log); } *logger_service; void logger_init_mutexes(); LOGGER_HANDLE *logger_open(const char *path, unsigned long long size_limit, + unsigned long long buffer_limit, unsigned int rotations); int logger_close(LOGGER_HANDLE *log); int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr); int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...); int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size); - int logger_rotate(LOGGER_HANDLE *log); + int logger_rotate(LOGGER_HANDLE *log, const unsigned int n_rotations); + int logger_rename_file(LOGGER_HANDLE *log, const char* path); + int logger_resize_buffer(LOGGER_HANDLE *log, unsigned long long buffer_limit); + int logger_resize_size(LOGGER_HANDLE *log, unsigned long long size_limit); + int logger_flush(LOGGER_HANDLE *log); } extern "C" { extern struct my_md5_service_st { diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp index fbb4f5910ecf9..65a2f9e4a3cb4 100644 --- a/include/mysql/plugin_auth.h.pp +++ b/include/mysql/plugin_auth.h.pp @@ -128,22 +128,32 @@ void (*logger_init_mutexes)(); LOGGER_HANDLE* (*open)(const char *path, unsigned long long size_limit, + unsigned long long buffer_limit, unsigned int rotations); int (*close)(LOGGER_HANDLE *log); int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr); int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...); int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size); - int (*rotate)(LOGGER_HANDLE *log); + int (*rotate)(LOGGER_HANDLE *log, const unsigned int n_rotations); + int (*rename_file)(LOGGER_HANDLE *log, const char *path); + int (*resize_buffer)(LOGGER_HANDLE *log, unsigned long long buffer_limit); + int (*resize_size)(LOGGER_HANDLE *log, unsigned long long size_limit); + int (*flush)(LOGGER_HANDLE *log); } *logger_service; void logger_init_mutexes(); LOGGER_HANDLE *logger_open(const char *path, unsigned long long size_limit, + unsigned long long buffer_limit, unsigned int rotations); int logger_close(LOGGER_HANDLE *log); int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr); int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...); int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size); - int logger_rotate(LOGGER_HANDLE *log); + int logger_rotate(LOGGER_HANDLE *log, const unsigned int n_rotations); + int logger_rename_file(LOGGER_HANDLE *log, const char* path); + int logger_resize_buffer(LOGGER_HANDLE *log, unsigned long long buffer_limit); + int logger_resize_size(LOGGER_HANDLE *log, unsigned long long size_limit); + int logger_flush(LOGGER_HANDLE *log); } extern "C" { extern struct my_md5_service_st { diff --git a/include/mysql/plugin_data_type.h.pp b/include/mysql/plugin_data_type.h.pp index be20dcccd557a..c21e367404bb8 100644 --- a/include/mysql/plugin_data_type.h.pp +++ b/include/mysql/plugin_data_type.h.pp @@ -128,22 +128,32 @@ void (*logger_init_mutexes)(); LOGGER_HANDLE* (*open)(const char *path, unsigned long long size_limit, + unsigned long long buffer_limit, unsigned int rotations); int (*close)(LOGGER_HANDLE *log); int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr); int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...); int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size); - int (*rotate)(LOGGER_HANDLE *log); + int (*rotate)(LOGGER_HANDLE *log, const unsigned int n_rotations); + int (*rename_file)(LOGGER_HANDLE *log, const char *path); + int (*resize_buffer)(LOGGER_HANDLE *log, unsigned long long buffer_limit); + int (*resize_size)(LOGGER_HANDLE *log, unsigned long long size_limit); + int (*flush)(LOGGER_HANDLE *log); } *logger_service; void logger_init_mutexes(); LOGGER_HANDLE *logger_open(const char *path, unsigned long long size_limit, + unsigned long long buffer_limit, unsigned int rotations); int logger_close(LOGGER_HANDLE *log); int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr); int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...); int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size); - int logger_rotate(LOGGER_HANDLE *log); + int logger_rotate(LOGGER_HANDLE *log, const unsigned int n_rotations); + int logger_rename_file(LOGGER_HANDLE *log, const char* path); + int logger_resize_buffer(LOGGER_HANDLE *log, unsigned long long buffer_limit); + int logger_resize_size(LOGGER_HANDLE *log, unsigned long long size_limit); + int logger_flush(LOGGER_HANDLE *log); } extern "C" { extern struct my_md5_service_st { diff --git a/include/mysql/plugin_encryption.h.pp b/include/mysql/plugin_encryption.h.pp index 21edc27e4e350..b235dae1814ab 100644 --- a/include/mysql/plugin_encryption.h.pp +++ b/include/mysql/plugin_encryption.h.pp @@ -128,22 +128,32 @@ void (*logger_init_mutexes)(); LOGGER_HANDLE* (*open)(const char *path, unsigned long long size_limit, + unsigned long long buffer_limit, unsigned int rotations); int (*close)(LOGGER_HANDLE *log); int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr); int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...); int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size); - int (*rotate)(LOGGER_HANDLE *log); + int (*rotate)(LOGGER_HANDLE *log, const unsigned int n_rotations); + int (*rename_file)(LOGGER_HANDLE *log, const char *path); + int (*resize_buffer)(LOGGER_HANDLE *log, unsigned long long buffer_limit); + int (*resize_size)(LOGGER_HANDLE *log, unsigned long long size_limit); + int (*flush)(LOGGER_HANDLE *log); } *logger_service; void logger_init_mutexes(); LOGGER_HANDLE *logger_open(const char *path, unsigned long long size_limit, + unsigned long long buffer_limit, unsigned int rotations); int logger_close(LOGGER_HANDLE *log); int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr); int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...); int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size); - int logger_rotate(LOGGER_HANDLE *log); + int logger_rotate(LOGGER_HANDLE *log, const unsigned int n_rotations); + int logger_rename_file(LOGGER_HANDLE *log, const char* path); + int logger_resize_buffer(LOGGER_HANDLE *log, unsigned long long buffer_limit); + int logger_resize_size(LOGGER_HANDLE *log, unsigned long long size_limit); + int logger_flush(LOGGER_HANDLE *log); } extern "C" { extern struct my_md5_service_st { diff --git a/include/mysql/plugin_ftparser.h.pp b/include/mysql/plugin_ftparser.h.pp index 58b8274fcb0cc..5b09e059f279e 100644 --- a/include/mysql/plugin_ftparser.h.pp +++ b/include/mysql/plugin_ftparser.h.pp @@ -128,22 +128,32 @@ void (*logger_init_mutexes)(); LOGGER_HANDLE* (*open)(const char *path, unsigned long long size_limit, + unsigned long long buffer_limit, unsigned int rotations); int (*close)(LOGGER_HANDLE *log); int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr); int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...); int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size); - int (*rotate)(LOGGER_HANDLE *log); + int (*rotate)(LOGGER_HANDLE *log, const unsigned int n_rotations); + int (*rename_file)(LOGGER_HANDLE *log, const char *path); + int (*resize_buffer)(LOGGER_HANDLE *log, unsigned long long buffer_limit); + int (*resize_size)(LOGGER_HANDLE *log, unsigned long long size_limit); + int (*flush)(LOGGER_HANDLE *log); } *logger_service; void logger_init_mutexes(); LOGGER_HANDLE *logger_open(const char *path, unsigned long long size_limit, + unsigned long long buffer_limit, unsigned int rotations); int logger_close(LOGGER_HANDLE *log); int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr); int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...); int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size); - int logger_rotate(LOGGER_HANDLE *log); + int logger_rotate(LOGGER_HANDLE *log, const unsigned int n_rotations); + int logger_rename_file(LOGGER_HANDLE *log, const char* path); + int logger_resize_buffer(LOGGER_HANDLE *log, unsigned long long buffer_limit); + int logger_resize_size(LOGGER_HANDLE *log, unsigned long long size_limit); + int logger_flush(LOGGER_HANDLE *log); } extern "C" { extern struct my_md5_service_st { diff --git a/include/mysql/plugin_function.h.pp b/include/mysql/plugin_function.h.pp index f1c4ad93b33ac..d4f6396440880 100644 --- a/include/mysql/plugin_function.h.pp +++ b/include/mysql/plugin_function.h.pp @@ -128,22 +128,32 @@ void (*logger_init_mutexes)(); LOGGER_HANDLE* (*open)(const char *path, unsigned long long size_limit, + unsigned long long buffer_limit, unsigned int rotations); int (*close)(LOGGER_HANDLE *log); int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr); int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...); int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size); - int (*rotate)(LOGGER_HANDLE *log); + int (*rotate)(LOGGER_HANDLE *log, const unsigned int n_rotations); + int (*rename_file)(LOGGER_HANDLE *log, const char *path); + int (*resize_buffer)(LOGGER_HANDLE *log, unsigned long long buffer_limit); + int (*resize_size)(LOGGER_HANDLE *log, unsigned long long size_limit); + int (*flush)(LOGGER_HANDLE *log); } *logger_service; void logger_init_mutexes(); LOGGER_HANDLE *logger_open(const char *path, unsigned long long size_limit, + unsigned long long buffer_limit, unsigned int rotations); int logger_close(LOGGER_HANDLE *log); int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr); int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...); int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size); - int logger_rotate(LOGGER_HANDLE *log); + int logger_rotate(LOGGER_HANDLE *log, const unsigned int n_rotations); + int logger_rename_file(LOGGER_HANDLE *log, const char* path); + int logger_resize_buffer(LOGGER_HANDLE *log, unsigned long long buffer_limit); + int logger_resize_size(LOGGER_HANDLE *log, unsigned long long size_limit); + int logger_flush(LOGGER_HANDLE *log); } extern "C" { extern struct my_md5_service_st { diff --git a/include/mysql/plugin_password_validation.h.pp b/include/mysql/plugin_password_validation.h.pp index 5f9bd1b398933..2149783dd6c52 100644 --- a/include/mysql/plugin_password_validation.h.pp +++ b/include/mysql/plugin_password_validation.h.pp @@ -128,22 +128,32 @@ void (*logger_init_mutexes)(); LOGGER_HANDLE* (*open)(const char *path, unsigned long long size_limit, + unsigned long long buffer_limit, unsigned int rotations); int (*close)(LOGGER_HANDLE *log); int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr); int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...); int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size); - int (*rotate)(LOGGER_HANDLE *log); + int (*rotate)(LOGGER_HANDLE *log, const unsigned int n_rotations); + int (*rename_file)(LOGGER_HANDLE *log, const char *path); + int (*resize_buffer)(LOGGER_HANDLE *log, unsigned long long buffer_limit); + int (*resize_size)(LOGGER_HANDLE *log, unsigned long long size_limit); + int (*flush)(LOGGER_HANDLE *log); } *logger_service; void logger_init_mutexes(); LOGGER_HANDLE *logger_open(const char *path, unsigned long long size_limit, + unsigned long long buffer_limit, unsigned int rotations); int logger_close(LOGGER_HANDLE *log); int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr); int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...); int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size); - int logger_rotate(LOGGER_HANDLE *log); + int logger_rotate(LOGGER_HANDLE *log, const unsigned int n_rotations); + int logger_rename_file(LOGGER_HANDLE *log, const char* path); + int logger_resize_buffer(LOGGER_HANDLE *log, unsigned long long buffer_limit); + int logger_resize_size(LOGGER_HANDLE *log, unsigned long long size_limit); + int logger_flush(LOGGER_HANDLE *log); } extern "C" { extern struct my_md5_service_st { diff --git a/include/mysql/service_logger.h b/include/mysql/service_logger.h index 5979901bdd0c3..8b965c19601cd 100644 --- a/include/mysql/service_logger.h +++ b/include/mysql/service_logger.h @@ -24,17 +24,22 @@ @file logger service - Log file with rotation implementation. + Log file with buffered writing and rotation implementation. - This service implements logging with possible rotation - of the log files. Interface intentionally tries to be similar to FILE* - related functions. + This service implements logging with possible buffered writing + and rotation of the log files. Interface intentionally tries to + be similar to FILE* related functions. So that one can open the log with logger_open(), specifying - the limit on the logfile size and the rotations number. + the limit on the logfile size, possible buffer size and the + rotations number. + + If buffer size is given, messages are written to buffer. + If size of messages in buffer grow over the specified + limit, they are written to logfile. Then it's possible to write messages to the log with - logger_printf or logger_vprintf functions. + logger_printf, logger_vprintf or logger_write functions. As the size of the logfile grows over the specified limit, it is renamed to 'logfile.1'. The former 'logfile.1' becomes @@ -63,37 +68,55 @@ extern struct logger_service_st { void (*logger_init_mutexes)(); LOGGER_HANDLE* (*open)(const char *path, unsigned long long size_limit, + unsigned long long buffer_limit, unsigned int rotations); int (*close)(LOGGER_HANDLE *log); int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr); int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...); int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size); - int (*rotate)(LOGGER_HANDLE *log); + int (*rotate)(LOGGER_HANDLE *log, const unsigned int n_rotations); + int (*rename_file)(LOGGER_HANDLE *log, const char *path); + int (*resize_buffer)(LOGGER_HANDLE *log, unsigned long long buffer_limit); + int (*resize_size)(LOGGER_HANDLE *log, unsigned long long size_limit); + int (*flush)(LOGGER_HANDLE *log); } *logger_service; #ifdef MYSQL_DYNAMIC_PLUGIN #define logger_init_mutexes logger_service->logger_init_mutexes -#define logger_open(path, size_limit, rotations) \ - (logger_service->open(path, size_limit, rotations)) +#define logger_open(path, size_limit, buffer_limit, rotations) \ + (logger_service->open(path, size_limit, buffer_limit, rotations)) #define logger_close(log) (logger_service->close(log)) -#define logger_rotate(log) (logger_service->rotate(log)) +#define logger_rotate(log, rotations) (logger_service->rotate(log, rotations)) #define logger_vprintf(log, fmt, argptr) (logger_service->\ vprintf(log, fmt, argptr)) #define logger_printf (*logger_service->printf) #define logger_write(log, buffer, size) \ (logger_service->write(log, buffer, size)) +#define logger_rename_file(log, path) \ + (logger_service->rename_file(log, path)) +#define logger_resize_buffer(log, buffer_limit) \ + (logger_service->resize_buffer(log, path)) +#define logger_resize_size(log, size_limit) \ + (logger_service->resize_size(log, size_limit)) +#define logger_flush(log) \ + (logger_service->flush(log)) #else void logger_init_mutexes(); LOGGER_HANDLE *logger_open(const char *path, unsigned long long size_limit, + unsigned long long buffer_limit, unsigned int rotations); int logger_close(LOGGER_HANDLE *log); int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr); int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...); int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size); - int logger_rotate(LOGGER_HANDLE *log); + int logger_rotate(LOGGER_HANDLE *log, const unsigned int n_rotations); + int logger_rename_file(LOGGER_HANDLE *log, const char* path); + int logger_resize_buffer(LOGGER_HANDLE *log, unsigned long long buffer_limit); + int logger_resize_size(LOGGER_HANDLE *log, unsigned long long size_limit); + int logger_flush(LOGGER_HANDLE *log); #endif diff --git a/include/wsrep.h b/include/wsrep.h index e4535deabfe5c..e5ab917399353 100644 --- a/include/wsrep.h +++ b/include/wsrep.h @@ -23,11 +23,17 @@ #define IF_WSREP(A,B) A #define DBUG_ASSERT_IF_WSREP(A) DBUG_ASSERT(A) -extern ulong wsrep_debug; // wsrep_mysqld.cc +/** wsrep_debug_mode is controlled by wsrep_debug and +wsrep_buffered_error_log_buffer_size variables. +If any of these are set we output also debug messages. */ +extern ulong wsrep_debug_mode; // wsrep_var.cc + extern void WSREP_LOG(void (*fun)(const char* fmt, ...), const char* fmt, ...); -#define WSREP_DEBUG(...) \ - if (wsrep_debug) WSREP_LOG(sql_print_information, ##__VA_ARGS__) +#define WSREP_DEBUG(...) \ + if (wsrep_debug_mode) \ + WSREP_LOG(sql_print_debug, ##__VA_ARGS__) + #define WSREP_INFO(...) WSREP_LOG(sql_print_information, ##__VA_ARGS__) #define WSREP_WARN(...) WSREP_LOG(sql_print_warning, ##__VA_ARGS__) #define WSREP_ERROR(...) WSREP_LOG(sql_print_error, ##__VA_ARGS__) @@ -47,7 +53,7 @@ extern void WSREP_LOG(void (*fun)(const char* fmt, ...), const char* fmt, ...); ); #define WSREP_LOG_CONFLICT(bf_thd, victim_thd, bf_abort) \ - if (wsrep_debug || wsrep_log_conflicts) \ + if (wsrep_debug_mode || wsrep_log_conflicts) \ { \ WSREP_INFO("cluster conflict due to %s for threads:", \ (bf_abort) ? "high priority abort" : "certification failure" \ diff --git a/mysql-test/include/galera_variables_ok.inc b/mysql-test/include/galera_variables_ok.inc index e420b3af6c30b..3dc9c65566954 100644 --- a/mysql-test/include/galera_variables_ok.inc +++ b/mysql-test/include/galera_variables_ok.inc @@ -1,6 +1,6 @@ --disable_query_log ---let $galera_variables_ok = `SELECT COUNT(*) = 51 FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIKE 'wsrep%'` +--let $galera_variables_ok = `SELECT COUNT(*) = 53 FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIKE 'wsrep%'` --if (!$galera_variables_ok) { --skip Galera number of variables has changed! diff --git a/mysql-test/include/galera_variables_ok_debug.inc b/mysql-test/include/galera_variables_ok_debug.inc index e420b3af6c30b..3dc9c65566954 100644 --- a/mysql-test/include/galera_variables_ok_debug.inc +++ b/mysql-test/include/galera_variables_ok_debug.inc @@ -1,6 +1,6 @@ --disable_query_log ---let $galera_variables_ok = `SELECT COUNT(*) = 51 FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIKE 'wsrep%'` +--let $galera_variables_ok = `SELECT COUNT(*) = 53 FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIKE 'wsrep%'` --if (!$galera_variables_ok) { --skip Galera number of variables has changed! diff --git a/mysql-test/include/send_kill_to_mysqld.inc b/mysql-test/include/send_kill_to_mysqld.inc new file mode 100644 index 0000000000000..857426daece90 --- /dev/null +++ b/mysql-test/include/send_kill_to_mysqld.inc @@ -0,0 +1,38 @@ +# ==== Purpose ==== +# +# send kill signal to mysqld process. +# +# ==== Usage ==== +# +# [--let $_kill_signal= 9] +# --source include/send_kill_to_mysqld.inc +# +# Parameters: +# +# $_kill_signal +# Which signal should be sent to mysqld. (default: 9 / SIGKILL) + +if ($_kill_signal == '') +{ + --let $_kill_signal = 9 +} +--echo Sending kill signal $_kill_signal to mysqld ... + +# Write file to make mysql-test-run.pl expect the crash, but don't start it +--source include/expect_crash.inc + +# Kill the connected server +--disable_reconnect +--let KILL_NODE_PIDFILE = `SELECT @@pid_file` +--let KILL_SIGNAL = $_kill_signal +--perl + my $pid_filename = $ENV{'KILL_NODE_PIDFILE'}; + my $mysqld_pid = `cat $pid_filename`; + my $kill_signal = $ENV{'KILL_SIGNAL'}; + chomp($mysqld_pid); + chomp($kill_signal); + system("kill -$kill_signal $mysqld_pid"); + exit(0); +EOF + +--source include/wait_until_disconnected.inc diff --git a/mysql-test/suite/galera/r/galera_defaults.result b/mysql-test/suite/galera/r/galera_defaults.result index 56c45b71632ca..14a5cd41f089f 100644 --- a/mysql-test/suite/galera/r/galera_defaults.result +++ b/mysql-test/suite/galera/r/galera_defaults.result @@ -19,6 +19,10 @@ ORDER BY VARIABLE_NAME; VARIABLE_NAME VARIABLE_VALUE WSREP_ALLOWLIST WSREP_AUTO_INCREMENT_CONTROL ON +WSREP_BUFFERED_ERROR_LOG_BUFFER_SIZE 0 +WSREP_BUFFERED_ERROR_LOG_FILENAME +WSREP_BUFFERED_ERROR_LOG_FILE_SIZE 0 +WSREP_BUFFERED_ERROR_LOG_ROTATIONS 10 WSREP_CERTIFICATION_RULES strict WSREP_CERTIFY_NONPK ON WSREP_CLUSTER_ADDRESS gcomm:// diff --git a/mysql-test/suite/galera/r/galera_var_buffered_error_log_buffer_size.result b/mysql-test/suite/galera/r/galera_var_buffered_error_log_buffer_size.result new file mode 100644 index 0000000000000..6ebcf93580533 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_var_buffered_error_log_buffer_size.result @@ -0,0 +1,86 @@ +connection node_2; +connection node_1; +connection node_2; +SELECT @@global.wsrep_buffered_error_log_filename; +@@global.wsrep_buffered_error_log_filename +galera_buffered_error_log.err +SELECT @@global.wsrep_buffered_error_log_buffer_size; +@@global.wsrep_buffered_error_log_buffer_size +102400 +SELECT @@global.wsrep_buffered_error_log_file_size; +@@global.wsrep_buffered_error_log_file_size +4194304 +CREATE TABLE t1(a int not null primary key) engine=innodb; +INSERT INTO t1 SELECT * FROM seq_1_to_1000; +# Change buffer size larger +SET GLOBAL wsrep_buffered_error_log_buffer_size = 202400; +SHOW WARNINGS; +Level Code Message +Testing that old log contains something logged +FOUND 1 /WSREP: Loading provider/ in galera_buffered_error_log.err +SELECT @@global.wsrep_buffered_error_log_filename; +@@global.wsrep_buffered_error_log_filename +galera_buffered_error_log.err +SELECT @@global.wsrep_buffered_error_log_buffer_size; +@@global.wsrep_buffered_error_log_buffer_size +202400 +SELECT @@global.wsrep_buffered_error_log_file_size; +@@global.wsrep_buffered_error_log_file_size +4194304 +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +EXPECT_1000 +1000 +DROP TABLE t1; +# Change buffer size smaller +SET GLOBAL wsrep_buffered_error_log_buffer_size = 102400; +SHOW WARNINGS; +Level Code Message +Testing that log contains something logged +FOUND 4 /DROP TABLE/ in galera_buffered_error_log.err +SELECT @@global.wsrep_buffered_error_log_filename; +@@global.wsrep_buffered_error_log_filename +galera_buffered_error_log.err +SELECT @@global.wsrep_buffered_error_log_buffer_size; +@@global.wsrep_buffered_error_log_buffer_size +102400 +SELECT @@global.wsrep_buffered_error_log_file_size; +@@global.wsrep_buffered_error_log_file_size +4194304 +# Try to change buffer size to unsupported size i.e too large +SET GLOBAL wsrep_buffered_error_log_buffer_size = 4194400; +ERROR 42000: Variable 'wsrep_buffered_error_log_buffer_size' can't be set to the value of '4194400' +SHOW WARNINGS; +Level Code Message +Warning 1231 Parameter 'wsrep_buffered_error_log_size' should be at range 102400-419430 because wsrep_buffered_error_log_file_size=4194304 +Error 1231 Variable 'wsrep_buffered_error_log_buffer_size' can't be set to the value of '4194400' +SELECT @@global.wsrep_buffered_error_log_filename; +@@global.wsrep_buffered_error_log_filename +galera_buffered_error_log.err +SELECT @@global.wsrep_buffered_error_log_buffer_size; +@@global.wsrep_buffered_error_log_buffer_size +102400 +SELECT @@global.wsrep_buffered_error_log_file_size; +@@global.wsrep_buffered_error_log_file_size +4194304 +# Try to change buffer size to unsupported size i.e too small +SET GLOBAL wsrep_buffered_error_log_buffer_size = 8196; +ERROR 42000: Variable 'wsrep_buffered_error_log_buffer_size' can't be set to the value of '8196' +SHOW WARNINGS; +Level Code Message +Warning 1231 Parameter 'wsrep_buffered_error_log_size' should be at range 102400-419430 because wsrep_buffered_error_log_file_size=4194304 +Error 1231 Variable 'wsrep_buffered_error_log_buffer_size' can't be set to the value of '8196' +SELECT @@global.wsrep_buffered_error_log_filename; +@@global.wsrep_buffered_error_log_filename +galera_buffered_error_log.err +SELECT @@global.wsrep_buffered_error_log_buffer_size; +@@global.wsrep_buffered_error_log_buffer_size +102400 +SELECT @@global.wsrep_buffered_error_log_file_size; +@@global.wsrep_buffered_error_log_file_size +4194304 +# Reset buffer size to original size +SET GLOBAL wsrep_buffered_error_log_buffer_size = 102400; +SHOW WARNINGS; +Level Code Message +Warning 1231 Parameter 'wsrep_buffered_error_log_size' should be at range 102400-419430 because wsrep_buffered_error_log_file_size=4194304 +Error 1231 Variable 'wsrep_buffered_error_log_buffer_size' can't be set to the value of '8196' diff --git a/mysql-test/suite/galera/r/galera_var_buffered_error_log_file_size.result b/mysql-test/suite/galera/r/galera_var_buffered_error_log_file_size.result new file mode 100644 index 0000000000000..cacac77cad304 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_var_buffered_error_log_file_size.result @@ -0,0 +1,56 @@ +connection node_2; +connection node_1; +connection node_2; +SELECT @@global.wsrep_buffered_error_log_filename; +@@global.wsrep_buffered_error_log_filename +galera_buffered_error_log.err +SELECT @@global.wsrep_buffered_error_log_buffer_size; +@@global.wsrep_buffered_error_log_buffer_size +10240 +SELECT @@global.wsrep_buffered_error_log_file_size; +@@global.wsrep_buffered_error_log_file_size +204800 +CREATE TABLE t1(a int not null primary key auto_increment, count int) engine=innodb; +# Change file size larger +SET GLOBAL wsrep_buffered_error_log_file_size=262144; +# List error log files - should have 3 files +galera_buffered_error_log.err +galera_buffered_error_log.err.1 +galera_buffered_error_log.err.2 +SELECT @@global.wsrep_buffered_error_log_filename; +@@global.wsrep_buffered_error_log_filename +galera_buffered_error_log.err +SELECT @@global.wsrep_buffered_error_log_buffer_size; +@@global.wsrep_buffered_error_log_buffer_size +10240 +SELECT @@global.wsrep_buffered_error_log_file_size; +@@global.wsrep_buffered_error_log_file_size +262144 +SELECT COUNT(*) AS EXPECT_2000 FROM t1; +EXPECT_2000 +2000 +DROP TABLE t1; +# Change file size smaller +SET GLOBAL wsrep_buffered_error_log_file_size=131072; +# List error log files - should be 3 files +galera_buffered_error_log.err +galera_buffered_error_log.err.1 +galera_buffered_error_log.err.2 +SELECT @@global.wsrep_buffered_error_log_filename; +@@global.wsrep_buffered_error_log_filename +galera_buffered_error_log.err +SELECT @@global.wsrep_buffered_error_log_buffer_size; +@@global.wsrep_buffered_error_log_buffer_size +10240 +SELECT @@global.wsrep_buffered_error_log_file_size; +@@global.wsrep_buffered_error_log_file_size +131072 +# Try to change buffer size to unsupported size i.e too small +SET GLOBAL wsrep_buffered_error_log_file_size=1024; +ERROR 42000: Variable 'wsrep_buffered_error_log_file_size' can't be set to the value of '1024' +# Reset file size to original size +SET GLOBAL wsrep_buffered_error_log_file_size=204800; +# List error log files - should be 3 files +galera_buffered_error_log.err +galera_buffered_error_log.err.1 +galera_buffered_error_log.err.2 diff --git a/mysql-test/suite/galera/r/galera_var_buffered_error_log_filename.result b/mysql-test/suite/galera/r/galera_var_buffered_error_log_filename.result new file mode 100644 index 0000000000000..913465fdf6c12 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_var_buffered_error_log_filename.result @@ -0,0 +1,33 @@ +connection node_2; +connection node_1; +connection node_2; +SELECT @@global.wsrep_buffered_error_log_filename; +@@global.wsrep_buffered_error_log_filename +galera_buffered_error_log.err +SELECT @@global.wsrep_buffered_error_log_buffer_size; +@@global.wsrep_buffered_error_log_buffer_size +102400 +SELECT @@global.wsrep_buffered_error_log_file_size; +@@global.wsrep_buffered_error_log_file_size +1048576 +CREATE TABLE t1(a int not null primary key) engine=innodb; +INSERT INTO t1 SELECT * FROM seq_1_to_1000; +# Change file name +Testing that old log contains something logged +FOUND 1 /WSREP: Loading provider/ in galera_buffered_error_log.err +SELECT @@global.wsrep_buffered_error_log_filename; +@@global.wsrep_buffered_error_log_filename +galera_buffered_error_log2.err +SELECT @@global.wsrep_buffered_error_log_buffer_size; +@@global.wsrep_buffered_error_log_buffer_size +102400 +SELECT @@global.wsrep_buffered_error_log_file_size; +@@global.wsrep_buffered_error_log_file_size +1048576 +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +EXPECT_1000 +1000 +DROP TABLE t1; +# Change file name back to original +Testing that second log contains something logged +FOUND 4 /DROP TABLE/ in galera_buffered_error_log2.err diff --git a/mysql-test/suite/galera/r/galera_var_buffered_error_log_rotations.result b/mysql-test/suite/galera/r/galera_var_buffered_error_log_rotations.result new file mode 100644 index 0000000000000..edf8167149c9c --- /dev/null +++ b/mysql-test/suite/galera/r/galera_var_buffered_error_log_rotations.result @@ -0,0 +1,69 @@ +connection node_2; +connection node_1; +connection node_2; +SELECT @@global.wsrep_buffered_error_log_filename; +@@global.wsrep_buffered_error_log_filename +galera_buffered_error_log.err +SELECT @@global.wsrep_buffered_error_log_buffer_size; +@@global.wsrep_buffered_error_log_buffer_size +10240 +SELECT @@global.wsrep_buffered_error_log_file_size; +@@global.wsrep_buffered_error_log_file_size +102400 +SELECT @@global.wsrep_buffered_error_log_rotations; +@@global.wsrep_buffered_error_log_rotations +5 +CREATE TABLE t1(a int not null primary key auto_increment, count int) engine=innodb; +# List error log files - max file number .5 +galera_buffered_error_log.err +galera_buffered_error_log.err.1 +galera_buffered_error_log.err.2 +galera_buffered_error_log.err.3 +galera_buffered_error_log.err.4 +galera_buffered_error_log.err.5 +# Change rotations larger +SET GLOBAL wsrep_buffered_error_log_rotations=6; +# List error log files - max file number .6 +galera_buffered_error_log.err +galera_buffered_error_log.err.1 +galera_buffered_error_log.err.2 +galera_buffered_error_log.err.3 +galera_buffered_error_log.err.4 +galera_buffered_error_log.err.5 +galera_buffered_error_log.err.6 +SELECT @@global.wsrep_buffered_error_log_filename; +@@global.wsrep_buffered_error_log_filename +galera_buffered_error_log.err +SELECT @@global.wsrep_buffered_error_log_buffer_size; +@@global.wsrep_buffered_error_log_buffer_size +10240 +SELECT @@global.wsrep_buffered_error_log_file_size; +@@global.wsrep_buffered_error_log_file_size +102400 +SELECT @@global.wsrep_buffered_error_log_rotations; +@@global.wsrep_buffered_error_log_rotations +6 +# Change rotations smaller and use different name +SET GLOBAL wsrep_buffered_error_log_rotations=2; +SELECT COUNT(*) AS EXPECT_2000 FROM t1; +EXPECT_2000 +3000 +DROP TABLE t1; +# List error log files - max file number .2 +galera_buffered_error_log2.err +galera_buffered_error_log2.err.1 +galera_buffered_error_log2.err.2 +SELECT @@global.wsrep_buffered_error_log_filename; +@@global.wsrep_buffered_error_log_filename +galera_buffered_error_log2.err +SELECT @@global.wsrep_buffered_error_log_buffer_size; +@@global.wsrep_buffered_error_log_buffer_size +10240 +SELECT @@global.wsrep_buffered_error_log_file_size; +@@global.wsrep_buffered_error_log_file_size +102400 +SELECT @@global.wsrep_buffered_error_log_rotations; +@@global.wsrep_buffered_error_log_rotations +2 +# Reset +SET @@global.wsrep_buffered_error_log_rotations=5; diff --git a/mysql-test/suite/galera/t/galera_var_buffered_error_log_buffer_size.cnf b/mysql-test/suite/galera/t/galera_var_buffered_error_log_buffer_size.cnf new file mode 100644 index 0000000000000..edb6815695cd5 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_var_buffered_error_log_buffer_size.cnf @@ -0,0 +1,9 @@ +!include ../galera_2nodes.cnf + +[mysqld] +wsrep-debug=1 + +[mysqld.2] +wsrep_buffered_error_log_buffer_size=100K +wsrep_buffered_error_log_file_size=4M +wsrep_buffered_error_log_filename="galera_buffered_error_log.err" diff --git a/mysql-test/suite/galera/t/galera_var_buffered_error_log_buffer_size.test b/mysql-test/suite/galera/t/galera_var_buffered_error_log_buffer_size.test new file mode 100644 index 0000000000000..409b2588189f6 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_var_buffered_error_log_buffer_size.test @@ -0,0 +1,69 @@ +--source include/galera_cluster.inc +--source include/have_sequence.inc + +--connection node_2 +--replace_regex /.*galera_buffered_error_log.err.*/galera_buffered_error_log.err/ +SELECT @@global.wsrep_buffered_error_log_filename; +SELECT @@global.wsrep_buffered_error_log_buffer_size; +SELECT @@global.wsrep_buffered_error_log_file_size; + +CREATE TABLE t1(a int not null primary key) engine=innodb; +INSERT INTO t1 SELECT * FROM seq_1_to_1000; + +--echo # Change buffer size larger +SET GLOBAL wsrep_buffered_error_log_buffer_size = 202400; +SHOW WARNINGS; + +--echo Testing that old log contains something logged +--let SEARCH_FILE= $MYSQLTEST_VARDIR/mysqld.2/data/galera_buffered_error_log.err +--let ABORT_ON = NOT_FOUND +--let SEARCH_PATTERN=WSREP: Loading provider +--source include/search_pattern_in_file.inc + +--replace_regex /.*galera_buffered_error_log.err.*/galera_buffered_error_log.err/ +SELECT @@global.wsrep_buffered_error_log_filename; +SELECT @@global.wsrep_buffered_error_log_buffer_size; +SELECT @@global.wsrep_buffered_error_log_file_size; + +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +DROP TABLE t1; + +--echo # Change buffer size smaller +SET GLOBAL wsrep_buffered_error_log_buffer_size = 102400; +SHOW WARNINGS; + +--echo Testing that log contains something logged +--let SEARCH_FILE= $MYSQLTEST_VARDIR/mysqld.2/data/galera_buffered_error_log.err +--let ABORT_ON = NOT_FOUND +--let SEARCH_PATTERN=DROP TABLE +--source include/search_pattern_in_file.inc + +--replace_regex /.*galera_buffered_error_log.err.*/galera_buffered_error_log.err/ +SELECT @@global.wsrep_buffered_error_log_filename; +SELECT @@global.wsrep_buffered_error_log_buffer_size; +SELECT @@global.wsrep_buffered_error_log_file_size; + +--echo # Try to change buffer size to unsupported size i.e too large +--error ER_WRONG_VALUE_FOR_VAR +SET GLOBAL wsrep_buffered_error_log_buffer_size = 4194400; +SHOW WARNINGS; + +--replace_regex /.*galera_buffered_error_log.err.*/galera_buffered_error_log.err/ +SELECT @@global.wsrep_buffered_error_log_filename; +SELECT @@global.wsrep_buffered_error_log_buffer_size; +SELECT @@global.wsrep_buffered_error_log_file_size; + +--echo # Try to change buffer size to unsupported size i.e too small +--error ER_WRONG_VALUE_FOR_VAR +SET GLOBAL wsrep_buffered_error_log_buffer_size = 8196; +SHOW WARNINGS; + +--replace_regex /.*galera_buffered_error_log.err.*/galera_buffered_error_log.err/ +SELECT @@global.wsrep_buffered_error_log_filename; +SELECT @@global.wsrep_buffered_error_log_buffer_size; +SELECT @@global.wsrep_buffered_error_log_file_size; + +--echo # Reset buffer size to original size +SET GLOBAL wsrep_buffered_error_log_buffer_size = 102400; +SHOW WARNINGS; + diff --git a/mysql-test/suite/galera/t/galera_var_buffered_error_log_file_size.cnf b/mysql-test/suite/galera/t/galera_var_buffered_error_log_file_size.cnf new file mode 100644 index 0000000000000..93d029970fb78 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_var_buffered_error_log_file_size.cnf @@ -0,0 +1,13 @@ +!include ../galera_2nodes.cnf + +[mysqld] +wsrep-debug=1 + +[mysqld.2] +wsrep_buffered_error_log_buffer_size=10K +wsrep_buffered_error_log_file_size=200K +wsrep_buffered_error_log_filename="galera_buffered_error_log.err" +wsrep_buffered_error_log_rotations=2 +loose-galera-log_file-size + + diff --git a/mysql-test/suite/galera/t/galera_var_buffered_error_log_file_size.test b/mysql-test/suite/galera/t/galera_var_buffered_error_log_file_size.test new file mode 100644 index 0000000000000..4a7ae5e3a1601 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_var_buffered_error_log_file_size.test @@ -0,0 +1,69 @@ +--source include/galera_cluster.inc +--source include/have_sequence.inc +--source include/force_restart.inc + +--connection node_2 +--replace_regex /.*galera_buffered_error_log.err.*/galera_buffered_error_log.err/ +SELECT @@global.wsrep_buffered_error_log_filename; +SELECT @@global.wsrep_buffered_error_log_buffer_size; +SELECT @@global.wsrep_buffered_error_log_file_size; + +CREATE TABLE t1(a int not null primary key auto_increment, count int) engine=innodb; + +--let $inserts=1000 +--let $count=0 +--disable_query_log +while($count < $inserts) +{ + --eval insert into t1 values (NULL,$count) + --eval update t1 set count = $count+100 where count = $count + --inc $count +} +--enable_query_log + +--echo # Change file size larger +SET GLOBAL wsrep_buffered_error_log_file_size=262144; + +--echo # List error log files - should have 3 files +--list_files $MYSQLTEST_VARDIR/mysqld.2/data galera_buffered_error_log* + +--replace_regex /.*galera_buffered_error_log.err.*/galera_buffered_error_log.err/ +SELECT @@global.wsrep_buffered_error_log_filename; +SELECT @@global.wsrep_buffered_error_log_buffer_size; +SELECT @@global.wsrep_buffered_error_log_file_size; + +--let $inserts=1000 +--let $count=0 +--disable_query_log +while($count < $inserts) +{ + --eval insert into t1 values (NULL,$count) + --eval update t1 set count = $count+100 where count = $count + --inc $count +} +--enable_query_log + +SELECT COUNT(*) AS EXPECT_2000 FROM t1; +DROP TABLE t1; + +--echo # Change file size smaller +SET GLOBAL wsrep_buffered_error_log_file_size=131072; + +--echo # List error log files - should be 3 files +--list_files $MYSQLTEST_VARDIR/mysqld.2/data galera_buffered_error_log* + +--replace_regex /.*galera_buffered_error_log.err.*/galera_buffered_error_log.err/ +SELECT @@global.wsrep_buffered_error_log_filename; +SELECT @@global.wsrep_buffered_error_log_buffer_size; +SELECT @@global.wsrep_buffered_error_log_file_size; + +--echo # Try to change buffer size to unsupported size i.e too small +--error ER_WRONG_VALUE_FOR_VAR +SET GLOBAL wsrep_buffered_error_log_file_size=1024; + +--echo # Reset file size to original size +SET GLOBAL wsrep_buffered_error_log_file_size=204800; + +--echo # List error log files - should be 3 files +--list_files $MYSQLTEST_VARDIR/mysqld.2/data galera_buffered_error_log* + diff --git a/mysql-test/suite/galera/t/galera_var_buffered_error_log_filename.cnf b/mysql-test/suite/galera/t/galera_var_buffered_error_log_filename.cnf new file mode 100644 index 0000000000000..8171a3fc4f258 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_var_buffered_error_log_filename.cnf @@ -0,0 +1,9 @@ +!include ../galera_2nodes.cnf + +[mysqld] +wsrep-debug=1 + +[mysqld.2] +wsrep_buffered_error_log_buffer_size=100Kb +wsrep_buffered_error_log_file_size=1M +wsrep_buffered_error_log_filename="galera_buffered_error_log.err" diff --git a/mysql-test/suite/galera/t/galera_var_buffered_error_log_filename.test b/mysql-test/suite/galera/t/galera_var_buffered_error_log_filename.test new file mode 100644 index 0000000000000..b9884d2394424 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_var_buffered_error_log_filename.test @@ -0,0 +1,41 @@ +--source include/galera_cluster.inc +--source include/have_sequence.inc + +--connection node_2 +--replace_regex /.*galera_buffered_error_log.err.*/galera_buffered_error_log.err/ +SELECT @@global.wsrep_buffered_error_log_filename; +SELECT @@global.wsrep_buffered_error_log_buffer_size; +SELECT @@global.wsrep_buffered_error_log_file_size; + +CREATE TABLE t1(a int not null primary key) engine=innodb; +INSERT INTO t1 SELECT * FROM seq_1_to_1000; + +--echo # Change file name +--disable_query_log +--eval SET GLOBAL wsrep_buffered_error_log_filename="galera_buffered_error_log2.err" +--enable_query_log + +--echo Testing that old log contains something logged +--let SEARCH_FILE= $MYSQLTEST_VARDIR/mysqld.2/data/galera_buffered_error_log.err +--let ABORT_ON = NOT_FOUND +--let SEARCH_PATTERN=WSREP: Loading provider +--source include/search_pattern_in_file.inc + +--replace_regex /.*galera_buffered_error_log2.err.*/galera_buffered_error_log2.err/ +SELECT @@global.wsrep_buffered_error_log_filename; +SELECT @@global.wsrep_buffered_error_log_buffer_size; +SELECT @@global.wsrep_buffered_error_log_file_size; + +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +DROP TABLE t1; + +--echo # Change file name back to original +--disable_query_log +--eval SET GLOBAL wsrep_buffered_error_log_filename="galera_buffered_error_log.err" +--enable_query_log + +--echo Testing that second log contains something logged +--let SEARCH_FILE= $MYSQLTEST_VARDIR/mysqld.2/data/galera_buffered_error_log2.err +--let ABORT_ON = NOT_FOUND +--let SEARCH_PATTERN=DROP TABLE +--source include/search_pattern_in_file.inc diff --git a/mysql-test/suite/galera/t/galera_var_buffered_error_log_rotations.cnf b/mysql-test/suite/galera/t/galera_var_buffered_error_log_rotations.cnf new file mode 100644 index 0000000000000..9e22940f2789f --- /dev/null +++ b/mysql-test/suite/galera/t/galera_var_buffered_error_log_rotations.cnf @@ -0,0 +1,13 @@ +!include ../galera_2nodes.cnf + +[mysqld] +wsrep-debug=1 + +[mysqld.2] +wsrep_buffered_error_log_buffer_size=10K +wsrep_buffered_error_log_file_size=100K +wsrep_buffered_error_log_filename="galera_buffered_error_log.err" +wsrep_buffered_error_log_rotations=5 +loose-galera-log_rotations + + diff --git a/mysql-test/suite/galera/t/galera_var_buffered_error_log_rotations.test b/mysql-test/suite/galera/t/galera_var_buffered_error_log_rotations.test new file mode 100644 index 0000000000000..c50773f009a02 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_var_buffered_error_log_rotations.test @@ -0,0 +1,86 @@ +--source include/galera_cluster.inc +--source include/have_sequence.inc +--source include/force_restart.inc + +--connection node_2 +--replace_regex /.*galera_buffered_error_log.err.*/galera_buffered_error_log.err/ +SELECT @@global.wsrep_buffered_error_log_filename; +SELECT @@global.wsrep_buffered_error_log_buffer_size; +SELECT @@global.wsrep_buffered_error_log_file_size; +SELECT @@global.wsrep_buffered_error_log_rotations; + +CREATE TABLE t1(a int not null primary key auto_increment, count int) engine=innodb; + +--let $inserts=1000 +--let $count=0 +--disable_query_log +while($count < $inserts) +{ + --eval insert into t1 values (NULL,$count) + --eval update t1 set count = $count+100 where count = $count + --inc $count +} +--enable_query_log + +--echo # List error log files - max file number .5 +--list_files $MYSQLTEST_VARDIR/mysqld.2/data galera_buffered_error_log* + +--echo # Change rotations larger +SET GLOBAL wsrep_buffered_error_log_rotations=6; + +--let $inserts=1000 +--let $count=0 +--disable_query_log +while($count < $inserts) +{ + --eval insert into t1 values (NULL,$count) + --eval update t1 set count = $count+100 where count = $count + --inc $count +} +--enable_query_log + +--echo # List error log files - max file number .6 +--list_files $MYSQLTEST_VARDIR/mysqld.2/data galera_buffered_error_log* + +--replace_regex /.*galera_buffered_error_log.err.*/galera_buffered_error_log.err/ +SELECT @@global.wsrep_buffered_error_log_filename; +SELECT @@global.wsrep_buffered_error_log_buffer_size; +SELECT @@global.wsrep_buffered_error_log_file_size; +SELECT @@global.wsrep_buffered_error_log_rotations; + +--echo # Change rotations smaller and use different name +--disable_query_log +--eval SET GLOBAL wsrep_buffered_error_log_filename="galera_buffered_error_log2.err" +--enable_query_log +SET GLOBAL wsrep_buffered_error_log_rotations=2; + +--let $inserts=1000 +--let $count=0 +--disable_query_log +while($count < $inserts) +{ + --eval insert into t1 values (NULL,$count) + --eval update t1 set count = $count+100 where count = $count + --inc $count +} +--enable_query_log + +SELECT COUNT(*) AS EXPECT_2000 FROM t1; +DROP TABLE t1; + +--echo # List error log files - max file number .2 +--list_files $MYSQLTEST_VARDIR/mysqld.2/data galera_buffered_error_log2* + +--replace_regex /.*galera_buffered_error_log2.err.*/galera_buffered_error_log2.err/ +SELECT @@global.wsrep_buffered_error_log_filename; +SELECT @@global.wsrep_buffered_error_log_buffer_size; +SELECT @@global.wsrep_buffered_error_log_file_size; +SELECT @@global.wsrep_buffered_error_log_rotations; + +--echo # Reset +--disable_query_log +--eval SET GLOBAL wsrep_buffered_error_log_filename="galera_buffered_error_log.err" +--enable_query_log +SET @@global.wsrep_buffered_error_log_rotations=5; + + diff --git a/mysql-test/suite/sys_vars/r/sysvars_wsrep.result b/mysql-test/suite/sys_vars/r/sysvars_wsrep.result index 9310119071c9a..4e49ccc56d01e 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_wsrep.result +++ b/mysql-test/suite/sys_vars/r/sysvars_wsrep.result @@ -31,6 +31,66 @@ ENUM_VALUE_LIST OFF,ON READ_ONLY NO COMMAND_LINE_ARGUMENT OPTIONAL GLOBAL_VALUE_PATH NULL +VARIABLE_NAME WSREP_BUFFERED_ERROR_LOG_BUFFER_SIZE +SESSION_VALUE NULL +GLOBAL_VALUE 0 +GLOBAL_VALUE_ORIGIN COMPILE-TIME +DEFAULT_VALUE 0 +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE BIGINT UNSIGNED +VARIABLE_COMMENT Size of the buffered error log buffer +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 18446744073709551615 +NUMERIC_BLOCK_SIZE 1 +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +GLOBAL_VALUE_PATH NULL +VARIABLE_NAME WSREP_BUFFERED_ERROR_LOG_FILENAME +SESSION_VALUE NULL +GLOBAL_VALUE +GLOBAL_VALUE_ORIGIN COMPILE-TIME +DEFAULT_VALUE +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE VARCHAR +VARIABLE_COMMENT Filename of the buffered error log +NUMERIC_MIN_VALUE NULL +NUMERIC_MAX_VALUE NULL +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +GLOBAL_VALUE_PATH NULL +VARIABLE_NAME WSREP_BUFFERED_ERROR_LOG_FILE_SIZE +SESSION_VALUE NULL +GLOBAL_VALUE 0 +GLOBAL_VALUE_ORIGIN COMPILE-TIME +DEFAULT_VALUE 0 +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE BIGINT UNSIGNED +VARIABLE_COMMENT Max size of the buffered error log file +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 18446744073709551615 +NUMERIC_BLOCK_SIZE 1 +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +GLOBAL_VALUE_PATH NULL +VARIABLE_NAME WSREP_BUFFERED_ERROR_LOG_ROTATIONS +SESSION_VALUE NULL +GLOBAL_VALUE 10 +GLOBAL_VALUE_ORIGIN COMPILE-TIME +DEFAULT_VALUE 10 +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE INT UNSIGNED +VARIABLE_COMMENT Number of log rotations before log is removed +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 999999 +NUMERIC_BLOCK_SIZE 1 +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED +GLOBAL_VALUE_PATH NULL VARIABLE_NAME WSREP_CERTIFICATION_RULES SESSION_VALUE NULL GLOBAL_VALUE strict diff --git a/mysql-test/suite/sys_vars/r/wsrep_buffered_error_log_buffer_size_basic.result b/mysql-test/suite/sys_vars/r/wsrep_buffered_error_log_buffer_size_basic.result new file mode 100644 index 0000000000000..5b11b3c869e06 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/wsrep_buffered_error_log_buffer_size_basic.result @@ -0,0 +1,39 @@ +SET @start_value = @@global.wsrep_buffered_error_log_buffer_size; +SELECT @start_value; +@start_value +0 +SET @@global.wsrep_buffered_error_log_buffer_size = 102400; +ERROR 42000: Variable 'wsrep_buffered_error_log_buffer_size' can't be set to the value of '102400' +SHOW WARNINGS; +Level Code Message +Warning 1231 Cannot set 'wsrep_buffered_error_log_size' to a value other than 0 because wsrep is switched off. +Error 1231 Variable 'wsrep_buffered_error_log_buffer_size' can't be set to the value of '102400' +SELECT @@global.wsrep_buffered_error_log_buffer_size; +@@global.wsrep_buffered_error_log_buffer_size +0 +SET @@global.wsrep_buffered_error_log_buffer_size = 0; +SELECT @@global.wsrep_buffered_error_log_buffer_size; +@@global.wsrep_buffered_error_log_buffer_size +0 +SET @@session.wsrep_buffered_error_log_buffer_size = 0; +ERROR HY000: Variable 'wsrep_buffered_error_log_buffer_size' is a GLOBAL variable and should be set with SET GLOBAL +SELECT @@session.wsrep_buffered_error_log_buffer_size; +ERROR HY000: Variable 'wsrep_buffered_error_log_buffer_size' is a GLOBAL variable +SET @@global.wsrep_buffered_error_log_buffer_size = -10; +Warnings: +Warning 1292 Truncated incorrect wsrep_buffered_error_log_buff... value: '-10' +SELECT @@global.wsrep_buffered_error_log_buffer_size; +@@global.wsrep_buffered_error_log_buffer_size +0 +SET @@global.wsrep_buffered_error_log_buffer_size = "/foo/bar.txt"; +ERROR 42000: Incorrect argument type to variable 'wsrep_buffered_error_log_buffer_size' +SHOW WARNINGS; +Level Code Message +Error 1232 Incorrect argument type to variable 'wsrep_buffered_error_log_buffer_size' +SELECT @@global.wsrep_buffered_error_log_buffer_size; +@@global.wsrep_buffered_error_log_buffer_size +0 +SET @@global.wsrep_buffered_error_log_buffer_size = @start_value; +SELECT @@global.wsrep_buffered_error_log_buffer_size; +@@global.wsrep_buffered_error_log_buffer_size +0 diff --git a/mysql-test/suite/sys_vars/r/wsrep_buffered_error_log_file_size_basic.result b/mysql-test/suite/sys_vars/r/wsrep_buffered_error_log_file_size_basic.result new file mode 100644 index 0000000000000..db5b6132c1d83 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/wsrep_buffered_error_log_file_size_basic.result @@ -0,0 +1,39 @@ +SET @start_value = @@global.wsrep_buffered_error_log_file_size; +SELECT @start_value; +@start_value +0 +SET @@global.wsrep_buffered_error_log_file_size = 420; +ERROR 42000: Variable 'wsrep_buffered_error_log_file_size' can't be set to the value of '420' +SHOW WARNINGS; +Level Code Message +Warning 1231 Cannot set 'wsrep_buffered_error_log_file_size' to a value other than 0 because wsrep is switched off. +Error 1231 Variable 'wsrep_buffered_error_log_file_size' can't be set to the value of '420' +SELECT @@global.wsrep_buffered_error_log_file_size; +@@global.wsrep_buffered_error_log_file_size +0 +SET @@global.wsrep_buffered_error_log_file_size = 0; +SELECT @@global.wsrep_buffered_error_log_file_size; +@@global.wsrep_buffered_error_log_file_size +0 +SET @@session.wsrep_buffered_error_log_file_size = 0; +ERROR HY000: Variable 'wsrep_buffered_error_log_file_size' is a GLOBAL variable and should be set with SET GLOBAL +SELECT @@session.wsrep_buffered_error_log_file_size; +ERROR HY000: Variable 'wsrep_buffered_error_log_file_size' is a GLOBAL variable +SET @@global.wsrep_buffered_error_log_file_size = -10; +Warnings: +Warning 1292 Truncated incorrect wsrep_buffered_error_log_file... value: '-10' +SELECT @@global.wsrep_buffered_error_log_file_size; +@@global.wsrep_buffered_error_log_file_size +0 +SET @@global.wsrep_buffered_error_log_file_size = "/foo/bar.txt"; +ERROR 42000: Incorrect argument type to variable 'wsrep_buffered_error_log_file_size' +SHOW WARNINGS; +Level Code Message +Error 1232 Incorrect argument type to variable 'wsrep_buffered_error_log_file_size' +SELECT @@global.wsrep_buffered_error_log_file_size; +@@global.wsrep_buffered_error_log_file_size +0 +SET @@global.wsrep_buffered_error_log_file_size = @start_value; +SELECT @@global.wsrep_buffered_error_log_file_size; +@@global.wsrep_buffered_error_log_file_size +0 diff --git a/mysql-test/suite/sys_vars/r/wsrep_buffered_error_log_filename_basic.result b/mysql-test/suite/sys_vars/r/wsrep_buffered_error_log_filename_basic.result new file mode 100644 index 0000000000000..2eca2753434e8 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/wsrep_buffered_error_log_filename_basic.result @@ -0,0 +1,30 @@ +SET @start_value = @@global.wsrep_buffered_error_log_filename; +SELECT @start_value; +@start_value +NULL +SET @size_start_value = @@global.wsrep_buffered_error_log_buffer_size; +SELECT @size_start_value; +@size_start_value +0 +SET @@global.wsrep_buffered_error_log_filename = "/tmp/bar.txt"; +ERROR 42000: Variable 'wsrep_buffered_error_log_filename' can't be set to the value of '/tmp/bar.txt' +SHOW WARNINGS; +Level Code Message +Warning 1231 Cannot set 'wsrep_buffered_error_log_filename' because wsrep is switched off. +Error 1231 Variable 'wsrep_buffered_error_log_filename' can't be set to the value of '/tmp/bar.txt' +SELECT @@global.wsrep_buffered_error_log_filename; +@@global.wsrep_buffered_error_log_filename +NULL +SET @@global.wsrep_buffered_error_log_filename = ''; +SELECT @@global.wsrep_buffered_error_log_filename; +@@global.wsrep_buffered_error_log_filename + +SET @@session.wsrep_buffered_error_log_filename = OFF; +ERROR HY000: Variable 'wsrep_buffered_error_log_filename' is a GLOBAL variable and should be set with SET GLOBAL +SELECT @@session.wsrep_buffered_error_log_filename; +ERROR HY000: Variable 'wsrep_buffered_error_log_filename' is a GLOBAL variable +SET @@global.wsrep_buffered_error_log_filename = @start_value; +SET @@global.wsrep_buffered_error_log_buffer_size = @size_start_value; +SELECT @@global.wsrep_buffered_error_log_filename; +@@global.wsrep_buffered_error_log_filename +NULL diff --git a/mysql-test/suite/sys_vars/r/wsrep_buffered_error_log_rotations_basic.result b/mysql-test/suite/sys_vars/r/wsrep_buffered_error_log_rotations_basic.result new file mode 100644 index 0000000000000..5b11b3c869e06 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/wsrep_buffered_error_log_rotations_basic.result @@ -0,0 +1,39 @@ +SET @start_value = @@global.wsrep_buffered_error_log_buffer_size; +SELECT @start_value; +@start_value +0 +SET @@global.wsrep_buffered_error_log_buffer_size = 102400; +ERROR 42000: Variable 'wsrep_buffered_error_log_buffer_size' can't be set to the value of '102400' +SHOW WARNINGS; +Level Code Message +Warning 1231 Cannot set 'wsrep_buffered_error_log_size' to a value other than 0 because wsrep is switched off. +Error 1231 Variable 'wsrep_buffered_error_log_buffer_size' can't be set to the value of '102400' +SELECT @@global.wsrep_buffered_error_log_buffer_size; +@@global.wsrep_buffered_error_log_buffer_size +0 +SET @@global.wsrep_buffered_error_log_buffer_size = 0; +SELECT @@global.wsrep_buffered_error_log_buffer_size; +@@global.wsrep_buffered_error_log_buffer_size +0 +SET @@session.wsrep_buffered_error_log_buffer_size = 0; +ERROR HY000: Variable 'wsrep_buffered_error_log_buffer_size' is a GLOBAL variable and should be set with SET GLOBAL +SELECT @@session.wsrep_buffered_error_log_buffer_size; +ERROR HY000: Variable 'wsrep_buffered_error_log_buffer_size' is a GLOBAL variable +SET @@global.wsrep_buffered_error_log_buffer_size = -10; +Warnings: +Warning 1292 Truncated incorrect wsrep_buffered_error_log_buff... value: '-10' +SELECT @@global.wsrep_buffered_error_log_buffer_size; +@@global.wsrep_buffered_error_log_buffer_size +0 +SET @@global.wsrep_buffered_error_log_buffer_size = "/foo/bar.txt"; +ERROR 42000: Incorrect argument type to variable 'wsrep_buffered_error_log_buffer_size' +SHOW WARNINGS; +Level Code Message +Error 1232 Incorrect argument type to variable 'wsrep_buffered_error_log_buffer_size' +SELECT @@global.wsrep_buffered_error_log_buffer_size; +@@global.wsrep_buffered_error_log_buffer_size +0 +SET @@global.wsrep_buffered_error_log_buffer_size = @start_value; +SELECT @@global.wsrep_buffered_error_log_buffer_size; +@@global.wsrep_buffered_error_log_buffer_size +0 diff --git a/mysql-test/suite/sys_vars/t/wsrep_buffered_error_log_buffer_size_basic.test b/mysql-test/suite/sys_vars/t/wsrep_buffered_error_log_buffer_size_basic.test new file mode 100644 index 0000000000000..a2631b340c3aa --- /dev/null +++ b/mysql-test/suite/sys_vars/t/wsrep_buffered_error_log_buffer_size_basic.test @@ -0,0 +1,29 @@ +--source include/have_wsrep.inc + +SET @start_value = @@global.wsrep_buffered_error_log_buffer_size; +SELECT @start_value; + +--error ER_WRONG_VALUE_FOR_VAR +SET @@global.wsrep_buffered_error_log_buffer_size = 102400; +SHOW WARNINGS; +SELECT @@global.wsrep_buffered_error_log_buffer_size; +SET @@global.wsrep_buffered_error_log_buffer_size = 0; +SELECT @@global.wsrep_buffered_error_log_buffer_size; + +--error ER_GLOBAL_VARIABLE +SET @@session.wsrep_buffered_error_log_buffer_size = 0; +--Error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT @@session.wsrep_buffered_error_log_buffer_size; + +# No error, truncation +SET @@global.wsrep_buffered_error_log_buffer_size = -10; +SELECT @@global.wsrep_buffered_error_log_buffer_size; + +--error ER_WRONG_TYPE_FOR_VAR +SET @@global.wsrep_buffered_error_log_buffer_size = "/foo/bar.txt"; +SHOW WARNINGS; +SELECT @@global.wsrep_buffered_error_log_buffer_size; + +SET @@global.wsrep_buffered_error_log_buffer_size = @start_value; +SELECT @@global.wsrep_buffered_error_log_buffer_size; + diff --git a/mysql-test/suite/sys_vars/t/wsrep_buffered_error_log_file_size_basic.test b/mysql-test/suite/sys_vars/t/wsrep_buffered_error_log_file_size_basic.test new file mode 100644 index 0000000000000..8f0d129506d95 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/wsrep_buffered_error_log_file_size_basic.test @@ -0,0 +1,29 @@ +--source include/have_wsrep.inc + +SET @start_value = @@global.wsrep_buffered_error_log_file_size; +SELECT @start_value; + +--error ER_WRONG_VALUE_FOR_VAR +SET @@global.wsrep_buffered_error_log_file_size = 420; +SHOW WARNINGS; +SELECT @@global.wsrep_buffered_error_log_file_size; +SET @@global.wsrep_buffered_error_log_file_size = 0; +SELECT @@global.wsrep_buffered_error_log_file_size; + +--error ER_GLOBAL_VARIABLE +SET @@session.wsrep_buffered_error_log_file_size = 0; +--Error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT @@session.wsrep_buffered_error_log_file_size; + +# No error, truncation +SET @@global.wsrep_buffered_error_log_file_size = -10; +SELECT @@global.wsrep_buffered_error_log_file_size; + +--error ER_WRONG_TYPE_FOR_VAR +SET @@global.wsrep_buffered_error_log_file_size = "/foo/bar.txt"; +SHOW WARNINGS; +SELECT @@global.wsrep_buffered_error_log_file_size; + +SET @@global.wsrep_buffered_error_log_file_size = @start_value; +SELECT @@global.wsrep_buffered_error_log_file_size; + diff --git a/mysql-test/suite/sys_vars/t/wsrep_buffered_error_log_filename_basic.test b/mysql-test/suite/sys_vars/t/wsrep_buffered_error_log_filename_basic.test new file mode 100644 index 0000000000000..f15ce05156f39 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/wsrep_buffered_error_log_filename_basic.test @@ -0,0 +1,24 @@ +--source include/have_wsrep.inc + +SET @start_value = @@global.wsrep_buffered_error_log_filename; +SELECT @start_value; +SET @size_start_value = @@global.wsrep_buffered_error_log_buffer_size; +SELECT @size_start_value; + +--error ER_WRONG_VALUE_FOR_VAR +SET @@global.wsrep_buffered_error_log_filename = "/tmp/bar.txt"; +SHOW WARNINGS; +SELECT @@global.wsrep_buffered_error_log_filename; +SET @@global.wsrep_buffered_error_log_filename = ''; +SELECT @@global.wsrep_buffered_error_log_filename; + + +--Error ER_GLOBAL_VARIABLE +SET @@session.wsrep_buffered_error_log_filename = OFF; +--Error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT @@session.wsrep_buffered_error_log_filename; + + +SET @@global.wsrep_buffered_error_log_filename = @start_value; +SET @@global.wsrep_buffered_error_log_buffer_size = @size_start_value; +SELECT @@global.wsrep_buffered_error_log_filename; diff --git a/mysql-test/suite/sys_vars/t/wsrep_buffered_error_log_rotations_basic.test b/mysql-test/suite/sys_vars/t/wsrep_buffered_error_log_rotations_basic.test new file mode 100644 index 0000000000000..a2631b340c3aa --- /dev/null +++ b/mysql-test/suite/sys_vars/t/wsrep_buffered_error_log_rotations_basic.test @@ -0,0 +1,29 @@ +--source include/have_wsrep.inc + +SET @start_value = @@global.wsrep_buffered_error_log_buffer_size; +SELECT @start_value; + +--error ER_WRONG_VALUE_FOR_VAR +SET @@global.wsrep_buffered_error_log_buffer_size = 102400; +SHOW WARNINGS; +SELECT @@global.wsrep_buffered_error_log_buffer_size; +SET @@global.wsrep_buffered_error_log_buffer_size = 0; +SELECT @@global.wsrep_buffered_error_log_buffer_size; + +--error ER_GLOBAL_VARIABLE +SET @@session.wsrep_buffered_error_log_buffer_size = 0; +--Error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT @@session.wsrep_buffered_error_log_buffer_size; + +# No error, truncation +SET @@global.wsrep_buffered_error_log_buffer_size = -10; +SELECT @@global.wsrep_buffered_error_log_buffer_size; + +--error ER_WRONG_TYPE_FOR_VAR +SET @@global.wsrep_buffered_error_log_buffer_size = "/foo/bar.txt"; +SHOW WARNINGS; +SELECT @@global.wsrep_buffered_error_log_buffer_size; + +SET @@global.wsrep_buffered_error_log_buffer_size = @start_value; +SELECT @@global.wsrep_buffered_error_log_buffer_size; + diff --git a/mysql-test/suite/wsrep/r/variables.result b/mysql-test/suite/wsrep/r/variables.result index 9a3c4169ac83b..9ae934f5e9ade 100644 --- a/mysql-test/suite/wsrep/r/variables.result +++ b/mysql-test/suite/wsrep/r/variables.result @@ -1,72 +1,73 @@ # Correct Galera library found SHOW GLOBAL STATUS LIKE 'wsrep%'; Variable_name Value -wsrep_local_state_uuid # -wsrep_protocol_version # -wsrep_last_committed # -wsrep_replicated # -wsrep_replicated_bytes # -wsrep_repl_keys # -wsrep_repl_keys_bytes # -wsrep_repl_data_bytes # -wsrep_repl_other_bytes # -wsrep_received # -wsrep_received_bytes # -wsrep_local_commits # -wsrep_local_cert_failures # -wsrep_local_replays # -wsrep_local_send_queue # -wsrep_local_send_queue_max # -wsrep_local_send_queue_min # -wsrep_local_send_queue_avg # -wsrep_local_recv_queue # -wsrep_local_recv_queue_max # -wsrep_local_recv_queue_min # -wsrep_local_recv_queue_avg # -wsrep_local_cached_downto # -wsrep_flow_control_paused_ns # -wsrep_flow_control_paused # -wsrep_flow_control_sent # -wsrep_flow_control_recv # -wsrep_flow_control_active # -wsrep_flow_control_requested # -wsrep_cert_deps_distance # +wsrep_applier_thread_count # wsrep_apply_oooe # wsrep_apply_oool # -wsrep_apply_window # wsrep_apply_waits # -wsrep_commit_oooe # -wsrep_commit_oool # -wsrep_commit_window # -wsrep_local_state # -wsrep_local_state_comment # +wsrep_apply_window # +wsrep_causal_reads # +wsrep_cert_deps_distance # wsrep_cert_index_size # wsrep_cert_interval # -wsrep_open_transactions # -wsrep_open_connections # -wsrep_incoming_addresses # +wsrep_cluster_capabilities # +wsrep_cluster_conf_id # +wsrep_cluster_size # +wsrep_cluster_state_uuid # +wsrep_cluster_status # wsrep_cluster_weight # +wsrep_commit_oooe # +wsrep_commit_oool # +wsrep_commit_window # +wsrep_connected # wsrep_desync_count # wsrep_evs_delayed # wsrep_evs_evict_list # wsrep_evs_repl_latency # wsrep_evs_state # +wsrep_flow_control_active # +wsrep_flow_control_paused # +wsrep_flow_control_paused_ns # +wsrep_flow_control_recv # +wsrep_flow_control_requested # +wsrep_flow_control_sent # wsrep_gcomm_uuid # wsrep_gmcast_segment # -wsrep_applier_thread_count # -wsrep_cluster_capabilities # -wsrep_cluster_conf_id # -wsrep_cluster_size # -wsrep_cluster_state_uuid # -wsrep_cluster_status # -wsrep_connected # +wsrep_incoming_addresses # +wsrep_last_committed # wsrep_local_bf_aborts # +wsrep_local_cached_downto # +wsrep_local_cert_failures # +wsrep_local_commits # wsrep_local_index # +wsrep_local_recv_queue # +wsrep_local_recv_queue_avg # +wsrep_local_recv_queue_max # +wsrep_local_recv_queue_min # +wsrep_local_replays # +wsrep_local_send_queue # +wsrep_local_send_queue_avg # +wsrep_local_send_queue_max # +wsrep_local_send_queue_min # +wsrep_local_state # +wsrep_local_state_comment # +wsrep_local_state_uuid # +wsrep_open_connections # +wsrep_open_transactions # +wsrep_protocol_version # wsrep_provider_capabilities # wsrep_provider_name # wsrep_provider_vendor # wsrep_provider_version # wsrep_ready # +wsrep_received # +wsrep_received_bytes # +wsrep_repl_data_bytes # +wsrep_repl_keys # +wsrep_repl_keys_bytes # +wsrep_repl_other_bytes # +wsrep_replicated # +wsrep_replicated_bytes # wsrep_rollbacker_thread_count # wsrep_thread_count # # Should show nothing. @@ -89,6 +90,10 @@ SELECT VARIABLE_NAME FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NA VARIABLE_NAME WSREP_ALLOWLIST WSREP_AUTO_INCREMENT_CONTROL +WSREP_BUFFERED_ERROR_LOG_BUFFER_SIZE +WSREP_BUFFERED_ERROR_LOG_FILENAME +WSREP_BUFFERED_ERROR_LOG_FILE_SIZE +WSREP_BUFFERED_ERROR_LOG_ROTATIONS WSREP_CERTIFICATION_RULES WSREP_CERTIFY_NONPK WSREP_CLUSTER_ADDRESS diff --git a/mysql-test/suite/wsrep/r/variables_debug.result b/mysql-test/suite/wsrep/r/variables_debug.result index 50d695fed4be2..bd04a9c791681 100644 --- a/mysql-test/suite/wsrep/r/variables_debug.result +++ b/mysql-test/suite/wsrep/r/variables_debug.result @@ -41,6 +41,7 @@ wsrep_commit_window # wsrep_local_state # wsrep_local_state_comment # wsrep_cert_index_size # +wsrep_causal_reads # wsrep_cert_interval # wsrep_open_transactions # wsrep_open_connections # @@ -90,6 +91,10 @@ SELECT VARIABLE_NAME FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NA VARIABLE_NAME WSREP_ALLOWLIST WSREP_AUTO_INCREMENT_CONTROL +WSREP_BUFFERED_ERROR_LOG_BUFFER_SIZE +WSREP_BUFFERED_ERROR_LOG_FILENAME +WSREP_BUFFERED_ERROR_LOG_FILE_SIZE +WSREP_BUFFERED_ERROR_LOG_ROTATIONS WSREP_CERTIFICATION_RULES WSREP_CERTIFY_NONPK WSREP_CLUSTER_ADDRESS diff --git a/mysql-test/suite/wsrep/t/variables.test b/mysql-test/suite/wsrep/t/variables.test index c28638e78f1fb..e4f1658361230 100644 --- a/mysql-test/suite/wsrep/t/variables.test +++ b/mysql-test/suite/wsrep/t/variables.test @@ -8,6 +8,7 @@ source include/check_galera_version.inc; source include/galera_variables_ok.inc; +--sorted_result --replace_column 2 # SHOW GLOBAL STATUS LIKE 'wsrep%'; diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt index 1a08bafda99e2..013080cf383f6 100644 --- a/mysys/CMakeLists.txt +++ b/mysys/CMakeLists.txt @@ -46,7 +46,7 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c my_default.c my_uuid.c wqueue.c waiting_threads.c ma_dyncol.c ../sql-common/my_time.c my_rdtsc.c psi_noop.c my_atomic_writes.c my_cpu.c my_likely.c my_largepage.c - file_logger.c my_dlerror.c crc32/crc32c.cc + file_logger.cc my_dlerror.c crc32/crc32c.cc my_timezone.cc my_thread_name.cc) IF (WIN32) diff --git a/mysys/file_logger.cc b/mysys/file_logger.cc new file mode 100644 index 0000000000000..9a92c50a16cff --- /dev/null +++ b/mysys/file_logger.cc @@ -0,0 +1,454 @@ +/* Copyright (C) 2012-2025 Monty Program Ab + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ + + +#ifndef FLOGGER_SKIP_INCLUDES +#include "my_global.h" +#include +#include +#include +#include +#include +#include +#include +#include +#endif /*FLOGGER_SKIP_INCLUDES*/ + +#ifndef flogger_mutex_init +#define flogger_mutex_init(A,B,C) mysql_mutex_init(A,B,C) +#define flogger_mutex_destroy(A) mysql_mutex_destroy(A) +#define flogger_mutex_lock(A) mysql_mutex_lock(A) +#define flogger_mutex_unlock(A) mysql_mutex_unlock(A) +#endif /*flogger_mutex_init*/ + +#ifdef HAVE_PSI_INTERFACE +/* These belong to the service initialization */ +static PSI_mutex_key key_LOCK_logger_service; +static PSI_mutex_info mutex_list[]= +{{ &key_LOCK_logger_service, "logger_service_file_st::lock", PSI_FLAG_GLOBAL}}; +#endif + +struct logger_handle_st +{ + logger_handle_st() : data(nullptr), size_limit(0), buffer_limit(0), rotations(0) + {} + // We are using a pointer to string to guarantee that we can decrease the size + // of the buffer + // memory buffer storing the log messages + std::unique_ptr data; + unsigned long long size_limit; + unsigned long long buffer_limit; + unsigned int rotations; + File file; + char path[FN_REFLEN]; + size_t path_len; + mysql_mutex_t lock; + + void resize_buffer(void); +}; + +void logger_handle_st::resize_buffer(void) +{ + std::unique_ptr new_buffer(new std::string()); + new_buffer->reserve(buffer_limit); + data.swap(new_buffer); +} + +#define LOG_FLAGS (O_APPEND | O_CREAT | O_WRONLY) + +static unsigned int n_dig(unsigned int i) +{ + unsigned int n=1; + if (i < 10) + n= 1; + else if (i < 100) + n= 2; + else if (i < 1000) + n= 3; + else if (i < 10000) + n= 4; + else if (i < 100000) + n= 5; + else if (i < 1000000) + n= 6; + return n; +} + + +LOGGER_HANDLE *logger_open(const char *path, + unsigned long long size_limit, + unsigned long long buffer_limit, + unsigned int rotations) +{ + LOGGER_HANDLE new_log; + /* + I don't think we ever need more rotations, + but if it's so, the rotation procedure should be adapted to it. + */ + if (rotations > 9999999) + return 0; + + new_log.path_len= strlen(fn_format(new_log.path, path, + mysql_data_home, "", MY_UNPACK_FILENAME)); + + if (new_log.path_len+n_dig(rotations)+1 > FN_REFLEN) + { + errno= ENAMETOOLONG; + /* File path too long */ + return 0; + } + if ((new_log.file= my_open(new_log.path, LOG_FLAGS, MYF(0))) < 0) + { + errno= my_errno; + /* Check errno for the cause */ + return 0; + } + + struct logger_handle_st* l_handle(new logger_handle_st()); + + l_handle->rotations= rotations; + l_handle->size_limit= size_limit; + l_handle->buffer_limit= buffer_limit; + l_handle->path_len= new_log.path_len; + strcpy(l_handle->path, new_log.path); + l_handle->file= new_log.file; + + flogger_mutex_init(key_LOCK_logger_service, &l_handle->lock, + MY_MUTEX_INIT_FAST); + + if (!buffer_limit) + return (LOGGER_HANDLE*)l_handle; + + l_handle->resize_buffer(); + + return (LOGGER_HANDLE*)l_handle; +} + +int logger_close(LOGGER_HANDLE *log) +{ + int result; + File file= log->file; + flogger_mutex_destroy(&log->lock); + if ((result= my_close(file, MYF(0)))) + errno= my_errno; + delete log; + return result; +} + + +static char *logname(LOGGER_HANDLE *log, char *buf, unsigned int n_log) +{ + sprintf(buf+log->path_len, ".%0*u", n_dig(log->rotations), n_log); + return buf; +} + + +static int do_rotate(LOGGER_HANDLE *log) +{ + char namebuf[FN_REFLEN]; + int result; + unsigned int i; + char *buf_old, *buf_new, *tmp; + + if (log->rotations == 0) + return 0; + + memcpy(namebuf, log->path, log->path_len); + + buf_new= logname(log, namebuf, log->rotations); + buf_old= log->path; + for (i=log->rotations-1; i>0; i--) + { + logname(log, buf_old, i); + if (!access(buf_old, F_OK) && + (result= my_rename(buf_old, buf_new, MYF(0)))) + goto exit; + tmp= buf_old; + buf_old= buf_new; + buf_new= tmp; + } + if ((result= my_close(log->file, MYF(0)))) + goto exit; + namebuf[log->path_len]= 0; + result= my_rename(namebuf, logname(log, log->path, 1), MYF(0)); + log->file= my_open(namebuf, LOG_FLAGS, MYF(0)); +exit: + errno= my_errno; + return log->file < 0 || result; +} + + +/* + Return 1 if we should rotate the log +*/ + +my_bool logger_time_to_rotate(LOGGER_HANDLE *log) +{ + my_off_t filesize; + if (log->rotations > 0) + { + filesize= my_tell(log->file, MYF(0)); + if (filesize != (my_off_t) -1) + { + filesize+= log->data->size(); // Add buffer + if ((unsigned long long)filesize >= log->size_limit) + return 1; + } + } + + return 0; +} + + +int logger_vprintf(LOGGER_HANDLE *log, const char* fmt, va_list ap) +{ + int result=0; + char cvtbuf[1024]; + size_t n_bytes; + + flogger_mutex_lock(&log->lock); + if (logger_time_to_rotate(log) && do_rotate(log)) + { + result= -1; + errno= my_errno; + goto exit; /* Log rotation needed but failed */ + } + + n_bytes= my_vsnprintf(cvtbuf, sizeof(cvtbuf), fmt, ap); + if (n_bytes >= sizeof(cvtbuf)) + n_bytes= sizeof(cvtbuf) - 1; + + if (log->data.get() == nullptr || log->data->capacity() == 0) + { + result= (int)my_write(log->file, (uchar *) cvtbuf, n_bytes, MYF(0)); + } + else + { + // Buffered logging + const size_t msg_size = log->data->size() + n_bytes; + if (msg_size > log->data->capacity() - 1) + logger_flush(log); + *(log->data)+= cvtbuf; + } + +exit: + flogger_mutex_unlock(&log->lock); + return result; +} + + +static int logger_write_r(LOGGER_HANDLE *log, my_bool allow_rotations, + const char *buffer, size_t size) +{ + int result=0; + + flogger_mutex_lock(&log->lock); + if (allow_rotations && logger_time_to_rotate(log) && do_rotate(log)) + { + result= -1; + errno= my_errno; + goto exit; /* Log rotation needed but failed */ + } + + if (log->data.get() == nullptr || log->data->capacity() == 0) + { + result= (int)my_write(log->file, (uchar *) buffer, size, MYF(0)); + } + else + { + // Buffered logging + const size_t msg_size = log->data->size() + size; + if (msg_size > log->data->capacity() - 1) + result= logger_flush(log); + *(log->data)+= buffer; + } + +exit: + flogger_mutex_unlock(&log->lock); + return result; +} + + +int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size) +{ + return logger_write_r(log, TRUE, buffer, size); +} + +int logger_rotate(LOGGER_HANDLE *log, const unsigned int n_rotations) +{ + int result=0; + flogger_mutex_lock(&log->lock); + if (n_rotations) + log->rotations= n_rotations; + result= do_rotate(log); + flogger_mutex_unlock(&log->lock); + + return result; +} + + +int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...) +{ + int result; + va_list args; + va_start(args,fmt); + result= logger_vprintf(log, fmt, args); + va_end(args); + return result; +} + +void logger_init_mutexes() +{ +#ifdef HAVE_PSI_INTERFACE + if (unlikely(PSI_server)) + PSI_server->register_mutex("sql_logger", mutex_list, 1); +#endif +} + +/** Resize buffer size. + +@param[in,out] log log handle + +@return 0 success, !0 for error */ +int logger_resize_buffer(LOGGER_HANDLE *log, unsigned long long buffer_limit) +{ + if (log->data.get() != nullptr && buffer_limit == log->data->capacity()) + return 0; + + flogger_mutex_lock(&log->lock); + // Write out what we have currently, that way we don't have + // to deal with old data in the buffer + logger_flush(log); + log->buffer_limit= buffer_limit; + + if (buffer_limit == 0) + { + log->data.reset(); + } + else + { + log->resize_buffer(); + } + + flogger_mutex_unlock(&log->lock); + return 0; +} + +/** Flush buffered log to the disk. + +Note that this function does not use mutexes, thus +it should be called from function that does or +in shutdown or from signal handler. + +@param[in,out] log log handle + +@return 0 success, !0 for error */ +int logger_flush(LOGGER_HANDLE *log) +{ + size_t result= 0; + + if (log->data.get() == nullptr || log->data->size() == 0) + return 0; + + const size_t curr_size= log->data->capacity(); + if (logger_time_to_rotate(log) && do_rotate(log)) + { + /* Check errno for the cause */ + errno= my_errno; + result= 1; + goto exit; + } + + result= my_write(log->file, (uchar *) log->data->data(), log->data->size(), MYF(0)); + + if (result == (size_t)-1) + { + /* Check errno for the cause */ + errno= my_errno; + goto exit; + } + + result= 0; + log->data->clear(); + log->data->reserve(curr_size); + +exit: + return result; +} + +/** Set a new file size limit. + +If file size limit is changed we rotate to new log file +if limit is reached. + +@param[in,out] log log handle +@param[in] size_limit file size limit + +@return 0 success, !0 for error */ +int logger_resize_size(LOGGER_HANDLE *log, unsigned long long size_limit) +{ + int ret= 0; + + if (size_limit == log->size_limit) + return ret; // nothing to do + + flogger_mutex_lock(&log->lock); + + if ((ret= logger_flush(log))) + goto exit; + + log->size_limit= size_limit; + +exit: + flogger_mutex_unlock(&log->lock); + return ret; +} + + +/** Set a new file name. + +@param[in,out] log log handle +@param[in] path new file name + +@return 0 success, !0 for error */ +int logger_rename_file(LOGGER_HANDLE *log, const char *path) +{ + int res=0; + + flogger_mutex_lock(&log->lock); + + if ((res= logger_flush(log))) + goto exit; + + if ((res= my_close(log->file, MYF(0)))) + { + /* Check errno for the cause */ + errno= my_errno; + goto exit; + } + + log->path_len= strlen(fn_format(log->path, path, + mysql_data_home, "", MY_UNPACK_FILENAME)); + + if ((log->file= my_open(log->path, LOG_FLAGS, MYF(0))) < 0) + { + errno= my_errno; + /* Check errno for the cause */ + res= 1; + } +exit: + flogger_mutex_unlock(&log->lock); + return res; +} diff --git a/mysys/file_logger.c b/plugin/server_audit/file_logger.c similarity index 100% rename from mysys/file_logger.c rename to plugin/server_audit/file_logger.c diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c index be4e0b2294dfa..4b4528c1ce0ad 100644 --- a/plugin/server_audit/server_audit.c +++ b/plugin/server_audit/server_audit.c @@ -248,12 +248,14 @@ static my_off_t loc_tell(File fd) #ifdef HAVE_PSI_INTERFACE #undef HAVE_PSI_INTERFACE -#include -#include "../../mysys/file_logger.c" +// Note: as this file is still C, these files are +// added to this directory to avoid changing this. +#include "service_logger.h" +#include "file_logger.c" #define HAVE_PSI_INTERFACE #else -#include -#include "../../mysys/file_logger.c" +#include "service_logger.h" +#include "file_logger.c" #endif #endif /*!MARIADB_ONLY*/ diff --git a/plugin/server_audit/service_logger.h b/plugin/server_audit/service_logger.h new file mode 100644 index 0000000000000..b8d2b1eaf17a1 --- /dev/null +++ b/plugin/server_audit/service_logger.h @@ -0,0 +1,105 @@ +/* Copyright (C) 2012 Monty Program Ab + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ + +#ifndef MYSQL_SERVICE_LOGGER_INCLUDED +#define MYSQL_SERVICE_LOGGER_INCLUDED + +#ifndef MYSQL_ABI_CHECK +#include +#endif + +/** + @file + logger service + + Log file with rotation implementation. + + This service implements logging with possible rotation + of the log files. Interface intentionally tries to be similar to FILE* + related functions. + + So that one can open the log with logger_open(), specifying + the limit on the logfile size and the rotations number. + + Then it's possible to write messages to the log with + logger_printf or logger_vprintf functions. + + As the size of the logfile grows over the specified limit, + it is renamed to 'logfile.1'. The former 'logfile.1' becomes + 'logfile.2', etc. The file 'logfile.rotations' is removed. + That's how the rotation works. + + The rotation can be forced with the logger_rotate() call. + + Finally the log should be closed with logger_close(). + +@notes: + Implementation checks the size of the log file before it starts new + printf into it. So the size of the file gets over the limit when it rotates. + + The access is secured with the mutex, so the log is threadsafe. +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct logger_handle_st LOGGER_HANDLE; + +extern struct logger_service_st { + void (*logger_init_mutexes)(); + LOGGER_HANDLE* (*open)(const char *path, + unsigned long long size_limit, + unsigned int rotations); + int (*close)(LOGGER_HANDLE *log); + int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr); + int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...); + int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size); + int (*rotate)(LOGGER_HANDLE *log); +} *logger_service; + +#ifdef MYSQL_DYNAMIC_PLUGIN + +#define logger_init_mutexes logger_service->logger_init_mutexes +#define logger_open(path, size_limit, rotations) \ + (logger_service->open(path, size_limit, rotations)) +#define logger_close(log) (logger_service->close(log)) +#define logger_rotate(log) (logger_service->rotate(log)) +#define logger_vprintf(log, fmt, argptr) (logger_service->\ + vprintf(log, fmt, argptr)) +#define logger_printf (*logger_service->printf) +#define logger_write(log, buffer, size) \ + (logger_service->write(log, buffer, size)) +#else + + void logger_init_mutexes(); + LOGGER_HANDLE *logger_open(const char *path, + unsigned long long size_limit, + unsigned int rotations); + int logger_close(LOGGER_HANDLE *log); + int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr); + int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...); + int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size); + int logger_rotate(LOGGER_HANDLE *log); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /*MYSQL_SERVICE_LOGGER_INCLUDED*/ + diff --git a/plugin/sql_errlog/sql_errlog.c b/plugin/sql_errlog/sql_errlog.c index 6608bda5cce2a..b865f88511842 100644 --- a/plugin/sql_errlog/sql_errlog.c +++ b/plugin/sql_errlog/sql_errlog.c @@ -151,7 +151,7 @@ static int sql_error_log_init(void *p __attribute__((unused))) { logger_init_mutexes(); - logfile= logger_open(filename, size_limit, rotations); + logfile= logger_open(filename, size_limit, 0, rotations); if (logfile == NULL) { fprintf(stderr, "Could not create file '%s'\n", filename); @@ -175,7 +175,7 @@ static void rotate_log(MYSQL_THD thd __attribute__((unused)), void *var_ptr __attribute__((unused)), const void *save __attribute__((unused))) { - (void) logger_rotate(logfile); + (void) logger_rotate(logfile, 0); } diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 95a83d1244093..e714fd48d15ef 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -17,6 +17,7 @@ IF(WITH_WSREP AND NOT EMBEDDED_LIBRARY) SET(WSREP_SOURCES + wsrep_buffered_error_log.cc wsrep_client_service.cc wsrep_high_priority_service.cc wsrep_server_service.cc diff --git a/sql/handler.cc b/sql/handler.cc index 570fff8e0edcd..bbe7fc72877bd 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2343,13 +2343,16 @@ int ha_rollback_trans(THD *thd, bool all) transaction_participant *ht= ha_info->ht(); if ((err= ht->rollback(thd, all))) { - // cannot happen my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err); error=1; #ifdef WITH_WSREP - WSREP_WARN("handlerton rollback failed, thd %lld %lld conf %d SQL %s", - thd->thread_id, thd->query_id, thd->wsrep_trx().state(), - thd->query()); + if (WSREP(thd)) + WSREP_WARN("ht->rollback() failed, thd %lld %lld conf %d " + " err=%s wsrep=%s SQL %s", + thd->thread_id, thd->query_id, thd->wsrep_trx().state(), + strerror(err), + wsrep::to_c_string(thd->wsrep_cs().current_error()), + wsrep_thd_query(thd)); #endif /* WITH_WSREP */ } status_var_increment(thd->status_var.ha_rollback_count); @@ -2361,7 +2364,7 @@ int ha_rollback_trans(THD *thd, bool all) } #ifdef WITH_WSREP - if (thd->is_error()) + if (WSREP(thd) && thd->is_error()) { WSREP_DEBUG("ha_rollback_trans(%lld, %s) rolled back: %s: %s; is_real %d", thd->thread_id, all?"TRUE":"FALSE", wsrep_thd_query(thd), diff --git a/sql/log.cc b/sql/log.cc index 59168b08f8139..e8129815478ad 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -68,6 +68,7 @@ #ifdef WITH_WSREP #include "wsrep_trans_observer.h" #include "wsrep_status.h" +#include "wsrep_var.h" #endif /* WITH_WSREP */ #ifdef HAVE_REPLICATION @@ -403,11 +404,12 @@ Silence_log_table_errors::handle_condition(THD *, return TRUE; } -sql_print_message_func sql_print_message_handlers[3] = +sql_print_message_func sql_print_message_handlers[4] = { sql_print_information, sql_print_warning, - sql_print_error + sql_print_error, + sql_print_debug }; @@ -10024,7 +10026,12 @@ static void print_buffer_to_file(enum loglevel level, const char *buffer, struct tm *start; THD *thd= 0; size_t tag_length= 0; - char tag[NAME_LEN]; + char tag[NAME_LEN] = {'\0'}; + bool buf_allocated= false; + char tmp_buf[MAX_LOG_BUFFER_SIZE]= {'\0'}; + size_t len= MAX_LOG_BUFFER_SIZE-1; + char *buf = &tmp_buf[0]; + DBUG_ENTER("print_buffer_to_file"); DBUG_PRINT("enter",("buffer: %s", buffer)); @@ -10049,7 +10056,11 @@ static void print_buffer_to_file(enum loglevel level, const char *buffer, localtime_r(&skr, &tm_tmp); start=&tm_tmp; - fprintf_stderr( "%d-%02d-%02d %2d:%02d:%02d %lu [%s] %.*s%.*s\n", + assert(level <= DEBUG_LEVEL); + const char* level_msg[] = + { "ERROR", "Warning", "Note", "Debug" }; + + len= snprintf(buf, len, "%d-%02d-%02d %2d:%02d:%02d %lu [%s] %.*s%.*s\n", start->tm_year + 1900, start->tm_mon+1, start->tm_mday, @@ -10057,14 +10068,51 @@ static void print_buffer_to_file(enum loglevel level, const char *buffer, start->tm_min, start->tm_sec, (unsigned long) (thd ? thd->thread_id : 0), - (level == ERROR_LEVEL ? "ERROR" : level == WARNING_LEVEL ? - "Warning" : "Note"), + level_msg[level], (int) tag_length, tag, (int) length, buffer); - fflush(stderr); + if (len > sizeof(tmp_buf) -1 ) + { + len += 2; // safety + buf= (char *)my_malloc(PSI_INSTRUMENT_ME, len, MYF(MY_WME)); + buf_allocated= true; + len = snprintf(buf, len, "%d-%02d-%02d %2d:%02d:%02d %lu [%s] %.*s%.*s\n", + start->tm_year + 1900, + start->tm_mon+1, + start->tm_mday, + start->tm_hour, + start->tm_min, + start->tm_sec, + (unsigned long) (thd ? thd->thread_id : 0), + level_msg[level], + (int) tag_length, tag, + (int) length, buffer); + } #ifdef WITH_WSREP + // Use normal logging if log level is not DEBUG OR + // if user requested DEBUG level logging and buffered + // error log is not on. + if (level < DEBUG_LEVEL || + ((wsrep_debug_mode & WSREP_DEBUG_MODE_DEBUG) && + !(wsrep_debug_mode & WSREP_DEBUG_MODE_BUFFERED))) + { +#endif + fprintf(stderr, "%s", buf); + fflush(stderr); +#ifdef WITH_WSREP + } + + // Use buffred logging if log level is not DEBUG AND + // buffered logging is requested OR + // if user requested DEBUG level logging and buffered + // error log on. + if ((level < DEBUG_LEVEL && (wsrep_debug_mode & WSREP_DEBUG_MODE_BUFFERED)) || + ((wsrep_debug_mode & WSREP_DEBUG_MODE_DEBUG) && + (wsrep_debug_mode & WSREP_DEBUG_MODE_BUFFERED))) + wsrep_buffered_error_log.log(buf, len); + if (level <= WARNING_LEVEL) { wsrep::reporter::log_level const lvl = (level <= ERROR_LEVEL ? @@ -10074,6 +10122,9 @@ static void print_buffer_to_file(enum loglevel level, const char *buffer, } #endif /* WITH_WSREP */ + if (buf_allocated) + my_free(buf); + mysql_mutex_unlock(&LOCK_error_log); DBUG_VOID_RETURN; } @@ -10111,6 +10162,17 @@ int vprint_msg_to_log(enum loglevel level, const char *format, va_list args) } #endif /* EMBEDDED_LIBRARY */ +void sql_print_debug(const char *format, ...) +{ + va_list args; + DBUG_ENTER("sql_print_debug"); + + va_start(args, format); + error_log_print(DEBUG_LEVEL, format, args); + va_end(args); + + DBUG_VOID_RETURN; +} void sql_print_error(const char *format, ...) { diff --git a/sql/log.h b/sql/log.h index 2f3b6508f58d9..05613b7e6445c 100644 --- a/sql/log.h +++ b/sql/log.h @@ -1372,6 +1372,8 @@ void sql_print_error(const char *format, ...); void sql_print_warning(const char *format, ...); void sql_print_information(const char *format, ...); void sql_print_information_v(const char *format, va_list ap); +void sql_print_debug(const char *format, ...); + typedef void (*sql_print_message_func)(const char *format, ...); extern sql_print_message_func sql_print_message_handlers[]; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 28f02f7162fdd..3218675229b66 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1333,9 +1333,10 @@ void Buffered_log::print() case WARNING_LEVEL: sql_print_warning("Buffered warning: %s", m_message.c_ptr_safe()); break; + case DEBUG_LEVEL: case INFORMATION_LEVEL: /* - Messages printed as "information" still end up in the mysqld *error* log, + Messages printed as "information" or "debug" still end up in the mysqld *error* log, but with a [Note] tag instead of an [ERROR] tag. While this is probably fine for a human reading the log, it is upsetting existing automated scripts used to parse logs, @@ -2065,6 +2066,10 @@ static void clean_up(bool print_message) free_error_messages(); /* Tell main we are ready */ logger.cleanup_end(); +#ifdef WITH_WSREP + wsrep_buffered_error_log.write_to_disk(); + wsrep_buffered_error_log.close(); +#endif /* WITH_WSREP */ sys_var_end(); free_charsets(); @@ -5038,6 +5043,13 @@ static int init_server_components() error_handler_hook= my_message_sql; proc_info_hook= set_thd_stage_info; +#ifdef WITH_WSREP + /* Init function will determine if we use buffered error log or not */ + wsrep_buffered_error_log.init(); + if (wsrep_debug) + wsrep_debug_mode |= WSREP_DEBUG_MODE_DEBUG; +#endif + /* Set up hook to handle disk full */ my_sleep_for_space= mariadb_sleep_for_space; diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc index 96020c68b2bc5..30b09abddb40a 100644 --- a/sql/signal_handler.cc +++ b/sql/signal_handler.cc @@ -29,6 +29,10 @@ #include "wsrep_server_state.h" #endif /* WITH_WSREP */ +#ifdef WITH_WSREP +#include "wsrep_mysqld.h" +#endif + #ifdef _WIN32 #include #include @@ -147,6 +151,10 @@ extern "C" sig_handler handle_fatal_signal(int sig) bool print_invalid_query_pointer= false; #endif +#ifdef WITH_WSREP + wsrep_buffered_error_log.write_to_disk(); +#endif + if (segfaulted) { my_safe_printf_stderr("Fatal " SIGNAL_FMT " while backtracing\n", sig); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 12445dd778231..d12de5cd2dec0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1651,7 +1651,8 @@ dispatch_command_return dispatch_command(enum enum_server_command command, THD * if (WSREP(thd) && thd->wsrep_next_trx_id() == WSREP_UNDEFINED_TRX_ID) { thd->set_wsrep_next_trx_id(thd->query_id); - WSREP_DEBUG("assigned new next trx id: %" PRIu64, thd->wsrep_next_trx_id()); + WSREP_DEBUG("Thread %llu assigned new next trx id: %" PRIu64, + thd_get_thread_id(thd),thd->wsrep_next_trx_id()); } #endif /* WITH_WSREP */ diff --git a/sql/sql_plugin_services.inl b/sql/sql_plugin_services.inl index 2114f3560a7ec..dfe1426dc50ae 100644 --- a/sql/sql_plugin_services.inl +++ b/sql/sql_plugin_services.inl @@ -114,7 +114,11 @@ static struct logger_service_st logger_service_handler= { logger_vprintf, logger_printf, logger_write, - logger_rotate + logger_rotate, + logger_rename_file, + logger_resize_buffer, + logger_resize_size, + logger_flush }; static struct thd_autoinc_service_st thd_autoinc_handler= { diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index af07c636bc2b6..c09b24d793370 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -69,7 +69,8 @@ #include #ifdef WITH_WSREP #include "wsrep_mysqld.h" -#endif +#include "wsrep_buffered_error_log.h" +#endif /* WITH_WSREP */ #define PCRE2_STATIC 1 /* Important on Windows */ #include "pcre2.h" /* pcre2 header file */ @@ -5224,7 +5225,7 @@ Sys_proxy_protocol_networks( ON_CHECK(check_proxy_protocol_networks), ON_UPDATE(fix_proxy_protocol_networks)); -static bool check_log_path(sys_var *self, THD *thd, set_var *var) +bool check_log_path(sys_var *self, THD *thd, set_var *var) { if (!var->value) return false; // DEFAULT is ok @@ -6520,6 +6521,37 @@ static Sys_var_charptr Sys_wsrep_allowlist( READ_ONLY GLOBAL_VAR(wsrep_allowlist), CMD_LINE(REQUIRED_ARG), DEFAULT("")); +static Sys_var_charptr_fscs Sys_wsrep_buffered_error_log_filename( + "wsrep_buffered_error_log_filename", "Filename of the buffered error log", + PREALLOCATED GLOBAL_VAR(wsrep_buffered_error_log_filename), CMD_LINE(REQUIRED_ARG), + DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(wsrep_buffered_error_log_filename_check), + ON_UPDATE(wsrep_buffered_error_log_filename_update)); + +static Sys_var_ulonglong Sys_wsrep_buffered_error_log_buffer_size( + "wsrep_buffered_error_log_buffer_size", "Size of the buffered error log buffer", + GLOBAL_VAR(wsrep_buffered_error_log_buffer_size), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, SIZE_T_MAX), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD, + NOT_IN_BINLOG, + ON_CHECK(wsrep_buffered_error_log_buffer_size_check), + ON_UPDATE(wsrep_buffered_error_log_buffer_size_update)); + +static Sys_var_ulonglong Sys_wsrep_buffered_error_log_file_size( + "wsrep_buffered_error_log_file_size", "Max size of the buffered error log file", + GLOBAL_VAR(wsrep_buffered_error_log_file_size), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, SIZE_T_MAX), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD, + NOT_IN_BINLOG, + ON_CHECK(wsrep_buffered_error_log_file_size_check), + ON_UPDATE(wsrep_buffered_error_log_file_size_update)); + +static Sys_var_uint Sys_wsrep_buffered_error_log_rotations ( + "wsrep_buffered_error_log_rotations", "Number of log rotations before log is removed", + GLOBAL_VAR(wsrep_buffered_error_log_rotations), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, 999999), + DEFAULT(10), BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(wsrep_buffered_error_log_rotations_check), + ON_UPDATE(wsrep_buffered_error_log_rotations_update)); + #endif /* WITH_WSREP */ static bool fix_host_cache_size(sys_var *, THD *, enum_var_type) diff --git a/sql/wsrep_buffered_error_log.cc b/sql/wsrep_buffered_error_log.cc new file mode 100644 index 0000000000000..27345362113b4 --- /dev/null +++ b/sql/wsrep_buffered_error_log.cc @@ -0,0 +1,160 @@ +/* Copyright (C) 2025 Codership Oy + + Created by Zsolt Parragi + Modified by Jan Lindström + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ + +#include "wsrep_buffered_error_log.h" +#include "wsrep.h" +#include "wsrep_mysqld.h" + +Buffered_error_logger wsrep_buffered_error_log; +const char *wsrep_buffered_error_log_filename= nullptr; +unsigned long long wsrep_buffered_error_log_buffer_size= 0; +unsigned long long wsrep_buffered_error_log_file_size= 0; +uint wsrep_buffered_error_log_rotations= 0; + +void Buffered_error_logger::init() +{ + logfile= nullptr; + + if (wsrep_buffered_error_log_buffer_size > 0 && + wsrep_buffered_error_log_file_size > 0 && + wsrep_buffered_error_log_filename != nullptr && + strlen(wsrep_buffered_error_log_filename) > 0) + { + logfile= logger_open(wsrep_buffered_error_log_filename, + wsrep_buffered_error_log_file_size, + wsrep_buffered_error_log_buffer_size, + wsrep_buffered_error_log_rotations); + + if (!logfile) + { + WSREP_WARN("Could not open buffered error log %s error=%s (%d).", + wsrep_buffered_error_log_filename, + strerror(errno), errno); + wsrep_disable_logging(); + } + else + { + wsrep_debug_mode |= WSREP_DEBUG_MODE_BUFFERED; + } + } + + return; +} + +void Buffered_error_logger::resize_buffer(const std::size_t buffer_size) +{ + if (!logfile) + return; + + if (logger_resize_buffer(logfile, buffer_size)) + { + wsrep_disable_logging(); + WSREP_WARN("Resize of buffered error log %s to size %zd failed error=%s (%ld).", + wsrep_buffered_error_log_filename, buffer_size, + strerror(errno), errno); + } +} + +void Buffered_error_logger::resize_file_size(const std::size_t file_size) +{ + if (!logfile) + return; + + if (logger_resize_size(logfile, file_size)) + { + wsrep_disable_logging(); + WSREP_WARN("Resize of buffered error log %s file size to %zd failed error=%s (%ld).", + wsrep_buffered_error_log_filename, file_size, + strerror(errno), errno); + } +} + +void Buffered_error_logger::rename_file(const char* new_name) +{ + if (!logfile) + return; + + if (logger_rename_file(logfile, new_name)) + { + wsrep_disable_logging(); + WSREP_WARN("Rename of buffered error log %s to %s failed error=%s (%ld).", + wsrep_buffered_error_log_filename, new_name, + strerror(errno), errno); + } +} + +Buffered_error_logger::~Buffered_error_logger() +{ + if (logfile) + { + logger_close(logfile); + logfile= nullptr; + } +} + +void Buffered_error_logger::log(const char *msg, const std::size_t len) +{ + if (logfile) + { + if (logger_write(logfile, msg, len)) + { + wsrep_disable_logging(); + WSREP_WARN("Log write to buffered error log %s failed error=%s (%ld).", + wsrep_buffered_error_log_filename, + strerror(errno), errno); + } + } +} + +void Buffered_error_logger::write_to_disk() +{ + if (logfile) + { + if (logger_flush(logfile)) + { + wsrep_disable_logging(); + WSREP_WARN("Log write to buffered error log %s failed error=%s (%ld).", + wsrep_buffered_error_log_filename, + strerror(errno), errno); + } + } +} + +void Buffered_error_logger::close() +{ + if (logfile) + { + logger_flush(logfile); + logger_close(logfile); + logfile= nullptr; + } +} + +void Buffered_error_logger::rotate(const uint n_rotations) +{ + if (!logfile || n_rotations == 0) + return; + + if (logger_rotate(logfile, n_rotations)) + { + wsrep_disable_logging(); + WSREP_WARN("Rotation of buffered error log %s failed error=%s (%ld).", + wsrep_buffered_error_log_filename, + strerror(errno), errno); + } +} diff --git a/sql/wsrep_buffered_error_log.h b/sql/wsrep_buffered_error_log.h new file mode 100644 index 0000000000000..9735282cb45df --- /dev/null +++ b/sql/wsrep_buffered_error_log.h @@ -0,0 +1,56 @@ +/* Copyright (C) 2025 Codership Oy + + Created by Zsolt Parragi + Modified by Jan Lindström + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#ifndef WSREP_BUFFERED_ERROR_LOG_H +#define WSREP_BUFFERED_ERROR_LOG_H 1 + +#include +#include +#include +#include +#include +#include +#include +#include + +/** Stores log messages in a fixed size buffer, which can be dumped by large + * chunks instead of line by line, to increase performance for high throughput + * scenarios. + * + * The buffer is also dumped by the crash reporting code and during shutdown to + * ensure that nothing is lost, only delayed. + */ +class Buffered_error_logger +{ +private: + LOGGER_HANDLE* logfile; + + public: + void init(); + void resize_buffer(const std::size_t buffer_size); + void resize_file_size(const std::size_t file_size); + void rename_file(const char* new_name); + void rotate(const uint n_rotations); + + ~Buffered_error_logger(); + + void log(const char *msg, const std::size_t len); + void write_to_disk(); + void close(); +}; + +#endif /* WSREP_BUFFERED_ERROR_LOG */ diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index cf8b9d36c9120..e759d54d5623c 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2008, 2023 Codership Oy - Copyright (c) 2020, 2022, MariaDB +/* Copyright (c) 2008, 2025 Codership Oy + Copyright (c) 2020, 2024, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -130,6 +130,8 @@ uint wsrep_ignore_apply_errors= 0; std::atomic wsrep_thread_create_failed; +ulong wsrep_debug_mode= 0; + /* * End configuration options */ @@ -4041,3 +4043,14 @@ void wsrep_commit_empty(THD* thd, bool all) } DBUG_VOID_RETURN; } + +void wsrep_disable_logging(void) +{ + // Disable buffered error logging + wsrep_debug_mode &= ~WSREP_DEBUG_MODE_BUFFERED; + // Disable also wsrep_debug logging + wsrep_debug_mode &= WSREP_DEBUG_MODE_DEBUG; + // Set wsrep_debug to NONE + wsrep_debug=0; + WSREP_WARN("Buffered error logging and wsrep debug logging disabled."); +} diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index 183dc65b00707..204d42a0e301d 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -1,4 +1,4 @@ -/* Copyright 2008-2023 Codership Oy +/* Copyright 2008-2024 Codership Oy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -38,6 +38,7 @@ typedef struct st_mysql_show_var SHOW_VAR; #include "wsrep/streaming_context.hpp" #include "wsrep_api.h" #include +#include "wsrep_buffered_error_log.h" #define WSREP_UNDEFINED_TRX_ID ULONGLONG_MAX @@ -145,6 +146,13 @@ enum enum_wsrep_mode { extern const char *wsrep_fragment_units[]; extern const char *wsrep_SR_store_types[]; +/* Modes for wsrep debug error logging */ +enum enum_wsrep_debug_mode { + WSREP_DEBUG_MODE_OFF = 0x0, + WSREP_DEBUG_MODE_DEBUG = 0x1, + WSREP_DEBUG_MODE_BUFFERED = 0x2 +}; + // MySQL status variables extern my_bool wsrep_connected; extern const char* wsrep_cluster_state_uuid; @@ -158,6 +166,11 @@ extern const char* wsrep_provider_version; extern const char* wsrep_provider_vendor; extern char* wsrep_provider_capabilities; extern char* wsrep_cluster_capabilities; +extern unsigned long long wsrep_buffered_error_log_buffer_size; +extern unsigned long long wsrep_buffered_error_log_file_size; +extern const char* wsrep_buffered_error_log_filename; +extern Buffered_error_logger wsrep_buffered_error_log; +extern uint wsrep_buffered_error_log_rotations; int wsrep_show_status(THD *thd, SHOW_VAR *var, void *buff, system_status_var *status_var, enum_var_type scope); @@ -593,6 +606,9 @@ wsrep::key wsrep_prepare_key_for_toi(const char* db, const char* table, void wsrep_wait_ready(THD *thd); void wsrep_ready_set(bool ready_value); + +void wsrep_disable_logging(void); + #else /* !WITH_WSREP */ /* These macros are needed to compile MariaDB without WSREP support diff --git a/sql/wsrep_trans_observer.h b/sql/wsrep_trans_observer.h index 25e71638efd74..1e216803b9fd6 100644 --- a/sql/wsrep_trans_observer.h +++ b/sql/wsrep_trans_observer.h @@ -472,12 +472,6 @@ static inline int wsrep_after_statement(THD* thd) { DBUG_ENTER("wsrep_after_statement"); - WSREP_DEBUG("wsrep_after_statement for %lu client_state %s " - " client_mode %s trans_state %s", - thd_get_thread_id(thd), - wsrep::to_c_string(thd->wsrep_cs().state()), - wsrep::to_c_string(thd->wsrep_cs().mode()), - wsrep::to_c_string(thd->wsrep_cs().transaction().state())); int ret= ((thd->wsrep_cs().state() != wsrep::client_state::s_none && thd->wsrep_cs().mode() == Wsrep_client_state::m_local) && !thd->internal_transaction() ? diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc index 83e017a2fc312..03b47476c72fd 100644 --- a/sql/wsrep_var.cc +++ b/sql/wsrep_var.cc @@ -1,4 +1,4 @@ -/* Copyright 2008-2022 Codership Oy +/* Copyright 2008-2025 Codership Oy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -596,6 +596,11 @@ bool wsrep_debug_update(sys_var *self, THD* thd, enum_var_type type) else Wsrep_server_state::instance().debug_log_level(wsrep_debug); + if (wsrep_debug) + wsrep_debug_mode |= WSREP_DEBUG_MODE_DEBUG; + else + wsrep_debug_mode &= ~WSREP_DEBUG_MODE_DEBUG; + return false; } @@ -1121,3 +1126,173 @@ bool wsrep_gtid_domain_id_update(sys_var* self, THD *thd, enum_var_type) return false; } +bool wsrep_buffered_error_log_buffer_size_update(sys_var *, THD *, enum_var_type) +{ + wsrep_buffered_error_log.resize_buffer(wsrep_buffered_error_log_buffer_size); + + if (wsrep_buffered_error_log_buffer_size) + wsrep_debug_mode |= WSREP_DEBUG_MODE_BUFFERED; + else + wsrep_debug_mode &= ~WSREP_DEBUG_MODE_BUFFERED; + + return false; +} + +bool wsrep_buffered_error_log_buffer_size_check(sys_var *self, THD* thd, set_var *var) +{ + const unsigned long long new_buffer_size= var->save_result.ulonglong_value; + + if (!new_buffer_size) + return false; + + if (!WSREP(thd)) + { + push_warning (thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "Cannot set 'wsrep_buffered_error_log_size' to a value other than " + "0 because wsrep is switched off."); + return true; + } + + const unsigned long long max_size= wsrep_buffered_error_log_file_size / 10; + const unsigned long long min_size= wsrep_debug ? 100 * 1024 : 10 * 1024; + + if (new_buffer_size < min_size || new_buffer_size > max_size) + { + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "Parameter 'wsrep_buffered_error_log_size' should be at range" + " %llu-%llu because wsrep_buffered_error_log_file_size=%llu", + min_size, max_size, + wsrep_buffered_error_log_file_size); + return true; + } + + return false; +} + +bool wsrep_buffered_error_log_file_size_update(sys_var *, THD *, enum_var_type) +{ + wsrep_buffered_error_log.resize_file_size(wsrep_buffered_error_log_file_size); + return false; +} + +bool wsrep_buffered_error_log_file_size_check(sys_var *self, THD* thd, set_var *var) +{ + const unsigned long long new_file_size= var->save_result.ulonglong_value; + + if (!new_file_size) + return false; + + if (!WSREP(thd)) + { + push_warning (thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "Cannot set 'wsrep_buffered_error_log_file_size' to a value other than " + "0 because wsrep is switched off."); + return true; + } + + if (!wsrep_buffered_error_log_buffer_size) + { + push_warning (thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "Cannot set 'wsrep_buffered_error_log_file_size' to a value other than " + "0 because wsrep_buffered_error_log_buffer_size is 0."); + return true; + } + + if (new_file_size < wsrep_buffered_error_log_buffer_size * 10) + { + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "Cannot set 'wsrep_buffered_error_log_file_size' too small " + "should be at least %llu.", wsrep_buffered_error_log_buffer_size * 10); + return true; + } + + return false; +} + +extern bool check_log_path(sys_var *self, THD *thd, set_var *var); // sys_var.cc + +bool wsrep_buffered_error_log_filename_update(sys_var*, THD* thd, enum_var_type type) +{ + // empty + if (!wsrep_buffered_error_log_filename || + strlen(wsrep_buffered_error_log_filename) == 0) + return false; + + wsrep_buffered_error_log.rename_file(wsrep_buffered_error_log_filename); + return false; +} + +bool wsrep_buffered_error_log_filename_check(sys_var *self, THD* thd, set_var *var) +{ + // Allow empty + if (!var->value || + !var->save_result.string_value.str || + strlen(var->save_result.string_value.str) == 0) + return false; + + if (!WSREP(thd)) + { + push_warning (thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "Cannot set 'wsrep_buffered_error_log_filename' " + "because wsrep is switched off."); + return true; + } + + if (!wsrep_buffered_error_log_buffer_size || !wsrep_buffered_error_log_file_size) + { + push_warning (thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "Cannot set 'wsrep_buffered_error_log_filename' " + "because wsrep_buffered_error_log_buffer_size or" + "wsrep_buffered_error_log_file_size is 0."); + return true; + } + + if (check_log_path(self, thd, var)) + { + push_warning_printf (thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "Cannot set 'wsrep_buffered_error_log_filename' to %s", + var->save_result.string_value.str); + return true; + } + + return false; +} + +bool wsrep_buffered_error_log_rotations_update(sys_var *, THD *, enum_var_type) +{ + wsrep_buffered_error_log.rotate(wsrep_buffered_error_log_rotations); + return false; +} + +bool wsrep_buffered_error_log_rotations_check(sys_var *self, THD* thd, set_var *var) +{ + const longlong new_rotations= (longlong)var->save_result.ulonglong_value; + + if (!WSREP(thd) && new_rotations) + { + push_warning (thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "Cannot set 'wsrep_buffered_error_log_rotations' to a value other than " + "0 because wsrep is switched off."); + return true; + } + + if (!wsrep_buffered_error_log_buffer_size && new_rotations) + { + push_warning (thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "Cannot set 'wsrep_buffered_error_log_rotations' to a value other than " + "0 because wsrep_buffered_error_log_buffer_size is 0."); + return true; + } + + return false; +} diff --git a/sql/wsrep_var.h b/sql/wsrep_var.h index 6b10530ae97ce..182812728c949 100644 --- a/sql/wsrep_var.h +++ b/sql/wsrep_var.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2013-2022 Codership Oy +/* Copyright (C) 2013-2025 Codership Oy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -109,6 +109,15 @@ extern bool wsrep_gtid_seq_no_check CHECK_ARGS; extern bool wsrep_gtid_domain_id_update UPDATE_ARGS; extern bool wsrep_mode_check CHECK_ARGS; + +extern bool wsrep_buffered_error_log_buffer_size_update UPDATE_ARGS; +extern bool wsrep_buffered_error_log_buffer_size_check CHECK_ARGS; +extern bool wsrep_buffered_error_log_file_size_update UPDATE_ARGS; +extern bool wsrep_buffered_error_log_file_size_check CHECK_ARGS; +extern bool wsrep_buffered_error_log_filename_check CHECK_ARGS; +extern bool wsrep_buffered_error_log_filename_update UPDATE_ARGS; +extern bool wsrep_buffered_error_log_rotations_update UPDATE_ARGS; +extern bool wsrep_buffered_error_log_rotations_check CHECK_ARGS; #else /* WITH_WSREP */ #define wsrep_provider_init(X)