该脚本用于实现 root 用户在 Linux 操作系统下的 Docker 中安装单体架构 MySQL

Shell 脚本 Git 仓库地址

Gitee:https://gitee.com/tongchaowei/common-shell/tree/main/root

执行脚本

bash ./docker-mysql-install-single.sh

image.png

需要注意的

  • 该脚本会先检查是否安装了社区版 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


Logo

一起探索未来云端世界的核心,云原生技术专区带您领略创新、高效和可扩展的云计算解决方案,引领您在数字化时代的成功之路。

更多推荐