Docker部署MySQL:CIFS挂载目录下InnoDB无法锁定文件报错
问题场景
使用mysql:8.0.31-debian容器,将容器内/var/lib/mysql目录映射到宿主机通过CIFS挂载的/mnt/mysqlshare目录实现数据持久化。宿主机与容器内mysql用户的uid/gid均为999,交互式进入容器切换为mysql用户可正常读写目录,但容器启动时反复出现以下InnoDB错误:
2022-12-08T21:12:56.435340Z 0 [ERROR] [MY-012894] [InnoDB] Unable to open './#innodb_redo/#ib_redo0' (error: 11).
2022-12-08T21:12:56.435784Z 0 [ERROR] [MY-012574] [InnoDB] Unable to lock ./#innodb_redo/#ib_redo0 error: 13
解决方案
1. 优化CIFS挂载参数
CIFS默认的锁机制、inode管理逻辑会与InnoDB底层操作冲突,修改挂载命令添加以下关键参数:
nobrl:禁用字节范围锁,避免InnoDB锁操作与CIFS锁机制冲突serverino:使用服务器端inode编号,避免本地inode重复导致的文件识别异常file_mode=0644,dir_mode=0755:明确设置文件、目录权限,确保MySQL读写权限合规
修改后的挂载命令:
sudo mount -t cifs -o username=linuxmount,cache=none,vers=3.0,uid=999,gid=999,rw,nobrl,serverino,file_mode=0644,dir_mode=0755 [networkpath] /mnt/mysqlshare
2. 调整InnoDB的IO刷新方式
MySQL默认使用O_DIRECT直接IO模式,但多数CIFS共享不支持该模式,需改为fsync模式:
方式一:启动容器时添加命令行参数
docker run -d --name mysql \ -v /mnt/mysqlshare:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=your_root_password \ mysql:8.0.31-debian \ --innodb_flush_method=fsync
方式二:配置my.cnf文件
在/mnt/mysqlshare目录下创建my.cnf文件:
[mysqld] innodb_flush_method=fsync
启动容器时可将该配置文件挂载到容器的/etc/mysql/my.cnf位置,确保MySQL加载该配置。
3. 清理损坏文件并重新初始化挂载目录
挂载目录下已生成的部分文件因启动错误可能损坏,需彻底清理后重新初始化:
# 停止并删除现有容器 docker stop mysql && docker rm mysql # 清空挂载目录下的所有文件 sudo rm -rf /mnt/mysqlshare/* # 重新挂载(若之前已卸载) sudo mount -t cifs -o username=linuxmount,cache=none,vers=3.0,uid=999,gid=999,rw,nobrl,serverino,file_mode=0644,dir_mode=0755 [networkpath] /mnt/mysqlshare # 重新启动容器初始化数据 docker run -d --name mysql \ -v /mnt/mysqlshare:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=your_root_password \ mysql:8.0.31-debian \ --innodb_flush_method=fsync
4. 检查CIFS服务器端配置(可选)
若使用Samba作为CIFS共享源,需确保smb.conf中开启oplocks支持:
[your_share_name] oplocks = yes level2 oplocks = yes
Windows共享则需确认共享权限允许修改、写入,且文件锁定功能未被禁用。
内容的提问来源于stack exchange,提问作者klarC

