数据库数据迁移完成后完整性的校验

0    166    2

Tags:

👉 本文共约17166个字,系统预计阅读时间或需65分钟。

数据库数据验证是指对迁移后数据库数据的一致性进行验证。

数据库的迁移大体上可以分为物理全量迁移、物理增量迁移、逻辑全量迁移和逻辑增量迁移。其中,针对数据库物理全量迁移来说,迁移前的源库和迁移后的目标库肯定是一致的。因为物理全量迁移是基于物理文件的冷备迁移,不存在数据的变动,所以,数据库的一致性可以得到保证。

  • 物理冷备全量迁移(例如rman全备、冷备等方式),数据肯定是一致的。

  • 数据校验主要是针对增量迁移和逻辑迁移来说的。

  • 增量迁移对Oracle来说,若增量点不一致,则不能恢复,所以一般也不会丢失数据。

    但是,针对MSSQL从阿里云到华为云做增量恢复碰到过一次数据丢失的情况。

  • 逻辑迁移要有严格的步骤,步骤不报错,基本数据也不丢失。

不过,客户肯定不认啥物理迁移,逻辑迁移、增量还是全量迁移的,只要数据迁移前后数据比对的一个结果。

所以,我们可以从以下几个方面来比对

1,从数据库对象方面上来判断、鉴别

  • 从总数量上来进行判断,看迁移前后,表、视图、存储过程、存储函数、触发器等用户对象的 总数量 能否和源库对应上。
  • 然后 , 再 对各个 表的总记录数做一个count 操作,来比对行数 。
  • 最后,对于视图、存储过程、函数等内容,可以将其DDL语句导出成txt可读文件,再通过文本比对工具进行比对即可。

2,从业务上来判断,把应用程序跑起来,进应用程序界面上,跑一整套流程下来,看看是否正常

3、 对数据库表内容进行比对,一般使用工具或脚本进行比对。

  • Oracle数据库:dbms_comparison包、minus相减法、dbms_utility.get_hash_value计算hash值、 PL/SQL Developer 工具等
  • SQL Server数据库:Visual Studio工具即SQL Server Data Tools (SSDT)、SQLDiff或tablediff.exe工具针对单表比对、Red Gate的SQL Compare工具,需要注意: 对于 SSDT工具来说,需要对比的2个库都必须有主键或唯一键才能进行比对
  • MySQL数据库:用mysqldiff+mysqldbcompare工具


Oracle 数据库

在开发过程中,遇到了需要比对两个数据库是否完全一致。通过PL/SQL可以为我们提供很好的帮助。

方式1:使用 \dbms_comparison包****

官方文档:

DBMS_COMPARISION简介:

​ 这个软件包是oracle提供的可以再两个数据之间做object是比对。并且呢如果在比对过程中如果源端数据和目标端数据不一致,那么可以选择是从源端在将数据复制到目标端,还是从目标端在复制到源端,最终达到数据一致性的结果。该包也是通过创建dblink来实现的。这个工具的使用大体分为四步:

第一步:使用create_compare去创建一个比对动作

第二步:使用compare函数去进行数据对象之间的比对

第三步:我们在去查看比对结果,相应的record会记录到不同视图中如下:

DBA_COMPARISON_SCAN

USER_COMPARISON_SCAN

DBA_COMPARISON_SCAN_VALUES

USER_COMPARISON_SCAN_VALUES

DBA_COMPARISON_ROW_DIF

USER_COMPARISON_ROW_DIF

第四不:如果数据不一致,那么可以使用convert去将数据同步

大家可能会说,如果我进行了两次数据比对,那么如何区分呢,这就是oracle自己会给你设计一个标示了。这个函数是recheck。后续介绍:

还有一个问题,那就是这个包能做哪些数据比对?

答案是:对表、视图、物化视图、同义词等

DBMS_COMPARISION限制:

当然了任何一个工具都有自己的限制,那么这个包呢?

