前言
背景也是比较简单,阿里云的配置并不是很高,并且需要定期备份到自己家里的电脑上,觉得还是比较麻烦,因此考虑是不是可以搞成数据库主从或者双向同步的形式,这样数据都会在阿里云以及家里都及时同步,也省去了备份的操作。因此研究了下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数据库双向同步