该脚本用于实现 root 用户在 Linux 操作系统下的 Docker 中安装单体架构 MySQL
Shell 脚本 Git 仓库地址
Gitee:https://gitee.com/tongchaowei/common-shell/tree/main/root
执行脚本
bash ./docker-mysql-install-single.sh
需要注意的
- 该脚本会先检查是否安装了社区版 Docker,如果没有安装,则会退出脚本的执行,所以请先完成社区版 Docker 的安装
- 该脚本会进行如下目录的映射:
- /log: /var/log/mysql:MySQL 日志文件存放目录
- /data:/var/lib/mysql,MySQL 数据表和数据文件存放的目录
- /conf:/etc/mysql,MySQL 配置文件目录
- /mysql-files:/var/lib/mysql-files,MySQL 相关文件,这个映射主要是防止报错
- /csv:/var/lib/mysql-csv,MySQL 配置文件中配置的用于存放数据库 csv 格式导出文件
- 该脚本启动容器时,会自动设置的参数如下:
--restart=always
:跟随系统启动而自启--privileged=true
:容器具有 root 权限
MySQL 配置文件
配置文件中的配置项的说明,可以参考:https://www.yuque.com/u27599042/ugk6po/uosu9hbt78g24g0x
该脚本在成功启动 MySQL 容器后,编写的配置文件内容如下:
配置文件存放位置:$docker_mysql_home/conf/conf.d/my.cnf
docker_mysql_home:Docker 安装 MySQL 相关映射目录和文件的家目录
# MySQL 服务端的相关配置
[mysqld]
# MySQL 集群中的每个 MySQL 服务端的唯一标识
# server-id=1
# MySQL 服务端运行监听来自客户端连接的端口号
port=3306
# 是否跳过(关闭) MySQL 服务端的域名解析
# 1 表示跳过(关闭) MySQL 服务端的域名解析
skip_name_resolve=1
# MySQL 服务端关闭交互式连接前等待活动的时间
# 如果超过这个时间,客户端还未发送数据过来,服务端则会断开本次连接。
# interactive_timeout=28800
# MySQL 服务端等待来自非交互式连接的客户端的数据的最长时间
# 如果超过这个时间,客户端还未发送数据过来,服务端则会断开本次连接。
wait_timeout=300
# MySQL 服务端的默认时区
default-time_zone='+8:00'
# MySQL 服务端的默认存储引擎
default-storage-engine=InnoDB
# MySQL 服务端的字符集编码
character-set-server=utf8mb4
# MySQL 服务端的比较规则
# 要和 character-set-server 配置项配置的 MySQL 服务端的字符集编码对应
collation-server=utf8mb4_general_ci
# 客户端连接 MySQL 服务端时使用的字符集
init_connect='SET NAMES utf8mb4'
# MySQL 服务端是否对 SQL 语句大小写敏感
# 1 表示对 SQL 语句大小写不敏感
lower_case_table_names=1
# MySQL 服务端使用的默认密码校验规则插件
# MySQL 8.3.0 中“mysql_native_password”已弃用,并将在将来的版本中删除。请改用caching_sha2_password'
# default_authentication_plugin=mysql_native_password
default_authentication_plugin=caching_sha2_password
# 如果进行要进行如下配置项的配置修改,log-error 需要手动创建 error.log 文件,否则会报错,
# datadir secure_file_priv 需要在容器启动时做好目录映射,且存放数据表和数据文件的目录要保证为空,否则会报错
# 报错日志写入位置
# log-error=/var/lib/mysql/log/error.log
# MySQL 服务端进程 ID 的存放文件及其位置
pid-file=/var/lib/mysql/mysqld.pid
# MySQL 服务端中的数据表和数据文件的存放位置
datadir=/var/lib/mysql
# MySQL 数据库中数据表中的数据导出到 csv 文件中,csv 文件的存放位置
secure_file_priv=/var/lib/mysql-csv
# 连接访问 MySQL 的客户端的相关配置
[client]
# MySQL 接收来自客户端连接访问请求时客户端使用的字符集
default-character-set=utf8mb4
Shell 脚本源码
#!/bin/bash
# 该脚本用于实现 root 用户在 Linux 操作系统下的 Docker 中安装单体架构 MySQL
# 临时保存并修改语言环境
LANG_temp=$LANG
LANG=zh_CN.UTF-8
# 还原语言环境
function re_lang () {
# 将语言环境修改回原来的值
LANG=$LANG_temp
}
# 还原语言环境,并无异常退出
function re_lang_exit () {
re_lang
exit 0
}
function success_text () {
echo -e -n "\033[32m【SUCCESS】\033[0m"
}
function warn_text () {
echo -e -n "\033[33m【WARN】\033[0m"
}
function error_text () {
echo -e -n "\033[31m【ERROR】\033[0m"
}
# 如果传入的目录不存在,进行目录的创建
function mkdir_404 () {
if [ ! -d $1 ]; then
warn_text
echo "目录 $1 不存在,进行目录的创建..."
mkdir -p $1
success_text
echo "目录 $1 创建成功"
else
success_text
echo "目录 $1 已存在,无需进行创建."
fi
}
# 检查是否安装了社区版 Docker
is_docker_ce_install=`rpm -q docker-ce | grep '未安装软件包.*'`
if [ ${#is_yum_install} -gt 0 ]; then
error_text
echo '还未安装社区版 Docker,请先进行安装.'
re_lang_exit
fi
# 启动 Docker 并开启 Docker 开机自启,确保 Docker 处于运行状态
echo "Docker 启动中..."
systemctl start docker || re_lang_exit
echo "开启 Docker 开机自启中..."
systemctl enable docker || re_lang_exit
# 要进行安装的 MySQL 的版本
docker_mysql_version_default=latest
read -p "请输入要安装的 MySQL 版本(默认 $docker_mysql_version_default):" docker_mysql_version
if [ -z "$docker_mysql_version" ]; then
docker_mysql_version=$docker_mysql_version_default
fi
# Docker MySQL 镜像名称
if [ "$docker_mysql_version" = "latest" ]; then
docker_mysql_image_name=mysql
else
docker_mysql_image_name=mysql:$docker_mysql_version
fi
# Docker 安装 MySQL 相关映射目录和文件的家目录
docker_mysql_home_default=/home/docker/mysql
read -p "请输入 Docker 安装 MySQL 相关映射目录和文件的家目录(默认 $docker_mysql_home_default):" docker_mysql_home
if [ -z "$docker_mysql_home" ]; then
docker_mysql_home=$docker_mysql_home_default
fi
# 需要进行映射的目录
need_map_dir=( /log /data /conf /mysql-files /csv )
# 目录如果不存在,进行目录的创建
mkdir_404 $docker_mysql_home
for (( i=0; i<${#need_map_dir[*]}; i++ )); do
# 删除原先存在的 MySQL 容器的映射目录
rm -rf $docker_mysql_home${need_map_dir[i]}
warn_text
echo "已删除 $docker_mysql_home${need_map_dir[i]} 目录及其子目录和其中的文件"
mkdir_404 $docker_mysql_home${need_map_dir[i]}
done
# 查询 Docker 中是否存在 MySQL 镜像,不存在,进行镜像的拉取
docker_mysql_image=`docker images -a | grep 'mysql' | grep "$docker_mysql_version"`
if [ -z "$docker_mysql_image" ]; then
warn_text
echo "Docker 中不存在 $docker_mysql_image_name 镜像"
echo "开始拉取镜像 $docker_mysql_image_name..."
docker pull $docker_mysql_image_name || re_lang_exit
success_text
echo "拉取 $docker_mysql_image_name 镜像成功"
else
success_text
echo "镜像 $docker_mysql_image_name 已存在,无需进行拉取"
fi
# MySQL Docker 容器名称
docker_mysql_container_name=mysql$docker_mysql_version
# 判断容器是否存在,如果存在,手动输入指定容器名称
while true; do
if [ ! -z "`docker ps -a | grep \"$docker_mysql_container_name\"`" ]; then
error_text
echo "名称为 $docker_mysql_container_name 的 Docker 容器已经存在"
read -p "请输入新 Docker 容器名称:" docker_mysql_container_name
else
if [ -z "$docker_mysql_container_name" ]; then
error_text
echo "Docker 容器名称不能为空."
read -p "请输入新 Docker 容器名称:" docker_mysql_container_name
continue
fi
break
fi
done
# 先运行一个 MySQL docker 容器,获取初始的配置文件后,将其删除
docker run --name $docker_mysql_container_name -d $docker_mysql_image_name || re_lang_exit
docker cp $docker_mysql_container_name:/etc/mysql $docker_mysql_home${need_map_dir[2]} || re_lang_exit
mv $docker_mysql_home${need_map_dir[2]}/mysql/* $docker_mysql_home${need_map_dir[2]}/ || re_lang_exit
docker rm -f $docker_mysql_container_name || re_lang_exit
# MySQL 容器运行时的端口,即容器的端口映射
while true; do
read -p "请输入 MySQL 容器运行映射的端口号(默认 3306):" mysql_port
if [ -z "$mysql_port" ]; then
mysql_port=3306
fi
# 判断端口是否被占用
if [ ! -z "`lsof -i:$mysql_port`" ]; then
error_text
echo "端口 $mysql_port 已经被占用,请选择未被占用的端口号."
else
break
fi
done
# MySQL root 用户的初始密码
read -p "请输入 MySQL 数据库 root 用户的初始密码(默认 root):" mysql_root_pwd
if [ -z "$mysql_root_pwd" ]; then
mysql_root_pwd=root
fi
# 运行 MySQL 容器,
docker run \
-p $mysql_port:3306 \
--name $docker_mysql_container_name \
--restart=always \
--privileged=true \
-v $docker_mysql_home/conf:/etc/mysql \
-v $docker_mysql_home/data:/var/lib/mysql \
-v $docker_mysql_home/log:/var/log/mysql \
-v $docker_mysql_home/mysql-files:/var/lib/mysql-files \
-v $docker_mysql_home/csv:/var/lib/mysql-csv \
-v /etc/localtime:/etc/localtime:ro \
-e MYSQL_ROOT_PASSWORD=$mysql_root_pwd \
-d $docker_mysql_image_name \
|| re_lang_exit
success_text
echo "MySQL 容器启动运行成功."
echo "MySQL 容器运行情况如下:"
docker ps -f name=$docker_mysql_container_name
# 编写 MySQL 配置文件
echo "开始编写 MySQL 配置文件..."
echo
tee $docker_mysql_home/conf/conf.d/my.cnf <<- EOF
# MySQL 服务端的相关配置
[mysqld]
# MySQL 集群中的每个 MySQL 服务端的唯一标识
# server-id=1
# MySQL 服务端运行监听来自客户端连接的端口号
port=3306
# 是否跳过(关闭) MySQL 服务端的域名解析
# 1 表示跳过(关闭) MySQL 服务端的域名解析
skip_name_resolve=1
# MySQL 服务端关闭交互式连接前等待活动的时间
# 如果超过这个时间,客户端还未发送数据过来,服务端则会断开本次连接。
# interactive_timeout=28800
# MySQL 服务端等待来自非交互式连接的客户端的数据的最长时间
# 如果超过这个时间,客户端还未发送数据过来,服务端则会断开本次连接。
wait_timeout=300
# MySQL 服务端的默认时区
default-time_zone='+8:00'
# MySQL 服务端的默认存储引擎
default-storage-engine=InnoDB
# MySQL 服务端的字符集编码
character-set-server=utf8mb4
# MySQL 服务端的比较规则
# 要和 character-set-server 配置项配置的 MySQL 服务端的字符集编码对应
collation-server=utf8mb4_general_ci
# 客户端连接 MySQL 服务端时使用的字符集
init_connect='SET NAMES utf8mb4'
# MySQL 服务端是否对 SQL 语句大小写敏感
# 1 表示对 SQL 语句大小写不敏感
lower_case_table_names=1
# MySQL 服务端使用的默认密码校验规则插件
# MySQL 8.3.0 中“mysql_native_password”已弃用,并将在将来的版本中删除。请改用caching_sha2_password'
# default_authentication_plugin=mysql_native_password
default_authentication_plugin=caching_sha2_password
# 如果进行要进行如下配置项的配置修改,log-error 需要手动创建 error.log 文件,否则会报错,
# datadir secure_file_priv 需要在容器启动时做好目录映射,且存放数据表和数据文件的目录要保证为空,否则会报错
# 报错日志写入位置
# log-error=/var/lib/mysql/log/error.log
# MySQL 服务端进程 ID 的存放文件及其位置
pid-file=/var/lib/mysql/mysqld.pid
# MySQL 服务端中的数据表和数据文件的存放位置
datadir=/var/lib/mysql
# MySQL 数据库中数据表中的数据导出到 csv 文件中,csv 文件的存放位置
secure_file_priv=/var/lib/mysql-csv
# 连接访问 MySQL 的客户端的相关配置
[client]
# MySQL 接收来自客户端连接访问请求时客户端使用的字符集
default-character-set=utf8mb4
EOF
success_text
echo "MySQL 配置文件编写完成."
echo "重启 MySQL 容器..."
docker restart $docker_mysql_container_name || re_lang_exit
success_text
echo "重启 MySQL 容器成功."
re_lang