ProxySQL's own docs and most runbooks suggest backing up the Admin tables with mysqldump. With MySQL 8.0's mysqldump this no longer works: it aborts on connect, before dumping anything.
Because the usual recipe pipes through a filter —
mysqldump -uadmin -padmin -h127.0.0.1 -P6032 --no-tablespaces --skip-triggers --replace main \
| grep '^REPLACE' > backup.sql
— the failure is silent: you get a 0-byte file and exit 0, and only discover it at restore time, which is typically mid-upgrade.
mariadb-dump works today, so there is a workaround, but mysqldump is what most people reach for.
Environment
- ProxySQL 3.0.10-426-gf5f1e14, Ubuntu 22.04, admin on 127.0.0.1:6032
mysqldump 8.0.46 (Ubuntu mysql-client-core-8.0)
mariadb-dump 10.6.23 — works, produces a complete dump that restores correctly
What mysqldump 8.0 sends
Captured with general_log on a real MySQL, then replayed statement-by-statement against Admin:
| Statement |
Admin |
/*!40100 SET @@SQL_MODE='' */ |
OK |
/*!40103 SET TIME_ZONE='+00:00' */ |
OK |
/*!80000 SET SESSION information_schema_stats_expiry=0 */ |
OK (versioned comment ignored) |
SET SESSION NET_READ_TIMEOUT=86400, SESSION NET_WRITE_TIMEOUT=86400 |
FAIL — aborts the dump |
SHOW VARIABLES LIKE 'gtid_mode' |
OK |
SELECT @@GLOBAL.GTID_EXECUTED |
FAIL |
show tables / show table status like ... |
OK |
LOCK TABLES ... READ / UNLOCK TABLES |
OK |
SET SQL_QUOTE_SHOW_CREATE=1 |
OK |
SET SESSION character_set_results = 'binary' |
OK |
show create table / show fields from |
OK |
SELECT /*!40001 SQL_NO_CACHE */ * FROM ... |
OK |
SELECT ... FROM information_schema.COLUMN_STATISTICS |
FAIL |
Most of the protocol surface is already there — the dump dies on the first SET SESSION.
The three failures
1. SET SESSION <var> — the blocker. The scope keyword is not parsed; SESSION is absorbed into the variable name:
mysql> SET SESSION NET_READ_TIMEOUT=86400;
ERROR 1045 (28000): ProxySQL Admin Error: ERROR: Unknown global variable: 'SESSION NET_READ_TIMEOUT'.
mysql> SET SESSION autocommit=1;
ERROR 1045 (28000): ProxySQL Admin Error: ERROR: Unknown global variable: 'SESSION autocommit'.
Note the second one: autocommit is a known variable, and it still fails — so this is about the SESSION keyword, not about the variable being unknown. No mysqldump flag avoids this statement.
2. SELECT @@GLOBAL.<var> — @@scope.var is not parsed:
mysql> SELECT @@GLOBAL.gtid_executed;
ERROR 1045 (28000): ProxySQL Admin Error: near ".": syntax error
mysql> SELECT @@global.version;
ERROR 1045 (28000): ProxySQL Admin Error: near ".": syntax error
Avoidable with --set-gtid-purged=OFF.
3. information_schema.COLUMN_STATISTICS does not exist — avoidable with --column-statistics=0.
Inconsistency noticed while testing
Single-variable SET is stricter than the multi-variable form:
mysql> SET sql_mode=""; -- FAIL: Unknown global variable: 'sql_mode'
mysql> SET autocommit=1, sql_mode=""; -- OK
Same unknown variable, two different outcomes depending on whether it is alone in the statement. Probably unintended regardless of this issue.
Suggested scope
Minimum to unblock mysqldump (with --set-gtid-purged=OFF --column-statistics=0):
To make plain mysqldump work with no flags:
Reproduce
mysqldump -uadmin -padmin -h127.0.0.1 -P6032 --no-tablespaces --skip-triggers --replace main > /tmp/b.sql
echo "exit=$? size=$(stat -c%s /tmp/b.sql)" # exit=2 size=0
Found while verifying the backup procedure in ProxySQL training material against a live instance.
🤖 Generated with Claude Code
ProxySQL's own docs and most runbooks suggest backing up the Admin tables with
mysqldump. With MySQL 8.0'smysqldumpthis no longer works: it aborts on connect, before dumping anything.Because the usual recipe pipes through a filter —
— the failure is silent: you get a 0-byte file and exit 0, and only discover it at restore time, which is typically mid-upgrade.
mariadb-dumpworks today, so there is a workaround, butmysqldumpis what most people reach for.Environment
mysqldump8.0.46 (Ubuntumysql-client-core-8.0)mariadb-dump10.6.23 — works, produces a complete dump that restores correctlyWhat mysqldump 8.0 sends
Captured with
general_logon a real MySQL, then replayed statement-by-statement against Admin:/*!40100 SET @@SQL_MODE='' *//*!40103 SET TIME_ZONE='+00:00' *//*!80000 SET SESSION information_schema_stats_expiry=0 */SET SESSION NET_READ_TIMEOUT=86400, SESSION NET_WRITE_TIMEOUT=86400SHOW VARIABLES LIKE 'gtid_mode'SELECT @@GLOBAL.GTID_EXECUTEDshow tables/show table status like ...LOCK TABLES ... READ/UNLOCK TABLESSET SQL_QUOTE_SHOW_CREATE=1SET SESSION character_set_results = 'binary'show create table/show fields fromSELECT /*!40001 SQL_NO_CACHE */ * FROM ...SELECT ... FROM information_schema.COLUMN_STATISTICSMost of the protocol surface is already there — the dump dies on the first
SET SESSION.The three failures
1.
SET SESSION <var>— the blocker. The scope keyword is not parsed;SESSIONis absorbed into the variable name:Note the second one:
autocommitis a known variable, and it still fails — so this is about theSESSIONkeyword, not about the variable being unknown. Nomysqldumpflag avoids this statement.2.
SELECT @@GLOBAL.<var>—@@scope.varis not parsed:Avoidable with
--set-gtid-purged=OFF.3.
information_schema.COLUMN_STATISTICSdoes not exist — avoidable with--column-statistics=0.Inconsistency noticed while testing
Single-variable
SETis stricter than the multi-variable form:Same unknown variable, two different outcomes depending on whether it is alone in the statement. Probably unintended regardless of this issue.
Suggested scope
Minimum to unblock
mysqldump(with--set-gtid-purged=OFF --column-statistics=0):SESSION/GLOBAL/LOCALscope prefix inSETNET_READ_TIMEOUT,NET_WRITE_TIMEOUT, …) rather than erroring — these are client-side hints and harmless as no-opsSETstrictnessTo make plain
mysqldumpwork with no flags:SELECT @@GLOBAL.<var>/@@session.<var>information_schema.COLUMN_STATISTICSReproduce
Found while verifying the backup procedure in ProxySQL training material against a live instance.
🤖 Generated with Claude Code