mysql 8.0双栈唯一有效配置是bind-address = ::,它创建af_inet6 socket并依赖内核net.ipv6.bindv6only=0接收ipv4映射连接;其他写法均启动失败。

bind-address = :: 是唯一有效的双栈配置写法
MySQL 8.0 不支持 bind-address = 0.0.0.0,::、bind-address = [::] 或任何逗号分隔/方括号语法。写错会直接启动失败,报错类似:Unknown suffix '::' for variable 'bind_address' 或 Failed to set up socket。只有 bind-address = :: 这一种值能触发双栈监听逻辑——它让 mysqld 创建一个 AF_INET6 socket,并依赖内核的 IPV6_V6ONLY=0 行为接收 IPv4-mapped IPv6 连接(如 ::ffff:192.168.1.100)。
-
bind-address = 0.0.0.0→ 纯 IPv4,netstat -tuln只见*:3306 -
bind-address = ::1→ 仅本地 IPv6 回环,和127.0.0.1完全隔离 - 留空或注释掉
bind-address→ MySQL 8.0 默认等效于127.0.0.1,不是双栈
必须同步检查的三个系统级前提条件
改完 my.cnf 不等于双栈就通了。以下三项缺一不可,任一缺失都会导致连接失败或超时:
-
skip-name-resolve = ON:否则客户端用 IPv6 地址连接(如mysql -h 2001:db8::1)时,MySQL 会卡在反向 DNS 解析,最终报错Host '2001:db8::1' is not allowed to connect——这不是权限问题,是解析超时 -
net.ipv6.bindv6only = 0:Linux 默认值,运行sysctl net.ipv6.bindv6only验证;若为1,则::只收 IPv6,IPv4 连接会被静默拒绝 - 确认未启用
skip-networking,且启动时没加--skip-networking参数
IPv6 权限授权与客户端连接的实际约束
即使 socket 监听成功,权限和客户端格式不对照样连不上:
- 授权语句中 host 必须用 IPv6 字面量,例如
'user'@'2001:db8::/64'❌ 不合法(MySQL 不支持 CIDR);正确写法是'user'@'2001:db8::%'(左对齐通配,::在 pattern 中只能出现一次) - 客户端连接 IPv6 地址必须用方括号包裹:
mysql -h '[2001:db8::1]';老版本客户端(如 MySQL 5.6)可能不识别[::1],建议升级或改用mysql --protocol=TCP -h ::1 - 云环境必须单独配 IPv6 安全组规则:AWS/阿里云等平台的 IPv4 入方向规则**不覆盖 IPv6**,需显式添加协议 TCP、端口 3306、源地址
::/0或具体前缀
验证不能只看 netstat,要分层实测
netstat -tuln | grep :3306 显示 :::3306 只说明 socket 创建成功,不代表可连。必须按顺序实测:
- 本地 IPv6 回环:
mysql -h '::1' -P 3306 -u root→ 验证服务端 IPv6 基础能力 - 本地 IPv4 回环(走双栈 socket):
mysql -h '127.0.0.1' -P 3306 -u root→ 验证内核bindv6only=0是否生效 - 远程 IPv6 地址:
mysql -h '[2001:db8::100]' -P 3306 -u user→ 验证防火墙、安全组、路由可达性
最容易被忽略的是 skip-name-resolve = ON 和云平台 IPv6 安全组——这两个点一旦漏掉,所有调试都会卡在“连接被拒绝”或“Host not allowed”这种误导性错误里。











