基于xtrabackup的主从同步
基于xtrabackup的主从同步
作者 |
刘畅 |
时间 |
2020-9-21 |
服务器版本:CentOS Linux release 7.5.1804
主机名 |
ip地址 |
服务器配置 |
安装软件 |
密码 |
mysql01 |
172.16.1.151 |
2核/2G/60G |
01 mysql5.7.31(二进制版),主节点。 02 percona-xtrabackup |
|
mysql02 |
172.16.1.152 |
2核/2G/60G |
01 mysql5.7.31(二进制版),未初始化的空库,从节点。 02 percona-xtrabackup |
|
目录
1 基于gtid方式增加从库
1.1 前提条件#
1 主库(172.16.1.151)my.cnf配置文件
# cat /etc/my.cnf
[client]
port = 3306
default-character-set = utf8
socket = /usr/local/mysql/data/mysql.sock
[mysql]
no-auto-rehash
[mysqld]
user = mysql
port = 3306
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
socket = /usr/local/mysql/data/mysql.sock
bind-address = 0.0.0.0
pid-file = /usr/local/mysql/data/mysqld.pid
character-set-server = utf8
collation-server = utf8_general_ci
log-error = /usr/local/mysql/data/mysqld.log
slow_query_log = ON
long_query_time = 2
slow_query_log_file = /usr/local/mysql/data/mysql-slow.log
max_connections = 10240
open_files_limit = 65535
innodb_buffer_pool_size = 1G
innodb_flush_log_at_trx_commit = 2
innodb_log_file_size = 256M
transaction_isolation = READ-COMMITTE
default-storage-engine = innodb
innodb_file_per_table = on
symbolic-links = 0
explicit_defaults_for_timestamp = 1
skip-name-resolve
lower_case_table_names = 1
server-id = 1
log-bin = /usr/local/mysql/data/mysql-bin
binlog_cache_size = 4M
binlog_format = mixed
max_binlog_cache_size = 8M
max_binlog_size = 512M
expire_logs_days = 14
gtid_mode = ON
enforce_gtid_consistency = ON
[mysqldump]
quick
max_allowed_packet = 32M
创建mysql用户
# groupadd -g 1600 mysql
# useradd -g mysql -u 1600 -M -s /sbin/nologin mysql
# id mysql
uid=1600(mysql) gid=1600(mysql) 组=1600(mysql)
初始化mysql数据库
# /usr/local/mysql/bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
修改数据库密码
# grep 'temporary password' /usr/local/mysql/data/mysqld.log
2020-09-03T15:36:48.970741Z 1 [Note] A temporary password is generated for root@localhost: Kf;Aj:zNk7&3
# mysql -uroot -p'Kf;Aj:zNk7&3'
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'mysql5.7@2021';
mysql> exit;
创建复制账户
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' IDENTIFIED BY 'repl@2020';
# cat /etc/my.cnf
[client]
port = 3306
default-character-set = utf8
socket = /usr/local/mysql/data/mysql.sock
[mysql]
no-auto-rehash
[mysqld]
user = mysql
port = 3306
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
socket = /usr/local/mysql/data/mysql.sock
bind-address = 0.0.0.0
pid-file = /usr/local/mysql/data/mysqld.pid
character-set-server = utf8
collation-server = utf8_general_ci
log-error = /usr/local/mysql/data/mysqld.log
slow_query_log = ON
long_query_time = 2
slow_query_log_file = /usr/local/mysql/data/mysql-slow.log
max_connections = 10240
open_files_limit = 65535
innodb_buffer_pool_size = 1G
innodb_flush_log_at_trx_commit = 2
innodb_log_file_size = 256M
transaction_isolation = READ-COMMITTE
default-storage-engine = innodb
innodb_file_per_table = on
symbolic-links = 0
explicit_defaults_for_timestamp = 1
skip-name-resolve
lower_case_table_names = 1
server-id = 2
slave-skip-errors=1007,1022,1050,1062,1169
relay-log=/usr/local/mysql/data/relay-log
max_relay_log_size=512M
relay-log-purge=ON
read-only
gtid_mode = ON
enforce_gtid_consistency = ON
[mysqldump]
quick
max_allowed_packet = 32M
# groupadd -g 1600 mysql
# useradd -g mysql -u 1600 -M -s /sbin/nologin mysql
# id mysql
uid=1600(mysql) gid=1600(mysql) 组=1600(mysql)
# cat /usr/lib/systemd/system/mysqld.service
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
Type=forking
PIDFile=/usr/local/mysql/data/mysqld.pid
TimeoutSec=0
PermissionsStartOnly=true
# ExecStartPre=/usr/local/mysql/bin/mysqld_pre_systemd
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf --daemonize --pid-file=/usr/local/mysql/data/mysqld.pid $MYSQLD_OPTS
EnvironmentFile=-/etc/sysconfig/mysql
LimitNOFILE = 65535
Restart=on-failure
RestartPreventExitStatus=1
PrivateTmp=false
1.2 主库操作(172.16.1.151)#
1 登录主库创建库、表、数据
mysql> create database test;
mysql> use test;
mysql> create table user (name varchar(50));
mysql> insert into user(name) values("zhangsan");
mysql> show global variables like "%gtid%";
# mkdir -p /mysql_backup/
# innobackupex -uroot -p"mysql5.7@2021" --stream=tar /mysql_backup/ 2>/dev/null |gzip >/mysql_backup/`date +%F_%H-%M-%S`.tar.gz
# du -sh /mysql_backup/2020-10-21_14-07-57.tar.gz
580K /mysql_backup/2020-10-21_14-07-57.tar.gz
3 将备份的主库发送到从库
# scp -rp /mysql_backup/2020-10-21_14-07-57.tar.gz root@172.16.1.152:/tmp/
1.3 从库操作(172.16.1.152)#
1 解压主库备份
# mkdir -p /tmp/mysql_data/
# cd /tmp/mysql_data/
# tar -xzf /tmp/2020-10-21_14-07-57.tar.gz
# ls -l
2 回滚事务日志
# innobackupex --apply-log --redo-only /tmp/mysql_data/
3 完全还原备份库
# innobackupex --defaults-file=/etc/my.cnf --copy-back /tmp/mysql_data/
# ls -l --full-time /usr/local/mysql/data/
4 查看主库的binlog_pos点
# cat /usr/local/mysql/data/xtrabackup_info
binlog_pos = filename 'mysql-bin.000003', position '750', GTID of the last change '994634a3-f6fc-11ea-a9d8-000c290fbdd4:1-5'
5 启动从数据库
# chown -R mysql.mysql /usr/local/mysql/
# systemctl start mysqld
# cat /usr/local/mysql/data/auto.cnf
[auto]
server-uuid=6651dc51-1366-11eb-a67e-000c29c5b550
6 设置已执行过的gtid
# mysql -uroot -p'mysql5.7@2021'
mysql> reset slave;
# 清空从节点信息
mysql> reset master;
# 清空mysql.gtid_executed表信息
mysql> SET GLOBAL GTID_PURGED='994634a3-f6fc-11ea-a9d8-000c290fbdd4:1-5';
# 设置已执行过的gtid
mysql> show global variables like "%gtid%";
mysql> select * from mysql.gtid_executed;
7 配置连接主库信息
# mysql> CHANGE MASTER TO
MASTER_HOST='172.16.1.151',
MASTER_PORT=3306,
MASTER_USER='repl',
MASTER_PASSWORD='repl@2020',
MASTER_AUTO_POSITION=1;
8 启动主从复制
mysql> start slave;
mysql> show slave status\G;
1.4 补充#
1 mysql.gtid_executed表
GTID持久化的介质,MySQL启动阶段会读取这个表来获取gtid_executed变量的值。mysql.gtid_executed表修改时机为在BINLOG发生切换的时候保存,直到上一个BINLOG文件
执行过的全部GTID,它不是实时更新的。
2 gtid_executed变量
MySQL数据库已经执行了哪些GTID事务,处于内存中。show slave status中的executed_gtid_set也取自这里。
3 gtid_purged变量
由于BINLOG文件的删除(如purge binary logfiles或者超过expire_logs_days设置)已经丢失的GTID事务,同时在搭建备库的我们使用set global gtid_purged变量来提示MySQL哪些GTID事务我已经执行过了。
4 通过percona-xtrabackup备份库,备份的是数据库及库中的表文件,其它文件不会备份(例如:主库的binlog文件,从库的relay-log、master.info文件),当启动数据库时根据my.cnf文件再生成相应的文件。
2 基于传统二进制增加从库
2.1 前提条件#
1 主库(172.16.1.151)my.cnf配置文件
# cat /etc/my.cnf
[client]
port = 3306
default-character-set = utf8
socket = /usr/local/mysql/data/mysql.sock
[mysql]
no-auto-rehash
[mysqld]
user = mysql
port = 3306
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
socket = /usr/local/mysql/data/mysql.sock
bind-address = 0.0.0.0
pid-file = /usr/local/mysql/data/mysqld.pid
character-set-server = utf8
collation-server = utf8_general_ci
log-error = /usr/local/mysql/data/mysqld.log
slow_query_log = ON
long_query_time = 2
slow_query_log_file = /usr/local/mysql/data/mysql-slow.log
max_connections = 10240
open_files_limit = 65535
innodb_buffer_pool_size = 1G
innodb_flush_log_at_trx_commit = 2
innodb_log_file_size = 256M
transaction_isolation = READ-COMMITTE
default-storage-engine = innodb
innodb_file_per_table = on
symbolic-links = 0
explicit_defaults_for_timestamp = 1
skip-name-resolve
lower_case_table_names = 1
server-id = 1
log-bin = /usr/local/mysql/data/mysql-bin
binlog_cache_size = 4M
binlog_format = mixed
max_binlog_cache_size = 8M
max_binlog_size = 512M
expire_logs_days = 14
[mysqldump]
quick
max_allowed_packet = 32M
创建mysql用户
# groupadd -g 1600 mysql
# useradd -g mysql -u 1600 -M -s /sbin/nologin mysql
# id mysql
uid=1600(mysql) gid=1600(mysql) 组=1600(mysql)
初始化mysql数据库
# /usr/local/mysql/bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
修改数据库密码
# grep 'temporary password' /usr/local/mysql/data/mysqld.log
2020-09-03T15:36:48.970741Z 1 [Note] A temporary password is generated for root@localhost: Kf;Aj:zNk7&3
# mysql -uroot -p'Kf;Aj:zNk7&3'
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'mysql5.7@2021';
mysql> exit;
创建复制账户
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' IDENTIFIED BY 'repl@2020';
mysql> flush privileges;
2 从库(172.16.1.152)my.cnf配置文件
# cat /etc/my.cnf
[client]
port = 3306
default-character-set = utf8
socket = /usr/local/mysql/data/mysql.sock
[mysql]
no-auto-rehash
[mysqld]
user = mysql
port = 3306
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
socket = /usr/local/mysql/data/mysql.sock
bind-address = 0.0.0.0
pid-file = /usr/local/mysql/data/mysqld.pid
character-set-server = utf8
collation-server = utf8_general_ci
log-error = /usr/local/mysql/data/mysqld.log
slow_query_log = ON
long_query_time = 2
slow_query_log_file = /usr/local/mysql/data/mysql-slow.log
max_connections = 10240
open_files_limit = 65535
innodb_buffer_pool_size = 1G
innodb_flush_log_at_trx_commit = 2
innodb_log_file_size = 256M
transaction_isolation = READ-COMMITTE
default-storage-engine = innodb
innodb_file_per_table = on
symbolic-links = 0
explicit_defaults_for_timestamp = 1
skip-name-resolve
lower_case_table_names = 1
server-id = 2
slave-skip-errors=1007,1022,1050,1062,1169
relay-log=/usr/local/mysql/data/relay-log
max_relay_log_size=512M
relay-log-purge=ON
read-only
[mysqldump]
quick
max_allowed_packet = 32M
创建mysql 用户
# groupadd -g 1600 mysql
# useradd -g mysql -u 1600 -M -s /sbin/nologin mysql
# id mysql
uid=1600(mysql) gid=1600(mysql) 组=1600(mysql)
3 mysqld.service
# cat /usr/lib/systemd/system/mysqld.service
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
Type=forking
PIDFile=/usr/local/mysql/data/mysqld.pid
TimeoutSec=0
PermissionsStartOnly=true
# ExecStartPre=/usr/local/mysql/bin/mysqld_pre_systemd
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf --daemonize --pid-file=/usr/local/mysql/data/mysqld.pid $MYSQLD_OPTS
EnvironmentFile=-/etc/sysconfig/mysql
LimitNOFILE = 65535
Restart=on-failure
RestartPreventExitStatus=1
PrivateTmp=false
2.2 主库操作(172.16.1.151)#
1 登录主库创建库、表、数据
mysql> reset master;
# 因为在上面我修改了root密码、创建了用于主从复制的'repl'@'%'用户,并刷新了
# 权限表,这些操作的pos点都被记录了下来,为了下面实验一致,我将binlog日
# 志重置,从重新开始。
mysql> create database test;
mysql> use test;
mysql> create table user (name varchar(50));
mysql> insert into user(name) values("zhangsan");
mysql> show master status;
2 使用xtrabackup在线备份主库
# mkdir -p /mysql_backup/
# innobackupex -uroot -p"mysql5.7@2021" --stream=tar /mysql_backup/ 2>/dev/null |gzip >/mysql_backup/`date +%F_%H-%M-%S`.tar.gz
# du -sh /mysql_backup/2020-10-21_16-23-39.tar.gz
580K /mysql_backup/2020-10-21_16-23-39.tar.gz
3 将备份的主库发送到从库
# scp -rp /mysql_backup/2020-10-21_16-23-39.tar.gz root@172.16.1.152:/tmp/
2.3 从库操作(172.16.1.152)#
1 解压主库备份
# mkdir -p /tmp/mysql_data/
# cd /tmp/mysql_data/
# tar -xzf /tmp/2020-10-21_16-23-39.tar.gz
# ls -l --full-time
2 回滚事务日志
# innobackupex --apply-log --redo-only /tmp/mysql_data/
3 完全还原备份库
# innobackupex --defaults-file=/etc/my.cnf --copy-back /tmp/mysql_data/
# ls -l --full-time /usr/local/mysql/data/
4 查看主库的binlog_pos点
# cat /usr/local/mysql/data/xtrabackup_info
binlog_pos = filename 'mysql-bin.000001', position '750'
5 启动从数据库
# chown -R mysql.mysql /usr/local/mysql/
# systemctl start mysqld
# cat /usr/local/mysql/data/auto.cnf
[auto]
server-uuid=6651dc51-1366-11eb-a67e-000c29c5b550
6 清空主库信息
# mysql -uroot -pmysql5.7@2021
mysql> reset slave;
# 清空从节点信息
mysql> reset master;
# 清空mysql.gtid_executed表信息
7 配置连接主库信息
# mysql> CHANGE MASTER TO
MASTER_HOST='172.16.1.151',
MASTER_PORT=3306,
MASTER_USER='repl',
MASTER_PASSWORD='repl@2020',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=750;
8 启动主从复制
mysql> start slave;
mysql> show slave status\G;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