作者:杨涛涛
资深数据库专家,专研 MySQL 十余年。善于 MySQL、PostgreSQL、MongoDB 等开源数据库相干的备份复原、SQL 调优、监控运维、高可用架构设计等。目前任职于爱可生,为各大运营商及银行金融企业提供 MySQL 相干技术支持、MySQL 相干课程培训等工作。
本文起源:原创投稿
*爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。
特分享进去最近在整顿 MySQL 热备工具的试验题目时遇到的 REDO 日志归档问题!
MySQL 的 REDO 日志归档性能在 8.0.17 版本后公布,目标是为了解决应用 MySQL 热备工具比方 mysqlbackup 、xtrabackup 等备份 REDO 日志的速度慢于业务生成 REDO 日志的速度而导致的备份数据不统一问题(未及时备份的 RRDO 日志被提前笼罩写入!)。
MySQL的 REDO 日志归档性能开启非常简单,只需对参数innodb_redo_log_archive_dirs简略设置即可。
set persist innodb_redo_log_archive_dirs='redo_archive1:/redo_mysql/3306'
其中 redo_archive1 是一个标签,能够轻易起名字;/redo_mysql/3306 用来指定REDO 日志归档寄存的地位。
我在应用的过程中,遇到几个细节问题:
1. REDO 日志归档的目录权限、属主等肯定要设置正确,要不然可能会有以下几种谬误输入 (MySQL 客户端提醒谬误,热备工具可能提醒正告!):
谬误1:ERROR 3844 (HY000): Redo log archive directory '/redo_mysql/3306' does not exist or is not a directory
后期须要创立的目录与相干权限设定如下:
# 归档目录得提前建![root@ytt-pc ~]# mkdir -p /redo_mysql/3306 # 设置归档目录拜访权限,只容许属主齐全拜访。[root@ytt-pc ~]# chmod -R 700 /redo_mysql/3306/
接下来应用MySQL管理员用户或者具备system_variables_admin权限的用户来在线设置此变量:
# 设置变量<mysql:8.0.32:(none)>set persist innodb_redo_log_archive_dirs='redo_archive1:/redo_mysql/3306';Query OK, 0 rows affected (0.01 sec) # 查看变量<mysql:8.0.32:(none)>show variables like 'innodb_redo_log_archive_dirs';+------------------------------+--------------------------------+| Variable_name | Value |+------------------------------+--------------------------------+| innodb_redo_log_archive_dirs | redo_archive1:/redo_mysql/3306 |+------------------------------+--------------------------------+1 row in set (0.00 sec)
应用mysqlbackup来发动一个备份:
[root@ytt-pc /]# mysqlbackup --defaults-file=/etc/my.cnf --defaults-group-suffix=@3306 --login-path=backup_pass2 --backup-dir=/tmp/full --show-progress backup #备份实现后,有一个正告:mysqlbackup completed OK! with 1 warnings #往前翻此正告:这里是具体内容!。230329 13:43:48 MAIN WARNING: MySQL query 'DO innodb_redo_log_archive_start('redo_archive1','16800686281315958');': 3844, Redo log archive directory '/redo_mysql/3306/16800686281315958' does not exist or is not a directory
谬误1是因为拜访归档目录的属主不具备写权限,修复谬误1:确认运行MySQL实例的OS用户为 ytt。
[root@ytt-pc 3306]# ps aux | grep mysqldytt 4625 1.0 4.5 1800264 373112 ? Ssl 12:47 0:00 /usr/sbin/mysqld --defaults-group-suffix=@3306
给/redo_mysql/3306 设置属于OS用户ytt的权限:谬误1被修复。
[root@ytt-pc /]# chown -R ytt.ytt /redo_mysql
此时应用mysqlbackup 从新发动一个热备,会产生一个新的错误代码, 咱们把它命名为谬误2。
谬误2:其实是一个正告!依据错误代码内容,提醒为无权限操作此目录(OS errno: 13 - Permission denied)。
230329 13:48:10 MAIN WARNING: MySQL query 'DO innodb_redo_log_archive_start('redo_archive1','16800688906187002');': 3847, Cannot create redo log archive file '/redo_mysql/3306/16800688906187002/archive.01132dcf-cde1-11ed-971f-0800272d8a05.000001.log' (OS errno: 13 - Permission denied)
问题产生的起因是调用mysqlbackup的OS用户不具备归档日志目录的写权限,必须应用对应的OS用户来调用mysqlbackup。
以下是解决办法和被动验证步骤。
# 解决办法:须要切换到此目录OS属主用户: [root@ytt-pc tmp]# su ytt[ytt@ytt-pc tmp]$ mysqlbackup --defaults-file=/etc/my.cnf --defaults-group-suffix=@3306 --login-path=backup_pass2 --backup-dir=/tmp/full backup # 备份实现,无报错: mysqlbackup completed OK! # 摘取其中归档日志的信息如下: 230329 14:46:00 MAIN INFO: Creating monitor for redo archive.230329 14:46:00 MAIN INFO: Started redo log archiving. # 对应的MySQL 日志内容为:mysqlbackup 备份过程中调用零碎函数innodb_redo_log_archive_start来激活 REDO 日志归档,调用零碎函数innodb_redo_log_archive_stop来敞开 REDO 日志归档。 这里do是MySQL一个特有的语法,只执行不输入,有点相似其余数据库的perform语句。 2023-03-29T06:46:00.553205Z 47 Query SELECT @@GLOBAL.innodb_redo_log_archive_dirs2023-03-29T06:46:00.553389Z 47 Query DO innodb_redo_log_archive_start('redo_archive1','16800723605224011').. 2023-03-29T06:46:03.895591Z 47 Query DO innodb_redo_log_archive_stop()
2. 用于 REDO 日志归档的 MySQL 用户必须有 innodb_redo_log_archive 权限。
<mysql:8.0.32:(none)>show grants for backup_user2\G...*************************** 2. row ***************************Grants for backup_user2@%: GRANT BACKUP_ADMIN,ENCRYPTION_KEY_ADMIN,INNODB_REDO_LOG_ARCHIVE,SYSTEM_VARIABLES_ADMIN ON *.* TO `backup_user2`@`%`...5 rows in set (0.00 sec)
3. REDO 日志归档性能除了应用热备工具来调用外,也能够间接在 MySQL 客户端来调用。
[ytt@ytt-pc ~]$ mysql --login-path=backup_pass2Welcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id is 41Server version: 8.0.32 MySQL Community Server - GPL ... Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. <mysql:8.0.32:(none)>DO innodb_redo_log_archive_start('redo_archive1','20230329');Query OK, 0 rows affected (0.02 sec)
对应的归档日志:
[ytt@ytt-pc 20230329]$ pwd/redo_mysql/3306/20230329[ytt@ytt-pc 20230329]$ du -sh archive.01132dcf-cde1-11ed-971f-0800272d8a05.000001.log 4.0K archive.01132dcf-cde1-11ed-971f-0800272d8a05.000001.log
期间造点数据,能够看到归档日志的大小变动:由4K增长到128M
[ytt@ytt-pc 20230329]$ du -sh archive.01132dcf-cde1-11ed-971f-0800272d8a05.000001.log 128M archive.01132dcf-cde1-11ed-971f-0800272d8a05.000001.log