利用sql profile固定执行计划加快OGG同步

ogg是逻辑同步,不想ADG利用后镜像直接修改block中的内容,ogg是根据redo片中SQL,以及SQL对应的后镜像值进行表的修改,这样如果大表上面没有索引,或者走错索引就会导致同步慢。但是OGG都是单表update,所以很容易优化SQL。以下利用sql profile固定执行计划,清除sharedpool对应的执行计划达到重新利用正常的执行计划

-bash-3.2$ ogg

Oracle GoldenGate Command Interpreter for Oracle

Version 11.2.1.0.6 16211226 OGGCORE_11.2.1.0.6_PLATFORMS_130418.1829_FBO

Solaris, sparc, 64bit (optimized), Oracle 11g on Apr 22 2013 15:23:39

Copyright (C) 1995, 2013, Oracle and/or its affiliates. All rights reserved.

GGSCI (ODSDB) 1> info all

Program     Status      Group       Lag at Chkpt  Time Since Chkpt

MANAGER     RUNNING

JAGENT      STOPPED

REPLICAT    RUNNING     RP10        00:00:00      00:00:03

REPLICAT    RUNNING     RP7         00:00:06      00:00:03

REPLICAT    RUNNING     RPS1        42:41:14      00:00:01

REPLICAT    RUNNING     RPS2        00:00:00      00:00:10

REPLICAT    RUNNING     RPS2A       00:00:00      00:00:00

REPLICAT    RUNNING     RPS2B       00:00:00      00:00:00

REPLICAT    RUNNING     RPS3        00:00:00      00:00:02

REPLICAT    RUNNING     RPS3A       00:00:00      00:00:03

REPLICAT    RUNNING     RPS3B       00:00:00      00:00:02

REPLICAT    RUNNING     RPS4        00:00:00      00:00:07

REPLICAT    RUNNING     RPS4A       00:00:00      00:00:07

REPLICAT    RUNNING     RPS4B       00:00:00      00:00:07

REPLICAT    RUNNING     RPS4C       00:00:00      00:00:07

REPLICAT    RUNNING     RPS4D       00:00:00      00:00:08

REPLICAT    RUNNING     RPS4E       00:00:00      00:00:07

REPLICAT    RUNNING     RPS4F       00:00:00      00:00:07

REPLICAT    RUNNING     RPS4G       00:00:00      00:00:07

REPLICAT    RUNNING     RPS4H       00:00:00      00:00:07

REPLICAT    RUNNING     RPS4I       00:00:00      00:00:08

REPLICAT    RUNNING     RPS4J       00:00:00      00:00:07

跟他去了终端旁边,发现确实有个rps1进程延迟有点高。看着进程状态是RUNNING,但是根据我维护六年ogg来看,有可能是假象,那么怎么判断呢?

1,查看ggserr.log

2,查看dirrpt下面该进程的dsc文件

3,info 进程名多次,看看RBA是否有变化

经过以上几步rps1进程状态是正常的,延迟高问题出在哪里?view params rps1看到该进程只有一张表。那我们看看这个进程到底卡在哪里了

SQL> !ps -ef |grep rps1 |grep -v grep

orao 12169 11012   0   Jun 07 ?         614:58 /odogg/baseogg/replicat PARAMFILE /odsogg/baseogg/dirprm/rps1.prm REPORTFILE /

SQL> !ps -ef |grep 12169 |grep -v grep

orao 12170 12169   1   Jun 07 ?        2315:30 oracleodb (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))

orao 12169 11012   0   Jun 07 ?         614:58 /odogg/baseogg/replicat PARAMFILE /odsogg/baseogg/dirprm/rps1.prm REPORTFILE /

SQL> select s.sid,s.SERIAL#,sql_id from v$process p,v$session s where p.addr=s.paddr and p.spid=12170;

SID    SERIAL# SQL_ID

---------- ---------- -------------

5146        113 5099dwmx3s4mf

SQL> /

SID    SERIAL# SQL_ID

---------- ---------- -------------

5146        113 dzubcf8jm69yx

SQL> /

SID    SERIAL# SQL_ID

