Linux-Shell:mysql的bin_log日志清理

本文提供了一个自动清理MySQL Binlog日志的Shell脚本,该脚本能够定期清理日志,保留最近一周的日志,并支持自适应路径和循环处理多个数据库。脚本功能包括获取日志列表、筛选倒数第七天的日志、生成清理命令,并执行清理操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求:
1、自动处理mysql bin日志脚本
2、输出可读log
3、保留1周的日志
4、对所有数据库统一处理。

实现过程描述:

思路:两种方式实现
1、mysql目录通过ls获取bin日志目录并通过命令删除。
2、通过mysql命令获取bin日志,并通过命令删除。

相比较来说第二种更加容易实现。

功能语句:
mysql -h192.168.1.2 -uroot -pXXXXX < /home/GC_Tools/housekeeping/mysql_bin_log/bin/Getlog.sql > /home/GC_Tools/housekeeping/mysql_bin_log/bin/templog.txt

以上命令输出格式如下:
mysql-bin.001021        1073742032
mysql-bin.001022        1073742579
mysql-bin.001023        1073742818
mysql-bin.001024        1073741920
mysql-bin.001025        1073741915
mysql-bin.001026        790706635
第一列是日志名称,第二列是日志大小。
以上是截取的一部分内容,我们需要的数据是倒数第七天的日志名称。
通过mysql清理日志的命令去清理它之前的所有日志。

直接获取倒数第七行的数据:
tac templog.txt | sed -n 7p | awk -F ' ' '{print $1}'

以下给出简略版本,只实现功能:删除指定数据库的bin日志,保留七天日志。
#####################################
#!/bin/bash
TIME=`date +%Y%m%d%H%M%S`
BINPATH="/home/GC_Tools/housekeeping/mysql_bin_log"
SQLPARAM="mysql -h192.168.1.6 -uroot -pXXXXX"

echo $TIME "start clean" >> $BINPATH/log/clean.log
$SQLPARAM < $BINPATH/bin/Getlog.sql > templog.txt
BinLog=`tac templog.txt | sed -n 7p | awk -F ' ' '{print $1}'`
echo "Get the log's name is" \"$BinLog\" >>$BINPATH/log/clean.log
echo "purge binary logs to '$BinLog';" > temp.sql

$SQLPARAM < $BINPATH/bin/temp.sql >> $BINPATH/log/clean.log

#############################################
简略版本完成,功能测试正常。

接下来需要实现功能:
1、部署路径不要求,自适应。
2、读取数据库IP配置文件,并循环处理。

完整版本:

#!/bin/bash
#动态获取脚本路径
DIR="$( cd "$( dirname "$0"  )" && pwd  )"
BINPATH=`echo $DIR | sed -e 's/\/bin//'`
#获取当前系统时间
TIME=`date +%Y%m%d%H%M%S`
#while do 循环处理配置文件
while read LINE
do
#输出日志
echo $TIME >>$BINPATH/log/clean.log
echo $LINE >>$BINPATH/log/clean.log
#获取数据库ip
CHOST=`echo $LINE | awk -F ':' '{print $2}'`
#拼写数据库连接sql
SQLPARAM="mysql -h$CHOST -uroot -pXXXXX"
#查询当前连接数据库的日志信息列表
$SQLPARAM < $BINPATH/bin/Getlog.sql > $DIR/templog.txt
#获取倒数七天的日志名称
BinLog=`tac $DIR/templog.txt | sed -n 7p | awk -F ' ' '{print $1}'`
#拼写清理日志sql,并保存在临时文件
echo "purge binary logs to '$BinLog';" > $DIR/temp.sql
#执行sql,清理mysql日志
$SQLPARAM < $DIR/temp.sql >>$BINPATH/log/clean.log
rm -rf $DIR/templog.txt
rm -rf $DIR/temp.sql
#循环读取配置文件内容
done<$BINPATH/etc/clean.conf

ps:配置文件实例
clean.conf
DB2:192.168.1.3
DB4:192.168.1.4
DB5:192.168.1.5
DB6:192.168.1.6

