3.1 数据库连不上与远程访问不通
先给一个判断
“数据库连不上”不是一个问题,是五个问题。 从你的代码到数据库之间,隔着容器网络、实例状态、账号权限、端口放行四道关。症状一样,病根完全不同。这一节给你一套标准的分层排查法:先在本机测,再在容器间测,最后从外网测,走到哪一步断了,就是哪一层的问题。
现象:你属于哪一种
| 现象 | 说明 | 大概率病根 |
|---|---|---|
| A | 网站报“数据库连接失败” | 实例状态 / 连接信息 / 网络 |
| B | 本机命令行能连,程序连不上 | 连接信息填错( localhost vs 127.0.0.1 ) |
| C | 本机能连,别的机器连不上 | 访问权限 / 防火墙 / 安全组 |
| D | 时好时坏,偶尔断连 | 资源不足 / 连接数到上限 |
| E | 远程数据库(手动添加的)连不上 | 对端服务 / 网络 / 凭证 |
定位之前,先做这一步
不管你是哪种现象,在做任何“修复”动作之前,先确认数据库容器没有在被频繁重启:
# 看容器是不是在 Restarting(不停重启会让你的排查白做)
docker ps -a --filter "name=mysql" --format "table {{.Names}}\t{{.Status}}"
# 看系统资源是不是已经见底
free -h
df -h /
如果磁盘满了或内存爆了,先解决资源问题,数据库自己就恢复了,配置什么都别动。这是本节最值钱的一条经验:很多“数据库连不上”的根本原因是 4.2、4.3 节的问题。
定位:三段式连通性测试
第一段:数据库实例自己活着吗。
# 看数据库容器状态(容器名按实际替换)
docker ps | grep mysql
# 看容器最近日志,找启动失败原因
docker logs --tail 100 1panel-mysql
容器是 Exited 或一直 Restarting,先看日志。常见死因:端口冲突、磁盘满了、配置文件改错了(数据库配置文件默认挂载在 /opt/1panel/apps/mysql/[数据库名称]/conf/my.cnf,官方文档明确警告:错误的配置会导致服务不可用——改坏了可以在设置里尝试恢复默认配置)。
第二段:本机通不通。
# 测端口(端口从"连接信息"里看,默认 3306)
telnet 127.0.0.1 3306
# 或者
curl -v telnet://127.0.0.1:3306
端口能连通说明实例在监听。注意一个经典坑:MySQL 的连接信息里,“localhost” 和 “127.0.0.1” 在容器场景下不是一回事——容器里的 localhost 是容器自己。填连接信息时按 1Panel 数据库列表上方【连接信息】按钮里给的地址来,别自己猜。
第三段:账号和权限。 数据库创建时可以选访问权限(本地服务器 / 所有人 / 指定 IP),列表的【权限】按钮可以修改:
| 权限设置 | 含义 | 什么时候用 |
|---|---|---|
| 本地服务器 | 只允许本机连接(默认) | 网站和应用都在本机 |
| 所有人 | 任何 IP 都能连 | 图省事,但不安全 |
| 指定 IP | 只允许列出的 IP(逗号分隔) | 远程访问的推荐做法 |
修复:远程访问不通
现象 C 最常见。开通远程访问要走三道门,缺一不可:
- 数据库权限:列表操作列【权限】,改成“所有人”或“指定 IP”;
- 服务器防火墙:放行 MySQL 端口(系统 → 防火墙,或用命令):
# Firewalld(CentOS/RHEL)
firewall-cmd --zone=public --add-port=3306/tcp --permanent
firewall-cmd --reload
# UFW(Ubuntu/Debian)
ufw allow 3306/tcp
- 云安全组:云服务商控制台里放行同一端口。这一步不在服务器上,最容易被忘掉。
验证(在别的机器上执行):
# 测端口通不通
telnet 你的服务器IP 3306
# 用 mysql 客户端真的连一下(地址、端口、账号换自己的)
mysql -h 你的服务器IP -P 3306 -u 用户名 -p
安全提醒:把 MySQL 直接暴露到公网风险很高。推荐做法是“指定 IP”权限 + 只放行需要的来源 IP。如果只是自己远程管理,配个 SSH 隧道更安全,不用开任何公网端口。
修复:连接信息对不上
现象 B 的典型现场:命令行能用,程序报错。逐项对照【连接信息】:
| 检查项 | 常见错误 |
|---|---|
| 地址 | 容器外该用宿主机 IP 或容器名,不是 localhost |
| 端口 | 安装时自定义的端口,不一定是 3306 |
| 用户名 | 用的是数据库用户,不是 root(除非就是 root) |
| 密码 | 改过密码但程序没同步 |
| 库名 | 库还没创建,或者名字拼错了 |
一个调试技巧:在服务器上用【连接信息】里的地址 / 端口 / 账号手动连一次,连得上就说明凭证没问题,问题在程序的配置;连不上,继续看数据库日志。
修复:远程数据库(手动添加的)
在数据库列表上方【远程服务器】可以添加已有的数据库地址。连不上的排查清单:
- 对端数据库服务是否允许远程连接(大多数发行版默认只监听本地);
- 对端的账号是否允许从你这台机器的 IP 连入;
- 两者之间的网络是否通(
telnet 对端IP 端口); - 凭证是否正确。
注意:远程数据库出问题,不要在 1Panel 这台机器上重启什么服务,问题不在这儿。
一个完整的复现与修复
现象:WordPress 网站突然报“Error establishing a database connection”,昨天还好好的。
排查过程:
docker ps发现 MySQL 容器状态是Restarting,不停重启;docker logs看到最后几行报磁盘空间不足——根分区 100% 满了(磁盘占用的治理见 4.2 节);- 先清理日志和临时文件腾出空间,容器恢复正常重启。
修复后验证:网站首页恢复,进 WordPress 后台完整转一圈,确认数据没丢。
复盘要点:“突然全站报连接失败”且没人改过配置,第一怀疑对象是资源问题(磁盘满 / 内存不足),而不是配置问题。 磁盘满了 MySQL 会在日志里留下明显痕迹。
一个进阶情况:时好时坏
现象 D(间歇性断连)比“彻底连不上”更烦人。两个查看方向:
- 连接数到上限:数据库设置 → 当前状态,看连接数相关指标;用【性能调整】里的预设方案调整参数;
- 资源不足:内存紧张时容器可能被 OOM杀掉再重启,表现为“过一会儿就能连了”。看监控和系统日志确认:
# 看有没有 OOM 记录
dmesg | grep -i "out of memory" | tail -5
内存治理见 4.3 节。
一张速查表:症状 → 层次 → 动作
| 症状 | 断在哪 | 立刻做的动作 |
|---|---|---|
| 网站报连接失败,容器 Exited | 实例 | docker logs 看死因 |
| 容器在跑,本机 telnet 不通 | 端口/进程 | 看端口设置和容器日志 |
| 本机通,程序连不上 | 凭证/地址 | 对照【连接信息】逐项核实 |
| 本机通,外网不通 | 权限/防火墙/安全组 | 三道门逐个检查 |
| 间歇断连 | 资源/连接数 | 看监控、dmesg 查 OOM |
| 只有远程库连不上 | 对端 | 测对端端口和服务 |
用这张表的正确姿势:先花 30 秒确认“断在哪一层”,再动手;而不是一着急就开始改权限、改端口、改配置,把本来好的东西也改坏了。
本节要点
- 连不上先分层:实例活着 → 本机通 → 外网通,逐段排查;
- 远程访问要开三道门:数据库权限、服务器防火墙、云安全组;
- 连接信息以数据库列表【连接信息】为准,不要猜;
- “突然连不上且没改过配置”,先怀疑磁盘满或内存不足;
- 公网暴露 MySQL 用“指定 IP”权限,能收窄就收窄。
数据库的连接信息、权限和监控入口详见 1Panel 官方文档:MySQL,以官方文档为准。容器化数据库的地址和端口与宿主机上直接装的不完全一样,一切以【连接信息】页面给的为准。
下一节:数据库能连上了,但备份失败、恢复报错——数据类问题,每一步都要稳。