1、对于源端数据库版本必须是高于11.1,对于目标端数据库版本必须高于10.1

2.对于所有比对的数据库对象,必须是共享对象,也就是说每个对象的列个数和列的类型必须一致。如果列不一致,那么需要将比对的列使用column_list做个列表。

Database objects of different types can be compared and converged at different databases. For example, a table at one database and a materialized view at another database can be compared and converged with this package.

以上是说了比较容易理解的限制,下面在说一下索引列的限制:

1、在全库比对模式下,必须要有一个在 number, timestamp, interval, or DATE 数据类型的单一索引列,或是仅仅有一个包括这几种数据类型的复合索引,但是这个复合索引中设计到的列必须都是not null或是其中一列是一个主键列。

2、

For the scan modes CMP_SCAN_MODE_FULL and CMP_SCAN_MODE_CUSTOM to be supported, the database objects must have one of the following types of indexes:

  • A single-column index on a number, timestamp, interval, DATE, VARCHAR2, or CHAR data type column
  • A composite index that only includes number, timestamp, interval, DATE, VARCHAR2, or CHAR columns. Each column in the composite index must either have a NOT NULL constraint or be part of the primary key.

如果数据库没有满足这些要求,那么这个包将无法进行数据比对。

if the database objects have only one index, and it is a composite index that includes a NUMBER column and an NCHAR column, then the DBMS_COMPARISON package does not support them.

If these constraints are not present on a table, then use the index_schema_name and index_name parameters in the CREATE_COMPARISONprocedure to specify an index whose columns satisfy this requirement.

When a single index value identifies both a local row and a remote row, the two rows must be copies of the same row in the replicated tables. In addition, each pair of copies of the same row must always have the same index value.

DBms_comparison不支持的数据类型:

LONG、LANG RAW、ROWID、urowid、clob、nclob、blob、bfile另外还有如下两种:

1、udt(user-defined types,including object types, REFs, varrays, and nested tables)

2、oracle-supplied type (including any types, XML types, spatial types, and media types)


假设你所要进行数据比对的数据库其中有一个版本为11g且该表上有相应的主键索引(primary key index)或者唯一非空索引(unique key &not null)的话,那么恭喜你! 你可以借助11g 新引入的专门做数据对比的PL/SQL Package dbms_comparison来实现数据校验的目的,如以下演示:

