我的一些业务数据库比较大,虽然服务器配置完全满足业务运行,但当用mysqldump备份单个30GB左右的数据库时还是会IO延迟暴增,导致备份期间WEB短暂卡顿或中断。另外就算本地做RAID,再做异地备份,一旦真的RAID扑街你恢复异地备份也会失去备份间隔的数据。

鉴于此做数据库主从同步,从库仅作备份用就是最靠谱的备份方案了,从库的数据是实时的,异地备份也在从库进行,这样就完全不影响主库业务运行又拥有实时的数据备份,主库挂了还能短时间立即切换到从库恢复业务。

MariaDB主库配置my.cnf:

[mysqld]
log-bin=mysql-bin     # 启用二进制日志,mysql-bin是日志文件名前缀
binlog_format=ROW     # 保证数据复制和恢复的最高安全性和可靠性
server-id=1           # 唯一的服务器ID,每台服务器必须不同
gtid-domain-id=1      # 设置主服务器的GTID域ID
bind-address=0.0.0.0  # 允许远程连接,或者指定主服务器的IP地址

创建复制用户并赋予PRIVILEGES权限

CREATE USER 'repl_user'@'%' IDENTIFIED BY 'Password';
GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%';
FLUSH PRIVILEGES;

MariaDB从库配置my.cnf

[mysqld]
server-id=2
gtid-domain-id=1      # 从服务器通常与主服务器使用相同的GTID域ID
#log-bin=mysql-bin    # 可选: 如果从服务器将来可能成为主服务器,建议开启

如果主库存在数据,需要先备份导入从库。

首先登入root用户在数据库全局锁表

FLUSH TABLES WITH READ LOCK; 
如果你的MariaDB中所有数据库和所有表都使用InnoDB存储引擎,那么你可以用下面的mysqldump命令不锁表备份。InnoDB是事务型存储引擎。
--single-transaction 选项会利用InnoDB的事务特性,在备份开始时启动一个事务,从而在事务的隔离级别下创建一个数据快照。这个快照在整个备份过程中保持一致性,即使在备份进行时,数据库有新的写入操作,也不会影响备份的数据一致性。
备份完成后,该事务自动提交。因此,如果全部是InnoDB表,使用 --single-transaction
可以实现完全在线的无锁备份,主服务器的写入业务在备份期间可以持续进行,几乎没有停机时间。

记录当前日志位置

MariaDB [cndba]> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000008 |      401 |              |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

MariaDB [cndba]> SELECT BINLOG_GTID_POS(‘mysql-bin.000008', 401);
+------------------------------------------+
| binlog_gtid_pos('mysql-bin.000008', 401) |
+------------------------------------------+
| 0-2-6                                    |
+------------------------------------------+
1 row in set (0.00 sec)

退出后使用 mysqldump 进行备份(如果已经锁表,mysqldump执行完后会自动执行解锁)

mysqldump -u root -p --flush-logs --master-data=2 --single-transaction --routines --triggers --events --all-databases | gzip > full_backup.sql.gz

在从服务器恢复备份

gunzip < full_backup.sql.gz | mysql -u root -p

如果未锁表备份,则先解压full_backup.sql.gz,查看sql中的准确pot进行数据同步

[root@MariaDB mysql]# cat /tmp/slave.sql |more
-- MySQL dump 10.16  Distrib 10.2.12-MariaDB, for Linux (x86_64)
--
-- Host: localhost    Database: 
-- ------------------------------------------------------
-- Server version    10.2.12-MariaDB-log
……
--
-- Position to start replication or point-in-time recovery from
--
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000007', MASTER_LOG_POS=385;

在从库配置同步

MariaDB [(none)]> change master to master_host='192.168.56.2',master_user='repl_user',master_password='Password',master_log_file='mysql-bin.000007',master_log_pos=385;
Query OK, 0 rows affected (0.03 sec)

启动同步
MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.00 sec)

如果配置错误先停止slave,修改,在启动
MariaDB [(none)]> stop slave;
Query OK, 0 rows affected (0.01 sec)

然后在通过如下2个命令检查同步情况
MariaDB [(none)]> show slave status /G;
MariaDB [(none)]> show processlist;

然后启用GTID同步:
MariaDB [(none)]> stop slave;
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> change master to master_host='192.168.56.2',master_user='repl_user',master_password='Password',master_port=3306,master_use_gtid=slave_pos;
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.01 sec)

MariaDB [(none)]> show slave status /G
……
                   Using_Gtid: Slave_Pos
                  Gtid_IO_Pos: 0-1-5
      Replicate_Do_Domain_Ids: 
  Replicate_Ignore_Domain_Ids: 
                Parallel_Mode: conservative
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
1 row in set (0.00 sec)

如果是锁表备份的,导入备份后登入数据库,先根据备份期间查询的gtid设置GTID,再启动同步

MariaDB [(none)]> set global gtid_slave_pos='0-2-6';
Query OK, 0 rows affected (0.01 sec)

MariaDB [(none)]> change master to master_host='192.168.56.2',master_user='repl_user',master_password='Password',master_port=3306,master_use_gtid=slave_pos;
Query OK, 0 rows affected (0.01 sec)

MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.01 sec)

从服务器状态重置:

STOP SLAVE; #停止复制进程 RESET SLAVE; #清除服务器的复制位置,但保留连接参数(如主机名、用户名等)。 或
RESET SLAVE ALL; #这将清除所有复制信息,包括连接参数。适用于您希望从服务器完全重置的情况。
RESET MASTER; #清空GTID 执行记录

重要参考:https://www.cndba.cn/dave/article/2663

标签: none

添加新评论