【数据库】同步方式:DataGuard vs GoldenGate
一、基本概念
1.1 数据写入流程
在数据库中,数据文件存储着实际的数据,但在更新数据时,并不会直接更新磁盘上的数据文件。因为这涉及大量磁盘I/O,对性能影响非常大。当用户提交了一条DML请求,如update emp set ename='test' where id=1;
监听程序收到请求,会为该请求建立一个对应的服务器进程。服务器进程先扫描数据库缓冲区,检查是否包含id=1的数据块。如果有,则缓存命中直接更新,该数据块变脏;如果没有命中,服务器进程会将对应数据块先从磁盘上复制到缓冲区内,再进行更新操作。
如果数据库缓冲区存储的块和磁盘上的块不一致,该缓冲区就叫做“脏缓冲区”,脏缓冲区最终会由数据库写入器(DBWn)写入磁盘的数据文件中。DBWn并不会实时写入, 它会尽可能少的进行写入,只有在以下四种情况它会执行写入:
- a.没有任何可用缓冲区
- b.脏缓冲区过多
- c.3秒超时(最晚3秒会执行一次写入)
- d.遇到检查点,即checkPoint。检查点是个Oracle事件,比如数据库有序关闭的时候会有检查点,也可以手动触发
由于DBWn不是实时写入的,那假如系统突然断电了,缓冲区的数据还未写入磁盘,那缓冲区内commit的数据岂不就丢失了?其实数据不会丢失, 这就引出了重做日志(redo log)的概念。
1.2 什么是重做日志(redo log)
当用户执行DML操作,数据块发生改变时,产生的变更向量则会写入到重做日志文件中。有了这些记录,当系统由于断电等因素突然宕掉,数据库缓冲区内的大量脏数据还没来得及写入到数据文件中时,也可以通过redo log恢复。
相应的,日志写入也有一块内存区域叫日志缓冲区, 由日志写入器(LGWR)把日志缓冲区内的内容写入到磁盘的重做日志文件中。相比数据库写入器(DBWn),LGWR的写入要频繁的多。在下面三种情况LGWR会执行写入:
- a. commit时写入
- b.日志缓冲区的占用率达到1/3。
- c.DBWn要写入脏缓冲区前
当用户执行DML并且commit后,不一定会触发DBWn写入,但一定会触发LGWR写入。因此就算执行DML并且commit后,数据只写入了数据库缓冲区,而此时数据库缓冲区中的数据丢失了,也可以通过redo log恢复。
1.3 什么是归档日志(archive redo log)
所谓归档,就是将重做日志文件(redo log)永久保存到归档日志文件(archive redo log)中。archive redo log和redo log作用是一样的,只不过redo log会不断被重写,而archive redo log则不会,它保留了关于数据更改的完整的历史记录。 由ARCn进程负责将redo log备份到archive redo log。
以上就是数据写入的大体流程,数据库同步主要就是依赖重做日志(redo log)和归档日志(archive redo log)完成的。
二、容灾同步方式
2.1 Oracle Dataguard
原理
将redo log从原数据库传输到目标数据库,然后在目标数据库上应用这些日志文件,从而使目标数据库与源数据库保持同步。 执行步骤
- 客户端连接主库,发起更新数据的操作
- 在主库内存中完成数据的更改,生成redo log
- 客户端执行commit
- 主库将重做日志写入日志文件组,同时发送给备库
- 备库应用重做日志,应答主库
- 主库应答客户端
通过这个机制,实现每个在主库的更新操作,都会在备库应用,从而实现同步。对于备库的应答,可以设置最大可用模式(Maximum Availability)、最大性能模式(Maximum Performance)和最大保护模式(Maximum Protection)三种方式。在最大保护模式下,主库需将redo log传输到备库后才可完成操作,从而更好地保证一致性。
容灾系统常用的ADG( Active Data Guard),则是在DG的基础上,加入了可查询的功能,从而能够将一些报表类的业务压力从主库上分离出去。
保护模式 | 应答机制 |
---|---|
最大性能模式(Maximum Performance) | 主库不需要等待备库的回应即可应答客户端,主库与备库数据是异步的,主库出现故障会有数据丢失。如果备库出现故障,主库保持可用。对性能基本无影响。 |
最大保护模式(Maximum Protection) | 主库必须确认备库已经应用重做日志才能应答客户端,主库与备库数据是实时同步的,主库出现故障不会有数据丢失。如果备库出现故障,整个DG架构不可用。网络、备库读写速度等会影响整体性能。 |
最大可用模式(Maximum Availability) | 如果备库正常运行,则与最大保护模式一致,如果备库故障,则与最高性能模式保持一致。 |
备库类型
物理备库 | 逻辑备库 | |
---|---|---|
原理 | 主备物理结构一致(逻辑结构也一致),备库利用主库发送的redo log进行重做来同步 | 主备逻辑结构一致(物理结构不一致),备库利用主库发送过来的redo log重新解析为SQL语句,通过执行SQL语句来同步 |
优点 | 备库逻辑结构、物理结构均和主库保持一致,更强的一致性保证 | 更灵活,可以使用DBMS_LOGSTDBY包对备库做特殊设置 |
物理备库与主库SCN保持一致,逻辑备库只需要数据保持一致。
2.2 Oracle GoldenGate方式
原理
通过解析源数据库redo log 或者archive log获得数据的增量变化,然后通过TCP/IP投递到目标数据库,最后将这些变化解析还原应用到目标数据库,从而实现两边同步。DSG复制工具也是基于相似原理。
执行步骤
- 通过抽取进程(Extract Process)和复制进程(replicat process)进行初始化数据同步
- 抽取进程(Extract Process)在源端数据库中读取online redo log或者archive redo log,然后进行解析,只提取其中数据的变化信息,比如DML操作
- 将抽取的信息转换为OGG自定义的中间格式存放在队列文件(trail file)中
- 通过传输进程将队列文件(trail file)通过TCP/IP传送到目标端,可配置投递进程(Pump Process)将trail file文件以数据块的形式传送到目标端
- 目标端Server Collector进程接收从源端传输过来的数据变化信息,把信息缓存到队列文件trail file中
- 目标端复制进程(replicat process)从trail file中读取数据变化信息,并创建对应的SQL语句,应用到目标数据库,提交成功后更新自己的检查点,记录已经完成复制的位置,完成数据复制
三、总结
DataGuard | OGG | |
---|---|---|
原理 | 将redo log从源数据库传输到目标数据库,然后在目标数据库上应用这些日志文件 | 通过解析源数据库redo log 或者archive log获得数据的增量变化,然后通过TCP/IP投递到目标数据库,最后将这些变化解析还原应用到目标数据库 |
稳定性 | 作为灾备的稳定性极高 | 由于数据复制操作独立于数据库管理系统,因此不能确保数据零丢失 |
维护 | 维护简单,极少出现问题 | 命令行方式,维护较复杂 |
对象支持 | 完全支持 | 部分对象需手工创建与维护 |
目标端可用性 | 目标端处于恢复或只读状态 | 两端数据库是活动的,目标端可以提供实时的数据查询,也可以实现两端数据的同时写入 |
复制方式 | 可以实现实时复制 | GoldenGate可以提供秒一级的大量数据实时捕捉和投递,异步复制方式,无法实现同步复制 |
资源占用 | 复制通过数据库的LGWR进程或ARCN进程完成,占用数据库少量资源 | 业务高峰时在数据抽取转换时消耗系统资源较多,低峰时占用较小 |
异构数据库支持 | 仅运行在Oracle数据库上,且源端和目标端操作系统要求较严格 | 可以在不同类型和版本的数据库之间进行数据复制,也适用于不同操作系统间同步 |
DataGuard是实现Oracle数据库灾备的比较好的方式,我们的项目中也尝试使用OGG做灾备,主要遇到下面的问题:
1、两端数据库数据一致性的保障
DataGuard可以实现实时复制,且由数据库本身机制保证它的一致性。而OGG的数据复制操作独立于数据库管理系统,只能保证它抽取的变化数据都应用到目标端,但却不能确保两端数据库一定是一致的。虽然OGG目前在DML复制上很少出现问题,但我们还是写了许多额外的稽核脚本来确保两端数据一致。通过稽核,也发现确实会出现OGG本身未报错,但表数据不一致的情况。
2、对象的维护
部分对象需手工创建与维护,为了保证对象一致,还需要额外写脚本进行数据库对象稽核。
3、效率问题
如果在源端的表未建索引,且进行了大量的增删改操作时,会极大影响OGG的复制进程效率。如我们某个表没有建索引,批量更新删除48万数据,复制进程延迟了6个小时,才在目标端应用了15万的数据,最终跑了19个小时才将OGG追平。同理如果在源端trancate,也会导致大量数据变化,从而影响OGG效率。
总的来说,如果两端都是ORACLE,且操作系统相同,DataGuard是较好的方式。而如果要实现异构数据库间的数据同步,或者两端的操作系统不同,则只能选择OGG的方式。使用该种方式则需要在数据一致性保障、效率提升方面花更多功夫。
转载自:https://juejin.cn/post/7083402649961250847