diff --git a/mysql/CHANGELOG b/mysql/CHANGELOG index 82fd19c5b..46f6c18d5 100644 --- a/mysql/CHANGELOG +++ b/mysql/CHANGELOG @@ -1,5 +1,6 @@ ---- Changes since 2.641 ---- Added defaults for alpine linux and fix package installs +Added a Binary Logging page for enabling binary logs, setting their format, maximum file size and retention period, rotating logs on demand, and deleting old log files. ---- Changes since 1.140 ---- The not null flag and a default value can be specified for fields in new tables. The form for creating an initial table in a new database is now the same as the one for adding a table to an existing database. diff --git a/mysql/edit_binlogs.cgi b/mysql/edit_binlogs.cgi new file mode 100755 index 000000000..219fd1957 --- /dev/null +++ b/mysql/edit_binlogs.cgi @@ -0,0 +1,169 @@ +#!/usr/local/bin/perl +# Show binary logging status, configuration options and log cleanup + +require './mysql-lib.pl'; +$access{'perms'} == 1 || &error($text{'binlogs_ecannot'}); +&ReadParse(); +&ui_print_header(undef, $text{'binlogs_title'}, "", "binlogs"); + +# Make sure config exists +$conf = &get_mysql_config(); +if (!$conf) { + print &text('cnf_efile', "$config{'my_cnf'}", + "../config.cgi?$module_name"),"

