故障现象
2026 年 9 月 1 日,TLBB 服务端日志持续出现数据库连接错误:
SQLSTATE=HY000
NativeError=2002
ErrorMessage=[unixODBC][ma-3.1.15]
Can't connect to server on '127.0.0.1' (115)
NativeError=2002 表示 ODBC 无法连接 MariaDB 的 TCP 端口。如果是数据库密码错误,一般会显示:
Access denied for user
现场检查
检查 MariaDB 状态:
systemctl status mariadb --no-pager -l
结果为:
Active: failed (Result: exit-code)
since Tue 2026-09-01 06:06:45 CST
Main PID: exited, status=1/FAILURE
Status: "MariaDB server is down"
检查端口和进程:
ss -lntp | grep 3306
pgrep -a mariadbd
两条命令均没有结果,说明 MariaDB 进程已经退出,127.0.0.1:3306 没有监听。
故障时间线
系统自动更新日志显示:
2026-09-01 06:05:42 Starting unattended upgrades script
2026-09-01 06:06:09 Upgrade: libmysqlclient21
2026-09-01 06:06:42 Upgrade: zlib1g
更新过程中多次出现:
/usr/bin/mandb: can't write to /var/cache/man/2444008:
No space left on device
随后 needrestart 尝试重新启动 MariaDB:
Restarting services...
systemctl restart mariadb.service
Job for mariadb.service failed because the control process exited with error code.
MariaDB 最终在 06:06:45 进入失败状态。
完整故障链路为:
根分区空间耗尽
↓
Ubuntu 自动更新继续安装软件包
↓
needrestart 自动重启 MariaDB
↓
MariaDB 无法创建或扩展必要文件
↓
mariadb.service 启动失败
↓
3306 端口停止监听
↓
TLBB 服务端数据库操作失败
当前磁盘已经重新释放出约 8.6G 空间。由于旧日志已经发生轮转,无法确认当时具体由哪个单一文件占满,但磁盘写满、服务重启和 MariaDB 启动失败的时间完全吻合。
修复过程
确认磁盘已有足够空间后,清除失败状态并启动数据库:
systemctl reset-failed mariadb
systemctl start mariadb
检查状态:
systemctl is-active mariadb
systemctl status mariadb --no-pager -l
ss -lntp | grep 3306
恢复结果:
Active: active (running)
Status: "Taking your SQL requests now..."
Server socket created on IP: '0.0.0.0', port: '3306'
ready for connections
确认数据库版本和字符集:
mariadb --protocol=socket -e "
SELECT VERSION(), @@port, @@character_set_server, @@collation_server;
SHOW DATABASES;
"
检查关键业务表:
CHECK TABLE web.account QUICK;
检查结果:
status OK
数据库恢复后,Billing 自动重新建立连接:
Database reconnect succeeded; Billing schema validation required
Database schema ready Version=3
恢复瞬间出现过一次:
Write error: Broken pipe (32)
这是数据库停机前建立的旧 ODBC 连接失效后,第一次继续使用产生的正常现象。随后连接已经重新建立,dberror.log 未继续增长。
数据库停机期间执行的部分写入 SQL 可能失败。虽然没有发现数据文件和关键表损坏,但仍应保留并检查该时间段的 dberror.log,确认是否存在需要人工补偿的重要操作。
如何避免再次发生
1. 设置磁盘容量告警
根分区建议至少保留 5G,使用率达到 85% 时告警:
df -h /
df -i /
du -xhd1 /home /var /root 2>/dev/null | sort -h
监控脚本:
#!/bin/sh
USED=$(df -P / | awk 'NR==2 {gsub("%", "", $5); print $5}')
if [ "$USED" -ge 85 ]; then
logger -p daemon.warning \
"TLBB disk warning: root filesystem usage is ${USED}%"
fi
2. 限制系统日志占用
创建 /etc/systemd/journald.conf.d/tlbb.conf:
[Journal]
SystemMaxUse=500M
RuntimeMaxUse=100M
MaxRetentionSec=14day
应用配置:
systemctl restart systemd-journald
3. 为 TLBB 日志配置轮转
创建 /etc/logrotate.d/tlbb-server:
/home/tlbb/Server/Log/*.log {
daily
rotate 14
compress
delaycompress
copytruncate
missingok
notifempty
}
检查配置:
logrotate -d /etc/logrotate.d/tlbb-server
4. 控制 core 转储数量
Server 的 core 文件需要保留用于分析崩溃,但不能无限积累:
- 只保留最近 3 至 5 个 core;
- 修复验证完成后删除旧文件;
- 定期检查
/home/tlbb/coredump;
- 始终为根分区预留至少
5G。
5. 避免自动更新直接重启数据库
不建议关闭安全更新,但正式服务器不应在无人值守状态下直接重启 MariaDB。
创建 /etc/needrestart/conf.d/tlbb.conf:
$nrconf{restart} = 'l';
更新后由管理员在维护时间执行:
df -h /
systemctl restart mariadb
systemctl is-active mariadb
6. 增加 MariaDB 失败重试
执行:
systemctl edit mariadb
写入:
[Service]
Restart=on-failure
RestartSec=30s
应用配置:
systemctl daemon-reload
自动重试只能作为补充保护。如果磁盘持续写满,MariaDB 仍然无法启动,磁盘监控和日志轮转才是根本措施。
总结
本次故障由磁盘空间耗尽引起。Ubuntu 自动更新期间重启 MariaDB,数据库因无法写入必要文件而启动失败,最终导致 TLBB 服务端无法连接 3306 端口。
释放磁盘空间并重新启动 MariaDB 后,InnoDB 正常加载,关键表检查通过,TLBB 服务端自动重新建立数据库连接,无需重启五个服务端程序。后续应重点完善磁盘告警、日志轮转、core 文件管理和服务维护策略。