RAC环境中threads变更后如何确保goldengate继续正常复制

        当rac节点变更的时候,比如我们添加或者删除了集群中的节点,理所当然会对节点对应的log threads进行添加或者删除,但会造成goldengate的map log threads的顺序发生紊乱。在进行这一类行为变更的时候,特别需要注意goldengate端也需要进行特别处理。

         比如,在节点添加之前,goldengate map log threads顺序如下(数据库log thread在后,下同):

         1—>1 (假设是sequence 100,rba 1001)

         2—>2(假设是sequence 88,rba 3009)

        当添加节点后,map log threads的顺序会变成:

        1—->3(sequence 88,rba 3009)

        2—->1(sequence 100,rba 1001)

        3—->2(new)

        当ogg重新工作的时候,因为此时map的顺序发生了变化,因此会造成抽取进度出现问题。

【 阅读全文 】

goldengate–使用filter+@GETENV在线重新初始化指定的table

        在oracle-oracle goldengate的复制环境中,有时候会碰到一些紧急的问题一时无法修复,为了避免影响整个复制环境的复制进度,采取跳过错误事务或者跳过特定对象的办法使得goldengate继续同步;如果后续某个表不得不需要重新同步,而且应用是不间断进行事务操作的,在不停止应用和重建整个复制环境的情况下,为了保证数据的一致性,如何在线对特定的问题对象重新初始化和继续同步呢?

        处理的办法还是不少的,下面给出一个在replicat端过滤SCN事务的办法,来实现数据的一致同步。

        处理的思路就是首先在target上获得该表上某个特定SCN版本上的数据(比如使用导入导出或者数据泵),然后通过filter功能来筛选出该表上大于该commit scn的事务,从而确保事务的一致性。在goldengate v10之后,可以通过@GETENV函数直接获得事务的CSN。 

【 阅读全文 】

oracle-oracle goldengate零停机初始化的技巧

      在实施goldengate过程中,初始化的方案选择是一个重要的环节,尤其对一个7*24小时的系统环境来讲。一个出色的    goldengate的实施不应该以停机时间作为代价,合适的初始化方法完全可以做到零停机。 

      如果事务不间断进行,如何保证初始化过程中事务的完整性和数据的准确性呢(静态的初始化环境无需多讲)?实现方法还是多样的,从工作机制上来讲,归纳起来主要有2种。

     1. 利用 Keys + Handlecollisions

     2.利用 commit SCN/CSN

        Handlecollisions参数依赖于表上的Key(Primary key/Unique key)来对数据进行重复行和缺失行的处理,常在数据初始化过程中保证数据的一致性,gg文档上的初始化办法,比如initial load,都是用的这种办法。但是这种办法在实际的工程实施中是有相当大的限制。

        首先,该初始化办法性能比较糟糕,对于大型数据库来讲,并不合适。更严重的是,它有很大的缺陷性。(引自metalink doc):

1. When there is primary key update (PKUpdate), the HANDLECOLLISIONS method may lose data. The solution in the case of a primary key update is for Extract to fetch whole row by making a flashback query. However, this is not efficient and may not be possible in certain environments.

2. When a table does not have any type of key, HANDLECOLLISIONS may introduce duplicate rows in the table. One workaround is to add a primary or unique key to the target table.

3. The exact timestamp when the initial load was started may not be known (and different tables may have different start times), so it is almost inevitable that HANDLECOLLISIONS will be used for certain records un-necessarily. This could mask a real data integrity problem.

         在实际的工程实施中,个人不推荐使用基于Keys + Handlecollisions模式的初始化办法。

【 阅读全文 】

goldengate培训提纲<一>

     Blog一晃半年没有更新了,还真对不起每年交的空间和域名费。

     一连实施了好几个goldengate的项目,关注ogg也有好些时日了。这是前不久应客户要求做的goldengate的培训,share一下。因为用户只是应急容灾的应用,因此ogg上的很多功能当时并没有提及。接下来的blog会持续整理goldengate的一些问题和技巧。

