网站首页 > 技术文章 正文
前言
随着MySQL技术发展,通过垂直或水平拆分能够支持相当大的数据量,目前很多公司把SQLServer、Oracledb或其他数据库迁移到MySQL上,迁移数据量很大(数据库已经水平拆分成很多Shard),如何比较所有数据的一致性呢?
问题剖析
- 数据库迁移步骤:双写DB -> 数据一致性保证 -> 旧DB读流量逐步迁移到新DB -> 单写新DB -> 下线旧DB。迁移过程中问题很多,本章只给出数据已经同步到Hive,怎么校验Hive数据的一致性,线上一致性会在其他章节中给出。
 - 问题是:迁移地表有成百上千张,如何比较每张表的每个字段的一致性呢?
 
实现思路
- 思路:通过Job生成比较脚本,分发到调度系统,每天调度比较脚本,将比较不一致的结果存放到统计表中,通过报表平台将不一致日报发出,跟踪日报排查不一致问题,将问题反馈给大数据平台,让大数据平台解决不一致。
 - 统计表按天分区再按表分区d='2021-01-01',h=表名。
 - 大数据平台一致性校验可以校验出生产表的不一致和Hive同步的一致,前者需要开发排查解决,后者需要大数据平台解决。
 
- 表主键是orderid。
 
- 表主键不是orderid而是联合主键。
 
- UDF函数将所有业务字段拼接成string用于比较。
 
常见问题
- 时间日期类型Date、DateTime、Timestamp字段,SQL Server毫秒精度只到0,3,7结尾和MySQL不一致,需要对该类型截取处理,特别是业务字段是这样的类型是按需截取。
 - Float,Double字段存在精度问题,如果两边不一致需要通过CAST函数转换后再比较。
 - 对于带小数的字段,因SQL Server和MySQL报错的小数位不同,需要截取掉小数末尾的0后再比较。
 - SQL Server的xml类型和MySQL的text类型存储了xml数据时前会将xml头(<?xml version="1.0"?>)去掉,要单独处理。
 - 因两边数据同步时差,应排除掉当天的增量数据。
 - 特殊Case处理:忽略非业务字段,非严格字段导致截取的字段。
 
附UDF函数
import org.apache.hadoop.hive.ql.exec.UDF;
/**
 * @Description:全量字段拼接
 */
public class JointFieldsUdf extends UDF {
    public String evaluate(String... fields) {
        StringBuffer sb = new StringBuffer();
        for (String item : fields) {
            if (item != null) {
                //去掉含小数点数字末尾的零
                if (item.indexOf(".") > -1) {
                    sb.append(item.trim().replaceAll("(0)+#34;, "").replaceAll("\\.", "")).append("_");
                } else {
                    sb.append(item.trim()).append("_");
                }
            } else {
                sb.append(item).append("_");
            }
        }
        return sb.toString().substring(0, sb.length() - 1);
    }
}pom
<dependency>
    <groupId>org.apache.hive</groupId>
    <artifactId>hive-exec</artifactId>
    <version>2.2.0</version>
</dependency>好经验分享给你,关注我学知识!
- 上一篇: MySQL调优(mysql常用调优)
 - 下一篇: 数据库的三大范式(数据库的三大范式例题)
 
猜你喜欢
- 2025-09-03 InnoDB 聚集索引和非聚集索引、覆盖索引、回表、索引下推简述
 - 2025-06-10 如何理解Mysql的索引及他们的原理?
 - 2025-06-10 性能测试——测试常见的指标(测试性能指标有哪些)
 - 2025-06-10 mysql中的分区表和合并表详解(一个常见知识点)
 - 2025-06-10 Oracle优化-建立索引(三)(oracle 索引优化)
 - 2025-06-10 MySQL索引解析(联合索引/最左前缀/覆盖索引/索引下推)
 - 2025-06-10 你写的 SQL 查询为什么总是慢?揭秘 MySQL 索引机制与联合索引
 - 2025-06-10 回表、覆盖索引(sqlserver覆盖索引)
 - 2025-06-10 数据库主从复制,读写分离,分库分表,分区详解
 - 2025-06-10 如何在在量化交易程序中高效使用sqlite
 
- 最近发表
 - 
- 聊一下 gRPC 的 C++ 异步编程_grpc 异步流模式
 - [原创首发]安全日志管理中心实战(3)——开源NIDS之suricata部署
 - 超详细手把手搭建在ubuntu系统的FFmpeg环境
 - Nginx运维之路(Docker多段构建新版本并增加第三方模
 - 92.1K小星星,一款开源免费的远程桌面,让你告别付费远程控制!
 - Go 人脸识别教程_piwigo人脸识别
 - 安卓手机安装Termux——搭建移动服务器
 - ubuntu 安装开发环境(c/c++ 15)_ubuntu安装c++编译器
 - Rust开发环境搭建指南:从安装到镜像配置的零坑实践
 - Windows系统安装VirtualBox构造本地Linux开发环境
 
 
- 标签列表
 - 
- cmd/c (90)
 - c++中::是什么意思 (84)
 - 标签用于 (71)
 - 主键只能有一个吗 (77)
 - c#console.writeline不显示 (95)
 - pythoncase语句 (88)
 - es6includes (74)
 - sqlset (76)
 - apt-getinstall-y (100)
 - node_modules怎么生成 (87)
 - chromepost (71)
 - flexdirection (73)
 - c++int转char (80)
 - mysqlany_value (79)
 - static函数和普通函数 (84)
 - el-date-picker开始日期早于结束日期 (76)
 - js判断是否是json字符串 (75)
 - c语言min函数头文件 (77)
 - asynccallback (87)
 - localstorage.removeitem (77)
 - vector线程安全吗 (73)
 - java (73)
 - js数组插入 (83)
 - mac安装java (72)
 - 无效的列索引 (74)
 
 