\n"; + &ui_print_footer("", $text{'index_return'}); + exit; + } +# Prefer the main server section over generic MariaDB sections that can +# belong to a plugin-specific include file +($mysqld) = grep { $_->{'name'} eq 'mysqld' } @$conf; +($mysqld) = grep { $_->{'name'} eq 'mariadbd' } @$conf if (!$mysqld); +($mysqld) = grep { $_->{'name'} eq 'mariadb' } @$conf if (!$mysqld); +$mysqld || &error($text{'cnf_emysqld'}); +$mems = $mysqld->{'members'}; +$local = &is_mysql_local(); + +# Get the status reported by the running server +($curfile, $curpos) = &get_binary_log_status(); +@logs = &list_binary_logs(); +$liveformat = eval { + local $main::error_must_die = 1; + my $d = &execute_sql($master_db, + "show variables like 'binlog_format'"); + @{$d->{'data'}} ? $d->{'data'}->[0]->[1] : undef; + }; + +# Show tabs for configuration and log cleanup +@tabs = ( [ 'options', $text{'binlogs_tab_options'} ], + $curfile ? ( [ 'purge', $text{'binlogs_tab_purge'} ] ) : ( ) ); +%valid = map { $_->[0] => 1 } @tabs; +$mode = $in{'mode'} && $valid{$in{'mode'}} ? $in{'mode'} : 'options'; +print &ui_tabs_start(\@tabs, "mode", $mode, 1); + +# Configuration tab +print &ui_tabs_start_tab("mode", "options"); +print &ui_div($text{'binlogs_desc_options'}); +print &ui_form_start("save_binlogs.cgi", "post"); +print &ui_table_start($text{'binlogs_header'}, "width=100%", 2); + +# Current state, as one read-only row +if ($curfile) { + $total = 0; + foreach $l (@logs) { + $total += $l->{'size'}; + } + print &ui_table_row($text{'binlogs_active'}, + &text('binlogs_activeyes', "".&html_escape($curfile)."", + $curpos, scalar(@logs), &nice_size($total)). + ($liveformat ? " ".&text('binlogs_activefmt', + uc($liveformat)) : "")); + } +else { + print &ui_table_row($text{'binlogs_active'}, $text{'no'}); + } + +if ($local) { + # Enabled state considers both positive and negative directives, the + # live server status, and finally whether this server version logs + # by default when nothing is configured (as MySQL 8+ does) + $lbdir = &find("log_bin", $mems) || &find("log-bin", $mems); + $skipdir = &find("skip-log-bin", $mems) || + &find("skip_log_bin", $mems) || + &find("disable-log-bin", $mems) || + &find("disable_log_bin", $mems); + $lb = $lbdir ? $lbdir->{'value'} : undef; + $enabled = $skipdir ? 0 : $lbdir ? 1 : $curfile ? 1 : + &get_binlog_default_on(); + print &ui_table_row(&hlink($text{'binlogs_enabled'}, + "binlogs_enabled"), + &ui_yesno_radio("enabled", $enabled)); + + print &ui_table_row(&hlink($text{'binlogs_base'}, "binlogs_base"), + &ui_opt_textbox("base", $lb, 30, $text{'binlogs_base_def'})); + + $sid = &find_value("server_id", $mems); + $sid = &find_value("server-id", $mems) if (!defined($sid)); + print &ui_table_row(&hlink($text{'binlogs_serverid'}, + "binlogs_serverid"), + &ui_opt_textbox("serverid", $sid, 10, $text{'default'})); + + # Log format, which must be ROW for point-in-time recovery + $fmt = &find_value("binlog_format", $mems); + $fmt = &find_value("binlog-format", $mems) if (!defined($fmt)); + print &ui_table_row(&hlink($text{'binlogs_format'}, + "binlogs_format"), + &ui_select("format", uc($fmt // ''), + [ [ '', $text{'default'} ], + [ 'ROW', $text{'binlogs_format_row'} ], + [ 'MIXED', $text{'binlogs_format_mixed'} ], + [ 'STATEMENT', + $text{'binlogs_format_statement'} ] ])); + + # Maximum size of one log file before rotation + $maxsize = &find_value("max_binlog_size", $mems); + $maxsize = &find_value("max-binlog-size", $mems) + if (!defined($maxsize)); + print &ui_table_row(&hlink($text{'binlogs_maxsize'}, + "binlogs_maxsize"), + &ui_radio("maxsize_def", defined($maxsize) ? 0 : 1, + [ [ 1, $text{'default'} ], [ 0, " " ] ])."\n". + &mysql_size_input("maxsize", $maxsize)); + + # Retention period, stored in a variant-specific variable + ($ver, $variant) = &get_mysql_variant_cached(); + $secs = &find_value("binlog_expire_logs_seconds", $mems); + $days = &find_value("expire_logs_days", $mems); + $expire = defined($secs) ? &format_binlog_expire_days($secs) : + defined($days) ? $days : undef; + print &ui_table_row(&hlink($text{'binlogs_expire'}, + "binlogs_expire"), + &ui_opt_textbox("expire", $expire, 6, + $text{'binlogs_expire_def'}). + " ".$text{'binlogs_days'}); + + print &ui_table_end(); + print &ui_form_end([ [ "save", $text{'save'} ], + &is_mysql_running() > 0 ? + ( [ "restart", + $text{'binlogs_restart'} ] ) : ( ) ]); + } +else { + # Config file editing only works for a local database server + print &ui_table_end(); + print &ui_form_end(); + print &ui_alert($text{'binlogs_eremote'}, 'info'); + } +print &ui_tabs_end_tab("mode", "options"); + +# Log cleanup tab +if ($curfile) { + print &ui_tabs_start_tab("mode", "purge"); + print &ui_div($text{'binlogs_desc_purge'}); + print &ui_form_start("purge_binlogs.cgi", "post"); + print &ui_table_start($text{'binlogs_purgeheader'}, + "width=100%", 2); + print &ui_table_row(&hlink($text{'binlogs_purge'}, + "binlogs_purge"), + &ui_radio("mode", 0, + [ [ 0, &text('binlogs_purgedays', + &ui_textbox("days", 7, 6))."
" ], + [ 1, $text{'binlogs_purgeall'} ] ])); + print &ui_table_end(); + print &ui_form_end([ [ "purge", $text{'binlogs_purgeok'} ] ]); + print &ui_tabs_end_tab("mode", "purge"); + } + +print &ui_tabs_end(); + +# Button to close the current log and start a new one, which gives backups +# and log deletion a clean boundary to work with +if ($curfile) { + print &ui_hr(); + print &ui_buttons_start(); + print &ui_buttons_row("flush_binlogs.cgi", $text{'binlogs_rotateok'}, + &text('binlogs_rotatedesc', + "".&html_escape($curfile)."")); + print &ui_buttons_end(); + } + +&ui_print_footer("", $text{'index_return'}); diff --git a/mysql/edit_cnf.cgi b/mysql/edit_cnf.cgi index 9a6055dea..eaa35b820 100755 --- a/mysql/edit_cnf.cgi +++ b/mysql/edit_cnf.cgi @@ -13,9 +13,11 @@ if (!$conf) { &ui_print_footer("", $text{'index_return'}); exit; } -($mysqld) = grep { $_->{'name'} eq 'mysqld' || - $_->{'name'} eq 'mariadbd' || - $_->{'name'} eq 'mariadb' } @$conf; +# Prefer the main server section over generic MariaDB sections that can +# belong to a plugin-specific include file +($mysqld) = grep { $_->{'name'} eq 'mysqld' } @$conf; +($mysqld) = grep { $_->{'name'} eq 'mariadbd' } @$conf if (!$mysqld); +($mysqld) = grep { $_->{'name'} eq 'mariadb' } @$conf if (!$mysqld); $mysqld || &error($text{'cnf_emysqld'}); $mems = $mysqld->{'members'}; @@ -110,4 +112,3 @@ print &ui_form_end([ [ "save", $text{'save'} ], [ "restart", $text{'cnf_restart'} ] ]); &ui_print_footer("", $text{'index_return'}); - diff --git a/mysql/flush_binlogs.cgi b/mysql/flush_binlogs.cgi new file mode 100755 index 000000000..f859da3df --- /dev/null +++ b/mysql/flush_binlogs.cgi @@ -0,0 +1,13 @@ +#!/usr/local/bin/perl +# Close the current binary log and start writing a new one + +require './mysql-lib.pl'; +$access{'perms'} == 1 || &error($text{'binlogs_ecannot'}); +&error_setup($text{'binlogs_rotateerr'}); +&ReadParse(); + +my ($curfile) = &get_binary_log_status(); +$curfile || &error($text{'binlogs_epurgeoff'}); +&rotate_binary_logs(); +&webmin_log("flushbinlogs"); +&redirect("edit_binlogs.cgi"); diff --git a/mysql/help/binlogs.html b/mysql/help/binlogs.html new file mode 100644 index 000000000..265ae6044 --- /dev/null +++ b/mysql/help/binlogs.html @@ -0,0 +1,18 @@ +

Binary Logging
+ +This page can be used to enable or disable binary logging on the MySQL or +MariaDB database server, and to manage existing binary log files. Binary logs +record all changes made to databases, and are needed for replication and for +point-in-time recovery of backups.

+ +When binary logging is enabled, log files are written under the configured +base name and grow as changes are made. To stop them from filling up the disk, +a retention period can be set after which old logs are automatically deleted, +or old logs can be deleted immediately using the form at the bottom of the +page.

+ +For any changes on this page to take effect, the MySQL server must be +re-started, either with the Save and Restart MySQL button or using the +buttons on the module's main page.

+ +