【 阅读全文 】

When you Believe-2011,怡然前行

       曾期许做一个舞文泼墨者,将或喜或悲点缀到跳动的字里行间,洒脱自得;然而,不经意的却走向了it这个湖潭,逐流随波,几近五载。

       成长会让理性变成习惯,但感性亦不会荡然无存。

      恋上了随遇而安,却总爱奢华的瞻望。当踮起脚尖的时候,已然望不到尽头,剩下了就是不安与惶恐。这种惶恐近来愈发强烈,却着实不得不面对。岔路口上,或左或右需要是睿智;而坡路上,迎面总好过退缩。瓶颈虽不会无处不在,但却很难让它无处遁形。惶恐之由,想罢是生性中最脆弱的一面又蠢蠢欲动,夹杂着诸多不尽人意,难免碰触到最敏感的神经。

      漂泊了4个半年头后,在广州算是有了个尚未交付的栖息之所。心情沉重了很多,决非释然。想来这是一种微妙的感觉,诸如我们这般琐居的外乡人,独自飘零,兀自找寻。即便有了归属,心又归于何处。

      好好对待身边的人,朋友,亲人。谢谢陪伴自己一路走过的人。

      责任当是种爱的感知和传递。花自漂零,怡然前行。

 

                                                                                                                                             ——2011.3.22 广州

Cascaded Destinations/Cascaded Standby Databases

      Cascaded Destinations,简单的讲,就是为了避免主库的压力和干扰,将主库产生的redo通过一个standby传送到另外一个standby上,而不是直接通过primary到另外一个standby。在Oracle各版本的在线文档上,对此界定也并不一致。比如这样一个组合方式:Primary Database > Logical Standby Database  > Physical Standby Database,因为最后一层的standby并不和第一层的priamry database有直接关系,1-2和2-3分别自成体系,这并不是一个真正意义上的Cascaded Destination。但在10g和9i在线文档中,依然将这种模式列为cascaded destinations,而在11g中已经将这种情形排除。严格意义上的cascaded destination 支持如下组合场景:

1. Primary Database > Physical Standby Database with cascaded destination > Physical Standby Database
2. Primary Database > Physical Standby Database with cascaded destination > Logical Standby Database

     Cascaded Destinations的用处还是比较多的,例如使用dataguard做远程容灾的场景,使用Cascaded Destinations就远比local primary和romote standby直接做dataguard可靠。基于WAN上的dataguard的一个致命问题就是主备端的网络质量问题,这将对主端产生严重的影响,尽管可以通过async的方式来进行redo或者archive的传送,但在一个繁忙的系统中,这仍然是个极大的性能和稳定性隐患。通过Cascaded Destinations,redo/archive log的同步放到了local physical standby端上进行,主库产生的日志先传送到local standby,然后由local standby负责传送日志到remote standby。

 cascaded%20destinations[1]

       对于10g版本以上的该模型,通过日志传输参数VALID_FOR的功能,通过角色控制priamry/standby向remote database的日志传送,这样日常中local dataguard的switchover并不影响remote standby的同步且操作上更加平滑,另外,remote standby端配合Flashback Database,这样也避免了因为WAN上带宽有限,local database的Failover造成的remote standby的重建带来的数据传输问题。

       需要特别提出的是cascaded standby databases中的FAL的配置问题,正常情况下最后一级standby的日志是从上级standby上取得,并非直接从primary上传输,但特别情况下可直接由Primary向最后一级standby传送。如果最后一级standby的fal_server配置对应primary database和上级standby database,那么可能出现这么一种情况需要注意:上级standby database的对应的归档日志已经apply但已经不存在(比如被删除),因为下级 standby database存在一系列问题,恢复进度并没有赶上日志的传送速度,当正好需要上级standby上这部分log的时候,发现从上级standby上已经无法获得,这时候通过fal_server的配置可直接从primary向最后一级standby上传输,而不需要中转。

      Metalink doc上也相关记录如下:

