Skip to content

Powered by Grav

my.cnf lifecycle + mycnfup

my.cnf lifecycle + mycnfup

/etc/mysql/my.cnf is BOA-deployed and BOA-maintained. It is not hand-assembled per host: BOA ships a single template (aegir/conf/var/my.cnf.txt), re-deploys it verbatim, then sed-patches a handful of directives to match the Percona server actually installed. This page covers who writes it, when it is rewritten, how to protect a custom config across upgrades, and what mycnfup actually does (it is not the version migrator).

What lives where

TXT
/etc/mysql/my.cnf          BOA-deployed main config (from var/my.cnf.txt)
/etc/mysql/conf.d/         drop-in directory; the only !includedir BOA ships

BOA's deployed my.cnf ends with a single include line:

TXT
!includedir /etc/mysql/conf.d/

That is the whole BOA include chain. BOA does not include /etc/mysql/mysql.conf.d/ or /etc/mysql/percona-server.conf.d/ in its config — those belong to distro-default Percona/MySQL layouts, and even where percona-server.conf.d/ is present on a BOA box, BOA's my.cnf includes only conf.d/. (The xmass migration tool writes its GTID drop-in into the include directory my.cnf actually reads at runtime: it parses the active !includedir first — on a BOA box that resolves to conf.d — and only falls back to conf.d, then percona-server.conf.d, then mysql.conf.d, then /etc/mysql when my.cnf declares no !includedir. Detecting by directory existence alone would be wrong here, because percona-server.conf.d exists on the box yet BOA's my.cnf never parses it. That detection runs on both ends of a migration and is the migrator's own, not part of BOA's include chain.)

