You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker中MariaDB容器持续重启问题排查求助

MariaDB容器持续重启,外部IP触发正常关闭的排查与解决

问题描述

我有一个多Docker容器部署的Web应用,其中数据库使用mariadb:11.2.2镜像。初始启动后应用运行正常,可正常读写数据库,但运行数小时或数天后,数据库容器会持续重启。此时执行docker exec -it db-appointment mariadb --user root -ppassword进入容器时,提示目标数据库不存在。

相关配置(compose.yml)

services:
  db-appointment:
    container_name: db-appointment
    image: mariadb:11.2.2
    restart: always
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: db-appointment
    volumes:
      - db-appointment-data:/var/lib/mysql

  discovery:
    container_name: discovery
    build: ./discovery
    restart: always
    ports:
      - "8761:8761"

  calendar:
    container_name: calendar
    build: ./calendar
    restart: always
    ports:
      - "9001:9001"
    environment:
      EUREKA_CLIENT_SERVICEURL_DEFAULTZONE: http://discovery:8761/eureka
      SPRING_DATASOURCE_URL: jdbc:mariadb://db-appointment:3306/db-appointment?createDatabaseIfNotExist=true
    depends_on:
      - discovery
      - db-appointment

  ui:
    container_name: ui
    build: ./ui
    restart: always
    ports:
      - "8080:8080"
    environment:
      EUREKA_CLIENT_SERVICEURL_DEFAULTZONE: http://discovery:8761/eureka
    depends_on:
      - discovery
      - calendar

volumes:
  db-appointment-data:

已尝试的操作

  • 更换过多个MariaDB镜像版本
  • 检查应用代码是否存在内存/磁盘溢出问题
  • 确认宿主机磁盘空间充足
    以上操作均未解决问题。

关键日志信息

2024-01-14 19:42:18 0 [Note] mariadbd (initiated by: root[root] @  [94.156.64.78]): Normal shutdown
...
2024-01-15  4:48:04 0 [Note] mariadbd (initiated by: root[root] @  [94.156.71.112]): Normal shutdown

日志显示数据库由外部IP触发正常关闭,但无法确定具体触发原因。


排查方向与解决方案

  1. 限制数据库端口的外部访问
    当前配置将3306端口直接暴露给公网,外部IP可直接连接数据库。建议:

    • 删除ports: - "3306:3306"配置,仅允许内部容器通过服务名db-appointment访问3306端口(Docker内部DNS可解析服务名)。
    • 若必须外部访问,通过宿主机防火墙(如ufw、iptables)仅放行信任IP的3306端口请求,禁止公网任意IP访问。
  2. 收紧数据库用户权限

    • 查看当前root用户的授权范围:
      docker exec -it db-appointment mariadb -uroot -ppassword -e "SELECT user, host FROM mysql.user;"
      
    • 若root用户允许%(任意IP)访问,立即修改为仅允许内部网段或特定IP:
      REVOKE ALL PRIVILEGES ON *.* FROM 'root'@'%';
      GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost';
      GRANT ALL PRIVILEGES ON `db-appointment`.* TO 'root'@'172.%.%.%'; -- 匹配Docker默认桥接网段
      FLUSH PRIVILEGES;
      
    • 创建专用应用用户替代root连接数据库:
      CREATE USER 'app_user'@'%' IDENTIFIED BY 'your_secure_password';
      GRANT SELECT, INSERT, UPDATE, DELETE ON `db-appointment`.* TO 'app_user'@'%';
      FLUSH PRIVILEGES;
      
      同步更新calendar服务的环境变量:添加SPRING_DATASOURCE_USERNAME: app_user和SPRING_DATASOURCE_PASSWORD: your_secure_password。
  3. 启用MariaDB审计日志追踪操作
    通过审计日志记录所有连接和查询,定位触发关闭请求的具体来源:

    • 在db-appointment服务的volumes中添加自定义配置挂载:
      volumes:
        - db-appointment-data:/var/lib/mysql
        - ./my.cnf:/etc/mysql/my.cnf
      
    • 新建my.cnf文件并添加审计配置:
      [mariadb]
      plugin_load_add = server_audit
      server_audit_logging = ON
      server_audit_events = CONNECT,QUERY,DISCONNECT
      server_audit_file_path = /var/log/mysql/audit.log
      
    • 重启数据库容器后,查看审计日志(可将/var/log/mysql挂载到宿主机目录方便查看)。
  4. 检查数据卷与宿主机状态

    • 查看数据卷的实际存储路径:docker volume inspect db-appointment-data,检查路径下的数据库文件(如ibdata1、db-appointment目录)是否完整,有无损坏。
    • 若数据卷存在损坏,备份数据后删除数据卷重新初始化:
      docker-compose down -v
      docker-compose up -d
      
    • 检查宿主机系统日志(如journalctl -u docker或/var/log/syslog),排查是否存在OOM killer终止进程、磁盘IO异常等导致容器重启的情况。

内容的提问来源于stack exchange,提问作者Tom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 13:54:57