Wednesday, 27 September 2017

Goldengate for Kafka : how to send Tokens to Kafka from Goldengate

Requirement -

Recently i got one request from client to provide one unique identifier of the Source table to Kafka mostly Source Table name. 

As we do not have any Column in the table which can provide this information to the Kafka by simple Goldengate Mapping. 

To full-fill this requirement i Used Goldengate Tokens to give Source Table name with each generated topic to Kafka. 

for this configuration below changes are required. 



Source Side (Goldengate)

we need to add Token to the goldengate extract parameter file.  

TABLE Hr.Emp , tokens (SOURCE_TABLE = "Emp") ;




Target Side (Kafka)

we need to make below changes to kafka.props file at target goldengate configuration side 

gg.handler.kafkahandler.includeTokens=true



Note: before implementing above solution in to production please do testing of your requirement by your own in non production ENV . above solution is based on my requirement and experience. 

Tuesday, 4 July 2017

OGG-03528 | OGG-15052 - Goldengate For Kafka : Replicate stopped after Linux latest OS kernel updates

Situation 

After installing Linux latest OS kernel updates, Oracle Goldengate replicate process are stopped and showing below in report file. 

GGSCI > View report <Replicate name>

Report file show like below


2017-07-04 00:16:01  INFO    OGG-03528  The source database character set, as determined from the table definition file, is ISO-8859-1.
REPLICAT INR28
TARGETDB LIBFILE libggjava.so SET property=/goldengate/ggadmin/12.3.0/dirprm/kafka.props

2017-07-04 00:16:02  INFO    OGG-15052  Using Java class path: /goldengate/ggadmin/12.3.0/ggjava/ggjava.jar:/goldengate/ggadmin/12.3.0/dirprm:ggjava/resources/lib/op
tional/log4j-1.2.17.jar:ggjava/resources/lib/optional/slf4j-log4j12-1.7.6.jar.
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGBUS (0x7) at pc=0x00007f0369010eac, pid=48662, tid=139653265958272
#
# JRE version:  (8.0_66-b17) (build )
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.66-b17 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# j  sun.reflect.ReflectionFactory.<clinit>()V+0
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /goldengate/ggadmin/12.3.0/hs_err_pid48662.log
#

# If you would like to submit a bug report, please visit:


Reason - 
After Linux Kernel updates JVMController will not start and core dump is generated. 


Solution - 
As per Oracle Document Doc ID 2280962.1

we need to change below parameter values 

at GG_HOME/dirprm directory in kafka.props file 


BEFORE VALUE


