bind-address = :: 表示监听所有 IPv6 地址,默认兼容 IPv4(需内核 net.ipv6.conf.all.bindv6only=0),非自动双栈;MySQL 不支持多地址语法,仅认单值,且需配合 skip-name-resolve、IPv6 防火墙及系统级 IPv6 启用。

bind-address = :: 就是双栈,不是“加个IPv6地址”那么简单
MySQL 的 bind-address = :: 表示监听所有 IPv6 地址(包括 IPv4-mapped IPv6 地址),**但它不是自动双栈**——是否真正接受 IPv4 连接,取决于内核是否启用 IPv6 的 ipv6.bindv6only 选项(Linux 默认为 0)。若该内核参数为 1,则 :: 只收 IPv6;为 0(默认)时,:: 才能同时接收 IPv4 和 IPv6 连接。
常见错误是以为写成 bind-address = 0.0.0.0,:: 或 bind-address = [::] 就能双栈,但 MySQL 不支持逗号分隔或方括号语法,只认单值。写错会直接启动失败,报错:Unknown suffix '::' for variable 'bind_address' 或 Failed to set up socket。
-
bind-address = 0.0.0.0:仅 IPv4,不碰 IPv6 -
bind-address = :::IPv6 主导,但默认兼容 IPv4(需net.ipv6.conf.all.bindv6only = 0) -
bind-address = ::1:仅本地 IPv6 回环,和127.0.0.1是两个独立通道 - 留空或注释掉
bind-address:MySQL 5.7+ 多数等效于127.0.0.1,不是双栈
skip-name-resolve = ON 是 IPv6 连接稳定的前提
不加这句,只要客户端用 IPv6 地址连接(比如 mysql -h 2001:db8::1 -u user),MySQL 就会尝试反向 DNS 解析该地址。一旦 DNS 延迟、超时或返回 NXDOMAIN,连接就会卡在认证前,最终报错:Host '2001:db8::1' is not allowed to connect to this MySQL server——这不是权限问题,是解析失败导致流程中断。
启用后,MySQL 跳过所有 host 名字解析,只比对 mysql.user.host 字段的字面值。这意味着:
- 授权语句中不能写域名,如
'user'@'example.com'会失效 - 必须用 IP 字面量或
%,例如'user'@'2001:db8::%'或'user'@'%' -
FLUSH PRIVILEGES必须执行,IPv6 host 匹配不缓存,每次新连接都查表
IPv6 权限授权必须用完整压缩格式,通配符有严格限制
MySQL 的 host 匹配不支持 CIDR(如 /64)、不支持右对齐通配(如 'user'@'%::1'),只支持左对齐通配,且双冒号 :: 在 pattern 中只能出现一次。
正确写法:
-
GRANT ALL ON *.* TO 'user'@'2001:db8::1'(精确单地址) -
GRANT ALL ON *.* TO 'user'@'2001:db8::%'(推荐:匹配该前缀下所有地址) -
GRANT ALL ON *.* TO 'user'@'::1'(本地回环)
错误写法:
-
'user'@'2001:db8::/64'(被当字面字符串,无法匹配) -
'user'@'::%'(部分旧版本如 5.6 可能截断失败,不建议) -
'user'@'[2001:db8::1]'(方括号是客户端语法,服务端不识别)
操作系统和防火墙必须同步放开 IPv6,否则 bind-address 再对也没用
即使 my.cnf 配对了 bind-address = :: 和 skip-name-resolve = ON,如果系统层没开 IPv6,或者防火墙拦着,连接照样失败。
关键检查点:
- 运行
ping6 ::1确认本地 IPv6 协议栈可用 - 检查
sysctl net.ipv6.conf.all.disable_ipv6输出是否为0;若为1,需改/etc/sysctl.conf并sysctl -p - 确认网卡已分配全球单播 IPv6 地址(非
fe80::/10本地链路地址),用ip -6 addr show查看 - 防火墙规则要显式放行 IPv6:比如
ip6tables -A INPUT -p tcp --dport 3306 -j ACCEPT,或云平台安全组添加 IPv6 规则
最容易被忽略的是:MySQL 启动日志里不会明确说“IPv6 被系统禁用”,它只会安静地退回到 IPv4 监听模式。验证是否真在监听 IPv6,用 ss -tln | grep :3306,看到 *:3306 或 [::]:3306 才算成功。


















