启用docker mysql容器中的日志记录

mhe*_*ing 10 mysql logging docker

我正在尝试熟悉docker生态系统并尝试设置一个mysql数据库容器.有了docker-compose这个样子:

version: '2'
services:
  db:
    image: mysql:5.6.33@sha256:31ad2efd094a1336ef1f8efaf40b88a5019778e7d9b8a8579a4f95a6be88eaba
    volumes:
      - "./db/data:/var/lib/mysql"
      - "./db/log:/var/log/mysql"
      - "./db/conf:/etc/mysql/conf.d"
    restart: "yes"
    environment:
      MYSQL_ROOT_PASSWORD: rootpw
      MYSQL_DATABASE: db
      MYSQL_USER: db
      MYSQL_PASSWORD: dbpw
Run Code Online (Sandbox Code Playgroud)

我的conf目录包含一个文件:

[mysqld]
log_error       =/var/log/mysql/mysql_error.log
general_log_file=/var/log/mysql/mysql.log
general_log     =1
slow_query_log  =1
slow_query_log_file=/var/log/mysql/mysql_slow.log
long_query_time =2
log_queries_not_using_indexes = 1
Run Code Online (Sandbox Code Playgroud)

不幸的是我没有得到任何日志文件.设置本身是正确的,并使用cnf文件.连接到容器和创建3个文件后,chown他们mysql并重新启动容器,记录工作正常.

我很确定这是一种常见的情况,而我目前的运行方式似乎非常愚蠢.这样做的正确方法是什么?

我可以通过在Dockerfile中移动所有这些东西来改进我的方法,但这对我来说仍然很奇怪.

Bow*_*wer 10

由于奇怪的 PDO 绑定问题,我需要暂时启用日志记录,并且我想查看正在执行的实际查询。这个问题是最热门的搜索结果,我对任何答案都不满意。假设您已经为容器设置了卷,我让它按以下方式工作:

  1. 对数据库运行以下查询:
SET global general_log = on;
SET global general_log_file='/var/log/mysql/mysql.log';
SET global log_output = 'file'; 

Run Code Online (Sandbox Code Playgroud)
  1. 使用 获取容器 ID docker ps
  2. 跑步docker exec -it <id> /usr/bin/tail -f /var/log/mysql/mysql.log
  3. 完成后运行以下查询:SET global general_log = off;

如果您在设置变量时遇到问题general_log_file,您可能需要/bin/bash进入容器,然后使用正确的权限手动创建日志文件。


BMi*_*tch 7

连接到容器并创建 3 个文件后,将它们 chown 到 mysql 并重新启动容器,日志记录按预期工作。

这指向主机卷权限问题。当您从容器映射到主机时,不会对用户 ID 进行映射,并且容器内的 uid 附加的名称可能与外部非常不同。您需要使用容器用户可以写入的内容来初始化目录权限。一种简单的方法是创建一个组,该组有权写入主机和容器上的文件,然后将各种用户添加到您的映像和主机操作系统上的该组中。另一种选择是使用不能直接从主机访问的命名文件系统,并使用图像的目录权限对其进行初始化。


编辑:使用 docker-compose.yml 命名卷的示例非常简单:

version: '2'
volumes:
  mysql-data:
    driver: local
  mysql-log:
    driver: local
  mysql-conf:
    driver: local

services:
  db:
    image: mysql:5.6.33
    volumes:
      - "mysql-data:/var/lib/mysql"
      - "mysql-log:/var/log/mysql"
      - "mysql-conf:/etc/mysql/conf.d"
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: rootpw
      MYSQL_DATABASE: db
      MYSQL_USER: db
      MYSQL_PASSWORD: dbpw
Run Code Online (Sandbox Code Playgroud)

请注意,我还从您的映像名称中删除了 sha256,此引用会阻止您提取映像的修补版本。我也更喜欢“除非停止”重启策略,以便 Docker 在重启时做预期的事情。


pon*_*lus 6

我一直在寻找完全相同的东西,现在,有一种更好的方法可以做到这一点。

搬运工的MySQL写道:

可以将许多配置选项作为标志传递给mysqld。这将使您可以灵活地自定义容器,而无需cnf文件。例如,如果要更改所有表的默认编码和排序规则以使用UTF-8(utf8mb4),则运行以下命令:

$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
Run Code Online (Sandbox Code Playgroud)

在由docker组成的世界中,可以通过服务的“命令”部分传递这些参数:

command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
Run Code Online (Sandbox Code Playgroud)

在我的用例中,我只想打开日志并指定日志文件的路径:

 command: mysqld --general-log=1 --general-log-file=/var/log/mysql/general-log.log
Run Code Online (Sandbox Code Playgroud)

有了足够的体积(例如- ./logs/mysql.log:/var/log/mysql/general-log.log),就很容易达到它们。

这非常简单,避免了处理本地配置。它可以与任何MySQL Docker映像一起使用,并保持映像my.cnf所提供的原样。