如何通过外部表做数据一致性检查和配平
背景
随着微服务和分布式架构的兴起及用户对数据高可用的重视。现在系统中的数据会通过程序定时同步、抽数工具、复制工具等在多个数据库中存在多份。但因为程序异常、网络异常、数据异常等各种原因,会出现数据不一致的情况。如何能简单快速检测出数据不一致并且配平呢?本文通过PostgreSQL的fdw机制,介绍一种简单的配平方法。
环境准备
-
源数据库
- IP:xx.xx.12.11
- PORT:5432
- 版本:PostgreSQL 9.5.5
-
目标库
- IP:xx.xx.12.10
- PORT:5432
- 版本:PostgreSQL 9.5.5
创建代理表
- 第一步,创建远程服务
#假设数据库已经安装了postgres_fdw,未安装可以通过
create server uim_1122 foreign data wrapper postgres_fdw options (host 'xx.xx.12.11',port '5432' ,dbname 'taap');
- 第二步,创建人员映射
create user mapping for sa server uim_1122 options (user 'sa',password '123456')
- 第三步,创建代理模式
create schema db_uim_1122;
- 第四步,导入被代理的表
# 也可以通过create foregin table 手动创建
import foreign schema db_uim limit to (t_aty_user,t_aty_corp) from server uim_1122 into db_uim_1122;
一致性检查
- 检查目标库缺失数据
select u1.c_id from db_uim_1122.t_aty_user u1 where not exists (select * from db_uim.t_aty_user u2 where u1.c_id = u2.c_id);
c_id
-----------
219545603
158072921
(2 rows)
- 检查目标库多数据
select c_id from db_uim.t_aty_user u1 where not exists (select * from db_uim_1122.t_aty_user u2 where u1.c_id = u2.c_id);
c_id
------
(0 rows)
- 检查某些字段是否一致
# 可以手动写SQL检查
# 例如,检查c_id,c_name,c_passoword 不一致:
select c_id from db_uim.t_aty_user u1 where not exists (select * from db_uim_1122.t_aty_user u2 where u1.c_id = u2.c_id and u1.c_name = u2.c_name and u1.c_password = u2.c_password);
数据配平
- 配平缺失数据
insert into db_uim.t_aty_user select u1.* from db_uim_1122.t_aty_user u1 where not exists (select * from db_uim.t_aty_user u2 where u1.c_id = u2.c_id);
- 配平多余数据
delete from db_uim.t_aty_user where c_id in (select c_id from db_uim.t_aty_user u1 where not exists (select * from db_uim_1122.t_aty_user u2 where u1.c_id = u2.c_id))
- 矫正不一致数据
可以依据项目情况,写矫正SQL
总结
对于一些简单的情况,如数据量不是很大,要配平的表不是很多,可以通过数据库自带的外部表机制检测,如PostgreSQL的fdw,Sybase和SqlServer的代理表、Oracle的dblink、MySQL的federated 。当然,最好的方式是通过我司的“数据配平平台”实现!