MySQL Configuration File (/etc/my.cnf) Settings Not Being Applied: Debugging and Solutions


5 views

MySQL's configuration system follows a specific hierarchy when applying settings. The server checks these locations in order:

1. Command-line parameters (highest priority)
2. /etc/my.cnf
3. /etc/mysql/my.cnf
4. ~/.my.cnf
5. --defaults-extra-file specified files
6. Built-in defaults (lowest priority)

To verify which configuration files MySQL is actually reading, execute:

mysql --help | grep "Default options" -A 1

For a running server, check with:

SHOW VARIABLES LIKE '%config%';
SHOW VARIABLES LIKE '%collation%';
SHOW VARIABLES LIKE '%dir%';

The most frequent issues causing configuration problems include:

  • Incorrect file permissions (should be readable by mysql user)
  • Malformed INI syntax (unclosed quotes, missing section headers)
  • Conflicting settings from multiple config files
  • Using deprecated parameter names

Example of proper section headers:

[mysqld]
collation-server = utf8_unicode_ci
init-connect='SET NAMES utf8'
character-set-server = utf8

Create a test configuration file and verify it's being processed:

# Create test config
echo "[mysqld]" > /tmp/test.cnf
echo "des-key-file=/tmp/test_keys" >> /tmp/test.cnf

# Start MySQL with explicit config
mysqld_safe --defaults-file=/tmp/test.cnf --verbose --help

When troubleshooting startup problems, use these techniques:

# Check error log (location varies by installation)
tail -f /var/log/mysql/error.log

# Run in foreground with debug output
mysqld --defaults-file=/etc/my.cnf --console

# Verify privilege inheritance
namei -l /etc/my.cnf

For critical production systems, consider these best practices:

# Systemd override example (create /etc/systemd/system/mysql.service.d/override.conf)
[Service]
ExecStart=
ExecStart=/usr/sbin/mysqld --defaults-file=/etc/mysql/my.cnf --daemonize --pid-file=/var/run/mysqld/mysqld.pid

When file-based configuration proves problematic, consider:

# Runtime configuration using SET GLOBAL
SET GLOBAL collation_server = 'utf8_unicode_ci';

# Persistent configuration without config files
INSTALL PLUGIN validate_password SONAME 'validate_password.so';

# Using --init-command for specific settings
mysqld_safe --init-command="SET GLOBAL max_connections=200"

After making changes, always verify:

# Check if variables changed
SELECT * FROM performance_schema.variables_by_thread 
WHERE VARIABLE_NAME IN ('collation_server','character_set_server');

# Verify file-based parameters
SHOW VARIABLES WHERE Variable_name LIKE '%dir' 
OR Variable_name LIKE '%file%';

MySQL follows a specific order when loading configuration files. The standard search path is:

/etc/my.cnf
/etc/mysql/my.cnf
/usr/etc/my.cnf
~/.my.cnf

To verify which configuration files MySQL is actually using, run:

mysql --help | grep "Default options"

Or for a running server:

mysqladmin variables | grep -E 'basedir|datadir|version'

Debian systems often use an alternative configuration structure:

/etc/mysql/my.cnf (main file)
/etc/mysql/conf.d/ (additional configurations)
/etc/mysql/mysql.conf.d/ (server-specific settings)

Here's how to test where your settings might be getting overridden:

mysqld --verbose --help | grep -A1 "Default options"

The issue might stem from how your startup script invokes MySQL. Check for:

# Problematic line that might override configs
$bindir/mysqld_safe --defaults-file="/etc/my.cnf" --datadir="$datadir" ...

Better practice would be:

$bindir/mysqld_safe --defaults-extra-file=/etc/mysql/my.cnf &

Create a test configuration file to isolate the issue:

[mysqld]
collation-server = utf8mb4_unicode_ci
init-connect='SET NAMES utf8mb4'
character-set-server = utf8mb4

Then test with:

mysqld --defaults-file=/path/to/test.cnf --verbose --help

For modern Debian installations using systemd:

systemctl edit mysql.service

Add override configuration:

[Service]
ExecStartPre=/bin/sleep 10
Environment="MYSQLD_OPTS=--defaults-extra-file=/etc/mysql/my.cnf"

Enable detailed logging to track configuration loading:

[mysqld_safe]
log-error=/var/log/mysql/mysql-error.log
debug=d,info,error,query,general,where:O,/tmp/mysqld.trace

Ensure proper permissions (especially when using AppArmor/SELinux):

chmod 644 /etc/mysql/my.cnf
chown root:root /etc/mysql/my.cnf

After making changes, verify the running configuration:

mysql -e "SHOW VARIABLES LIKE 'collation%';"
mysql -e "SHOW VARIABLES LIKE 'character%';"