数据同步与订阅机制在异构系统中的应用
什么是数据同步与订阅
两个数据源之间的数据实时同步和根据自身业务需求自由消费增量数据.
应用场景
- 缓存更新策略
- 本地数据灾备
- 业务异步解耦
- 异地多活
- 数据异地灾备
- 数据异地多活
- 跨境数据同步
- 查询与报表分流
- 实时数据仓库
- 异构数据源数据实时同步
优势
- 业务解耦
- 高性能
- 安全可靠
- 实时性
原理
基于数据库的日志,解析数据库的日志来做数据同步和订阅
MySQL中有六种日志文件
- 重做日志(redo log)
- 回滚日志(undo log)
- 二进制日志(binlog)
- 错误日志(errorlog)
- 慢查询日志(slow query log)
- 一般查询日志(general log)
- 中继日志(relay log)
Undo + Redo事务的特点
- 为了保证持久性,必须在事务提交前将Redo Log持久化。
- 数据不需要在事务提交前写入磁盘,而是缓存在内存中。
- Redo Log 保证事务的持久性。
- Undo Log 保证事务的原子性。
- 有一个隐含的特点,数据必须要晚于redo log写入持久存储。
mysql演示binlog日志
- docker启动mysql数据库
# 默认启动目录下的docker-compose.yml文件 sudo docker-compose up -d
- 查看数据库中的各种日志文件
# 进入容器 sudo docker exec -ti 容器id /bin/sh # 进入mysql数据目录 cd /var/lib/mysql # 日志文件 ib_logfile0-->redo ibdata1-->undo mysql-bin.000001-->binlog # 查看binlog信息 show master logs; show binlog events in 'mysql-bin.000001'; # 重新开启一个binlog文件 flush logs;
- 演示远程binlog复制和查看binlog(可以物理备份binlog文件)
# docker中的mysql做远程数据库,配置可以访问 grant all privileges on *.* to root@'%' identified by 'root'; flush privileges; # 在本地机器做数据复制 /usr/local/mysql/bin/mysqlbinlog --read-from-remote-server --raw --host=127.0.0.1 --port=3307 --user=root --password --stop-never --result-file=./ mysql-bin.000001 # 查看binlog日志 /usr/local/mysql/bin/mysqlbinlog --no-defaults --base64-output="decode-rows" -v mysql-bin.000001 # 使用本地binlog日志进行数据恢复 /usr/local/mysql/bin/mysqlbinlog mysql-bin.000001 | mysql -h 127.0.0.1 -uroot -p -P3307 user
postgres演示
pg数据库之间逻辑订阅
- 发布端配置(表info初始化的时候自动生成)
# 启动服务
# 进入发布端容器
sudo docker exec -ti 发布端容器ID /bin/bash
# 进入数据库
psql -U postgres
# 创建发布(针对表info)
test=# create publication testpub1 for table info;
CREATE PUBLICATION
# 查看数据库有那些发布
test=# select * from pg_publication;
pubname | pubowner | puballtables | pubinsert | pubupdate | pubdelete | pubtruncate
----------+----------+--------------+-----------+-----------+-----------+-------------
testpub1 | 10 | f | t | t | t | t
(1 row)
# 查看发布端的信息
select * from pg_stat_replication;
select * from pg_replication_slots;
- 订阅端配置(表info初始化的时候自动生成) 订阅端配置参数
# 进入订阅端
# 创建订阅端
create subscription testsub1 connection 'host=postgres-send port=5432 user=postgres dbname=test password=meng' publication testpub1 with (enabled, create_slot, slot_name='sub1_from_pub1');
# 查看订阅者信息
select * from pg_subscription;
select * from pg_stat_subscription;
- 同步数据
# 查看数据
select * from info;
# 发布端插入数据
insert into info(name) values('test01');
# 订阅端查看数据
select * from info;
- 冲突的解决方法
1.修改订阅端的数据,删除照成冲突的主键,执行
ALTER SUBSCRIPTION testsub1 ENABLE
继续
辅助命令
# 删除全部容器
sudo docker ps -a | awk '{print $1}' | xargs sudo docker rm
# 删除全部数据卷
sudo docker volume ls | awk '{ print $2 }' | xargs sudo docker volume rm