Ubuntu Node.js 日志中的数据库连接问题排查与修复
一 快速定位流程
- 确认数据库服务是否运行:例如 MySQL 使用命令:sudo systemctl status mysql;未运行则启动:sudo systemctl start mysql。注意在 Ubuntu 上服务名通常是 mysql,而不是 mysqld。
- 核对连接配置:检查 host、port、user、password、database 是否正确,避免因配置错误导致连接被拒绝。
- 检查防火墙:使用 UFW 放行数据库端口(如 3306):sudo ufw allow 3306。
- 校验数据库用户权限:确保用户具备从应用所在主机连接的权限,必要时授予并刷新权限。
- 测试网络连通性:对数据库主机执行 ping your_db_host 排查网络问题。
- 查看详细日志:同时查看 Node.js 应用日志 与 数据库错误日志,获取具体错误原因。
- 重启服务:变更后重启 Node.js 应用 与 数据库服务 使配置生效。
二 常见错误与对应修复
- 服务未启动或名称错误:日志提示 “Connection refused/Can’t connect”。先用 sudo systemctl status mysql 确认状态;若提示找不到服务,改用 mysql 而非 mysqld。
- 配置错误:日志出现 “Access denied for user …” 或 “ER_ACCESS_DENIED_ERROR”。核对 host/port/user/password/database,必要时在代码中打印配置(避免泄露密码到生产日志)。
- 防火墙阻断:日志显示超时或无法建立连接。使用 sudo ufw allow 3306 放行数据库端口,或临时关闭防火墙验证。
- 权限不足:日志提示 “Access denied”。在数据库中执行 SELECT User, Host FROM mysql.user; 查看允许的主机,使用 GRANT … TO ‘user’@‘host’ IDENTIFIED BY ‘pwd’; FLUSH PRIVILEGES; 授予权限。
- 网络不通:日志显示 “ETIMEDOUT” 或 “ENOTFOUND”。执行 ping your_db_host 检查连通性,排查 VPC/安全组/路由 等网络策略。
- 驱动或认证不兼容:如 MySQL 8.0 默认使用新的认证插件,旧驱动可能报认证失败。升级驱动(如 mysql2/promise),或在创建用户时指定兼容的认证方式(如 mysql_native_password)。
三 日志与诊断命令清单
- 服务状态:
- 查看:sudo systemctl status mysql
- 启动:sudo systemctl start mysql
- 防火墙:
- 数据库权限:
- 查看用户与主机:SELECT User, Host FROM mysql.user;
- 授权并刷新:GRANT ALL PRIVILEGES ON your_db. TO ‘app’@‘your_host’ IDENTIFIED BY ‘pwd’; FLUSH PRIVILEGES;*
- 网络连通性:
- Node.js 日志查看:
- 实时查看:tail -f your_app.log
- 使用 PM2:pm2 logs
- 系统日志:
- 查看服务日志:journalctl -u your_node_service 或 journalctl -u mysql
- 数据库错误日志:
- 常见路径在 /var/log/mysql/error.log 或 /var/log/mysql/ 目录下,依据实际配置定位。
四 代码与配置优化建议
- 使用 Promise/async-await 正确处理异步连接,避免回调地狱与未捕获异常:
- 示例(mysql2/promise):
- const mysql = require(‘mysql2/promise’);
- const conn = await mysql.createConnection({ host:‘localhost’, user:‘u’, password:‘p’, database:‘db’ });
- 配置连接池并合理设置上限,避免连接风暴:
- 示例:
- const pool = mysql.createPool({ host:‘localhost’, user:‘u’, password:‘p’, database:‘db’, connectionLimit:10 });
- 统一日志输出,便于定位:
- 使用 Winston 输出结构化日志,区分 error/info,并写入文件便于排查。
- 变更后重启:
- 重启应用与数据库:sudo systemctl restart your_node_service,sudo systemctl restart mysql。
五 最小可复现实例与验证
- 安装依赖:
- 连接测试脚本(test-db.js):
- const mysql = require(‘mysql2/promise’);
- (async () => {
- try {
- const conn = await mysql.createConnection({ host:‘localhost’, user:‘test’, password:‘pwd’, database:‘testdb’, port:3306 });
- console.log(‘Connected’); await conn.end();
- } catch (err) {
- console.error(‘Connect error:’, err);
- }
- })();
- 验证步骤:
- 确认 MySQL 运行:sudo systemctl status mysql
- 放行端口:sudo ufw allow 3306
- 创建测试用户与库并授权:
- CREATE DATABASE IF NOT EXISTS testdb;
- CREATE USER ‘test’@‘localhost’ IDENTIFIED BY ‘pwd’;
- GRANT ALL PRIVILEGES ON testdb.* TO ‘test’@‘localhost’; FLUSH PRIVILEGES;
- 运行脚本并观察输出;若失败,结合 应用日志 与 数据库错误日志 定位。