When managing MySQL servers, situations often arise where the original my.cnf configuration file gets lost or corrupted, yet the server continues running with its current settings. This creates a critical need to reconstruct the configuration file without restarting the service.
The most straightforward method is querying the running server for its current configuration:
mysql -uroot -p -e "SHOW VARIABLES;" > current_mysql_config.txt
This exports all server variables to a text file. However, the output needs filtering since it includes both default and explicitly set values.
To extract only non-default values that would typically appear in my.cnf:
mysql -uroot -p -e "SHOW VARIABLES WHERE Variable_name NOT LIKE 'performance_schema%' AND Variable_name NOT LIKE 'have%' AND Variable_name NOT LIKE 'version%' AND Variable_name NOT LIKE 'ssl%' AND Variable_name != 'hostname' AND Variable_name != 'port' AND Value != ''" > filtered_config.txt
For a proper my.cnf format conversion, use this Perl one-liner:
mysql -uroot -p -NBe "SHOW VARIABLES" | \ perl -ne 'print "[mysqld]\n" if $. == 1; print if /^(?!version|timestamp|performance_schema)/' | \ awk '{print $1 "=" $2}' > reconstructed_my.cnf
For more comprehensive export including persisted variables:
mysqldump --defaults-file=/etc/mysql/my.cnf \ --all-databases \ --routines \ --no-data \ --flush-logs \ --master-data=2 \ --hex-blob \ --triggers \ --single-transaction \ --set-gtid-purged=OFF \ --no-create-info \ --skip-triggers \ --skip-add-drop-table \ --skip-comments \ --skip-disable-keys \ --skip-extended-insert \ --skip-lock-tables \ --result-file=full_config_export.cnf
Before applying the reconstructed file, verify it won't cause conflicts:
mysqld --defaults-file=reconstructed_my.cnf --validate-config
When you need to recover or backup your MySQL configuration from a running server, the simplest method is using mysqld --verbose --help
combined with some filtering:
# For MySQL 5.7+:
mysqld --verbose --help | grep -A 100 "Default options" > /etc/mysql/my.cnf
# For MySQL 8.0+ with more precise filtering:
mysqld --help --verbose | awk 'BEGIN {flag=0} /Default options are read from the following files/ {flag=1; next} /The following groups are read/ {flag=0} flag' > /etc/mysql/my.cnf
For more advanced cases where you need active runtime configuration (not just defaults), query the Performance Schema:
mysql -e "SELECT VARIABLE_NAME, VARIABLE_VALUE
FROM performance_schema.variables
WHERE VARIABLE_NAME NOT LIKE '%PASSWORD%'
AND VARIABLE_NAME NOT LIKE '%SECRET%'
ORDER BY VARIABLE_NAME" > current_config.txt
Here's a script that converts runtime variables to valid my.cnf format:
#!/bin/bash
mysql -NBe "SHOW VARIABLES" | awk '
BEGIN {
print "[mysqld]"
}
!/innodb_buffer_pool_dump_at_shutdown|innodb_buffer_pool_load_at_startup/ {
printf "%-45s = ", $1
if ($2 ~ /^[0-9]+$/) {
print $2
} else {
print "\"" $2 "\""
}
}' > reconstructed.cnf
Important: Remove any sensitive variables like passwords before using the output.
For comprehensive configuration management:
pt-config-diff
from Percona Toolkit
mysqldefconf
(community tool)
mysql_config_editor
(official utility)
Remember that some settings may appear differently in runtime versus config file:
# Example difference:
SHOW VARIABLES LIKE 'max_allowed_packet'; --> 67108864
# While in my.cnf it should be:
max_allowed_packet = 64M