---------- ---------- -------------

5146        113 dzubcf8jm69yx

SQL> /

SID    SERIAL# SQL_ID

---------- ---------- -------------

5146        113 dzubcf8jm69yx

询问了一下维护过该系统的同事,说是不是统计信息太旧。顺着思路往下走走

SQL> select OWNER,TABLE_NAME,LAST_ANALYZED from dba_tables where table_name='TF_F_USER_REVGRPTAG';

OWNER             TABLE_NAME        LAST_ANALYZED

-------------------------------------------------------------------------------

TTT              TF_F_USER_REXXX     2017-06-26 00:20:56

SQL>  select table_name,num_rows from dba_tables where owner='TTT' and table_name='TF_F_USER_REXXX';

TABLE_NAME              NUM_ROWS

------------------------------ ----------

TF_F_USER_REXXX          409269832

SQL> select count(*) from TTT.TF_F_USER_REXXX;

COUNT(*)

----------

409955510

接下来我们看看该sql执行计划是不是走错了?

d594d65363f64eb424e2c89fe1143fd9.png

两条执行计划,很明显137632316运行了5400次但是执行时间却远远高于第二个执行计划。

b8cd73bc191975b57e2c9a7883a406fc.png

8e18110ab1ba2f9ed363ff7197347d0e.png

用sql profile绑定一下执行计划

SQL> @coe_xfr_sql_profile.sql

Parameter 1:

SQL_ID (required)

Enter value for 1: dzubcf8jm69yx

PLAN_HASH_VALUE AVG_ET_SECS

--------------- -----------

2320424968        .004

137632316      21.119

Parameter 2:

PLAN_HASH_VALUE (required)

Enter value for 2: 2320424968

Values passed to coe_xfr_sql_profile:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

SQL_ID         : "dzubcf8jm69yx"

PLAN_HASH_VALUE: "2320424968"

查看是否绑定成功

SQL>select name from dba_sql_profiles;

NAME

------------------------------

coe_dzubcf8jm69yx_2320424968

SYS_SQLPROF_015d075ccdd40000

coe_a5hgtqfq09tcu_229988255

在将内存中的该sql语句清除出去

SQL>select address,hash_value,executions,parse_calls from v$sql where sql_TEXT like 'UPDATE "TTT"."TF_F_USER_RExxxx" SET "PARTITION_ID" = :a27,"USER_ID" = :a28%';

ADDRESS          HASH_VALUE EXECUTIONS PARSE_CALLS

---------------- ---------- ---------- -----------

00000017673EA5E8 4198240878        100           0

00000017CF3E0000  897328139        673           0

00000017982D40D0 1588244011          8           0

000000049D04B1A8  590555101         10           0

00000017AA525230 4271852353          2           0

0000001777FC6A20 3666847391        735           0

00000017B9154A58 1180290247          1           0

7 rows selected.

SQL>alter session set events '5614566 trace name context forever';

Session altered.

SQL>exec dbms_shared_pool.purge('00000017673EA5E8,4198240878','C');

PL/SQL procedure successfully completed.

SQL>exec dbms_shared_pool.purge('00000017CF3E0000,897328139','C');

exec db

PL/SQL procedure successfully completed.

SQL>ms_shared_pool.purge('00000017982D40D0,1588244011','C');

PL/SQL procedure successfully completed.

SQL>exec dbms_shared_pool.purge('000000049D04B1A8,590555101','C');

PL/SQL procedure successfully completed.

SQL>exec dbms_shared_pool.purge('00000017AA525230,4271852353','C');

PL/SQL procedure successfully completed.

SQL>exec dbms_shared_pool.purge('0000001777FC6A20,3666847391','C');

PL/SQL procedure successfully completed.

SQL>exec dbms_shared_pool.purge('00000017B9154A58,1180290247','C');

PL/SQL procedure successfully completed.

--------

清理过程还可以通过DDL表改动做到强制硬解析

细粒度对表DDL操作

–收集统计信息后,OGG复制执行的SQL执行计划没有改变,对表DDL,让SQL硬解析