If primary receives a FAL request from the remote standby in the above case then It ships the archive logs directly to the remote standby without going via cascaded standby.

Oracle读写分离架构

       读写分离是架构分布式系统的一个重要思想。不少系统整体处理能力并不能同业务的增长保持同步,因此势必会带来瓶颈,单纯的升级硬件并不能一劳永逸。针对业务类型特点,需要从架构模式上进行一系列的调整,比如业务模块的分割,数据库的拆分等等。

       集中式和分布式是两个对立的模式,不同行业的应用特点也决定了架构的思路。如互联网行业中一些门户站点,出于技术和成本等方面考虑,更多的采用开源的数据库产品(如MYSQL),由于大部分是典型的读多写少的请求,因此为MYSQL及其复制技术大行其道提供了条件。而相对一些传统密集交易型的行业,比如电信业、金融业等,考虑到单点处理能力和可靠性、稳定性等问题,可能更多的采用商用数据库,比如DB2、Oracle等。

       就数据库层面来讲,大部分传统行业核心库采用集中式的架构思路,采用高配的小型机做主机载体,因为数据库本身和主机强大的处理能力,数据库端一般能支撑业务的运转,因此,Oracle读写分离式的架构相对MYSQL来讲,相对会少。

       前段时间一直在规划公司新的数据库架构,考虑到我们的业务特点,采用Oracle读写分离的思路,Writer DB和Reader  DB采用日志复制软件实现实时同步; Writer DB负责交易相关的实时查询和事务处理,Reader DB负责只读接入,处理一些非实时的交易明细,报表类的汇总查询等。同时,为了满足高可用性和扩展性等要求,对读写端适当做外延,比如Writer DB采用HA或者RAC的架构模式,Reader DB可以采用多套,通过负载均衡或者业务分离的方式,有效分担读库的压力。

       对于Shared-nothing的数据库架构模式,核心的一个问题就是读写库的实时同步;另外,虽然Reader  DB只负责业务查询,但并不代表数据库在功能上是只读的。只读是从应用角度出发,为了保证数据一致和冲突考虑,因为查询业务模块可能需要涉及一些中间处理,如果需要在数据库里面处理(取决与应用需求和设计),所以Reader  DB在功能上仍然需要可写。

【 阅读全文 】

Undocumented Way–通过手工创建sql profiles固定执行计划进行SQL调优

        一直以来对SQL profiles都是爱恨有加。SQL profiles的灵活和一些特性(比如对SQL语句级的类似cursor_sharing功能,对非绑定变量环境非常实用),在不很多不能修改应用代码的场景下最小风险的对SQL语句进行调优,是传统的outline无法比拟的;但是用过SQL profile的朋友应该都清楚,按官方的SQL tuning Advisor提供的sql profies生成办法,由于包含了太多了nodirective Hints(比如OPT_ESTIMATE/COLUMN_STATS/TABLE_STATS等),并不能保证执行计划的稳定性,会随着外界的因素发生改变(比如表和索引的信息,柱状图等信息的变化) 。尽管二者都是依靠hints来提示或者指挥优化器完成执行计划的解析,但却不尽相同。通过SQL Tuning Advisor 生成的hints更多是为执行计划的生成提供评估和参考信息,而Outlinie Hints,倾向于指挥命令。

         前几天在查阅新书<Pro Oracle SQL>介绍的时候,看到作者blog上有提出了undocmented way手工构造SQL profile的例子,确实能像outline一样,强制固定住执行计划,这顿时让我觉得柳暗花明,因为我之前一直对SQL profiles的稳定性大伤脑筋。结合最近的几次项目调优,使用这种办法固定SQL计划,效果相当不错。

        手工构造SQL Profiles,可以使用oracle提供的dbms_sqltune.import_sql_profile过程。

【 阅读全文 】