For drop-in fragments the read order is my.cnf first, then conf.d/*.cnf; later fragments override earlier ones.

Deploy and per-version patch

There is no per-host generation step and no marker stamped into the file. The mechanism is two stages, both in lib/functions/sql.sh.inc:

  1. Deploy the template verbatim. On a fresh DB install the package's own my.cnf is moved aside to /var/backups/package.my.cnf and BOA copies aegir/conf/var/my.cnf.txt over /etc/mysql/my.cnf. On a config-update pass BOA re-deploys the same template (unless custom-config protection is on — see below).
  2. Sed-patch per installed Percona version. BOA comments/uncomments the version-specific directives so the file is valid for the Percona server binary that will actually parse it. On a config-update pass that version comes from _check_mysql_version(), which reads /usr/sbin/mysqld --no-defaults -V and falls back to the mysql client only when no server binary resolves; every branch in _sql_conf_update() keys on that value, not on the configured _DB_SERIES target. --no-defaults keeps the probe from parsing /etc/mysql/my.cnf, so a config the server is rejecting cannot blind the probe. The distinction matters mid-upgrade: a partial apt transaction can leave an 8.x client beside a 5.7 server, and a file patched for the target series under the older binary carries directives that binary cannot parse. The same pass reconciles the InnoDB sizing directives with the installed binary for that reason — innodb_redo_log_capacity is commented out on 5.7, innodb_log_file_size on 8.4 and newer, and nothing is stripped when no binary resolves — so a mismatched box heals in directives sync instead of staying unstartable. The one exception is the fresh-install deploy, which keys its logging patch on _DB_SERIES; there the series just installed and the installed binary are the same thing.

The template carries every version's logging block commented out, and BOA enables exactly the set the running version understands:

Percona series Logging directives enabled
5.7 log_syslog (with log_syslog_facility / log_syslog_include_pid)
8.0 log_error, log_error_verbosity, mysqlx
8.4+ log_error, optional syseventlog sink, mysqlx; mysql_native_password=ON re-enabled, and authentication_policy=mysql_native_password,, set beside it

The 8.4 auth pair matters for legacy PHP: loading the native plugin alone is not enough, because the handshake greeting advertises the server's default first-factor plugin, and a PHP 5.6 client aborts on a caching_sha2 greeting before the user's own plugin is even consulted — a php56-pool site loses its database on the web while CLI Drush stays healthy. With the policy set, the greeting is native; caching_sha2 users (and every modern-PHP site) still authenticate normally via the client auth-switch. When an existing box's my.cnf predates the template line, the config pass inserts it.

Critically, every config pass resets logging first — it comments out log_syslog, log_error, syseventlog, mysqlx and authentication_policy before re-enabling the set for the version in place. This is what makes a 5.7 → 8.0 upgrade start cleanly: a stale log_syslog left over from 5.7 makes 8.x abort on the unknown variable. The reset is idempotent (a leading # is collapsed, never doubled). The same pass also resets slow_query_log / long_query_time / slow_query_log_file (commented out) and re-disables performance_schema on 5.7 / re-enables it on 8.x.

Hardened template defaults

The shipped my.cnf.txt carries these defaults:

Directive Value Effect
secure_file_priv NULL LOAD DATA INFILE / SELECT … INTO OUTFILE to the server filesystem disabled entirely
local_infile OFF client-side LOAD DATA LOCAL INFILE disabled
mysqlx commented (disabled) X Protocol off in the template; enabled only on 8.0/8.4+ during the per-version sed pass
transaction-isolation READ-COMMITTED
skip-name-resolve on (BOA writes /etc/mysql/skip-name-resolve.txt whenever the DB host is local, which is the default; the directive is commented out only when that marker is absent) no reverse-DNS on connect

Leave secure_file_priv and local_infile as shipped unless a specific workload requires otherwise — they are deliberate anti-exfiltration defaults.

Protecting a custom config: _CUSTOM_CONFIG_SQL

BOA has no marker-diff override-detection. If you hand-edit /etc/mysql/my.cnf and leave the defaults alone, BOA re-deploys the template over your changes on the next config pass. To keep a fully custom my.cnf, set the protection toggle in /root/.barracuda.cnf:

SH
_CUSTOM_CONFIG_SQL=YES   # protects custom SQL config when YES

When _CUSTOM_CONFIG_SQL=YES, BOA does nothing to my.cnf — no re-deploy (_tune_sql_memory_limits skips the template copy), no version sed-patching or logging reset (_sql_conf_update bails to _DO_NOTHING), and no binary-log toggling. The protection holds on every host, including BOA-managed ones (_hostedSys=YES): on a managed host the version-sync block is entered, but the very first test inside it still short-circuits to _DO_NOTHING when the toggle is YES.

The protection does NOT hold through a Percona major upgrade. The staged major-upgrade path (5.7 → 8.0 → 8.x) force-resets the toggle for that run and calls the full tuning pass, which re-deploys the pristine template and re-derives every value from RAM. Your customised file is preserved under /var/backups/dragon/t/my.cnf-pre-*, but the live my.cnf comes out of a major hop fully BOA-derived, and the toggle in /root/.barracuda.cnf resumes protecting the new file afterwards. Plan a re-apply step into any major upgrade window on a box that runs a custom config.

The lower-risk pattern, if you only need additions, is to leave _CUSTOM_CONFIG_SQL=NO and drop fragments into /etc/mysql/conf.d/zz-operator-*.cnf. The zz- prefix sorts last, so those fragments override BOA's template directives, and they survive every re-deploy because BOA never touches conf.d/.

The middle path: per-knob pins

The derived model is dataset-aware (the buffer pool follows the measured table-data size under tiered ceilings — see Percona setup + tuning), but some boxes still need a value the formula would not pick. For that, per-knob pins in /root/.barracuda.cnf override a single value each — in either direction — while BOA keeps managing the rest of the file, and they keep working through Percona major upgrades because the tuning pass itself applies them:

SH
_SQL_BUFFER_POOL_FORCE=32768   # innodb_buffer_pool_size, MB
_SQL_TMP_TABLE_FORCE=256       # tmp_table_size + max_heap_table_size, MB
_SQL_KEY_BUFFER_FORCE=64       # key_buffer_size, MB
_SQL_LOG_FILE_SIZE_FORCE=2048  # log/redo base, MB (restart applies)
_SQL_MAX_CONNECTIONS_FORCE=300 # a count, not MB (restart applies)
_VALKEY_MAXMEM_FORCE=2048      # Valkey/Redis maxmemory, MB
_SOLR_HEAP_FORCE=10240         # Solr 7/9 JVM -Xmx, MB

Values are validated fail-closed: a plain integer only (no 32G-style suffixes), memory pins clamped against installed RAM; anything invalid is ignored with a NOTE and the derived value stays. A pool pin alone is restart-free — the log file size keeps deriving from the unpinned base, so the pool pin never drags the redo sizing (and its managed restart) along with it. The pool pin also deliberately does not move the per-session tmp_table_size budget. Full reference: barracuda-cnf.

mycnfup — memory tuner and mysqld controller

Despite the name, aegir/tools/bin/mycnfup is not the my.cnf version migrator — the version migration is in sql.sh.inc as described above. mycnfup is a memory tuner plus a mysqld start/stop/restart orchestrator, a positional-verb dispatcher (case "$1" in …):

Verb Action
tune (default) re-tune memory limits in my.cnf for current RAM
check root / readiness check
init start mysqld in init mode (first boot of a fresh install)
start start mysqld
stop stop mysqld
restart restart mysqld
stretch-first / stretch-second legacy two-stage Stretch OS upgrade helpers

It is normally invoked by BOA tooling — e.g. cluster runs mycnfup check, mycnfup tune, mycnfup init and mycnfup stop over SSH on DB nodes. There are no --target-version, --dry-run, --include or --target flags — those do not exist. Run a bare mycnfup (or mycnfup tune) to re-tune memory limits after a RAM change. Note that mycnfup carries its own legacy copy of the derivation and does not honour the per-knob pins — running it on a pinned box rewrites the pool back to the derived RAM fraction, and the pins only return at the next barracuda up-* run. Avoid it on pinned boxes.

Backups taken during an upgrade

Before re-deploying the template, the upgrade path copies the current my.cnf aside for diffing/rollback — to <vault>/dragon/t/my.cnf-pre-<serial>-<version>-<timestamp>, not to a /etc/mysql/my.cnf.backup-<timestamp> next to the live file. On a fresh DB install the distro package's my.cnf is preserved at /var/backups/package.my.cnf.

For your own hand-edits, take your own backup first:

SH
cp /etc/mysql/my.cnf /etc/mysql/my.cnf.$(date +%Y%m%d-%H%M%S).bak

Diagnosing my.cnf issues

SH
# Current Percona version + active InnoDB variables
mysql -e "SELECT VERSION();"
mysql -e "SHOW VARIABLES LIKE 'innodb_%';" | head

# Validate my.cnf syntax without restarting
mysqld --validate-config

# Which file each variable came from (Percona 8.0+)
mysql -e "SELECT * FROM performance_schema.variables_info \
  WHERE variable_source IN ('GLOBAL','COMMAND_LINE')" | head -50

The variables_info view in Percona 8.0+ tells you whether a variable came from my.cnf, a conf.d/*.cnf drop-in, the command line, or a runtime SET.

When operator overrides break upgrades

With _CUSTOM_CONFIG_SQL=NO (default), BOA re-deploys its template each pass, so stale operator directives in the main file are simply overwritten. The failure mode to watch for is a protected custom config (_CUSTOM_CONFIG_SQL=YES) carrying directives the new Percona major rejects — BOA will not fix those for you:

  • Custom InnoDB tuning invalid in the new major (e.g. an explicit innodb_log_file_size value 8.0+ refuses).
  • A sql_mode the new Percona rejects (e.g. NO_AUTO_CREATE_USER, gone in 8.0+).
  • Plugin loads for plugins that do not exist in the new version.
  • Logging directives from the previous Percona series — exactly what BOA's reset pass removes automatically when protection is off.

If a protected config blocks an upgrade: restore from the pre-upgrade copy under <vault>/dragon/t/, remove or update the conflicting directive, and re-run the upgrade.

  • Percona install + tuning — install, the staged upgrade, and the upgrade-time memory tuner (mycnfup tune re-sizes the buffers in my.cnf).
  • Dumps with mydumper — dumps run against this Percona instance.
  • Control files & INI_DB_SERIES, _DB_SERVER, _DB_BINARY_LOG, _CUSTOM_CONFIG_SQL, _CUSTOM_COLLATION_SQL, _USE_MYSQLTUNER at the barracuda.cnf level.
  • Reference appendix — the consolidated _VAR table.

© 2026 BOA Documentation. All rights reserved.