问题起因
最近在做AI大模型相关的项目,项目中因为要和大模型服务通信,涉及到的样本信息非常多,导致报文非常大,在写HTTP日志时,MySQL会报错,因为MySQL默认的最大报文长度(max_allowed_packet)是4M,如果请求的报文超过4M,会报错,如“Row size too large. The maximum row size for the used table type”。
最简单的解决办法就是修改MySQL配置,把max_allowed_packet适当调大一点。
docker挂载的配置文件不生效?
MySQL是使用docker compose镜像部署的,如下:
mysql:
image: mysql:5.7.44
container_name: mysql
ports:
- "${MYSQL_PORT}:3306"
volumes:
- ${WORK_DIR}mysql/conf.d/:/etc/mysql/conf.d/
#- ${WORK_DIR}mysql/mysql/my.cnf:/etc/mysql/my.cnf
#- ${WORK_DIR}mysql/my.cnf:/etc/my.cnf
- ${WORK_DIR}mysql/data/:/var/lib/mysql/
restart: always
networks:
- net
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
#MYSQL_MAX_ALLOWED_PACKET: 32M
TZ: ${TIME_ZONE}
配置的docker compose,启动后发现/etc/mysql/conf.d/下的my.cnf文件是正常挂载进容器中了,但是通过命令查看MySQL配置:
SHOW GLOBAL VARIABLES LIKE '%max_allowed_packet%';
发现没有生效。
刚开始怀疑是配置文件挂载路径问题,又换了挂载到/etc/mysql/my.cnf 、 /etc/my.cnf下也照样不生效。
参考网上的资料,理想情况下,只有 MySQL 服务账户(通常是 mysql 用户组)才能够访问my.cnf配置文件。所以怀疑是my.cnf配置文件的用户组和权限问题,加入一下用户和组:
sudo groupadd mygroup
sudo useradd -g mygroup myuser
修改my.cnf文件的所有权和权限:
chown mysql:mysql ${WORK_DIR}/mysql/conf.d/my.cnf
chmod 640 ${WORK_DIR}/mysql/conf.d/my.cnf
重启docker compose容器还是没有生效。
最后,没办法,进mysql容器,一探究竟,发现用户组根本不是宿主机上的mysql:mysql,
-rw-r----- 1 980 9700 746 Aug 1 19:32 my.cnf
怀疑是配置文件挂载后,容器内用户组用户丢失。
罪魁祸首——UID/GID 冲突
当你将宿主机上的文件挂载到 Docker 容器中时,文件的所有权和组信息可能会显示为数字 ID 而不是名称。这是因为 Docker 容器内的用户和组 ID 可能与宿主机上的不同,即使用户和组名相同。这种现象称为“UID/GID 冲突”。
解决方案
方法 1: 容器内外my.cnf使用相同的 UID 和 GID
1、获取容器内的 UID 和 GID:
MySQL 5.7 的官方镜像,可以使用以下方法来查找用户的 UID 和 GID:
docker inspect --format '{{ .Config.User }}' <container-id>
由于docker官方镜像已经访问不了了,我用的mysql镜像也不知道是不是官方的,反正之前上面的命名没有找到UID/GID,只能进容器查看
2、 在宿主机上设置相同的 UID 和 GID:
如果还没有创建 mysql 用户和用户组,可以创建并指定 UID 和 GID 与容器内的相同:
sudo groupadd -g 999 mysql
sudo useradd -r -u 999 -g 999 -s /sbin/nologin mysql
如果已经创建了 mysql 用户和用户组,你可以修改 UID 和 GID:
sudo usermod -u 999 mysql
sudo groupmod -g 999 mysql
方法 2: 容器启动时使用初始化脚本设置my.cnf的UID 和 GID
创建一个初始化脚本:
vim ./init.sh
#!/bin/bash
chown mysql:mysql /etc/mysql/conf.d/my.cnf
chmod 640 /etc/mysql/conf.d/my.cnf
使脚本可执行
chmod +x ./init.sh
docker compose中加入执行脚本
version: '3'
services:
db:
image: ${MYSQL_VERSION}
container_name: mysql
ports:
- "${MYSQL_PORT}:3306"
volumes:
- ${WORK_DIR}mysql/my.cnf:/etc/mysql/my.cnf
- ${WORK_DIR}mysql/data/:/var/lib/mysql/
- ./init.sh:/docker-entrypoint-initdb.d/init.sh
restart: always
networks:
- net
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
TZ: ${TIME_ZONE}
docker compose restart mysql,问题解决。
最近开始想搞一个面向IT从业人员的减压放松、学习类型的公众号,分享一下IT行业的动态、段子、新鲜事,当然也包括技术这档子事,感兴趣的朋友可以关注我一下: