Mariadb Replication

此文涉及的是全部数据库的同步,如果只想同步一个或几个数据库,请参照其他文章。

介绍

主从复制是通过重放binlog实现主库数据的异步复制。即当主库执行了一条sql命令,那么在从库同样的执行一遍,从而达到主从复制的效果。在这个过程中,master对数据的写操作记入二进制日志文件中(binlog),生成一个 log dump 线程,用来给从库的 i/o线程传binlog。而从库的i/o线程去请求主库的binlog,并将得到的binlog日志写到中继日志(relaylog)中,从库的sql线程,会读取relaylog文件中的日志,并解析成具体操作,通过主从的操作一致,而达到最终数据一致。

优劣

MariaDB Replication的一主多从的结构,主要目的是实现数据的多点备份(并没有故障自动转移和负载均衡)。

优势

  • 如果让后台读操作连接从数据库,让写操作连接主数据库,能起到读写分离的作用,这个时候多个从数据库可以做负载均衡。
  • 可以在某个从数据库中暂时中断复制进程,来备份数据,从而不影响主数据的对外服务。如果在master上执行备份,需要让master处于只读状态,这也意味这所有的write请求需要阻塞。
  • 主从复制是Mariadb自带的,无需借助第三方。
  • 数据被删除,可以从binlog日志中恢复。
  • 配置较为简单方便。

劣势

  • 从库要从binlog获取数据并重放,存在与主库写入数据的时间延迟,因此从库的数据总是要滞后主库。但并不完全算劣势,某些情况下可以增加延时时间实现撤销操作,不过也可以使用binlog实现。
  • 对主库与从库之间的网络延迟要求较高,若网络延迟太高,将加重上述的滞后,造成最终数据的不一致。
  • 所有主节点挂了,将不能对外提供写服务。

配置

主机方面

编辑文件/etc/my.cnf.d/mariadb-server.cnf ,增加以下内容

[mariadb]
log-bin
server_id=1  # 必须是一个唯一的ID
log-basename=master
binlog-format=mixed

然后重启服务器 systemctl restart mariadb

使用 mysql -uroot -p 打开打开数据库交互命令行,然后创建用于数据交换的用户。

CREATE USER 'replication_user'@'%' IDENTIFIED BY '<此处替换为你想要的密码>';
GRANT REPLICATION SLAVE ON *.* TO 'replication_user'@'%';

锁定表以防此过程中数据被修改。在配置完成前不要关闭上文所打开的mysql交互命令行。

在交互命令行里输入以下内容。

FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;

你将会看到以下输出:

+--------------------+----------+--------------+------------------+
| File               | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+--------------------+----------+--------------+------------------+
| master1-bin.000001 |      568 |              |                  |
+--------------------+----------+--------------+------------------+
  • FilePosition字段记录的是二进制文件的名字和位置。

在表锁定的情况下开始进行数据的迁移,通过mariadb-server.cnf文件的datadir可知数据库文件的位置。

可以使用拷贝文件的方式进行备份,也可以使用mysqldump的方法,后者更慢。

拷贝文件备份

  1. 在Shell( 主机 ) 中输入 mysqladmin -u root -p shutdown关闭数据库
  2. 在Shell( 主机 )中切换到数据库的数据文件目录然后输入 tar -cvf /tmp/mysql-backup.tar .
  3. /tmp/mysql-backup.tar文件迁移到从机服务器上。
  4. 在从机上,将拷贝的文件解压到数据库的数据目录上。方法为:在Shell中切换为数据库的数据目录,然后执行这条命令将之前的打包文件解包tar -xvf /tmp/mysql-backup.tar

MysqlDump备份

  1. 在主机Shell中执行 mysqldump -uroot -p -A --dump-slave > /tmp/mysql-backup.sql
  2. /tmp/mysql-backup.sql 转移到从机相同目录。
  3. 在从机Shell中执行 mysql -uroot -p < /tmp/mysql-backup.sql

从机方面

编辑文件/etc/my.cnf.d/mariadb-server.cnf ,增加以下内容

[mariadb]
server-id=2     # 唯一ID,可以设置为1到2^32-1的值
read_only=1     # 设置Slave库只读

然后重启MariaDB服务

mysqladmin -u root -p shutdown
systemctl start mariadb

通过mysql -uroot -p 进入数据库交互命令行,输入以下命令:

<记录文件的文件名><记录文件的文件位置>可以在主服务器通过 show master status; 获取

CHANGE MASTER TO
MASTER_HOST='<你的主服务器的地址>',
MASTER_USER='replication',
MASTER_PASSWORD='<上文你设置的密码>',
MASTER_LOG_FILE='<记录文件的文件名>',
MASTER_LOG_POS=<记录文件的文件位置>;
start slave;
show slave status\G

如果输出了,

Slave_IO_Running: Yes
Slave_SQL_Running: Yes

代表配置成功了,如果不全是Yes,说明某个步骤错误了。


其他问题

错误

Error: 1062 Duplicate entry

有可能会遇到1062错误,需要手动解决,遇到这个错误后服务器会停止复制操作。

mysql> set global sql_slave_skip_counter = 1;
mysql> start slave;

或者在/etc/my.cnf.d/mariadb-server.cnf 设置

slave-skip-errors=1062

注意事项

日志

数据库服务器上的二进制文件会越来越多,清理是必要的。通过设置自动清理可以清理过期的binlog.

mysql> show variables like 'expire_logs_days';

这个值默认是0,就是不进行自动清理。以下命令将值设置为7天。

mysql> set global expire_logs_days=7;
mysql> flush logs;

除了自动清理之外还可以使用手动删除。

mysql> purge binary logs to 'bin.000001'; # 将bin.000001之前的binlog清除
mysql> purge binary logs before '2021-06-15 13:09:51'; # 将指定时间之前的binlog清除

参考

MariaDB setting-up-replication

Mysql Dump

Mysql replication-options

Mysql purge-binary-logs