MariaDB数据库双向同步

前言

背景也是比较简单,阿里云的配置并不是很高,并且需要定期备份到自己家里的电脑上,觉得还是比较麻烦,因此考虑是不是可以搞成数据库主从或者双向同步的形式,这样数据都会在阿里云以及家里都及时同步,也省去了备份的操作。因此研究了下MariaDB的双向同步(由于我阿里云已经使用比较久了,用的是MySQL5.7,而家里的电脑后来是装的Debian,安装的MariaDB 10,结果是MySQL 5.7作为slave可以同步数据到MariaDB 10的master上,但是MariaDB 10作为slave则不能同步到MySQL 5.7上,因此做双向同步,版本一定要统一,至少大版本一定要统一;后来我就统一使用MariaDB了)。

主从配置

其实双向同步就是互为主从。因此只要配置一遍主从,那么双向就是把主从反过来再配置即可。由于家里的电脑是没有公网IP的,因此使用反向代理将相关服务都映射到主机本地端口上。因此网络拓扑如下:

拓扑图
  • 家里和阿里云各有一个数据库。
  • 手动处理下,将两个数据库的内容搞定为统一的内容,防止出现一些操作导致数据同步异常
    • 这个很重要,如果不同步导致binlog消费异常,则会导致同步异常中断,需要人工介入。
    • 由于我这里DB1是空的数据,所以处理起来很简单,只要把DB2的dump出来后,DB1上导入即可。
  • 由于家里没有公网IP,因此需要借助内网穿透的形式。
    • 将家里的数据库映射到阿里云的3316端口
    • 同样,将阿里云的数据库端口也映射到家里的3316端口
    • 以上使用frp来做双向穿透,下次有空再说说frp如何实现双向穿透。
  • 因此,我们需要做的就是将3306端口作为master,而3316作为slave。

以家里为master,阿里云为slave做一个配置说明。

首先,需要修改家里的DB1配置内容,配置文件为/etc/mysql/mariadb.conf.d/50-server.cnf

server-id              = 1
log_bin                = /var/log/mysql/mysql-bin.log
expire_logs_days       = 10
max_binlog_size        = 100M
binlog_do_db           = sync_db

binlog_do_db 配置只同步的数据库名称,如果有多个数据库表,则可以配置多行。也可以配置binlog_ignore_db,根据自己的实际情况配置吧,我这里只同步一个数据库。

同样,我们也需要修改阿里云上的DB2配置,只不过server-id = 2

接下来,获取DB1作为master的状态,命令为:

show master status;

+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |  256     | sync_db      |                  |
+------------------+----------+--------------+------------------+

记录下,DB1作为master的内容。接下来,需要创建用于同步的账号slave(账号名可以自己定义,master-slave统一即可):

GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%' IDENTIFIED BY 'your_slave_passwd';
flush privileges;

执行同步的时候,为了防止数据库变动,最好是将数据库锁定读写。接下来则需要操作DB2作为slave的配置了。首先,在DB2上确认可以通过3316连接到DB1上,使用上面的slave账号:

mysql -uslave -pyour_slave_passwd -hlocalhost -P3316

如果可以连接成功,那么说明对应配置没有问题。才能往下执行相关的配置。

CHANGE MASTER TO
MASTER_HOST='localhost',
MASTER_PORT=3316,
MASTER_USER='slave',
MASTER_PASSWORD='your_slave_passwd',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=256;

MASTER_LOG_FILE对应刚才在DB1上查询的file项, MASTER_LOG_POS 对应position项。执行成功后,可以执行以下命令来启动slave:

start slave;
show slave status \G;

如果出现问题,需要重新调整,那么需要stop后,reset则可以重新执行CHANGE MASTER TO的相关命令:

stop slave;
reset slave;

如果你执行 show slave status \G;命令的结果显示是:

Slave_IO_State: Waiting for master to send event
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

如果slave上的状态Slave_IO_Running: No,一般是与master的binlog消费没有对齐,这时候并不需要重新reset,只要停用slave后,change相关的logfile及pos:

# 先在master上获取对应的logfile及pos
show master status;
# 然后slave上根据master的信息,执行操作
stop slave;
change master to Master_Log_File='mysql-bin.000031',Master_Log_Pos=342;
start slave;

那么一般主从的同步就算成功了。同时,可以在DB1上执行命令:

show slave hosts;
+-----------+-----------+------+-----------+
| Server_id | Host      | Port | Master_id |
+-----------+-----------+------+-----------+
|         2 | localhost | 3306 |         1 |
+-----------+-----------+------+-----------+

那么说明DB2(server-id=2)已经成功作为DB1的slave了。接下来则反向操作。则可以实现双向同步。都执行成功后,可以做以下的操作,来简单验证是否双向同步:

  • 在DB1的sync_db创建一个表
  • 然后在DB2上show table
    • 如果DB2上有对应的表,那么则说明DB1作为master同步DB2成功
    • 如果无对应的表,则可以使用 show slave status \G; 命令看看对应的错误。
  • 在DB2上删除刚才同步过来的表。
  • 在DB1上show table
    • 如果DB1上的表也同步被删除,那么则说明DB2作为master同步DB1成功。
    • 如果对应表还存在,则需要使用show slave status \G; 命令看看对应的错误。

至此,如果都没有问题,那么主从双向配置则可以正常使用了。当然,如果我想要在家里编辑文档并同步到阿里云上,那么还有其他的一些操作是需要同步的,比如图片文件,并非全部同步的形式,因此还需要一些工作来支持一些非数据库的同步,这个可以使用rsync的命令来实现,这就不多说了。

转载请注明: 转载自elkPi.com

本文链接地址: MariaDB数据库双向同步

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Scroll to top