gg.classpath=/goldengate/ggadmin/12.3.0/dirprm:/dgt/kfk/kafka/kafka_2.10-0.10.1.0/libs/*
javawriter.bootoptions=-Xmx512m -Xms32m -Djava.class.path=/goldengate/ggadmin/12.3.0/ggjava/ggjava.jar:/goldengate/ggadmin/12.3.0/dirprm


Value After Fix

gg.classpath=/goldengate/ggadmin/12.3.0/dirprm:/dgt/kfk/kafka/kafka_2.10-0.10.1.0/libs/*
javawriter.bootoptions=-Xss2m -Xms512m -Xmx1024m -Djava.class.path=/goldengate/ggadmin/12.3.0/ggjava/ggjava.jar:/goldengate/ggadmin/12.3.0/dirprm



Note: Values may change with environment and versions in use .  Before considering changes in Production Environment please validate the same in Non-production or Testing environment.  

Friday, 26 May 2017

Move LOB column of a partition Table to a new Tablespace Oracle || dba_lob_partitions

To move LOB column of a partition table to a new Tablespace in the same Database use bellow approach.


alter table Schema_name.Table_name move partition Partition_ name lob(Column_name) store as (tablespace Tablespace_name); 


Replace red marked names with Object names in your ENV. 

Schema_name = Schema of the table of which you want to move the Lob column to new Tablespace.
Table_Name = Table name of which you want to move the Lob column to new Tablespace.
Partition_name= Partition name of the Table if you just want to move column of a specific partition.
Tablespace_name= Name of the table space where you want to move the Lob column.


To check the tablespace name after column move user below.

select TABLE_NAME,COLUMN_NAME,PARTITION_NAME,LOB_PARTITION_NAME,TABLESPACE_NAME from  dba_lob_partitions where  table_name='TABLE_NAME';

Wednesday, 15 March 2017

Goldengate Memory Utilization - Script

Automated Script to get Goldengate process Memory Utilization. 

Below script is a Plug and Play tool for getting memory Utilization of Goldengate Process running on HP-UX or Linux Machine. 

For Creating Script in your Environment do vi GG_MemoUtilization.ksh copy and pest below code


#!/bin/ksh

###########################################################
# +----------------------------------------------------------------------------+
# | Technology : Oracle Goldengate                                                 |
# | Orther      : Kamlesh Parmar (Kamleshparmar21@gmail.com)       |
# | FILE          : GG_MemoUtilization.ksh                                         |
# | PURPOSE   : This Script is Useful to get the Memory Utilization of   |
# |               Goldengate Extract and Replicat Process                     |
# | PARAMETERS   : None                                                              |
# | EXAMPLE      : sh GG_MemoUtilization.ksh                                   |
# +----------------------------------------------------------------------------+
###########################################################

###############################
# determine the OS type
###############################
OSNAME=`uname`

case "$OSNAME" in
  "HP-UX")
    echo "OSNAME = $OSNAME"
    ;;
  "Linux")
    echo "OSNAME = $OSNAME"
    ;;
  "*")
    echo "This script has not been verified on $OSNAME"
    exit 1
    ;;
esac

###############################
# set the temp file
###############################
TMPFILE=/tmp/ggmem.tmp
if [ -f $TMPFILE ]
then
  rm -f $TMPFILE
fi

################################
# loop over the gg process types
################################
PROCESSES="extract replicat"

for PROCESS in $PROCESSES
do
FLAG=""
FLAG=`ps -ef | grep $PROCESS | grep -v grep`

if [ -z "$FLAG" ]
  then
    echo
    echo
    echo
    echo "#####################################"
    echo "#---No $PROCESS processes found-----#"
    echo "#####################################"
    echo
    echo
    echo
 else
    echo
    echo
    echo "###########################################################"
    echo "#-------Individual $PROCESS Process Memory Usage--------- #"
    echo "###########i###############################################"
    echo
    case "$OSNAME" in
      "HP-UX")
        UNIX95=1 ps -e -o user,pid,vsz,sz,etime,args | grep -w $PROCESS |grep -v grep > $TMPFILE
        cat $TMPFILE | grep $PROCESS | awk '{ printf "%3.4f %s\n" , $3/1024/1024,"GB   "$8}' | sort -r
        ;;
      "Linux")
        ps -C $PROCESS -O rss > $TMPFILE
        cat $TMPFILE | grep $PROCESS | awk '{print $2/1024/1024, "GB", $12}' | sort -k 2
        ;;
      "*")
        echo "This script has not been verified on $OSNAME"
        exit 1
        ;;
    esac


    echo
    echo
    echo
    echo "#####################################"
    echo "#---Total $PROCESS Process Usage----#"
    echo "#####################################"
    echo
    case "$OSNAME" in
      "HP-UX")
        cat $TMPFILE | grep $PROCESS | awk '{count ++; sum=sum+$3; } END \
          { print "Number of processes      =",count; \
          print "AVG Memory usage/process =",sum/1024/1024/count, "GB"; \
          print "Total memory usage       =", sum/1024/1024,   "GB"}'
        ;;
      "Linux")
        ps -C $PROCESS -O rss > $TMPFILE
        cat $TMPFILE | grep $PROCESS | awk '{count ++; sum=sum+$2; } END \
          { print "Number of processes      =",count; \
          print "AVG Memory usage/process =",sum/1024/1024/count, "GB"; \
          print "Total memory usage       =", sum/1024/1024,  " GB"}'
        ;;
      "*")
        echo "This script has not been verified on $OSNAME"
        exit 1
        ;;
    esac
    rm -f $TMPFILE
  fi
done
echo
echo
exit 0 

Memory Utilization of Goldengate Process

Why GG process consumes memory ?

The Oracle redo log files contain both committed as well as uncommitted changes but GoldenGate only replicates committed transactions. So it needs some kind of cache where it can store the operation of each transaction until it receives a commit or rollback for that transaction. This is particularly significant for both large as well as long-running transactions.
This cache is a virtual memory pool or global cache for all the extract and replicate processes and sub-pools are allocated for each Extract log reader thread or Replicate trail reader thread as well as dedicated sub-pools for holding large data like BLOBs.

Documentation states: “While the actual amount of physical memory that is used by any Oracle GoldenGate process is controlled by the operating system, the cache manager keeps an Oracle GoldenGate process working within the soft limit of its global cache size, only allocating virtual memory on demand.”


Parameters to control memory usage in GG

CACHEMGR CACHESIZE {size}
CACHEMGR CACHEDIRECTORY {path} {size}
CACHEMGR CACHEBUFFERSIZE {size}

The CACHEMGR parameter controls the amount of virtual memory and temporary disk space that is available for caching uncommitted transaction data.

The CACHEMGR CACHESIZE parameter controls the virtual memory allocations and in GoldenGate versions 11.2 onwards for a 64-bit system the CACHESIZE by default is 64 GB.
While the CACHESIZE parameter controls the Virtual Memory, if that is exceeded then GoldenGate will swap data to disk temporarily and that is by default being allocated in the dirtmp sub-directory of the Oracle GoldenGate installation directory.

The dirtmp location will contain the .cm files. The cache manager assumes that all of the free space on the file system is available and will use it to create the .cm files until it becomes full. To regulate this we can use the CACHEMGR CACHEDIRECTORY parameter and provide both a size as well assign a directory location where these .cm files will be created.

The sizes of the initial and incremental buffers are controlled by the CACHEBUFFERSIZE option of CACHEMGR.

To know the Memory Utilization of Goldengate Process in your Environment use below Automated Script

Automated Script to know Memory Utilization of Goldengate Process  

Thursday, 10 November 2016

ORA-01555 / ORA-600 | _ktb_debug_flags Parameter

I recently faced this issue in our production ENV. 

After doing a SwitchOver from Production to replica, Replica was facing frequent ORA-01555 error for lots of the Read only Queries. 

After Investigation found below error in alert log

ORA-01555 / ORA-600 [ktbdchk1: bad dscn] / ktbGetDependentScn / Dependent scn violations as the block ITL has higher COMMIT SCN than block SCN

This is a Oracle bug in 11.2 as per the oracle doc. 

Bug 22241601 ORA-600 [kdsgrp1] / ORA-1555 / ORA-600 [ktbdchk1: bad dscn] / ORA-600 [2663] due to Invalid Commit SCN in INDEX ( Doc ID 1608167.1 ).

As a solution had to set below parameter on Production and replica both.

alter system set "_ktb_debug_flags"=8;

didn't faced Problem after using this parameter  :) 

Monday, 17 October 2016

Supplemental Logging for GoldenGate

What is supplemental logging?
Redo log files are generally used for instance recovery and media recovery. The data required for instance recovery and media recovery is automatically recorded in the redo log files. However a redo log based application may require that the additional columns need to be logged into redo log files. The process of adding these additional columns into redo log files is called supplemental logging.
Supplemental logging is not the default behavior of oracle database. It has to be enabled manually after the database is created. You can enable the supplemental logging at two levels
  1. DATABASE LEVEL
  2. TABLE LEVEL

Why is supplemental logging needed?
When a particular column is updated at the source database table for a set of rows, the values in the column or columns are logged by default. When these values are moved to the destination side, to which rows does Oracle apply them, or how does Oracle identify the rows to be updated? Supplemental logging provides the answers to these questions.

What is the use of supplemental logging in replication?
Supplemental logging places additional column data into the redo log file whenever an UPDATE operation is performed. At the least, minimal database-level supplemental logging must be enabled for any Change Data Capture source database.
When Supplemental Logging is enabled, either some selected columns or all columns are specified for extra logging. They are called a supplemental log group and consist of nothing but a set of additional columns that are being logged.

When the supplemental logging is active on a database, the redo logs contain other columns from tables to uniquely identify a row. If the table has a primary key or unique index defined, the only columns involved in the primary key or unique index will be registered in the redo logs along with the actual column(s) that has changed. 
If the table does not have any primary keys or unique index defined, Oracle will write all scalar columns from the table to identify the row. This may significantly increase the size of redo logs and will impact the log apply services on the logical standby site.

Depending on the set of additional columns logged there are two types of supplemental log groups:
  1. Unconditional supplemental log group
  2. Conditional supplemental log group

1. UNCONDITIONAL SUPPLEMENTAL LOG GROUP:
The before-images of specified columns are logged any time a row is updated, regardless of whether the update affected any of the specified columns. This can be referred to as an ALWAYS log group.

 2. CONDITIONAL SUPPLEMENTAL LOG GROUP:
The before-images of all specified columns are logged only if at least one of the columns in the log group is updated.

DATABASE LEVEL SUPPLEMENTAL LOGGING
How to check supplemental logging is enabled or not?
SQL> SELECT supplemental_log_data_min FROM v$database;
How to enable supplemental logging at database level?
SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
How to disable supplemental logging at database level?
SQL> ALTER DATABASE DROP SUPPLEMENTAL LOG DATA;

TABLE LEVEL SUPPLEMENTAL LOGGING:
TABLE LEVEL UNCONDITIONAL SUPPLEMENTAL LOGGING: 
  • Primary Key columns
  • All columns
  • Selected columns
To specify an unconditional supplemental log group for PRIMARY KEY column(s):
SQL > ALTER TABLE SCOTT. EMP ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY) COLUMNS;
To specify an unconditional supplemental log group that includes ALL TABLE columns:
SQL > ALTER TABLE SCOTT.EMP ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS;
To specify an unconditional supplemental log group that includes SELECTED columns:
SQL> ALTER TABLE SCOTT.EMP ADD SUPPLEMENTAL LOG GROUP t1_g1 (C1,C2) ALWAYS;

TABLE LEVEL CONDITIONAL SUPPLEMENTAL LOGGING: 
  • Foreign key
  • Unique
  • Any Columns
To specify a conditional supplemental log group that includes all FOREIGN KEY columns:
SQL> ALTER TABLE SCOTT.DEPT ADD SUPPLEMENTAL LOG DATA (FOREIGN KEY) COLUMNS;
To specify a conditional supplemental log group for UNIQUE column(s) and/or BITMAP index column(s):
SQL > ALTER TABLE SCOTT.EMP ADD SUPPLEMENTAL LOG DATA (UNIQUE) COLUMNS;
To specify a conditional supplemental log group that includes ANY columns:
SQL>ALTER TABLE SCOTT.EMP ADD SUPPLEMENTAL LOG GROUP t1_g1 (c1,c3);

 To drop supplemental logging:
SQL > ALTER TABLE <TABLE NAME >DROP SUPPLEMENTAL LOG DATA (ALL) COLUMNS;
SQL>ALTER TABLE <TABLE NAME >DROP SUPPLEMENTAL LOG DATA (PRIMARY KEY) COLUMNS;
SQL> ALTER TABLE <TABLE NAME> DROP SUPPLEMENTAL LOG DATA (UNIQUE) COLUMNS;
SQL> ALTER TABLE <TABLE NAME> DROP SUPPLEMENTAL LOG DATA (FOREIGN KEY) COLUMNS;


MINIMUM LEVEL OF SUPPLEMENTAL LOGGING

Minimum level of supplemental logging that is required for Oracle Goldengate as per oracle documentation.

ALTER DATABASE ADD SUPPLEMENTAL LOG DATA

By default, Oracle only logs changed columns for update operations. Normally, this means that primary key columns are not logged during an update operation. However, Replicat requires the primary key columns in order to apply the update on the target system. The ADD TRANDATA command in GGSCI is used to cause Oracle to log primary key columns for all updates.

For Golden gate replication minimum level of supplemental logging require is at primary key level to uniquely identify each row for replication purpose.

Golden gate command
ADD TRANDATA scott.DEPT 

Actually enable supplemental logging at table level on primary key and running this command in the background
ALTER TABLE "SCOTT"."DEPT" ADD SUPPLEMENTAL LOG GROUP "GGS_DEPT_1668166" ("DEPT_ID") ALWAYS 

we have to enable supplemental logging twice as per my understanding because of below reasons.

1. From oracle 10.2 onward minimum level of supplemental logging at database level is required before enabling supplemental logging at table level.

2. Golden gate require minimum primary key supplemental logging which is expensive if enabled at database level when only one schema or few tables are configured for replication. 

Hence basic supplemental logging enable at database level and specific primary key level on table level via Golden gate.


VIEWS to Check Supplemental logging 
DBA_LOG_GROUPS
DBA_LOG_GROUP_COLUMNS