comment on table  xx.xx is 'ogg_big_tab';
select owner,to_char(LAST_DDL_TIME,'yyyy-mm-dd hh24:mi:ss')
 from dba_objects where object_name='xx';
------------------------------------------------------------
xx                  2021-11-14 02:54:45

由于只是修改表的注释,所以实际操作是毫秒级别,不会像其它DDL操作执行几分钟、甚至几个小时阻塞业务正常DML操作。

-----------

     

keycols(primary_column_name); 作用是强制根据这个列做改动?

1.表存在主键
select   *   from   user_cons_columns   
  where   constraint_name   =   (select   constraint_name   from   user_constraints   
              where   table_name   =   'BST_FAVORITE'  and   constraint_type   ='P');   
2.对OGG复制进程添加参数指定主键列
map source_owner.table_name target target_owner.table_name;
添加参数
map source_owner.table_name target target_owner.table_name,keycols(primary_column_name);
3.对于不存在主键的表呢???
select count(*) from xxx; 得到表的数量,如果表很大,不执行最好。
通过dba_tab_columns 根据NUM_DISTINCT 得到最多distinct的列,及选择性好的列。
SQL> select COLUMN_NAME,NUM_NULLS,NUM_DISTINCT,to_char(LAST_ANALYZED,'yyyy-mm-dd') as "date" from dba_tab_columns where owner='cc' and table_name='cc' order by 3;
结合表的索引列
select a.uniqueness 索引类型,b.index_name 索引名称,b.column_name 字段 from user_indexes a ,user_ind_columns b

where a.table_name=b.table_name and a.index_name = b.index_name

and a.table_owner=upper('SAPSR3'and  a.table_name='ANLU' order by a.uniqueness desc;

  如果存在索引,并且选择性足够好,虽然不是主键列,但是可以直接使用keycols指定;

  如果不存在索引? 或者索引的选择性不够好,可以新增一个选择性好的索引,随后使用keycols进行指定。  

!!! 缺陷或者风险在于,因为是非主键,及时选择性好,如果存在null值,还是无法使用该索引,OGG 进程对应数据库session 执行SQL还是慢。 但是正常情况下可以解决该问题。

并且存在一个疑问,如果假设源端修改了一条记录,但是选择性好的column_name 在目标端对应2条记录,并且ogg复制进程使用keycols参数指定?  那么目标端是修改更新2条记录? 还是1条记录呢???

2.1 定位OGG复制进程在oracle数据库中的Session

$ps -ef|grep RP10
PID
20  RP10 ······
$ps -ef|grep 20
PID
60864  LOCAL=NO   [OGG Session process]
SQL> select s.sid,s.serial#,sql_id,p.program from v$process p,v$session s where p.addr=s.paddr and p.spid=60864;

       SID    SERIAL# SQL_ID         PROGRAM
------------------------------------------------
      2276    37851 2j664   oracle@cc (TNS V1-V3)

2.2 定位造成OGG复制进程延迟过高的SQL

通过ash视图,查询1天内这个OGG进程 session ,都在执行什么sql ,event信息。 ash视图间隔1s采样 active session 1次。因此捕捉到的次数越多,说明消耗花费的时间越多。
select sql_id,event,BLOCKING_SESSION,CURRENT_OBJ#,count(*) from v$active_session_history where SAMPLE_TIME>sysdate-1 and SESSION_ID=2276  and SESSION_SERIAL#=37851
 group by sql_id,event,BLOCKING_SESSION,CURRENT_OBJ# order by 5,4;
SQL_ID          EVENT                                   BLOCKING_SESSION CURRENT_OBJ#   COUNT(*)
------------- ---------------------------------------------------------------- ---------------- ------------ ----------
1n7zz8wb86jpw                                                   0         16
088mh1tws6wtm                                                  -1         19
2jt8ttg6b42b4                                                   0         75
9y2087cvvr4r9                                                   0        115
1n7zz8wb86jpw                                                  -1       4575
2cc4                                                           -1      18877
9y2087ccc9                                                     -1      62497
10 rows selected.

select * from table(dbms_xplan.display_cursor('2ccb4'));

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值