以上源端数据库版本为11.2.0.3 , 源表结构为test1(t1 number primary key,t2 varchar2(128),透过dblink链接到版本为10.2.0.1的目标端

目标端版本为10.2.0.1 , 表结构为test2(t1 number primary key,t2 varchar2(128))。

注意这里2张表上均必须有相同的主键索引或者伪主键索引(pseudoprimary key伪主键要求是唯一键且所有的成员列均是非空NOT NULL)。

实际创建comparison对象,并实施校验:

利用dbms_comparison.create_comparison创建comparison后,新建的comparison会出现在user_comparison视图中;

以上我们完成了comparison的创建,但实际的校验仍未发生我们利用10046事件监控这个数据对比过程:

可以看到以上过程中虽然没有避免对TEST1、TEST2表的全表扫描(FULL TABLE SCAN), 但是好在实际参与HASH JOIN FULL OUTER 的仅是访问索引后获得的少量数据,所以效率还是挺高的。

此外可以通过user_comparison_row_dif了解实际那些row存在差异,如:

以上利用dbms_comparison包完成了一次简单的数据比对,该方法适用于11g以上版本且要求表上有主键索引或非空唯一索引, 且不支持以下数据类型字段的比对

  • LONG
  • LONG RAW
  • ROWID
  • UROWID
  • CLOB
  • NCLOB
  • BLOB
  • BFILE
  • User-defined types (including object types, REFs, varrays, and nested tables)
  • Oracle-supplied types (including any types, XML types, spatial types, and media types)

若要比对存有以上类型字段的表,那么需要在create_comparison时指定column_list参数排除掉这些类型的字段。

方法1 dbms_comparison的优势在于可以提供详细的比较信息,且在有适当索引的前提下效率较高。
缺点在于有数据库版本的要求(at least 11gR1), 且也不支持LONG 、CLOB等字段的比较。

方式2:

利用minus Query 对比数据

这可以说是操作上最简单的一种方法,如:

MINUS Clause会导致2张表均在本地被全表扫描(TABLE FULL SCAN),且要求发生SORT排序。 若所对比的表上有大量的数据,那么排序的代价将会是非常大的, 因此这种方法的效率不高。

方式2 MINUS的优点在于操作简便,特别适合于小表之间的数据检验。
缺点在于 由于SORT排序可能导致在大数据量的情况下效率很低, 且同样不支持LOB 和 LONG 这样的大对象。

查询2个表之间的不同:

方式3:

使用not exists子句,如:

照理说在数据量较大的情况下not exists使用的HASH JOIN ANTI是在性能上是优于MINUS操作的, 但是当所要比较的表身处不同的2个数据库(distributed query)时将无法使用HASH JOIN ANTI,而会使用FILTER OPERATION这种效率极低的操作:

可以从以上执行计划看到FILTER 操作是十分昂贵的。

补充:

有网友反映可以通过增加 unnest hint 让CBO优化器在远程子查询有效的情况下整体考虑整个查询块,这样可以让执行计划用上HASH JOIN RIGHT ANTI, 这是我一开始没有考虑到的。

在此基础上加入ordered hint 可以让执行计划使用HASH JOIN ANTI

方式3 的优点在于操作简便, 且当需要对比的表位于同一数据库时效率要比MINUS方式高,但如果是distributed query分布式查询则效率可能会因FILTER操作而急剧下降,这时候需要我们手动添加unnest这样的SQL提示,以保证执行计划使用HASH JOIN ANTI操作,这样能够保证not exists方式的性能。not exists同样不支持CLOB等大对象。

方式4:

Toad、PL/SQL Developer等图形化工具都提供了compare table data的功能, 这里我们以Toad工具为例,介绍如何使用该工具校验数据:

打开Toad 链接数据库-> 点击Database-> Compare -> Data

toad_compare_data6

分别在Source 1和Source 2对话框中输入源表和目标表的信息

因为Toad的底层实际上使用了MINUS操作,所以提高SORT_AREA_SIZE有助于提高compare的性能,若使用AUTO PGA则可以不设置。

toad_compare_data6

选择所要比较的列

toad_compare_data6

toad_compare_data6

首先可以比较2张表的行数,点击Execute计算count

toad_compare_data6

使用MINUS 找出其中一张表上有,而另一张没有的行

toad_compare_data6

使用MINUS 找出所有的差别

toad_compare_data6

Toad的compare data功能是基于MINUS实现的,所以效率上并没有优势。但是通过图形界面省去了写SQL语句的麻烦。这种方法同样不支持LOB、LONG等对象。

1. PL/SQL Developer 工具使用


PLSQL Developer Tools菜单下有Compare User Objects和Compare Table Data功能。

① Tools –> compare user objects

该功能用于比较不同用户所拥有的对象(包括table、sequence、function、procedure、view等),并生成同步差异的sql脚本,用户通过执行该脚本,可保持两个用户的对象结构的同步,当然你也可以选择一个对象或者多个对象来进行比较。

操作步骤:
\1. 选择样本库的对比对象
\2. 选择目标库(Target Session..),即需修改和被同步的库
\3. 点击Compare按钮
\4. 在Differences选项卡,点击每个对象能查看消除差异的SQL,点击Apply SQL in Target Session执行
\5. 点击Show Differences按钮,显示具体区别

② Tools –> compare table data

该功能用于比较某些个表里面的数据是否一致,并自动生成同步差异的sql脚本,用户通过执行该脚本,就可以保持比较对象与被比较对象里面数据的同步。

操作步骤:
\1. 选择样本库的对比表
\2. 选择目标库(Target Session..),即需修改和被同步的库
\3. 点击Compare按钮
\4. 在Differences选项卡,点击每个表能查看消除差异的SQL
\5. 点击Apply SQL in Target Session执行

注: 主键相同值的记录做更新(Update)其他字段。



  1. 登录数据库A
  2. 打开【工具】菜单下的【比较用户对象】
  3. 点【目标会话】,登录数据库B

img

  1. 点击【比较】
  2. 切换到【差异】面板可以看到不同的对象以及更新语句
  3. 同理,我们也可以通过【比较表数据】来查看两库表数据的不同。

img

  1. 如果要将两库的表结构或者表数据进行同步的话,则拷贝出脚本并执行。

注意以下几种数据比对方式适用的前提条件:

\1. 所要比对的表的结构是一致的
\2. 比对过程中源端和 目标端 表上的数据都是静态的,没有任何DML修改

方式5:

这是一种别出心裁的做法。 将一行数据的上所有字段合并起来,并使用dbms_utility.get_hash_value对合并后的中间值取hash value,再将所有这些从各行所获得的hash值sum累加, 若2表的hash累加值相等则判定2表的数据一致。

简单来说,如下面这样:

对于列较多的表,手动去构造所有字段合并可能会比较麻烦,利用以下SQL可以快速构造出我们所需要的语句:

使用示范:

方式5 利用累加整行数据的hash来判定表上数据是否一致, 仅需要对2张表做全表扫描,效率上是这几种方法中最高的, 且能保证较高的准确率。

但是该hash方式存在以下几点不足:

\1. 所有字段合并的整行数据可能超过4000字节,这时会出现ORA-1498错误。换而言之使用这种方式的前提是表中任一行的行长不能超过4000 bytes,当然常规情况下很少会有一行数据超过4000 bytes,也可以通过dba_tables.avg_row_len平均行长的统计信息来判定,若avg_row_len<<4000 那么一般不会有溢出的问题。

\2. 该hash 方式仅能帮助判断 数据是否一致, 而无法提供更多有用的,例如是哪些行不一致等细节信息

\3. 同样的该hash方式对于lob、long字段也无能为力




SQL Server数据库

可以使用微软提供的专用数据库比对工具:Visual Studio 2017 (SSDT) --

SQL Server Data Tools (SSDT)

img

1.准备两个要比较的数据库

我这里有两个数据库,一个是本地的(JXPT_CS),一个是测试服务器的(JXPT_MS)。本次演练我将连接这两个数据库。

2.连接源数据库和目标数据库

所谓的源数据库和目标数据库也就是字面的意思(源>目标)将源数据中新增修改删除的数据同步到目标数据库中。

首先我们打开VS>工具>SQL Server>新建数据比较。

技术分享

选择源数据库

技术分享

我们选择数据库,点击连接

技术分享

选择目标 操作和选择源一样

技术分享

然后我们点击下一步

技术分享

3.比较源数据库和目标数据库

源数据库和目标数据库都选择完成后,然后选择要比较的表、字段和视图

技术分享

点开表,也可以根据需求选择相应的表

技术分享

点击完成,开始比较

技术分享

上面我们会看到各个表之间的数据差异,可以选择查看,可以以在下面Tab页切换查看。

本人提供Oracle(OCP、OCM)、MySQL(OCP)、PostgreSQL(PGCA、PGCE、PGCM)等数据库的培训和考证业务,私聊QQ646634621或微信dbaup66,谢谢!
AiDBA后续精彩内容已被站长无情隐藏,请输入验证码解锁本文!
验证码:
获取验证码: 请先关注本站微信公众号,然后回复“验证码”,获取验证码。在微信里搜索“AiDBA”或者“dbaup6”或者微信扫描右侧二维码都可以关注本站微信公众号。

标签:

Avatar photo

小麦苗

学习或考证,均可联系麦老师,请加微信db_bao或QQ646634621

您可能还喜欢...

发表回复