再再PS:
程序功能说明:
  定期(每周六晚)清理mysql的binlog,保留七天的日志,其余日志删除。
使用说明:
1、只需要在/etc配置文件内配置数据库名称与IP即可,不需要增加其他配置。

2、脚本本身没有检测数据库是否连接正常的功能,默认连接正常,如果数据库异常最好不要配置,不然会连接超时。


PS:写完之后发现,mysql其实有相应的配置项可以设置binlog的数量,汗颜....,不过脚本的功能和逻辑是想通的,也不算是完全没有价值和收获,当然有些大神直接一行shell命令就可以解决这个需求,我目前还在努力向这个方向迈进。

<think>问题分析:错误信息显示访问被拒绝,具体是用户'mgr_user'@'172.18.0.5'使用密码:NO。这表明在连接时没有使用密码(尽管我们通过环境变量设置了密码)。这通常是因为在引导过程中,密码没有被正确传递。解决方案:1.确保在引导命令中正确传递密码。在MySQL Router的引导命令中,密码通常是通过交互式提示输入的,但也可以通过配置文件或命令行选项提供。然而,在Docker环境中,我们可以通过标准输入传递密码,或者使用配置文件。2.另一种方法是使用MySQL Shell先创建路由器用户并授予必要的权限,然后再引导路由器。但根据错误,问题出在连接上,所以我们需要确保在连接字符串中包含了密码。3.注意:在连接字符串中,密码不能直接写在命令行中,因为这样不安全,而且MySQLRouter的引导命令也不支持在连接字符串中直接写密码。因此,我们需要通过其他方式提供密码。4.官方文档建议:在引导时,当需要密码时,会提示输入。在非交互式环境中(如Docker),我们可以使用以下方法之一:a)使用配置文件(例如:/etc/mysqlrouter/mysqlrouter.conf)预先设置,但引导过程需要先连接。b)通过标准输入传递密码。5.在Docker中,我们可以通过管道将密码传递给mysqlrouter进程。但是,由于我们使用的是`docker run`,我们可以使用`echo`命令将密码通过管道传入。6.修改命令:将密码通过标准输入传递给mysqlrouter引导命令。注意,在引导命令中,连接字符串中不包含密码,但是当需要密码时,程序会从标准输入读取。7.但是,根据错误信息,它使用的是密码:NO,说明没有提供密码。因此,我们需要在连接字符串中指定密码,或者通过其他方式提供。8.实际上,MySQL Router的引导命令允许在连接字符串中指定密码,但格式为:`user:password@host:port`。但是,这样在命令行中直接暴露密码不安全,而且如果密码包含特殊字符,可能会被解析错误。9.因此,我们可以修改连接字符串,将密码包含进去:`mgr_user:admin@mysql-master:3306`。10.注意:在连接字符串中指定密码时,如果密码中包含特殊字符(如@,:, /,等),需要进行URL编码。但这里密码是'admin',没有特殊字符。11.修改命令:将`--bootstrapmgr_user@mysql-master:3306`改为`--bootstrapmgr_user:admin@mysql-master:3306`。12.另外,确保MySQL用户'mgr_user'在主机'172.18.0.5'(即运行MySQLRouter的容器IP)上有访问权限。如果MySQL服务器只允许用户从特定主机连接,需要确保授权给这个IP或使用通配符。13.在MySQL服务器上执行如下命令(示例):```sqlCREATEUSER 'mgr_user'@'%'IDENTIFIED BY'admin';GRANTALL PRIVILEGESON *.* TO'mgr_user'@'%'WITH GRANT OPTION;```注意:这里使用'%'允许任何主机连接,仅用于测试。生产环境应限制IP。14.如果用户已经创建,但只授权给了特定主机,可以修改授权:```sqlGRANTALL PRIVILEGESON *.* TO'mgr_user'@'172.18.0.%'IDENTIFIED BY'admin';```15.或者,如果MySQL服务器配置了skip-name-resolve,那么授权是基于IP的,所以需要确保授权给MySQLRouter容器的IP。16.由于在Docker网络中,容器的IP是动态分配的,所以建议使用网络别名或子网授权。修改后的命令:```bashdockerrun --name mysql-router \--network mysql-net \-v /use01/docker/mysqlrouter:/etc/mysqlrouter\-eMYSQL_HOST=mysql-master\-eMYSQL_PORT=3306 \-e MYSQL_USER=mgr_user\-eMYSQL_PASSWORD='admin'\mysql/mysql-router:8.0.32 \mysqlrouter \--bootstrapmgr_user:admin@mysql-master:3306\#这里在连接字符串中包含了密码--conf-set-option=DEFAULT.name=router \--conf-set-option=metadata_cache:Cluster01.bootstrap_server_addresses=mysql-master:3306,mysql-slave1:3306,mysql-slave2:3306 \--conf-set-option=routing:read_write.bind_port=6446\--conf-set-option=routing:read_only.bind_port=6447 \--conf-set-option=routing:read_write_split.bind_port=6450\--force```如果密码包含特殊字符,可以使用URL编码。例如,密码`p@ss`编码后为`p%40ss`。但是,如果不想在命令行中暴露密码,另一种方法是使用配置文件。不过,在引导过程中,我们可以通过环境变量传递密码,但MySQLRouter引导命令并不直接支持从环境变量读取连接字符串中的密码。因此,我们采用在连接字符串中包含密码的方式。另外,确保MySQL用户'mgr_user'在MySQL服务器上确实存在,并且有足够的权限(例如,需要`CREATEUSER`权限,因为MySQLRouter在引导过程中会创建路由账户)。如果问题仍然存在,请检查MySQL服务器日志,查看连接尝试的详细错误。如果是因为SSL/TLS连接问题,可以尝试在连接字符串中添加`?ssl-mode=DISABLED`(如果服务器要求SSL而客户端未使用,或者反之)。例如:```bash--bootstrap "mgr_user:admin@mysql-master:3306?ssl-mode=DISABLED"```注意:禁用SSL仅用于测试,生产环境应使用SSL。最后,如果用户权限没有问题,且密码正确,那么可能是网络问题,确保容器间网络通信正常。下面是一个完整的示例,包括在连接字符串中指定密码和禁用SSL(如果需要):```bashdocker run--namemysql-router\--networkmysql-net\-v/use01/docker/mysqlrouter:/etc/mysqlrouter \-e MYSQL_HOST=mysql-master \-e MYSQL_PORT=3306\-eMYSQL_USER=mgr_user \-eMYSQL_PASSWORD='admin'\mysql/mysql-router:8.0.32\mysqlrouter\--bootstrap "mgr_user:admin@mysql-master:3306?ssl-mode=DISABLED"\--conf-set-option=DEFAULT.name=router\--conf-set-option=metadata_cache:Cluster01.bootstrap_server_addresses=mysql-master:3306,mysql-slave1:3306,mysql-slave2:3306 \--conf-set-option=routing:read_write.bind_port=6446\--conf-set-option=routing:read_only.bind_port=6447 \--conf-set-option=routing:read_write_split.bind_port=6450\--force```解释:1.在连接字符串中明确指定了密码(`mgr_user:admin@...`),这样MySQLRouter在连接时就会使用这个密码。2.添加了`?ssl-mode=DISABLED`参数,这是可选的,仅用于测试SSL连接问题。3.其他配置选项保持不变。如果问题解决,可以移除`?ssl-mode=DISABLED`并配置正确的SSL模式。另外,请注意,错误信息中的IP地址(172.18.0.5)是MySQL Router容器的IP,在MySQL服务器上,需要允许该IP的连接。如果MySQL服务器在容器内,并且使用同一个Docker网络,那么网络应该是通的。但是,授权问题需要解决。因此,在MySQL服务器容器中,执行如下SQL命令(使用root用户登录): ```sqlALTERUSER 'mgr_user'@'%'IDENTIFIED BY'admin'; FLUSH PRIVILEGES; ```或者,如果用户不存在,创建用户: ```sqlCREATE USER'mgr_user'@'%'IDENTIFIED BY'admin'; GRANT ALLPRIVILEGES ON*.*TO 'mgr_user'@'%'WITH GRANT OPTION;FLUSHPRIVILEGES;```注意:在生产环境中,应限制权限和访问IP。如果还是不行,可以尝试在MySQL服务器上查看连接错误日志,通常位于/var/log/mysql/error.log。在Docker中,可以通过以下命令查看日志: ```bashdocker logsmysql-server-container```其中,`mysql-server-container`是MySQL服务器容器的名称。最后,如果确定是权限问题,并且已经修改了权限,请确保在修改权限后重新尝试连接。由于Docker容器每次运行可能获得不同的IP,建议在创建用户时使用通配符'%',或者使用Docker的DNS名称(例如,使用容器名称)来授权,但MySQL的授权是基于主机IP或主机名的,所以使用通配符'%'更简单。如果MySQL服务器配置了`bind-address`,确保它监听的是`0.0.0.0`,而不仅仅是宿主机IP。在MySQL服务器的配置文件中(例如:`/etc/mysql/my.cnf`): ```ini[mysqld] bind-address=0.0.0.0```然后重启MySQL服务。综上所述,主要修改是在引导命令的连接字符串中加入密码,并确保MySQL用户有正确的权限和连接设置。现在,我们给出修改后的命令。</think>### 解决 MySQL Router 连接权限问题 您遇到的错误 `Access denied for user 'mgr_user'@'172.18.0.5'` 表明 MySQL Router 容器无法使用提供的凭证连接到 MySQL 主服务器。以下是完整的解决方案: #### 问题分析: 错误原因可能包括: 1. MySQL 用户权限不足 2. 用户不存在或密码错误 3. 主机限制(IP 地址未授权) 4. SSL/TLS 配置不匹配 5. 网络连接问题 #### 解决方案: ##### 1. 验证 MySQL 用户权限 在 MySQL 主服务器上执行以下 SQL 命令: ```sql -- 检查用户是否存在 SELECT user, host FROM mysql.user WHERE user = 'mgr_user'; -- 检查用户权限 SHOW GRANTS FOR 'mgr_user'@'%'; -- 创建或更新用户(使用实际密码) CREATE USER IF NOT EXISTS 'mgr_user'@'%' IDENTIFIED BY 'admin'; GRANT ALL PRIVILEGES ON *.* TO 'mgr_user'@'%' WITH GRANT OPTION; FLUSH PRIVILEGES; ``` ##### 2. 修正 Docker 命令中的连接问题 ```bash # 使用正确的连接格式(包含密码) docker run --name mysql-router \ --network mysql-net \ -v /use01/docker/mysqlrouter:/etc/mysqlrouter \ -e MYSQL_HOST=mysql-master \ -e MYSQL_PORT=3306 \ -e MYSQL_USER=mgr_user \ -e MYSQL_PASSWORD='admin' \ mysql/mysql-router:8.0.32 \ mysqlrouter \ --bootstrap "mgr_user:admin@mysql-master:3306" \ # 关键修改:包含密码 --conf-set-option=DEFAULT.name=router \ --conf-set-option=metadata_cache:Cluster01.bootstrap_server_addresses=mysql-master:3306,mysql-slave1:3306,mysql-slave2:3306 \ --conf-set-option=routing:read_write.bind_port=6446 \ --conf-set-option=routing:read_only.bind_port=6447 \ --conf-set-option=routing:read_write_split.bind_port=6450 \ --force ``` **关键修改:** - 在 `--bootstrap` 参数中使用 `"user:password@host:port"` 格式 - 确保密码正确包含在连接字符串中 ##### 3. 添加 SSL/TLS 配置选项 ```bash docker run --name mysql-router \ --network mysql-net \ -v /use01/docker/mysqlrouter:/etc/mysqlrouter \ -e MYSQL_HOST=mysql-master \ -e MYSQL_PORT=3306 \ -e MYSQL_USER=mgr_user \ -e MYSQL_PASSWORD='admin' \ mysql/mysql-router:8.0.32 \ mysqlrouter \ --bootstrap "mgr_user:admin@mysql-master:3306?ssl-mode=DISABLED" \ # 禁用SSL --conf-set-option=DEFAULT.name=router \ --conf-set-option=metadata_cache:Cluster01.bootstrap_server_addresses=mysql-master:3306,mysql-slave1:3306,mysql-slave2:3306 \ --conf-set-option=routing:read_write.bind_port=6446 \ --conf-set-option=routing:read_only.bind_port=6447 \ --conf-set-option=routing:read_write_split.bind_port=6450 \ --force ``` ##### 4. 使用交互式调试排查问题 ```bash # 运行临时调试容器 docker run -it --rm \ --network mysql-net \ -v /use01/docker/mysqlrouter:/etc/mysqlrouter \ -e MYSQL_HOST=mysql-master \ -e MYSQL_PORT=3306 \ -e MYSQL_USER=mgr_user \ -e MYSQL_PASSWORD='admin' \ --entrypoint /bin/bash \ mysql/mysql-router:8.0.32 # 在容器内测试连接 mysql -h mysql-master -u mgr_user -padmin -e "SHOW DATABASES;" # 检查网络连通性 ping mysql-master nc -zv mysql-master 3306 # 尝试手动引导 mysqlrouter --bootstrap "mgr_user:admin@mysql-master:3306" --force ``` ##### 5. 完整的 Docker Compose 解决方案 ```yaml version: '3.8' services: mysql-master: image: mysql:8.0 container_name: mysql-master environment: MYSQL_ROOT_PASSWORD: rootpassword MYSQL_USER: mgr_user MYSQL_PASSWORD: admin command: - --server-id=1 - --log-bin - --binlog-format=ROW - --gtid-mode=ON - --enforce-gtid-consistency=ON - --default-authentication-plugin=mysql_native_password volumes: - mysql_data:/var/lib/mysql networks: - mysql-net mysql-slave1: image: mysql:8.0 container_name: mysql-slave1 environment: MYSQL_ROOT_PASSWORD: rootpassword command: - --server-id=2 - --log-bin - --binlog-format=ROW - --gtid-mode=ON - --enforce-gtid-consistency=ON - --read-only=ON - --skip-slave-start - --default-authentication-plugin=mysql_native_password volumes: - mysql_data_slave1:/var/lib/mysql networks: - mysql-net depends_on: - mysql-master mysql-router: image: mysql/mysql-router:8.0.32 container_name: mysql-router depends_on: - mysql-master - mysql-slave1 environment: MYSQL_HOST: mysql-master MYSQL_PORT: 3306 MYSQL_USER: mgr_user MYSQL_PASSWORD: admin command: - mysqlrouter - --bootstrap - "$${MYSQL_USER}:$${MYSQL_PASSWORD}@$${MYSQL_HOST}:$${MYSQL_PORT}" - --conf-set-option=DEFAULT.name=router - --conf-set-option=metadata_cache:Cluster01.bootstrap_server_addresses=mysql-master:3306,mysql-slave1:3306 - --conf-set-option=routing:read_write.bind_port=6446 - --conf-set-option=routing:read_only.bind_port=6447 - --conf-set-option=routing:read_write_split.bind_port=6450 - --force volumes: - mysqlrouter_config:/etc/mysqlrouter ports: - "6446:6446" - "6447:6447" - "6450:6450" networks: - mysql-net networks: mysql-net: driver: bridge volumes: mysql_data: mysql_data_slave1: mysqlrouter_config: ``` #### 权限修复脚本 ```bash #!/bin/bash # fix_mysql_permissions.sh # 在主服务器容器内执行 docker exec mysql-master mysql -uroot -prootpassword <<EOF -- 创建或更新用户 CREATE USER IF NOT EXISTS 'mgr_user'@'%' IDENTIFIED BY 'admin'; GRANT ALL PRIVILEGES ON *.* TO 'mgr_user'@'%' WITH GRANT OPTION; FLUSH PRIVILEGES; -- 验证权限 SHOW GRANTS FOR 'mgr_user'@'%'; EOF # 获取路由器容器IP ROUTER_IP=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mysql-router) # 添加路由器IP到白名单 docker exec mysql-master mysql -uroot -prootpassword <<EOF CREATE USER IF NOT EXISTS 'mgr_user'@'$ROUTER_IP' IDENTIFIED BY 'admin'; GRANT ALL PRIVILEGES ON *.* TO 'mgr_user'@'$ROUTER_IP' WITH GRANT OPTION; FLUSH PRIVILEGES; EOF # 测试连接 docker exec mysql-router \ mysql -hmysql-master -umgr_user -padmin -e "SELECT @@version;" ``` #### 高级调试技巧 ##### 1. 检查 MySQL 服务器日志 ```bash # 查看 MySQL 主服务器日志 docker logs mysql-master | grep -i "access denied" # 检查错误日志 docker exec mysql-master tail -f /var/log/mysql/error.log ``` ##### 2. 网络诊断 ```bash # 检查容器网络 docker network inspect mysql-net # 测试容器间连接 docker run --rm --network mysql-net busybox ping mysql-master docker run --rm --network mysql-net busybox telnet mysql-master 3306 ``` ##### 3. 密码验证 ```bash # 验证密码是否正确 docker run --rm --network mysql-net \ mysql:8.0 mysql -hmysql-master -umgr_user -padmin -e "SELECT 1" ``` ##### 4. 使用 MySQL Shell 配置 InnoDB Cluster ```bash # 在 MySQL 主服务器上创建集群 docker exec -it mysql-master mysqlsh -uroot -prootpassword -- dba configureInstance('root@localhost:3306', {password: 'rootpassword'}) docker exec -it mysql-master mysqlsh -uroot -prootpassword -- dba createCluster('myCluster', {adoptFromGR: true}) # 添加从节点 docker exec -it mysql-master mysqlsh -uroot -prootpassword -- cluster = dba.getCluster('myCluster') docker exec -it mysql-master mysqlsh -uroot -prootpassword -- cluster.addInstance('mgr_user@mysql-slave1:3306', {password: 'admin'}) # 检查集群状态 docker exec -it mysql-master mysqlsh -uroot -prootpassword -- cluster.status() ``` #### 安全增强配置 ```bash # 创建专用路由器用户 docker exec mysql-master mysql -uroot -prootpassword <<EOF CREATE USER 'router_user'@'%' IDENTIFIED BY 'router_password'; GRANT CLONE_ADMIN, CONNECTION_ADMIN, EXECUTE, FILE, GROUP_REPLICATION_ADMIN, PERSIST_RO_VARIABLES_ADMIN, PROCESS, RELOAD, REPLICATION CLIENT, REPLICATION SLAVE, REPLICATION_APPLIER, REPLICATION_SLAVE_ADMIN, ROLE_ADMIN, SELECT, SHUTDOWN, SUPER, SYSTEM_USER, SYSTEM_VARIABLES_ADMIN ON *.* TO 'router_user'@'%'; FLUSH PRIVILEGES; EOF # 使用专用用户运行路由器 docker run --name mysql-router \ --network mysql-net \ -v /use01/docker/mysqlrouter:/etc/mysqlrouter \ -e MYSQL_HOST=mysql-master \ -e MYSQL_PORT=3306 \ -e MYSQL_USER=router_user \ -e MYSQL_PASSWORD='router_password' \ mysql/mysql-router:8.0.32 \ mysqlrouter \ --bootstrap "router_user:router_password@mysql-master:3306" \ --conf-set-option=DEFAULT.name=router \ --conf-set-option=metadata_cache:Cluster01.bootstrap_server_addresses=mysql-master:3306,mysql-slave1:3306,mysql-slave2:3306 \ --conf-set-option=routing:read_write.bind_port=6446 \ --conf-set-option=routing:read_only.bind_port=6447 \ --conf-set-option=routing:read_write_split.bind_port=6450 \ --force ``` #### 验证连接 ```bash # 测试路由器到主服务器的连接 docker exec mysql-router \ mysql -hmysql-master -umgr_user -padmin -e "SELECT @@server_id" # 检查路由器状态 docker exec mysql-router mysqlrouter --user=mysqlrouter status ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值