GoldenGate Discard file into Table : Ease of troubleshooting & Maintenance of discard History
In General, we would prefer to execute a simple query to identify why the replicat process has encountered an ABEND.
How can this be achieved ?
Just load the GoldenGate Discard file into Table of Database…..!!
GoldenGate discard file is a file that contains information about data that was unable to be applied during the data replication process. This can occur due to a variety of reasons, such as data type mismatches, primary key violations, or other data integrity issues. The discard file provides details on the specific data that was unable to be replicated, including the table name, row data, and error message. By reviewing the discard file, you can identify and troubleshoot issues with the data replication process.
With OCI GoldenGate’s UI functionality, you can only view the last 10 discards, However in some situation we might need to store these discards in a table for longer time and for future analysis, it is much more convenient to access the information this way instead of relying on the UI/CURL/Discard files stored on Disks.
To overcome and make our life simple, I have built a custom shell script to read the discard files and load the limited contents in to the database for quick troubleshooting.
How can this be achieved ?
Just load the GoldenGate Discard file into Table of Database…..!!
GoldenGate discard file is a file that contains information about data that was unable to be applied during the data replication process. This can occur due to a variety of reasons, such as data type mismatches, primary key violations, or other data integrity issues. The discard file provides details on the specific data that was unable to be replicated, including the table name, row data, and error message. By reviewing the discard file, you can identify and troubleshoot issues with the data replication process.
With OCI GoldenGate’s UI functionality, you can only view the last 10 discards, However in some situation we might need to store these discards in a table for longer time and for future analysis, it is much more convenient to access the information this way instead of relying on the UI/CURL/Discard files stored on Disks.
To overcome and make our life simple, I have built a custom shell script to read the discard files and load the limited contents in to the database for quick troubleshooting.
Sample Architecture
Prerequisites
- Running OCI GoldenGate Service / MSA GoldenGate on VM
- Adminclient installed on Virtual Machine that has access to OCI GoldenGate process. Download Adminclient from here.
- SQLPLUS Client has to be installed on VM.
- Bash & Shell capabilities.
- Target Database to store the information of Discard files.
DDL for Table
CREATE TABLE GGADMIN.DISCARD_TABLE
(ID VARCHAR2 (32) NOT NULL PRIMARY KEY,
TIME_STAMP VARCHAR2 (32),
REPLICAT_NAME VARCHAR2 (32),
DML_OPERATION VARCHAR2 (32),
TABLE_INFO CLOB,
ABEND_ERROR CLOB,
FULL_DISCARD CLOB);
Shell Script
USER=”ggadmin” —> GGADMIN Database username
PWD=”Password_123″ —> GGADMIN Database password
DBNAME=”atpdb_high” —> Connection string connection for Database. I am using Autonomous Database here
CURLUSER=”oggadmin” —> OCI GoldenGate username
CURLPASS=”Password_123″ —> This is the password to login to Goldengate
OCIGG_URL=”https://xyz123456.deployment.goldengate.us-ashburn-1.oci.oraclecloud.com” —> FQDN URL / IP Address
FILEPATH=”/DATA/OCIGG_FILES” —> Path to store the discard files in VM
REPNAME=”RPSWING” —> Add multiple replicat name with space
set TNS_ADMIN in the script
PWD=”Password_123″ —> GGADMIN Database password
DBNAME=”atpdb_high” —> Connection string connection for Database. I am using Autonomous Database here
CURLUSER=”oggadmin” —> OCI GoldenGate username
CURLPASS=”Password_123″ —> This is the password to login to Goldengate
OCIGG_URL=”https://xyz123456.deployment.goldengate.us-ashburn-1.oci.oraclecloud.com” —> FQDN URL / IP Address
FILEPATH=”/DATA/OCIGG_FILES” —> Path to store the discard files in VM
REPNAME=”RPSWING” —> Add multiple replicat name with space
set TNS_ADMIN in the script
Logic :
- Script spools out 2 discard files from CURL command i.e. n & n-1 discard files.
- Script checks the data has already been inserted into the table of database.
- If the data exist in the table it will ignore, if not it will insert the record.
- Key Columns of Comparison : TIME_STAMP, REPLICAT_NAME , DML_OPERATION
- You can create UNIQUE Index for all these 3 columns.
#!/bin/bash
USER="ggadmin"
PWD="Password_123"
DBNAME="atpdb_high"
CURLUSER="oggadmin"
CURLPASS="Password_123"
OCIGG_URL="https://xyz123456.deployment.goldengate.us-ashburn-1.oci.oraclecloud.com"
FILEPATH="/DATA/OCIGG_FILES"
REPNAME="RPSWING RPHIST"
dt=`date +\%Y-\%m-\%d-\%H-\%M-\%S`
##################################
export HOME=/home/opc
ORACLE_HOME=`cat $HOME/.bash_profile|grep $ORACLE_HOME|cut -d= -f2 | head -1`
export ORACLE_HOME
export TNS_ADMIN=$ORACLE_HOME/network/admin/ATP
###################################
if [[ -z "$ORACLE_HOME" ]]; then
echo "ORACLE_HOME path needs to be set in .bash_profile" 1>&2
exit 1
fi
if [[ -z "$FILEPATH" ]]; then
echo "FILEPATH needs to be set in the script" 1>&2
exit 1
fi
if [[ -z "$CURLUSER" ]]; then
echo "CURLUSER needs to be set in the script" 1>&2
exit 1
fi
if [[ -z "$OCIGG_URL" ]]; then
echo "OCIGG_URL needs to be set in the script" 1>&2
exit 1
fi
if [[ -z "$REPNAME" ]]; then
echo "REPLICAT NAME needs to be set in the script" 1>&2
exit 1
fi
PATH=$PATH:$ORACLE_HOME/bin
for p in $REPNAME
do
curl -s -u $CURLUSER:$CURLPASS -X GET $OCIGG_URL/services/v2/replicats/$p/info/reports/$p.dsc | jq > $FILEPATH/$p.out
#echo $FILEPATH/$p.out
curl -s -u $CURLUSER:$CURLPASS -X GET $OCIGG_URL/services/v2/replicats/$p/info/reports/"$p"0.dsc | jq > $FILEPATH/"$p"0.out
#echo $FILEPATH/"$p"0.out
done
RNAME=`awk '/lines/{y=1;next}y' $p.out | grep -oP '(?<=group )\w+'`
TABLE_INFO=`awk '/lines/{y=1;next}y' $p.out | grep "Problem replicating" | sed 's/\"//g' | sed 's/\,//g'`
ABEND_ERROR=`awk '/lines/{y=1;next}y' $p.out | grep Discarded | sed 's/\"//g' | sed 's/\,//g'`
FULL_DISCARD=`awk '/lines/{y=1;next}y' $p.out`
TIME_STAMP=`awk '/lines/{y=1;next}y' $p.out | grep -oP '(?<=opened: ).*' | tr -d ',"'`
#echo $TIME_STAMP
if awk '/lines/{y=1;next}y' $p.out | grep -oh "\w*update\w*" ; then
DML_OP=UPDATE
elif
awk '/lines/{y=1;next}y' $p.out | grep -oh "\w*delete\w*"; then
DML_OP=DELETE
elif
awk '/lines/{y=1;next}y' $p.out | grep -oh "\w*insert\w*"; then
DML_OP=INSERT
fi
DB_VALUES=`$ORACLE_HOME/bin/sqlplus -s /nolog <
Execution :
./Discard_Table.sh
Recommendation is to set up a cron job to execute this script every 2 or 5 minutes once.
Crontab Example : */5* * * * * /scripts/Discard_Table.sh >> /dev/null
./Discard_Table.sh
Recommendation is to set up a cron job to execute this script every 2 or 5 minutes once.
Crontab Example : */5* * * * * /scripts/Discard_Table.sh >> /dev/null
OUTPUT
select * from GGADMIN.DISCARD_TABLE;
Note : There is always scope for improvement in this code, and it can be customized further depending on your environment. If you encounter any issues with the script, please reach out to me through the comment section, and I will endeavor to improve and fix it.
More information about the discard files can be found here.
More information about the discard files can be found here.
Hope you found this article useful.
Disclaimer: The views expressed on this document are my own and do not necessarily reflect the views of Oracle..
Disclaimer: The views expressed on this document are my own and do not necessarily reflect the views of Oracle..